SABnzbd-0.7.20/ABOUT.txt0000644000000000000000000000405012433712601014636 0ustar00usergroup00000000000000******************************************* *** This is SABnzbd 0.7.20 *** ******************************************* SABnzbd is an open-source cross-platform binary newsreader. It simplifies the process of downloading from Usenet dramatically, thanks to its friendly web-based user interface and advanced built-in post-processing options that automatically verify, repair, extract and clean up posts downloaded from Usenet. SABnzbd also has a fully customizable user interface, and offers a complete API for third-party applications to hook into. There is an extensive Wiki on the use of SABnzbd. http://wiki.sabnzbd.org/ IMPORTANT INFORMATION about release 0.7.0: http://wiki.sabnzbd.org/introducing-0-7-0 Please also read the file "ISSUES.txt" ******************************************* *** Upgrading from 0.6.x *** ******************************************* Stop SABnzbd. Install new version Start SABnzbd. ******************************************* *** Upgrading from 0.5.x *** ******************************************* Stop SABnzbd. Uninstall current version, keeping the data. Install new version Start SABnzbd. The organization of the download queue is different from 0.5.x. 0.6.x will finish downloading an existing queue, but you cannot go back to an older version without losing your queue. Also, your sabnzbd.ini file will be upgraded, making it incompatible with release 0.5.x ******************************************* *** Upgrading from 0.4.x *** ******************************************* >>>>> PLEASE DOWNLOAD YOUR CURRENT QUEUE BEFORE UPGRADING <<<<<< When upgrading from a 0.4.x release such as 0.4.12 your old settings will be kept. You will however be given a fresh queue and history. If you have items in your queue from the older version of SABnzbd, you can either re-import the nzb files if you kept an nzb backup folder, or temporarily go back to 0.4.x until your queue is complete. The history is now stored in a better format meaning future upgrades should be backwards compatible. SABnzbd-0.7.20/CHANGELOG.txt0000644000000000000000000007553612433712601015274 0ustar00usergroup00000000000000------------------------------------------------------------------------------- 0.7.20 by The SABnzbd-Team ------------------------------------------------------------------------------- - Make sure that Rating support is suppressed completely when disabled. ------------------------------------------------------------------------------- 0.7.20RC2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Update unrar for (Snow)Leopard on Intel to 5.11 - Logging of the Pystone performance of the system ------------------------------------------------------------------------------- 0.7.20RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - OSX unrar now really updated to 5.11 - API call "Retry" now returns new job id - Support for NZB meta field 'x-rating-host' - Fix email test issue - Support of OSX Yosemite "Dark Mode" ------------------------------------------------------------------------------- 0.7.19 by The SABnzbd-Team ------------------------------------------------------------------------------- - Support double quotes to delineate parameters in category match lists. - When a comma is present in a file name, quotes are needed when passed to a user script - The after-unrar-check needs to take the "flat_unpack" option into account - When sanitizing names, preserve "." and ".." elements in paths ------------------------------------------------------------------------------- 0.7.19RC4 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix damaging of job's destination path on Windows ------------------------------------------------------------------------------- 0.7.19RC3 by The SABnzbd-Team ------------------------------------------------------------------------------- - Improve password trial when the system uses an older unrar tool ------------------------------------------------------------------------------- 0.7.19RC2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Make matching of SFV file against RAR-sets case-insensitive - Make sure final destination path is always sanitized and trimmed - Improve "check for unwanted extensions" - Upgrade unrar to version 5.11 (OSX and Windows) - Limit article cache to 1G to prevent a memory size bug in the _yenc module - Fix a number of problems with embedded passwords and folder size trimming - Allow "float" timestamps in RSS feeds - Expose 'rating_host' to Config->Special - Add Finnish translation ------------------------------------------------------------------------------- 0.7.19RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - More oznzb filtering - Fix OSX notification center problem - Fix sort order of RSS feeds - Prevent multiple pauses in "unwanted extensions" option - Change renaming scheme for duplicate files - Fix sorting of the queue ------------------------------------------------------------------------------- 0.7.18 by The SABnzbd-Team ------------------------------------------------------------------------------- - Update translations ------------------------------------------------------------------------------- 0.7.18RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Support for X-Failure header - Support for detecting unwanted extensions inside RAR files - Using priority Force will override duplicate detection - Notification: Respect NotifyOSD-preference and allow testing of values from UI - Prevent pseudo error message when testing "Notification Center" - Testing email based on values in UI instead of stored config - Don't trim file names when renaming them (so revert to old behavior) - Add "pause_pp" to the API - Pause/abort on encryption failed when pre-check was active - Also remove colons ":" with option sanitize_safe - Update DMG template - Fix potential crash when unpacking due to unset variable - Fix problem of cookie interference with other apps - Add API function server_stats - Support password embedding in file detail page and AddNZB dialog - Pause/Remove posts when unwanted extensions are detected (like .exe) - Fix issue with some RAR file sets leading to Windows "87" error - Handle 5xx RSS feed error messages ------------------------------------------------------------------------------- 0.7.17Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Implement "retry-after" header to support rate-limiting - Update OSX image to show Mavericks support ------------------------------------------------------------------------------- 0.7.17RC2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Support UNC paths in Sort expressions (Windows) - URL in the queue should not show up "sanitized" - Fix shutdown issue in PP queue - Allow "Force" to be set as priority in files overview - Special option "warn_dupl_jobs" to suppress/enable warnings for duplicate jobs - Fix problem with "sanitize" in "renamer" - Add (partial) RAR5 support - Fix some more password-in-filename issues - Prevent unwanted change of queue order after editing job details - Add password entry boxes in smpl and Classic skins - Prevent unrar zombies on some systems ------------------------------------------------------------------------------- 0.7.17RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix bug in rating system - Fix multiple encryption password issues - Allow Default category to be picked in Multi-Ops - Allow "force" prio to be picked in NZO page - Prevent PP queue timeout construction from keeping the CPU awake. - Special option "flat_unpack" ------------------------------------------------------------------------------- 0.7.17Beta2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix regression errors in Beta1 ------------------------------------------------------------------------------- 0.7.17Beta1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Add command line option --pidfile - Another fix for false encryption reports - Fix issue with OSX Mavericks Notification Center - Add support for 'x-dnzb-propername', 'x-dnzb-episodename', 'x-dnzb-year' in meta-data of NZB. To be used in TV Sorting - Add OZnzb features need to be enabled in config ->switches - Add integration with OZnzb indexer enhanced functionality, allows user access to ratings and reporting directly from SABnzbd interface. - Add automatic feedback to OZnzb on failed downloads (if enabled) - Add X-DNZB-Failure and X-DNZB-Details support - Fix issue with passwords embedded in file names - Updated translations ------------------------------------------------------------------------------- 0.7.16Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix Config->Special UI crash ------------------------------------------------------------------------------- 0.7.15Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix false encryption alarms for some posts - Add "password" dialog to Plush's job details page - Add special "sanitize_safe" to remove bad Windows characters on other platforms - Remove "news" section from Config skin - Fix for faulty par2cmdline on some embbeded Unix systems - Add GUID fields to the History RSS feed. ------------------------------------------------------------------------------- 0.7.14Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Another encryption detection fix (special case) - Missing mini-par2 sometimes prevents the other par2 files from being downloaded. - Make sure even invalid RAR files are fed to unrar and handle its reporting. ------------------------------------------------------------------------------- 0.7.13Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Another encryption detection fix - Special option "enable_recursion" to control recursive unpacking - When post has just one par2 set, use wildcard so that all files are used - Accept partial par2 file when only one is available - Accept "nzbname" parameter in api-call "add url" even when a ZIP file is retrieved. ------------------------------------------------------------------------------- 0.7.12Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix issue in encryption detection - Don't try to "join" a single X.000 file - Fix memory overflow caused by very large files to be joined - Make name sorting of the queue case-insensitive - Save data to disk after changing job password or other attributes - Add "resume_pp" entry to Plush pull-down menu when pause_pp event is scheduled - Deploy "abort when completion not possible" method also in pre-download check ------------------------------------------------------------------------------- 0.7.11Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Bad articles from some servers were accepted as valid data - Show warning when the decoder encounters I/O errors - Generic Sort failed to rename files when an extra folder level was present in the RAR files - Obfuscated file name support caused regular NZBs to verify slower ------------------------------------------------------------------------------- 0.7.10Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Disable obsolete newzbin bookmark readout - Show speed when downloading in Forced mode while paused - Plush History icons repair and unpack were swapped - Try to repair rar/par sets with obfuscated names - Reset "today" byte counters at midnight even when idle - Display next RSS scan moment in Cfg->RSS - An email about a failed should say that the download failed - Report errors coming from fully encrypted rar files - Accept NNTP error 400 without "too many connection" clues as a transient error. - Accept %fn (next to %fn.%ext) as end parameter in sorting strings. ------------------------------------------------------------------------------- 0.7.9Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix fatal error in decoder when encountering a malformed article - Fix compatibility with free.xsusenet.com - Small fix in smpl-black CSS ------------------------------------------------------------------------------- 0.7.8Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix problem with %fn substitution in Sorting - Add special "wait_for_dfolder", enables waiting for external temp download folder - Work-around for servers that do not support STAT command - Removed articles are now listed seperately in download report - Add "abort" option to encryption detection - Fix missing Retry link for "Out of retention" jobs. - Option to abort download when it is clear that not enough data is available - Support "nzbname" parameter in addfile/addlocalfile api calls for ZIP files with a single NZB - Support NZB-1.1 meta data "password" and "category" - Don't retry an empty but correct NZB from an indexer ------------------------------------------------------------------------------- 0.7.7Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Windows/OSX: Update unrar to 4.20 - Fix some issues with orphaned items - Generic sort didn't always rename media files in multi-part jobs properly - Optional web-ui watchdog - Always show RSS items in the same order as the original RSS feed - Remove unusable folders from folder selector (Plush skin) - Remove newzbin support ------------------------------------------------------------------------------- 0.7.6Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Recursive scanning when re-queuing downloaded NZB files - Log "User-Agent" header of API calls ------------------------------------------------------------------------------- 0.7.6Beta2 by The SABnzbd-Team ------------------------------------------------------------------------------- - A damaged smallest par2 can block fetching of more par2 files - Fix evaluation of schedules at startup - Make check for running SABnzbd instance more robust ------------------------------------------------------------------------------- 0.7.6Beta1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Handle par2 sets that were renamed after creation - Prevent blocking assembly of completed files, ( this resulted in excessive CPU and memory usage) - Fix speed issues with some Usenet servers due to unreachable IPv6 addresses - Fix issues with SFV-base checks - Prevent crash on Unix-Pythons that don't have the os.getloadavg() function - Successfully pre-checked job lost its attributes when those were changed during check - Remove version check when looking for a running instance of SABnzbd ------------------------------------------------------------------------------- 0.7.5Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Add missing %dn formula to Generic Sort - Improve RSS logging ------------------------------------------------------------------------------- 0.7.5RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Prevent stuck jobs at end of pre-check. - Fix issues with accented and special characters in names of downloaded files. - Adjust nzbmatrix category table. - Add 'prio_sort_list' special - Add special option 'empty_postproc'. - Prevent CherryPy crash when reading a cookie from another app which has a non-standard name. - Prevent crash when trying to open non-existing "complete" folder from Windows System-tray icon. - Fix problem with "Read" button when RSS feed name contains "&". - Prevent unusual SFV files from crashing post-processing. - OSX: Retina compatible menu-bar icons. - Don't show speed and ETA when download is paused during post-processing - Prevent soft-crash when api-function "addfile" is called without parameters. - Add news channel frame ------------------------------------------------------------------------------- 0.7.4Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Pre-queue script no longer got the show/season/episode information. - Prevent crash on startup when a fully downloaded job is still in download queue. - New RSS feed should no longer be considered new after first, but empty readout. - Make "auth" call backward-compatible with 0.6.x releases. - Config->Notifications: email and growl server addresses should not be marked as "url" type. - OSX: fix top menu queue info so that it shows total queue size ------------------------------------------------------------------------------- 0.7.4RC2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Pre-check failed to consider extra par2 files - Fixed unjustified warning that can occur with OSX Growl 2.0 - Show memory usage on Linux systems - Fix incorrect end-of-month quota reset - Fix UI refresh issue when using Safari on iOS6 ------------------------------------------------------------------------------- 0.7.4RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Remove potential queue stalling when downloading extra par2 files - Make Windows version less eager to use par2-classic - Fixed DMG images - Add missing encoding directive to Plush and Classic skins - Prevent oversized data in API-call "history" ------------------------------------------------------------------------------- 0.7.4Beta3 by The SABnzbd-Team ------------------------------------------------------------------------------- - All three OSX build in one DMG again - Minor bugfixes ------------------------------------------------------------------------------- 0.7.4Beta2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix failure to fetch more par2-files for posts with badly formatted subject lines - After successful pre-check, preserve a job's position in the queue - Restore SABnzbd icon for Growl - Fix "check new releases" option in Config skin - Separate DMG files for OSX Leopard/SL, Lion and MLion ------------------------------------------------------------------------------- 0.7.4Beta1 by The SABnzbd-Team ------------------------------------------------------------------------------- - OSX Mountain Lion Notification Center support - OSX Mountain Lion improved "keep awake" support - OSX: separate builds: one for Mountain Lion and one for all others - OSX removed 64bit code - Scheduler: action can now run on multiple weekdays - Scheduler: add "remove failed jobs" action - Special option: rss_odd_titles (see Wiki) - Support for HTTPS chain files (needed when you buy your own certificate) - Prevent jobs from showing up in queue and history simultaneously - Add parameter 'pp_active' to history elements in qstatus API call - Fix some minor par2 handling bugs - Prevent potential crash when an actively downloading job is deleted from the queue - Special option: 'overwrite_files' (See Wiki) - Don't try an SFV check when a retried job was already successfully verified by par2 - Enable compression of API call results - Log failed attempts to log in to the Web UI - A job with "forced" priority should keep that when fetching more par2 files - Updated translations ------------------------------------------------------------------------------- 0.7.3Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Rename Special "random_server_ip" to "randomize_server_ip" so that we can force the default to "Off". "On" kills speed on some servers. - Ignore pseudo NZB files that start with a period in the name - SFV failure now listed in History instead of issuing warnings - Translation updates - "502" errors about payments/credits will now block a server ------------------------------------------------------------------------------- 0.7.3Beta2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Try to keep OSX Mountain Lion awake as long as downloading/postprocessing runs - Prevent queue deadlock in case of fatally damaged par2 files - Add RSS filter-enable checkboxes to Plush, Smpl and Classic skins - Fix problem with saving modified paramters of an already enabled server - Extend "check new release" option with test releases ------------------------------------------------------------------------------- 0.7.3Beta1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Correct several errors in Sort function - Improve organization of Config->Servers - Support for nzbxxx.com - Make detection of samples less aggressive - Some minor corrections ------------------------------------------------------------------------------- 0.7.2Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix for NZB-icon issue when 0.7.0 was previously installed - Check validity of totals9.sab file - Fix startup problem when localhost has unexpected order of IP addresses ------------------------------------------------------------------------------- 0.7.2RC2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Improve support for nzbsrus.com - Don't try to show NZB age when not known yet - Prevent systems with unresolvable hostnames from always using 0.0.0.0 ------------------------------------------------------------------------------- 0.7.2RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix fatal error in nzbsrus.com support - Initial "quota left" was not set correctly when enabling quota - Report incorrect RSS filter expressions (instead of aborting analysis) - Improve detection of invalid articles (so that backup server will be tried) - Windows installer: improve NZB association so that a reboot isn't needed - Windows installer: don't remove settimngs by default when uninstalling - Fix sorting of rar files in job so that .rar preceeds .r00 ------------------------------------------------------------------------------- 0.7.1Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Disable VC90 check in Windows Installer as long as we're still on Python 2.5 - Windows: make sure \\server\share notation is never seen as a relative path ------------------------------------------------------------------------------- 0.7.1RC5 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix signing of OSX DMG - Fix endless par2-fetch loop after retrying failed job - Don't send "bad fetch" email when emailing is off - Add some support for nzbrus.com's non-VIP limiting ------------------------------------------------------------------------------- 0.7.1RC4 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix failure to grab NZBs from indexers that send compressed files. ------------------------------------------------------------------------------- 0.7.1RC3 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fixed stalling par2 fetches (after first verification run) - Fixed retry behaviour of NZB fetching from URL and add handling of nzbsrus.com error codes - Make sure that all malformed articles are retried on another server - Add no_ipv6 option that suppresses listing on ::1 (to be used if your system cannot handle that) - Prevent crash in QuickCheck when expected par2 file wasn't downloaded - Verification/repair would not be executed properly when one more RAR files missed their first article. - API calls "addurl" and "addid" (newzbin) can be used interchangeably (Fixes a problem in Qouch) ------------------------------------------------------------------------------- 0.7.1RC2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Improved backup of sabnzbd.ini file Will use backup when original is gone or become corrupt - Windows: Using ::1 as single webhost address would start IE instead of default browser ------------------------------------------------------------------------------- 0.7.1RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Plush skin: fix problems with pull-down menus in Mobile Safari - On some Linux and OSX systems using localhost would still make SABnzbd give access to other computers - Windows: the installer did not set an icon when associating NZB files with SABnzbd - Fix problem that the Opera browser had with Config->Servers - Retry a few times when accessing a mounted drive to create the final destination folder - Reduce load caused by WinTray and OSX topmenu ------------------------------------------------------------------------------- 0.7.0Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Updated translations ------------------------------------------------------------------------------- 0.7.0RC2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Suppress permission errors on paths containing ".AppleDouble" or ".DS_Store" (Required for NAS systems that support Apple AFP shares) - OSX/Windows: Set article cache to 200M when not already set. - Pre-check: lower default minimum completion rate to 100.2% ------------------------------------------------------------------------------- 0.7.0RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix for rare crash in par2 fetching - Another /nomedia fix - Quota reset wasn't done when quota-reset-time was passed while SABnzbd wasn't running. - Pre-check: required ratio for NZB without par2 files should be 100% and not the "safe" ratio ------------------------------------------------------------------------------- 0.7.0Beta8 by The SABnzbd-Team ------------------------------------------------------------------------------- - Disabled the .nomedia marker file feature. Those who want to try it, use the "nomedia_marker" setting in Config->Special It remains an experimental feature without guarantees - Add missing info in email about failed pre-check - Updated translations ------------------------------------------------------------------------------- 0.7.0Beta7 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix for .nomedia files not being deleted - Fix NZB re-queueing (due to .nomedia remaining) - Polish was missing in Windows installer and Dutch was incorrect - When Sort renames auxillirary files, it should disregard case - Fix crash in Wizard on some Linux systems ------------------------------------------------------------------------------- 0.7.0Beta6 by The SABnzbd-Team ------------------------------------------------------------------------------- - Upgrade unzip for Windows to 6.00 (supports ZIPs above 2G) - Lower threshold for pre-check to 100.5% - Fix removal of .nomedia file when using Sorting - Add Polish translation (using reduced character set) - Extension-based cleanup list now also removes extension-only files like ".sfv". - Several small issues ------------------------------------------------------------------------------- 0.7.0Beta5 by The SABnzbd-Team ------------------------------------------------------------------------------- - Solved serious connection problem with some providers - Windows Tray has the "restart" entries no under a Troubleshoot menu - Fix newzbin entries in History's "Source" field - During unpacking the destination folder will contain a ".nomedia" file which will keep mediaplayers temporarily from indexing - Pre-check jobs now require 101% completion rate (with a "special" parameter) - Unified OSX DMG ------------------------------------------------------------------------------- 0.7.0Beta4 by The SABnzbd-Team ------------------------------------------------------------------------------- - Add Portuguese (Brazil) language - Updated translations - Some odd NZB files led to blank initial filenames in file overview - Jobs that have 99.91%-99.99% completion rate should not be rounded to 100.0% - Windows Tray icon now has entry to show "complete" folder - Some minor fixes in code and Config skin - Individual RSS filter toggle ------------------------------------------------------------------------------- 0.7.0Beta3 by The SABnzbd-Team ------------------------------------------------------------------------------- - OSX/Linux: permissions are now also applied to the "temporary download folder" - Fix some issues in the Config skin. - The default for "apply max retries only on optional servers" is now 0, thus enabling the new anti-deadlock behaviour for all servers - Fix incompatibility with nzbsa.co.za indexer - Log all API calls (in debug mode) - Restore Python2.5 compatibility in growler.py - After a language change, register again with Growl - Clean up the api-call auth. It will now give preference to 'apikey'. - Fix detection of retry-able history entries for case-insensitive file systems. - API-calls "addfile" and "addlocalfile" returned an incorrect status value. - Add support for the peculiar Usenet provider "free.xsusenet.com". - OSX menu now uses the same formatting for speed as the skins. - Accept multiple items in API-calls "addurl" and "addid". The "name" and "nzbname" keywords can be repeated. ------------------------------------------------------------------------------- 0.7.0Beta2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix behavior when using host address 0.0.0.0 on a system that doesn't resolve localhost properly - Add Spanish translation ------------------------------------------------------------------------------- 0.7.0Beta1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Updated nzbmatrix categories - "Special" option allows incomplete/partial NZB files - Forbid "complete" being a subfolder of "incomplete" ------------------------------------------------------------------------------- 0.7.0Alpha3 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix failing join-by-par2 - Prevent API crash when deleting non-existing history item - Prevent UI crash message when looking at NZB details page of finished job - Config skin: fix path complettion in Config->Folders - Config skin: fixes to support "hide behind proxy" - Keep using unrar 4.10 for OSX Leopard and older, due to PPC support ------------------------------------------------------------------------------- 0.7.0Alpha2 by The SABnzbd-Team ------------------------------------------------------------------------------- - Fix disabled options in Config skin - Remove flags from the Wizard and Config skin - Replace real spaces in RSS-urls with %20 - Prevent double entries in History's "Source" section - Prevent crash when OSDNotify doesn't work properly - Small improvents in Windows installer ------------------------------------------------------------------------------- 0.7.0Alpha1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Not tracked ------------------------------------------------------------------------------- 0.6.15Final by The SABnzbd-Team ------------------------------------------------------------------------------- - Flag post-processing as failed when files cannot be moved/copied to destination - Fixed another newzbin link ------------------------------------------------------------------------------- 0.6.15RC1 by The SABnzbd-Team ------------------------------------------------------------------------------- - Change newzbin URL - Prevent setting watched-folder speed to 0 (while having no watched-folder) from triggering an inifinite loop. - Move "locale" construction from Plush skin to Python code. Some embedded Linux platforms show unstable behavior with the original construction. - Extend OSX menu with troubleshooting options - Add trailing slashes to internal Plush paths to support reverse proxies better. - Ignore whitespace around regular expressions in RSS filters. - Prevent crash on restoring URL-fetches when using --repair-all option - Fix "Repair" button on smpl Connection page. Current path fails when using a reverse proxy - Suppress "incompatible feed" error when doing a scheduled/automatic RSS read-out. - Add special setting to use "pickle" library instead of cPickle. SABnzbd-0.7.20/COPYRIGHT.txt0000644000000000000000000000277412433712601015347 0ustar00usergroup00000000000000 (c) Copyright 2007-2014 by "The SABnzbd-team" The SABnzbd-team is: Active team: ShyPike inpheaux zoggy OZnzb-dev Sleeping members sw1tch pairofdimes rAf Honorary member (and original author) Gregor Kaufmann The main contributors and moderators of the translations Danish: Rene (nordjyden6) Dutch: ShyPike French : rAf and Fox Ace German: Severin Heiniger Norwegian: Protx Romanian: nicusor Serbian: Ozzii Swedish: Malmis Spanish: Syquus Portuguese (Brazil): lrrosa Russian: Pavel Maryanov Polish: Tomasz 'Zen' Napierala 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See accompanying files GPL2.txt and GPL3.txt. SABnzbd-0.7.20/GPL2.txt0000644000000000000000000004310612433712601014475 0ustar00usergroup00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. SABnzbd-0.7.20/GPL3.txt0000644000000000000000000010451312433712601014476 0ustar00usergroup00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . SABnzbd-0.7.20/INSTALL.txt0000644000000000000000000001331312433712601015074 0ustar00usergroup00000000000000 SABnzbd 0.7.20 ------------------------------------------------------------------------------- 0) LICENSE ------------------------------------------------------------------------------- (c) Copyright 2007-2014 by "The SABnzbd-team" 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ------------------------------------------------------------------------------- 1) INSTALL with the Win32 installer ------------------------------------------------------------------------------- Just run the downloaded EXE file and the installer will start. It's just a simple standard installer. After installaton, find the SABnzbd program in the Start menu and start it. Within 5-10 seconds your web browser will start and show the user interface. Use the "Help" button in the web-interface to be directed to the Help Wiki. ------------------------------------------------------------------------------- 2) INSTALL pre-built Win32 binaries ------------------------------------------------------------------------------- Unzip pre-built version to any folder of your liking. Start the SABnzbd.exe program. Within 5-10 seconds your web browser will start and show the user interface. Use the "Help" button in the web-interface to be directed to the Help Wiki. ------------------------------------------------------------------------------- 3) INSTALL pre-built OSX binaries ------------------------------------------------------------------------------- Download the DMG file, mount and drag the SABnzbd icon to Programs. Just like you do with so many apps. Make sure you pick the right folder, depending on your OSX version. ------------------------------------------------------------------------------- 4) INSTALL with only sources ------------------------------------------------------------------------------- You need to have Python installed plus some non-standard Python modules and a few tools. Unix/Linux/OSX Python-2.5, 2.6 or 2.7 http://www.python.org OSX Leopard/SnowLeopard Python 2.6 http://www.activestate.com OSX Lion/MountainLion Apple Python 2.7 Included in OSX (default) Windows Python-2.7.latest http://www.activestate.com Essential modules cheetah-2.0.1+ http://www.cheetahtemplate.org/ (or use "pypm install cheetah") par2cmdline >= 0.4 http://parchive.sourceforge.net/ http://chuchusoft.com/par2_tbb/index.html (multi-core) Optional modules unrar >= 3.90+ http://www.rarlab.com/rar_add.htm unzip >= 5.52 http://www.info-zip.org/ yenc module >= 0.3 http://sabnzbd.sourceforge.net/yenc-0.3.tar.gz http://sabnzbd.sourceforge.net/yenc-0.3-w32fixed.zip (Win32-only) Optional modules Windows pyopenssl >= 0.11 http://pypi.python.org/pypi/pyOpenSSL (Binaries, including the OpenSSL libraries) Optional modules Unix/Linux/OSX pyopenssl >= 0.11 http://pypi.python.org/pypi/pyOpenSSL openssl => v0.9.8g+ http://www.openssl.org/ Make sure the OpenSSL libraries match with PyOpenSSL pynotify Should be part of GTK for Python support on Debian/Ubuntu If not, you cannot use the NotifyOSD feature. Embedded modules (only use the included version) CherryPy-3.2 rev2138 with patches http://www.cherrypy.org Unpack the ZIP-file containing the SABnzbd sources to any folder of your liking. If you want multiple languages, you need to compile the translations. Start this from a shell terminal (or command prompt): python tools/make_mo.py Start this from a shell terminal (or command prompt): python SABnzbd.py Within 5-10 seconds your web browser will start and show the user interface. Use the "Help" button in the web-interface to be directed to the Help Wiki. ------------------------------------------------------------------------------- 5) TROUBLESHOOTING ------------------------------------------------------------------------------- Your browser may start up with just an error page. This means that SABnzbd cannot use the default port 8080 to run its web-server on. Try to use another port, you'll need to use the a command window: SABnzbd.exe -s localhost:7777 or python SABnzbd.py -s localhost:7777 You may of course try other port numbers too. For troubleshooting you can use the program SABnzbd-console.exe. This will show a black window where logging information will be shown. This may help you solve problems easier. ------------------------------------------------------------------------------- 6) MORE INFORMATION ------------------------------------------------------------------------------- Visit the WIKI site: http://wiki.sabnzbd.org/ ------------------------------------------------------------------------------- 7) CREDITS ------------------------------------------------------------------------------- Several parts of SABnzbd were built by other people, illustrating the wonderful world of Free Open Source Software. See the licences folder of the main program and of the skin folders. SABnzbd-0.7.20/ISSUES.txt0000644000000000000000000001132312433712601015000 0ustar00usergroup00000000000000******************************************* *** Known issues *** ******************************************* - To prevent unexpectedly large NZBs from eating your download quota you can set the option 'size_limit' on the Config->Special page. Any NZB larger than this size will be set to paused and get a low priority. - When par2 or unrar hang up, never just stop SABnzbd. Instead use your operating system's task manager to stop the par2 or unrar program. Forcing SABnzbd to quit may damage your queues. Windows-only: If you keep having trouble with par2 multicore you can disable it in Config->Switches. This will force the use of the old and tried, but slower par2-classic program. - A bug in Windows 7 may cause severe memory leaks when you use SABnzbd in combination with some virus scanners and firewals. Install this hotfix: Description: http://support.microsoft.com/kb/979223/en-us Download location: http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=979223&kbln=en-us - Windows cannot handle pathnames longer than 254 characters. Currently, SABnzbd doesn't handle this problem gracefully. We have added the INI-only option "folder_length_max" in which you can set a maximum folder name size. For Windows the default is 128 and for others 256. A quite safe value for Windows would be 64. SABnzbd will take care of overlapping names. See: http://wiki.sabnzbd.org/configure-special-0-7 - Some Usenet servers have intermittent login (or other) problems. For these the server blocking method is not very favourable. There is an INI-only option that will limit blocks to 1 minute. no_penalties = 1 See: http://wiki.sabnzbd.org/configure-special-0-7 - Some third-party utilties try to probe SABnzbd API in such a way that you will often see warnings about unauthenticated access. If you are sure these probes are harmless, you can suppress the warnings by setting the option "api_warnings" to 0. See: http://wiki.sabnzbd.org/configure-special-0-7 - On OSX you may encounter downloaded files with foreign characters. The par2 repair may fail when the files were created on a Windows system. The problem is caused by the PAR2 utility and we cannot fix this now. This does not apply to files inside RAR files. - On Linux when you download files they may have the wrong character encoding. You will see this only when downloaded files contain accented characters. You need to fix it yourself by running the convmv utility (availaible for most Linux platforms). Possible the file system override setting 'fsys_type' might be solve things: See: http://wiki.sabnzbd.org/configure-special-0-7 - The "Watched Folder" sometimes fails to delete the NZB files it has processed. This happens when other software still accesses these files. Some third-party utilities supporting SABnzbd are known to do this. We cannot solve this problem, because the Operating System (read Windows) prevents the removal. - Memory usage can sometimes have high peaks. This makes using SABnzbd on very low memory systems (e.g. a NAS device or a router) a challenge. - SABnzbd is not compatible with some software firewall versions. The Mircosoft Windows Firewall works fine, but remember to tell this firewall that SABnzbd is allowed to talk to other computers. - When SABnzbd cannot send nofication emails, check your virus scanner, firewall or security suite. It may be blocking outgoing email. - When you are using external drives or network shares on OSX or Linux make sure that the drives are mounted. The operating system wil simply redirect your files to alternative locations. You may have trouble finding the files when mounting the drive later. On OSX, SABnzbd will not create new folders in /Volumes. The result will be a failed job that can be retried once the volume has been mounted. - If you use a mounted drive as "temporary download folder", it must be present when SABnzbd starts up. If not, SABnzbd will use the default location. You can make SABnzbd wait for a mount of the "temporary download folder" by setting Config->Special->wait_for_dfolder to 1. SABnzbd will appear to hang until the drive is mounted. - On some operating systems it looks like there is a problem with one of the standard Python libraries. It is possible that you get errors about saving admin files and even unexplained crashes. If so, you can enable the option for the alternative library. It has the same functionality, but is slower. We've had reports about this issue on non-mainstream Linux platforms. - OpenElec - Squeeze Linux There is a "special" option that will allow you to select an alternative library. use_pickle = 1 See: http://wiki.sabnzbd.org/configure-special-0-7 SABnzbd-0.7.20/PKG-INFO0000644000000000000000000000043612433712535014332 0ustar00usergroup00000000000000Metadata-Version: 1.0 Name: SABnzbd Version: 0.7.20 Summary: SABnzbd-0.7.20 Home-page: http://sabnzbd.org Author: The SABnzbd Team Author-email: team@sabnzbd.org License: GNU General Public License 2 (GPL2 or later) Description: Fully automated Usenet Binary Downloader Platform: posix SABnzbd-0.7.20/README.txt0000644000000000000000000000473012433712535014734 0ustar00usergroup00000000000000Release Notes - SABnzbd 0.7.20 ================================ ## Features - Support of OSX Yosemite "Dark Mode" - API call "Retry" now returns new job id (supporting nzbdrone) ## Bug fixes - OSX unrar now really updated to 5.11 for Lion and higher - unrar is now updated to 5.11 for Intel systems running (Snow)Leopard - (Snow)Leopard on PPC still only has unrar 4.01, no new versions from rarlabs - Fix email test issue ## What's new in 0.7.0 - Download quota management - Windows: simple system tray menu - Multi-platform Growl support - NotifyOSD support for Linux distros that have it - Option to set maximum number of retries for servers (prevents deadlock) - Pre-download check to estimate completeness (reliability is limited) - Prevent partial downloading of par2 files that are not needed yet - Config->Special for settings previously only available in the sabnzbd.ini file - For Usenet servers with multiple IP addresses, pick a random one per connection - Add pseudo-priority "Stop" that will send the job immediately to the post-processing queue - Allow jobs still waiting for post-processing to be deleted too - More persistent retries for unreliable indexers - Single Configuration skin for all others skins (there is an option for the old style) - Config->Special for settings that were previously only changeable in the sabnzbd.ini file - Add Spanish, Portuguese (Brazil) and Polish translations - Individual RSS filter toggle - Unified OSX DMG ## About SABnzbd is an open-source cross-platform binary newsreader. It simplifies the process of downloading from Usenet dramatically, thanks to its web-based user interface and advanced built-in post-processing options that automatically verify, repair, extract and clean up posts downloaded from Usenet. (c) Copyright 2007-2014 by "The SABnzbd-team" \ ### IMPORTANT INFORMATION about release 0.7.x ### Known problems and solutions - Read the file "ISSUES.txt" ### Upgrading from 0.6.x - Stop SABnzbd - Install new version - Start SABnzbd ### Upgrading from 0.5.x - Stop SABnzbd - Install new version - Start SABnzbd. The organization of the download queue is different from 0.5.x. 0.7.x will finish downloading an existing queue, but you cannot go back to an older version without losing your queue. Also, your sabnzbd.ini file will be upgraded, making it incompatible with release 0.5.x ### Upgrading from 0.4.x Download your current queue before upgrading. SABnzbd-0.7.20/SABHelper.py0000644000000000000000000001230412433712602015344 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import sys if sys.version_info < (2,5): print "Sorry, requires Python 2.5 or higher." sys.exit(1) import os import time import subprocess #------------------------------------------------------------------------------ try: import win32api, win32file import win32serviceutil, win32evtlogutil, win32event, win32service, pywintypes except ImportError: print "Sorry, requires Python module PyWin32." sys.exit(1) from util.mailslot import MailSlot from util.apireg import del_connection_info, set_connection_info #------------------------------------------------------------------------------ WIN_SERVICE = None #------------------------------------------------------------------------------ def HandleCommandLine(allow_service=True): """ Handle command line for a Windows Service Prescribed name that will be called by Py2Exe. You MUST set 'cmdline_style':'custom' in the package.py! """ win32serviceutil.HandleCommandLine(SABHelper) def start_sab(): return subprocess.Popen('net start SABnzbd', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).stdout.read() #------------------------------------------------------------------------------ def main(): mail = MailSlot() if not mail.create(10): return '- Cannot create Mailslot' active = False # SABnzbd should be running counter = 0 # Time allowed for SABnzbd to be silent while True: msg = mail.receive() if msg: if msg == 'restart': time.sleep(1.0) counter = 0 del_connection_info(user=False) start_sab() elif msg == 'stop': active = False del_connection_info(user=False) elif msg == 'active': active = True counter = 0 elif msg.startswith('api '): active = True counter = 0 cmd, url = msg.split() if url: set_connection_info(url.strip(), user=False) if active: counter += 1 if counter > 120: # 120 seconds counter = 0 start_sab() rc = win32event.WaitForMultipleObjects((WIN_SERVICE.hWaitStop, WIN_SERVICE.overlapped.hEvent), 0, 1000) if rc == win32event.WAIT_OBJECT_0: del_connection_info(user=False) mail.disconnect() return '' ##################################################################### # # Windows Service Support # import servicemanager class SABHelper(win32serviceutil.ServiceFramework): """ Win32 Service Handler """ _svc_name_ = 'SABHelper' _svc_display_name_ = 'SABnzbd Helper' _svc_deps_ = ["EventLog", "Tcpip"] _svc_description_ = 'Automated downloading from Usenet. ' \ 'This service helps SABnzbd to restart itself.' def __init__(self, args): global WIN_SERVICE win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) self.overlapped = pywintypes.OVERLAPPED() self.overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None) WIN_SERVICE = self def SvcDoRun(self): msg = 'SABHelper-service' self.Logger(servicemanager.PYS_SERVICE_STARTED, msg + ' has started') res = main() self.Logger(servicemanager.PYS_SERVICE_STOPPED, msg + ' has stopped' + res) def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def Logger(self, state, msg): win32evtlogutil.ReportEvent(self._svc_display_name_, state, 0, servicemanager.EVENTLOG_INFORMATION_TYPE, (self._svc_name_, unicode(msg))) def ErrLogger(self, msg, text): win32evtlogutil.ReportEvent(self._svc_display_name_, servicemanager.PYS_SERVICE_STOPPED, 0, servicemanager.EVENTLOG_ERROR_TYPE, (self._svc_name_, unicode(msg)), unicode(text)) ##################################################################### # # Platform specific startup code # if __name__ == '__main__': win32serviceutil.HandleCommandLine(SABHelper, argv=sys.argv) SABnzbd-0.7.20/SABnzbd.py0000755000000000000000000020363612433712602015077 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2014 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. import sys if sys.version_info < (2, 5): print "Sorry, requires Python 2.5, 2.6 or 2.7." sys.exit(1) import logging import logging.handlers import os import getopt import signal import socket import platform import time import re try: import Cheetah if Cheetah.Version[0] != '2': raise ValueError except ValueError: print "Sorry, requires Python module Cheetah 2.0rc7 or higher." sys.exit(1) except: print "The Python module Cheetah is required" sys.exit(1) import cherrypy if not cherrypy.__version__.startswith("3.2"): print "Sorry, requires Python module Cherrypy 3.2 (use the included version)" sys.exit(1) from cherrypy import _cpserver from cherrypy import _cpwsgi_server SQLITE_DLL = True try: from sqlite3 import version as sqlite3_version except: try: from pysqlite2.dbapi2 import version as sqlite3_version except: if os.name != 'nt': print "Sorry, requires Python module sqlite3" print "Try: apt-get install python-pysqlite2" sys.exit(1) else: SQLITE_DLL = False import sabnzbd import sabnzbd.lang import sabnzbd.interface from sabnzbd.constants import * import sabnzbd.newsunpack from sabnzbd.misc import get_user_shellfolders, real_path, \ check_latest_version, exit_sab, \ split_host, get_ext, create_https_certificates, \ windows_variant, ip_extract, set_serv_parms, get_serv_parms, globber from sabnzbd.panic import panic_tmpl, panic_port, panic_host, panic_fwall, \ panic_sqlite, panic, launch_a_browser, panic_xport import sabnzbd.scheduler as scheduler import sabnzbd.config as config import sabnzbd.cfg import sabnzbd.downloader from sabnzbd.encoding import unicoder, latin1 import sabnzbd.growler as growler from threading import Thread LOG_FLAG = False # Global for this module, signalling loglevel change _first_log = True def FORCELOG(txt): global _first_log if _first_log: os.remove('d:/temp/debug.txt') _first_log = False ff = open('d:/temp/debug.txt', 'a+') ff.write(txt) ff.write('\n') ff.close() #------------------------------------------------------------------------------ try: import win32api import win32serviceutil, win32evtlogutil, win32event, win32service, pywintypes win32api.SetConsoleCtrlHandler(sabnzbd.sig_handler, True) from util.mailslot import MailSlot from util.apireg import get_connection_info, set_connection_info, del_connection_info except ImportError: class MailSlot: pass if sabnzbd.WIN32: print "Sorry, requires Python module PyWin32." sys.exit(1) def guard_loglevel(): """ Callback function for guarding loglevel """ global LOG_FLAG LOG_FLAG = True #------------------------------------------------------------------------------ # Improved RotatingFileHandler # See: http://www.mail-archive.com/python-bugs-list@python.org/msg53913.html # http://bugs.python.org/file14420/NTSafeLogging.py # Thanks Erik Antelman # if sabnzbd.WIN32: import msvcrt import _subprocess import codecs def duplicate(handle, inheritable=False): target_process = _subprocess.GetCurrentProcess() return _subprocess.DuplicateHandle( _subprocess.GetCurrentProcess(), handle, target_process, 0, inheritable, _subprocess.DUPLICATE_SAME_ACCESS).Detach() class NewRotatingFileHandler(logging.handlers.RotatingFileHandler): def _open(self): """ Open the current base file with the (original) mode and encoding. Return the resulting stream. """ if self.encoding is None: stream = open(self.baseFilename, self.mode) newosf = duplicate(msvcrt.get_osfhandle(stream.fileno()), inheritable=False) newFD = msvcrt.open_osfhandle(newosf,os.O_APPEND) newstream = os.fdopen(newFD,self.mode) stream.close() return newstream else: stream = codecs.open(self.baseFilename, self.mode, self.encoding) return stream else: NewRotatingFileHandler = logging.handlers.RotatingFileHandler #------------------------------------------------------------------------------ class FilterCP3: ### Filter out all CherryPy3-Access logging that we receive, ### because we have the root logger def __init__(self): pass def filter(self, record): _cplogging = record.module == '_cplogging' # Python2.4 fix # record has no attribute called funcName under python 2.4 if hasattr(record, 'funcName'): access = record.funcName == 'access' else: access = True return not (_cplogging and access) class guiHandler(logging.Handler): """ Logging handler collects the last warnings/errors/exceptions to be displayed in the web-gui """ def __init__(self, size): """ Initializes the handler """ logging.Handler.__init__(self) self.size = size self.store = [] def emit(self, record): """ Emit a record by adding it to our private queue """ if len(self.store) >= self.size: # Loose the oldest record self.store.pop(0) try: self.store.append(self.format(record)) except UnicodeDecodeError: # Catch elusive Unicode conversion problems pass def clear(self): self.store = [] def count(self): return len(self.store) def last(self): if self.store: return self.store[len(self.store)-1] else: return "" def content(self): """ Return an array with last records """ return self.store #------------------------------------------------------------------------------ def print_help(): print print "Usage: %s [-f ] " % sabnzbd.MY_NAME print print "Options marked [*] are stored in the config file" print print "Options:" print " -f --config-file Location of config file" print " -s --server Listen on server:port [*]" print " -t --templates Template directory [*]" print " -2 --template2 Secondary template dir [*]" print print " -l --logging <0..2> Set logging level (-1=off, 0= least, 2= most) [*]" print " -w --weblogging <0..2> Set cherrypy logging (0= off, 1= on, 2= file-only) [*]" print print " -b --browser <0..1> Auto browser launch (0= off, 1= on) [*]" if sabnzbd.WIN32: print " -d --daemon Use when run as a service" else: print " -d --daemon Fork daemon process" print " --pid Create a PID file in the given folder (full path)" print " --pidfile Create a PID file with the given name (full path)" print print " --force Discard web-port timeout (see Wiki!)" print " -h --help Print this message" print " -v --version Print version information" print " -c --clean Remove queue, cache and logs" print " -p --pause Start in paused mode" print " --repair Add orphaned jobs from the incomplete folder to the queue" print " --repair-all Try to reconstruct the queue from the incomplete folder" print " with full data reconstruction" print " --https Port to use for HTTPS server" print " --log-all Log all article handling (for developers)" print " --console Force console logging for OSX app" print " --new Run a new instance of SABnzbd" print " --no_ipv6 Do not listen on IPv6 address [::1]" def print_version(): print """ %s-%s Copyright (C) 2008-2014, The SABnzbd-Team SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. """ % (sabnzbd.MY_NAME, sabnzbd.__version__) #------------------------------------------------------------------------------ def daemonize(): try: pid = os.fork() if pid > 0: sys.exit(0) except OSError: print "fork() failed" sys.exit(1) os.chdir(sabnzbd.DIR_PROG) os.setsid() # Make sure I can read my own files and shut out others prev= os.umask(0) os.umask(prev and int('077',8)) try: pid = os.fork() if pid > 0: sys.exit(0) except OSError: print "fork() failed" sys.exit(1) dev_null = file('/dev/null', 'r') os.dup2(dev_null.fileno(), sys.stdin.fileno()) #------------------------------------------------------------------------------ def Bail_Out(browserhost, cherryport, err=''): """Abort program because of CherryPy troubles """ logging.error(Ta('Failed to start web-interface') + ' : ' + str(err)) if not sabnzbd.DAEMON: if '13' in err: panic_xport(browserhost, cherryport) elif '49' in err: panic_host(browserhost, cherryport) else: panic_port(browserhost, cherryport) sabnzbd.halt() exit_sab(2) #------------------------------------------------------------------------------ def Web_Template(key, defweb, wdir): """ Determine a correct web template set, return full template path """ if wdir is None: try: wdir = fix_webname(key()) except: wdir = '' if not wdir: wdir = defweb if key: key.set(wdir) if not wdir: # No default value defined, accept empty path return '' full_dir = real_path(sabnzbd.DIR_INTERFACES, wdir) full_main = real_path(full_dir, DEF_MAIN_TMPL) logging.info("Web dir is %s", full_dir) if not os.path.exists(full_main): # Temporarily fix that allows missing Config if defweb == DEF_STDCONFIG: return '' # end temp fix logging.warning(Ta('Cannot find web template: %s, trying standard template'), full_main) full_dir = real_path(sabnzbd.DIR_INTERFACES, DEF_STDINTF) full_main = real_path(full_dir, DEF_MAIN_TMPL) if not os.path.exists(full_main): logging.exception('Cannot find standard template: %s', full_dir) panic_tmpl(full_dir) exit_sab(1) #sabnzbd.lang.install_language(real_path(full_dir, DEF_INT_LANGUAGE), sabnzbd.cfg.language(), wdir) return real_path(full_dir, "templates") #------------------------------------------------------------------------------ def CheckColor(color, web_dir): """ Check existence of color-scheme """ if color and os.path.exists(os.path.join(web_dir,'static/stylesheets/colorschemes/'+color+'.css')): return color elif color and os.path.exists(os.path.join(web_dir,'static/stylesheets/colorschemes/'+color)): return color else: return '' #------------------------------------------------------------------------------ def fix_webname(name): if name: xname = name.title() else: xname = '' if xname in ('Default', ): return 'Classic' elif xname in ('Classic', 'Plush', 'Mobile'): return xname elif xname in ('Smpl', 'Wizard'): return name.lower() elif xname in ('Config',): return 'Plush' else: return name #------------------------------------------------------------------------------ def GetProfileInfo(vista_plus): """ Get the default data locations """ ok = False if sabnzbd.DAEMON: # In daemon mode, do not try to access the user profile # just assume that everything defaults to the program dir sabnzbd.DIR_APPDATA = sabnzbd.DIR_PROG sabnzbd.DIR_LCLDATA = sabnzbd.DIR_PROG sabnzbd.DIR_HOME = sabnzbd.DIR_PROG if sabnzbd.WIN32: # Ignore Win32 "logoff" signal # This should work, but it doesn't # Instead the signal_handler will ignore the "logoff" signal #signal.signal(5, signal.SIG_IGN) pass ok = True elif sabnzbd.WIN32: specials = get_user_shellfolders() try: sabnzbd.DIR_APPDATA = '%s\\%s' % (specials['AppData'], DEF_WORKDIR) sabnzbd.DIR_LCLDATA = '%s\\%s' % (specials['Local AppData'], DEF_WORKDIR) sabnzbd.DIR_HOME = specials['Personal'] ok = True except: try: if vista_plus: root = os.environ['AppData'] user = os.environ['USERPROFILE'] sabnzbd.DIR_APPDATA = '%s\\%s' % (root.replace('\\Roaming', '\\Local'), DEF_WORKDIR) sabnzbd.DIR_HOME = '%s\\Documents' % user else: root = os.environ['USERPROFILE'] sabnzbd.DIR_APPDATA = '%s\\%s' % (root, DEF_WORKDIR) sabnzbd.DIR_HOME = root try: # Conversion to 8bit ASCII required for CherryPy sabnzbd.DIR_APPDATA = sabnzbd.DIR_APPDATA.encode('latin-1') sabnzbd.DIR_HOME = sabnzbd.DIR_HOME.encode('latin-1') ok = True except: # If unconvertible characters exist, use MSDOS name try: sabnzbd.DIR_APPDATA = win32api.GetShortPathName(sabnzbd.DIR_APPDATA) sabnzbd.DIR_HOME = win32api.GetShortPathName(sabnzbd.DIR_HOME) ok = True except: pass sabnzbd.DIR_LCLDATA = sabnzbd.DIR_APPDATA except: pass elif sabnzbd.DARWIN: home = os.environ.get('HOME') if home: sabnzbd.DIR_APPDATA = '%s/Library/Application Support/SABnzbd' % home sabnzbd.DIR_LCLDATA = sabnzbd.DIR_APPDATA sabnzbd.DIR_HOME = home ok = True else: # Unix/Linux home = os.environ.get('HOME') if home: sabnzbd.DIR_APPDATA = '%s/.%s' % (home, DEF_WORKDIR) sabnzbd.DIR_LCLDATA = sabnzbd.DIR_APPDATA sabnzbd.DIR_HOME = home ok = True if not ok: panic("Cannot access the user profile.", "Please start with sabnzbd.ini file in another location") exit_sab(2) #------------------------------------------------------------------------------ def print_modules(): """ Log all detected optional or external modules """ if sabnzbd.decoder.HAVE_YENC: logging.info("_yenc module... found!") else: if hasattr(sys, "frozen"): logging.error(Ta('_yenc module... NOT found!')) else: logging.info("_yenc module... NOT found!") if sabnzbd.newsunpack.PAR2_COMMAND: logging.info("par2 binary... found (%s)", sabnzbd.newsunpack.PAR2_COMMAND) else: logging.error(Ta('par2 binary... NOT found!')) if sabnzbd.newsunpack.PAR2C_COMMAND: logging.info("par2-classic binary... found (%s)", sabnzbd.newsunpack.PAR2C_COMMAND) if sabnzbd.newsunpack.RAR_COMMAND: logging.info("unrar binary... found (%s)", sabnzbd.newsunpack.RAR_COMMAND) else: logging.warning(Ta('unrar binary... NOT found')) if sabnzbd.newsunpack.ZIP_COMMAND: logging.info("unzip binary... found (%s)", sabnzbd.newsunpack.ZIP_COMMAND) else: logging.warning(Ta('unzip binary... NOT found!')) if not sabnzbd.WIN32: if sabnzbd.newsunpack.NICE_COMMAND: logging.info("nice binary... found (%s)", sabnzbd.newsunpack.NICE_COMMAND) else: logging.info("nice binary... NOT found!") if sabnzbd.newsunpack.IONICE_COMMAND: logging.info("ionice binary... found (%s)", sabnzbd.newsunpack.IONICE_COMMAND) else: logging.info("ionice binary... NOT found!") if sabnzbd.newswrapper.HAVE_SSL: logging.info("pyOpenSSL... found (%s)", sabnzbd.newswrapper.HAVE_SSL) else: logging.info("pyOpenSSL... NOT found - try apt-get install python-pyopenssl (SSL is optional)") #------------------------------------------------------------------------------ def all_localhosts(): """ Return all unique values of localhost in order of preference """ ips = ['127.0.0.1'] try: # Check whether IPv6 is available and enabled info = socket.getaddrinfo('::1', None) af, socktype, proto, canonname, sa = info[0] s = socket.socket(af, socktype, proto) s.close() except socket.error: return ips try: info = socket.getaddrinfo('localhost', None) except: # localhost does not resolve return ips ips = [] for item in info: item = item[4][0] if item not in ips: ips.append(item) return ips def check_resolve(host): """ Return True if 'host' resolves """ try: info = socket.getaddrinfo(host, None) except: # Does not resolve return False return True #------------------------------------------------------------------------------ def get_webhost(cherryhost, cherryport, https_port): """ Determine the webhost address and port, return (host, port, browserhost) """ if cherryhost == '0.0.0.0' and not check_resolve('127.0.0.1'): cherryhost = '' elif cherryhost == '::' and not check_resolve('::1'): cherryhost = '' if cherryhost is None: cherryhost = sabnzbd.cfg.cherryhost() else: sabnzbd.cfg.cherryhost.set(cherryhost) # Get IP address, but discard APIPA/IPV6 # If only APIPA's or IPV6 are found, fall back to localhost ipv4 = ipv6 = False localhost = hostip = 'localhost' try: info = socket.getaddrinfo(socket.gethostname(), None) except: # Hostname does not resolve try: # Valid user defined name? info = socket.getaddrinfo(cherryhost, None) except: if cherryhost not in ('localhost', '127.0.0.1', '::1'): cherryhost = '0.0.0.0' try: info = socket.getaddrinfo(localhost, None) except: info = socket.getaddrinfo('127.0.0.1', None) localhost = '127.0.0.1' for item in info: ip = str(item[4][0]) if ip.startswith('169.254.'): pass # Is an APIPA elif ':' in ip: ipv6 = True elif '.' in ip and not ipv4: ipv4 = True hostip = ip # A blank host will use the local ip address if cherryhost == '': if ipv6 and ipv4: # To protect Firefox users, use numeric IP cherryhost = hostip browserhost = hostip else: cherryhost = socket.gethostname() browserhost = cherryhost # 0.0.0.0 will listen on all ipv4 interfaces (no ipv6 addresses) elif cherryhost == '0.0.0.0': # Just take the gamble for this cherryhost = '0.0.0.0' browserhost = localhost # :: will listen on all ipv6 interfaces (no ipv4 addresses) elif cherryhost in ('::','[::]'): cherryhost = cherryhost.strip('[').strip(']') # Assume '::1' == 'localhost' browserhost = localhost # IPV6 address elif '[' in cherryhost or ':' in cherryhost: browserhost = cherryhost # IPV6 numeric address elif cherryhost.replace('.', '').isdigit(): # IPV4 numerical browserhost = cherryhost elif cherryhost == localhost: cherryhost = localhost browserhost = localhost else: # If on Vista and/or APIPA, use numerical IP, to help FireFoxers if ipv6 and ipv4: cherryhost = hostip browserhost = cherryhost # Some systems don't like brackets in numerical ipv6 if sabnzbd.DARWIN: cherryhost = cherryhost.strip('[]') else: try: info = socket.getaddrinfo(cherryhost, None) except: cherryhost = cherryhost.strip('[]') if ipv6 and ipv4 and \ (browserhost not in ('localhost', '127.0.0.1', '[::1]', '::1')): sabnzbd.AMBI_LOCALHOST = True logging.info("IPV6 has priority on this system, potential Firefox issue") if ipv6 and ipv4 and cherryhost == '' and sabnzbd.WIN32: logging.warning(Ta('Please be aware the 0.0.0.0 hostname will need an IPv6 address for external access')) if cherryhost == 'localhost' and not sabnzbd.WIN32 and not sabnzbd.DARWIN: # On the Ubuntu family, localhost leads to problems for CherryPy ips = ip_extract() if '127.0.0.1' in ips and '::1' in ips: cherryhost = '127.0.0.1' if ips[0] != '127.0.0.1': browserhost = '127.0.0.1' # This is to please Chrome on OSX if cherryhost == 'localhost' and sabnzbd.DARWIN: cherryhost = '127.0.0.1' browserhost = 'localhost' if cherryport is None: cherryport = sabnzbd.cfg.cherryport.get_int() else: sabnzbd.cfg.cherryport.set(str(cherryport)) if https_port is None: https_port = sabnzbd.cfg.https_port.get_int() else: sabnzbd.cfg.https_port.set(str(https_port)) # if the https port was specified, assume they want HTTPS enabling also sabnzbd.cfg.enable_https.set(True) if cherryport == https_port and sabnzbd.cfg.enable_https(): sabnzbd.cfg.enable_https.set(False) # Should have a translated message, but that's not available yet #logging.error(Ta('HTTP and HTTPS ports cannot be the same')) logging.error('HTTP and HTTPS ports cannot be the same') return cherryhost, cherryport, browserhost, https_port def attach_server(host, port, cert=None, key=None, chain=None): """ Define and attach server, optionally HTTPS """ if not (sabnzbd.cfg.no_ipv6() and '::1' in host): http_server = _cpwsgi_server.CPWSGIServer() http_server.bind_addr = (host, port) if cert and key: http_server.ssl_certificate = cert http_server.ssl_private_key = key http_server.ssl_certificate_chain = chain adapter = _cpserver.ServerAdapter(cherrypy.engine, http_server, http_server.bind_addr) adapter.subscribe() def is_sabnzbd_running(url, timeout=None): """ Return True when there's already a SABnzbd instance running. """ try: url = '%s&mode=version' % (url) ver = sabnzbd.newsunpack.get_from_url(url, timeout=timeout) return bool(ver and re.search(r'\d+\.\d+\.', ver)) except: return False def find_free_port(host, currentport): """ Return a free port, 0 when nothing is free """ n = 0 while n < 10 and currentport <= 49151: try: cherrypy.process.servers.check_port(host, currentport) return currentport except: currentport += 5 n += 1 return 0 def check_for_sabnzbd(url, upload_nzbs, allow_browser=True): """ Check for a running instance of sabnzbd on this port allow_browser==True|None will launch the browser, False will not. """ if allow_browser is None: allow_browser = True if is_sabnzbd_running(url): # Upload any specified nzb files to the running instance if upload_nzbs: from sabnzbd.utils.upload import upload_file for f in upload_nzbs: upload_file(url, f) else: # Launch the web browser and quit since sabnzbd is already running # Trim away everything after the final slash in the URL url = url[:url.rfind('/')+1] launch_a_browser(url, force=allow_browser) exit_sab(0) return True return False def copy_old_files(newpath): """ OSX only: If no INI file found but old one exists, copy it When copying the INI, also copy rss, bookmarks and watched-data """ if not os.path.exists(os.path.join(newpath, DEF_INI_FILE)): if not os.path.exists(newpath): os.mkdir(newpath) oldpath = os.environ['HOME'] + "/.sabnzbd" oldini = os.path.join(oldpath, DEF_INI_FILE) if os.path.exists(oldini): import shutil try: shutil.copy(oldini, newpath) except: pass oldpath = os.path.join(oldpath, DEF_CACHE_DIR) newpath = os.path.join(newpath, DEF_CACHE_DIR) if not os.path.exists(newpath): os.mkdir(newpath) try: shutil.copy(os.path.join(oldpath, RSS_FILE_NAME), newpath) except: pass try: shutil.copy(os.path.join(oldpath, BOOKMARK_FILE_NAME), newpath) except: pass try: shutil.copy(os.path.join(oldpath, SCAN_FILE_NAME), newpath) except: pass def evaluate_inipath(path): """ Derive INI file path from a partial path. Full file path: if file does not exist the name must contain a dot but not a leading dot. foldername is enough, the standard name will be appended. """ path = os.path.normpath(os.path.abspath(path)) inipath = os.path.join(path, DEF_INI_FILE) if os.path.isdir(path): return inipath elif os.path.isfile(path) or os.path.isfile(path + '.bak'): return path else: dirpart, name = os.path.split(path) if name.find('.') < 1: return inipath else: return path def cherrypy_logging(log_path, log_handler): """ Setup CherryPy logging """ log = cherrypy.log log.access_file = '' log.error_file = '' # Max size of 512KB maxBytes = getattr(log, "rot_maxBytes", 524288) # cherrypy.log cherrypy.log.1 cherrypy.log.2 backupCount = getattr(log, "rot_backupCount", 3) # Make a new RotatingFileHandler for the error log. fname = getattr(log, "rot_error_file", log_path) h = log_handler(fname, 'a', maxBytes, backupCount) h.setLevel(logging.DEBUG) h.setFormatter(cherrypy._cplogging.logfmt) log.error_log.addHandler(h) #------------------------------------------------------------------------------ def commandline_handler(frozen=True): """ Split win32-service commands are true parameters Returns: service, sab_opts, serv_opts, upload_nzbs """ service = '' sab_opts = [] serv_inst = False serv_opts = [os.path.normpath(os.path.abspath(sys.argv[0]))] upload_nzbs = [] # OSX binary: get rid of the weird -psn_0_123456 parameter for arg in sys.argv: if arg.startswith('-psn_'): sys.argv.remove(arg) break # Ugly hack to remove the extra "SABnzbd*" parameter the Windows binary # gets when it's restarted if len(sys.argv) > 1 and \ 'sabnzbd' in sys.argv[1].lower() and \ not sys.argv[1].startswith('-'): slice = 2 else: slice = 1 # Prepend options from env-variable to options info = os.environ.get('SABnzbd', '').split() info.extend(sys.argv[slice:]) try: opts, args = getopt.getopt(info, "phdvncw:l:s:f:t:b:2:", ['pause', 'help', 'daemon', 'nobrowser', 'clean', 'logging=', 'weblogging=', 'server=', 'templates', 'no_ipv6', 'template2', 'browser=', 'config-file=', 'force', 'version', 'https=', 'autorestarted', 'repair', 'repair-all', 'log-all', 'no-login', 'pid=', 'new', 'sessions', 'console', 'pidfile=', # Below Win32 Service options 'password=', 'username=', 'startup=', 'perfmonini=', 'perfmondll=', 'interactive', 'wait=', ]) except getopt.GetoptError: print_help() exit_sab(2) # Check for Win32 service commands if args and args[0] in ('install', 'update', 'remove', 'start', 'stop', 'restart', 'debug'): service = args[0] serv_opts.extend(args) if not service: # Get and remove any NZB file names for entry in args: if get_ext(entry) in ('.nzb', '.zip','.rar', '.gz'): upload_nzbs.append(os.path.abspath(entry)) for opt, arg in opts: if opt in ('password','username','startup','perfmonini', 'perfmondll', 'interactive', 'wait'): # Service option, just collect if service: serv_opts.append(opt) if arg: serv_opts.append(arg) else: if opt == '-f': arg = os.path.normpath(os.path.abspath(arg)) sab_opts.append((opt, arg)) return service, sab_opts, serv_opts, upload_nzbs def get_f_option(opts): """ Return value of the -f option """ for opt, arg in opts: if opt == '-f': return arg else: return None #------------------------------------------------------------------------------ def main(): global LOG_FLAG import sabnzbd # Due to ApplePython bug autobrowser = None autorestarted = False sabnzbd.MY_FULLNAME = sys.argv[0] sabnzbd.MY_NAME = os.path.basename(sabnzbd.MY_FULLNAME) fork = False pause = False inifile = None cherryhost = None cherryport = None https_port = None cherrypylogging = None clean_up = False logging_level = None web_dir = None web_dir2 = None vista_plus = False vista64 = False force_web = False repair = 0 api_url = None no_login = False re_argv = [sys.argv[0]] pid_path = None pid_file = None new_instance = False force_sessions = False osx_console = False no_ipv6 = False service, sab_opts, serv_opts, upload_nzbs = commandline_handler() for opt, arg in sab_opts: if opt == '--servicecall': sabnzbd.MY_FULLNAME = arg elif opt in ('-d', '--daemon'): if not sabnzbd.WIN32: fork = True autobrowser = False sabnzbd.DAEMON = True re_argv.append(opt) elif opt in ('-f', '--config-file'): inifile = arg re_argv.append(opt) re_argv.append(arg) elif opt in ('-h', '--help'): print_help() exit_sab(0) elif opt in ('-t', '--templates'): web_dir = arg elif opt in ('-2', '--template2'): web_dir2 = arg elif opt in ('-s', '--server'): (cherryhost, cherryport) = split_host(arg) elif opt in ('-n', '--nobrowser'): autobrowser = False elif opt in ('-b', '--browser'): try: autobrowser = bool(int(arg)) except: autobrowser = True elif opt in ('--autorestarted'): autorestarted = True elif opt in ('-c', '--clean'): clean_up = True elif opt in ('-w', '--weblogging'): try: cherrypylogging = int(arg) except: cherrypylogging = -1 if cherrypylogging < 0 or cherrypylogging > 2: print_help() exit_sab(1) elif opt in ('-l', '--logging'): try: logging_level = int(arg) except: logging_level = -2 if logging_level < -1 or logging_level > 2: print_help() exit_sab(1) elif opt in ('-v', '--version'): print_version() exit_sab(0) elif opt in ('-p', '--pause'): pause = True elif opt in ('--force',): force_web = True re_argv.append(opt) elif opt in ('--https',): https_port = int(arg) re_argv.append(opt) re_argv.append(arg) elif opt in ('--repair',): repair = 1 pause = True elif opt in ('--repair-all',): repair = 2 pause = True elif opt in ('--log-all',): sabnzbd.LOG_ALL = True elif opt in ('--no-login',): no_login = True elif opt in ('--pid',): pid_path = arg re_argv.append(opt) re_argv.append(arg) elif opt in ('--pidfile',): pid_file = arg re_argv.append(opt) re_argv.append(arg) elif opt in ('--new',): new_instance = True elif opt in ('--sessions',): re_argv.append(opt) force_sessions = True elif opt in ('--console',): re_argv.append(opt) osx_console = True elif opt in ('--no_ipv6',): no_ipv6 = True sabnzbd.MY_FULLNAME = os.path.normpath(os.path.abspath(sabnzbd.MY_FULLNAME)) sabnzbd.MY_NAME = os.path.basename(sabnzbd.MY_FULLNAME) sabnzbd.DIR_PROG = os.path.dirname(sabnzbd.MY_FULLNAME) sabnzbd.DIR_INTERFACES = real_path(sabnzbd.DIR_PROG, DEF_INTERFACES) sabnzbd.DIR_LANGUAGE = real_path(sabnzbd.DIR_PROG, DEF_LANGUAGE) org_dir = os.getcwd() if getattr(sys, 'frozen', None) == 'macosx_app': # Correct path if frozen with py2app (OSX) sabnzbd.MY_FULLNAME = sabnzbd.MY_FULLNAME.replace("/Resources/SABnzbd.py","/MacOS/SABnzbd") # Need console logging for SABnzbd.py and SABnzbd-console.exe consoleLogging = (not hasattr(sys, "frozen")) or (sabnzbd.MY_NAME.lower().find('-console') > 0) consoleLogging = consoleLogging and not sabnzbd.DAEMON # No console logging needed for OSX app noConsoleLoggingOSX = (not osx_console) and (sabnzbd.DIR_PROG.find('.app/Contents/Resources') > 0) if noConsoleLoggingOSX: consoleLogging = 1 LOGLEVELS = (logging.FATAL, logging.WARNING, logging.INFO, logging.DEBUG) # Setup primary logging to prevent default console logging gui_log = guiHandler(MAX_WARNINGS) gui_log.setLevel(logging.WARNING) format_gui = '%(asctime)s\n%(levelname)s\n%(message)s' gui_log.setFormatter(logging.Formatter(format_gui)) sabnzbd.GUIHANDLER = gui_log # Create logger logger = logging.getLogger('') logger.setLevel(logging.WARNING) logger.addHandler(gui_log) # Detect Windows variant if sabnzbd.WIN32: vista_plus, vista64 = windows_variant() sabnzbd.WIN64 = vista64 if not SQLITE_DLL: panic_sqlite(sabnzbd.MY_FULLNAME) exit_sab(2) if inifile: # INI file given, simplest case inifile = evaluate_inipath(inifile) else: # No ini file given, need profile data GetProfileInfo(vista_plus) # Find out where INI file is inifile = os.path.abspath(sabnzbd.DIR_PROG + '/' + DEF_INI_FILE) if not os.path.exists(inifile) and not os.path.exists(inifile + '.bak'): inifile = os.path.abspath(sabnzbd.DIR_LCLDATA + '/' + DEF_INI_FILE) if sabnzbd.DARWIN: copy_old_files(sabnzbd.DIR_LCLDATA) # If INI file at non-std location, then use program dir as $HOME if sabnzbd.DIR_LCLDATA != os.path.dirname(inifile): sabnzbd.DIR_HOME = os.path.dirname(inifile) # All system data dirs are relative to the place we found the INI file sabnzbd.DIR_LCLDATA = os.path.dirname(inifile) if not os.path.exists(inifile) and not os.path.exists(inifile + '.bak') and not os.path.exists(sabnzbd.DIR_LCLDATA): try: os.makedirs(sabnzbd.DIR_LCLDATA) except IOError: panic('Cannot create folder "%s".' % sabnzbd.DIR_LCLDATA, 'Check specified INI file location.') exit_sab(1) sabnzbd.cfg.set_root_folders(sabnzbd.DIR_HOME, sabnzbd.DIR_LCLDATA) res, msg = config.read_config(inifile) if not res: panic(msg, 'Specify a correct file or delete this file.') exit_sab(1) # Set root folders for HTTPS server file paths sabnzbd.cfg.set_root_folders2() if no_ipv6: sabnzbd.cfg.no_ipv6.set(True) # Determine web host address cherryhost, cherryport, browserhost, https_port = get_webhost(cherryhost, cherryport, https_port) enable_https = sabnzbd.cfg.enable_https() # When this is a daemon, just check and bail out if port in use if sabnzbd.DAEMON: if enable_https and https_port: try: cherrypy.process.servers.check_port(cherryhost, https_port) except IOError, error: Bail_Out(browserhost, cherryport) except: Bail_Out(browserhost, cherryport, '49') try: cherrypy.process.servers.check_port(cherryhost, cherryport) except IOError, error: Bail_Out(browserhost, cherryport) except: Bail_Out(browserhost, cherryport, '49') # Find external programs sabnzbd.newsunpack.find_programs(sabnzbd.DIR_PROG) # Windows instance is reachable through registry url = None if sabnzbd.WIN32 and not new_instance: url = get_connection_info() if url and check_for_sabnzbd(url, upload_nzbs, autobrowser): exit_sab(0) # If an instance of sabnzbd(same version) is already running on this port, launch the browser # If another program or sabnzbd version is on this port, try 10 other ports going up in a step of 5 # If 'Port is not bound' (firewall) do not do anything (let the script further down deal with that). ## SSL if enable_https: port = https_port or cherryport try: cherrypy.process.servers.check_port(browserhost, port) except IOError, error: if str(error) == 'Port not bound.': pass else: if not url: url = 'https://%s:%s/sabnzbd/api?' % (browserhost, port) if new_instance or not check_for_sabnzbd(url, upload_nzbs, autobrowser): newport = find_free_port(browserhost, port) if newport > 0: sabnzbd.cfg.https_port.set(newport) if https_port: https_port = newport else: http_port = newport except: Bail_Out(browserhost, cherryport, '49') ## NonSSL try: cherrypy.process.servers.check_port(browserhost, cherryport) except IOError, error: if str(error) == 'Port not bound.': pass else: if not url: url = 'http://%s:%s/sabnzbd/api?' % (browserhost, cherryport) if new_instance or not check_for_sabnzbd(url, upload_nzbs, autobrowser): port = find_free_port(browserhost, cherryport) if port > 0: sabnzbd.cfg.cherryport.set(port) cherryport = port except: Bail_Out(browserhost, cherryport, '49') if cherrypylogging is None: cherrypylogging = sabnzbd.cfg.log_web() else: sabnzbd.cfg.log_web.set(cherrypylogging) if logging_level is None: logging_level = sabnzbd.cfg.log_level() else: sabnzbd.cfg.log_level.set(logging_level) logdir = sabnzbd.cfg.log_dir.get_path() if fork and not logdir: print "Error:" print "I refuse to fork without a log directory!" sys.exit(1) if clean_up: xlist= globber(logdir) for x in xlist: if RSS_FILE_NAME not in x: try: os.remove(x) except: pass # Prevent the logger from raising exceptions # primarily to reduce the fallout of Python issue 4749 logging.raiseExceptions = 0 log_new = sabnzbd.cfg.log_new() if log_new: log_handler = NewRotatingFileHandler else: log_handler = logging.handlers.RotatingFileHandler sabnzbd.LOGFILE = os.path.join(logdir, DEF_LOG_FILE) logsize = sabnzbd.cfg.log_size.get_int() try: rollover_log = log_handler(\ sabnzbd.LOGFILE, 'a+', logsize, sabnzbd.cfg.log_backups()) format = '%(asctime)s::%(levelname)s::[%(module)s:%(lineno)d] %(message)s' rollover_log.setFormatter(logging.Formatter(format)) rollover_log.addFilter(FilterCP3()) sabnzbd.LOGHANDLER = rollover_log logger.addHandler(rollover_log) logger.setLevel(LOGLEVELS[logging_level+1]) except IOError: print "Error:" print "Can't write to logfile" exit_sab(2) if fork: try: x = sys.stderr.fileno x = sys.stdout.fileno ol_path = os.path.join(logdir, DEF_LOG_ERRFILE) out_log = file(ol_path, 'a+', 0) sys.stderr.flush() sys.stdout.flush() os.dup2(out_log.fileno(), sys.stderr.fileno()) os.dup2(out_log.fileno(), sys.stdout.fileno()) except AttributeError: pass else: try: x = sys.stderr.fileno x = sys.stdout.fileno if consoleLogging: console = logging.StreamHandler() console.addFilter(FilterCP3()) console.setLevel(LOGLEVELS[logging_level+1]) console.setFormatter(logging.Formatter(format)) logger.addHandler(console) if noConsoleLoggingOSX: logging.info('Console logging for OSX App disabled') so = file('/dev/null', 'a+') os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(so.fileno(), sys.stderr.fileno()) except AttributeError: pass logging.info('--------------------------------') logging.info('%s-%s (rev=%s)', sabnzbd.MY_NAME, sabnzbd.__version__, sabnzbd.__baseline__) if sabnzbd.WIN32: suffix = '' if vista_plus: suffix = ' (=Vista+)' if vista64: suffix = ' (=Vista+ x64)' try: logging.info('Platform=%s%s Class=%s', platform.platform(), suffix, os.name) except: logging.info('Platform=%s Class=%s', suffix, os.name) else: logging.info('Platform = %s', os.name) logging.info('Python-version = %s', sys.version) logging.info('Arguments = %s', sabnzbd.CMDLINE) if sabnzbd.cfg.log_level() > 1: try: s_ipv4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s_ipv4.connect(('google.com', 80)) logging.debug('My IPv4 address = %s', s_ipv4.getsockname()[0]) s_ipv4.close() except: logging.debug('Could not determine my IPv4 address') pass try: s_ipv6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) s_ipv6.connect(('ipv6.google.com', 80)) logging.debug('My IPv6 address = %s', s_ipv6.getsockname()[0]) s_ipv6.close() except: logging.debug('Could not determine my IPv6 address') pass # measure and log Pystone performance, and - if possible - CPU type try: # First try pystone from Python test libary from test.pystone import pystones except: # otherwise use the one provided by SABnzbd from util.pystone import pystones pystonetime,pystoneperformance = pystones(1000) logging.debug('CPU Pystone available performance is %s',int(pystoneperformance)) try: for myline in open("/proc/cpuinfo"): if myline.startswith(('model name')): logging.debug('CPU model name is %s', myline[13:].rstrip() ) break except: # probably not on Linux pass # OSX 10.5 I/O priority setting if sabnzbd.DARWIN: logging.info('[osx] IO priority setting') try: from ctypes import cdll libc = cdll.LoadLibrary('/usr/lib/libc.dylib') boolSetResult = libc.setiopolicy_np(0, 1, 3) logging.info('[osx] IO priority set to throttle for process scope') except: logging.info('[osx] IO priority setting not supported') logging.info('Read INI file %s', inifile) if autobrowser != None: sabnzbd.cfg.autobrowser.set(autobrowser) else: autobrowser = sabnzbd.cfg.autobrowser() if not sabnzbd.WIN_SERVICE and not getattr(sys, 'frozen', None) == 'macosx_app': signal.signal(signal.SIGINT, sabnzbd.sig_handler) signal.signal(signal.SIGTERM, sabnzbd.sig_handler) init_ok = sabnzbd.initialize(pause, clean_up, evalSched=True, repair=repair) if not init_ok: logging.error('Initializing %s-%s failed, aborting', sabnzbd.MY_NAME, sabnzbd.__version__) exit_sab(2) os.chdir(sabnzbd.DIR_PROG) web_dir = Web_Template(sabnzbd.cfg.web_dir, DEF_STDINTF, fix_webname(web_dir)) web_dir2 = Web_Template(sabnzbd.cfg.web_dir2, '', fix_webname(web_dir2)) web_dirc = Web_Template(None, DEF_STDCONFIG, '') wizard_dir = os.path.join(sabnzbd.DIR_INTERFACES, 'wizard') #sabnzbd.lang.install_language(os.path.join(wizard_dir, DEF_INT_LANGUAGE), sabnzbd.cfg.language(), 'wizard') sabnzbd.WEB_DIR = web_dir sabnzbd.WEB_DIR2 = web_dir2 sabnzbd.WEB_DIRC = web_dirc sabnzbd.WIZARD_DIR = wizard_dir sabnzbd.WEB_COLOR = CheckColor(sabnzbd.cfg.web_color(), web_dir) sabnzbd.cfg.web_color.set(sabnzbd.WEB_COLOR) sabnzbd.WEB_COLOR2 = CheckColor(sabnzbd.cfg.web_color2(), web_dir2) sabnzbd.cfg.web_color2.set(sabnzbd.WEB_COLOR2) logging.debug('Unwanted extensions are ... %s',sabnzbd.cfg.unwanted_extensions()) if fork and not sabnzbd.WIN32: daemonize() # Save the INI file config.save_config(force=True) if sabnzbd.WIN32 and sabnzbd.cfg.win_menu() and not sabnzbd.DAEMON: import sabnzbd.sabtray sabnzbd.WINTRAY = sabnzbd.sabtray.SABTrayThread() print_modules() cherrylogtoscreen = False sabnzbd.WEBLOGFILE = None if cherrypylogging: if logdir: sabnzbd.WEBLOGFILE = os.path.join(logdir, DEF_LOG_CHERRY) # Define our custom logger for cherrypy errors cherrypy_logging(sabnzbd.WEBLOGFILE, log_handler) if not fork: try: x= sys.stderr.fileno x= sys.stdout.fileno if cherrypylogging == 1: cherrylogtoscreen = True except: pass https_cert = sabnzbd.cfg.https_cert.get_path() https_key = sabnzbd.cfg.https_key.get_path() https_chain = sabnzbd.cfg.https_chain.get_path() if not (sabnzbd.cfg.https_chain() and os.path.exists(https_chain)): https_chain = None if enable_https: # If either the HTTPS certificate or key do not exist, make some self-signed ones. if not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key)): create_https_certificates(https_cert, https_key) if not (os.path.exists(https_cert) and os.path.exists(https_key)): logging.warning(Ta('Disabled HTTPS because of missing CERT and KEY files')) enable_https = False # Determine if this system has multiple definitions for 'localhost' hosts = all_localhosts() multilocal = len(hosts) > 1 and cherryhost in ('localhost', '0.0.0.0') # For 0.0.0.0 CherryPy will always pick IPv4, so make sure the secondary localhost is IPv6 if multilocal and cherryhost == '0.0.0.0' and hosts[1] == '127.0.0.1': hosts[1] = '::1' # The Windows binary requires numeric localhost as primary address if multilocal and cherryhost == 'localhost': cherryhost = hosts[0] if enable_https: if https_port: # Extra HTTP port for primary localhost attach_server(cherryhost, cherryport) if multilocal: # Extra HTTP port for secondary localhost attach_server(hosts[1], cherryport) # Extra HTTPS port for secondary localhost attach_server(hosts[1], https_port, https_cert, https_key, https_chain) cherryport = https_port elif multilocal: # Extra HTTPS port for secondary localhost attach_server(hosts[1], cherryport, https_cert, https_key) cherrypy.config.update({'server.ssl_certificate' : https_cert, 'server.ssl_private_key' : https_key, 'server.ssl_certificate_chain' : https_chain}) elif multilocal: # Extra HTTP port for secondary localhost attach_server(hosts[1], cherryport) if no_login: sabnzbd.cfg.username.set('') sabnzbd.cfg.password.set('') # Fix leakage in memory-based CherryPy session support by using file-based. # However, we don't really need session support. if force_sessions: sessions = sabnzbd.misc.create_real_path('sessions', sabnzbd.cfg.admin_dir.get_path(), 'sessions')[1] sabnzbd.misc.remove_all(sessions, 'session-*.lock', keep_folder=True) else: sessions = None mime_gzip = ('text/html', 'text/plain', 'text/css', 'text/xml', 'text/javascript', 'application/javascript', 'text/x-javascript', 'application/x-javascript', 'text/x-json', 'application/json' ) cherrypy.config.update({'server.environment': 'production', 'server.socket_host': cherryhost, 'server.socket_port': cherryport, 'log.screen': cherrylogtoscreen, 'engine.autoreload_frequency' : 100, 'engine.autoreload_on' : False, 'engine.reexec_retry' : 100, 'tools.encode.on' : True, 'tools.gzip.on' : True, 'tools.gzip.mime_types' : mime_gzip, 'tools.sessions.on' : bool(sessions), 'tools.sessions.storage_type' : 'file', 'tools.sessions.storage_path' : sessions, 'tools.sessions.timeout' : 60, 'request.show_tracebacks': True, 'checker.check_localhost' : bool(consoleLogging), 'error_page.401': sabnzbd.panic.error_page_401, 'error_page.404': sabnzbd.panic.error_page_404 }) static = {'tools.staticdir.on': True, 'tools.staticdir.dir': os.path.join(web_dir, 'static')} if web_dirc: staticcfg = {'tools.staticdir.on': True, 'tools.staticdir.dir': os.path.join(web_dirc, 'staticcfg')} wizard_static = {'tools.staticdir.on': True, 'tools.staticdir.dir': os.path.join(wizard_dir, 'static')} appconfig = {'/sabnzbd/api' : {'tools.basic_auth.on' : False}, '/api' : {'tools.basic_auth.on' : False}, '/m/api' : {'tools.basic_auth.on' : False}, '/rss' : {'tools.basic_auth.on' : False}, '/sabnzbd/rss' : {'tools.basic_auth.on' : False}, '/m/rss' : {'tools.basic_auth.on' : False}, '/sabnzbd/shutdown': {'streamResponse': True}, '/sabnzbd/static': static, '/static': static, '/sabnzbd/wizard/static': wizard_static, '/wizard/static': wizard_static } if web_dirc: appconfig['/sabnzbd/staticcfg'] = staticcfg appconfig['/staticcfg'] = staticcfg if web_dir2: static2 = {'tools.staticdir.on': True, 'tools.staticdir.dir': os.path.join(web_dir2, 'static')} appconfig['/sabnzbd/m/api'] = {'tools.basic_auth.on' : False} appconfig['/sabnzbd/m/rss'] = {'tools.basic_auth.on' : False} appconfig['/sabnzbd/m/shutdown'] = {'streamResponse': True} appconfig['/sabnzbd/m/static'] = static2 appconfig['/m/static'] = static2 appconfig['/sabnzbd/m/wizard/static'] = wizard_static appconfig['/m/wizard/static'] = wizard_static if web_dirc: appconfig['/sabnzbd/m/staticcfg'] = staticcfg appconfig['/m/staticcfg'] = staticcfg login_page = sabnzbd.interface.MainPage(web_dir, '/', web_dir2, '/m/', web_dirc, first=2) cherrypy.tree.mount(login_page, '/', config=appconfig) # Set authentication for CherryPy sabnzbd.interface.set_auth(cherrypy.config) logging.info('Starting web-interface on %s:%s', cherryhost, cherryport) sabnzbd.cfg.log_level.callback(guard_loglevel) try: # Use internal cherrypy check first to prevent ugly tracebacks cherrypy.process.servers.check_port(browserhost, cherryport) cherrypy.engine.start() except IOError, error: if str(error) == 'Port not bound.': if not force_web: panic_fwall(vista_plus) sabnzbd.halt() exit_sab(2) else: logging.error("Failed to start web-interface: ", exc_info = True) Bail_Out(browserhost, cherryport, str(error)) except socket.error, error: logging.error("Failed to start web-interface: ", exc_info = True) Bail_Out(browserhost, cherryport) except: logging.error("Failed to start web-interface: ", exc_info = True) Bail_Out(browserhost, cherryport) # Wait for server to become ready cherrypy.engine.wait(cherrypy.process.wspbus.states.STARTED) if enable_https: browser_url = "https://%s:%s/sabnzbd" % (browserhost, cherryport) else: browser_url = "http://%s:%s/sabnzbd" % (browserhost, cherryport) cherrypy.wsgiserver.REDIRECT_URL = browser_url sabnzbd.BROWSER_URL = browser_url if not autorestarted: launch_a_browser(browser_url) if sabnzbd.FOUNDATION: import sabnzbd.osxmenu sabnzbd.osxmenu.notify("SAB_Launched", None) growler.send_notification('SABnzbd%s' % growler.hostname(), T('SABnzbd %s started') % sabnzbd.__version__, 'startup') # Now's the time to check for a new version check_latest_version() autorestarted = False mail = None if sabnzbd.WIN32: if enable_https: mode = 's' else: mode = '' api_url = 'http%s://%s:%s/sabnzbd/api?apikey=%s' % (mode, browserhost, cherryport, sabnzbd.cfg.api_key()) if sabnzbd.WIN_SERVICE: mail = MailSlot() if mail.connect(): logging.info('Connected to the SABHelper service') mail.send('api %s' % api_url) else: logging.error('Cannot reach the SABHelper service') mail = None else: # Write URL directly to registry set_connection_info(api_url) if pid_path or pid_file: sabnzbd.pid_file(pid_path, pid_file, cherryport) # Start all SABnzbd tasks logging.info('Starting %s-%s', sabnzbd.MY_NAME, sabnzbd.__version__) try: sabnzbd.start() except: logging.exception("Failed to start %s-%s", sabnzbd.MY_NAME, sabnzbd.__version__) sabnzbd.halt() # Upload any nzb/zip/rar/nzb.gz files from file association if upload_nzbs: from sabnzbd.utils.upload import add_local for f in upload_nzbs: add_local(f) # Have to keep this running, otherwise logging will terminate timer = timer5 = 0 while not sabnzbd.SABSTOP: if sabnzbd.WIN_SERVICE: rc = win32event.WaitForMultipleObjects((sabnzbd.WIN_SERVICE.hWaitStop, sabnzbd.WIN_SERVICE.overlapped.hEvent), 0, 3000) if rc == win32event.WAIT_OBJECT_0: if mail: mail.send('stop') sabnzbd.save_state(flag=True) logging.info('Leaving SABnzbd') sabnzbd.SABSTOP = True return else: time.sleep(3) # Check for loglevel changes if LOG_FLAG: LOG_FLAG = False level = LOGLEVELS[sabnzbd.cfg.log_level()+1] logger.setLevel(level) if consoleLogging: console.setLevel(level) ### 30 sec polling tasks if timer > 9: timer = 0 # Keep OS awake (if needed) sabnzbd.keep_awake() # Restart scheduler (if needed) scheduler.restart() # Save config (if needed) config.save_config() # Check the threads if not sabnzbd.check_all_tasks(): autorestarted = True cherrypy.engine.execv = True # Notify guardian if sabnzbd.WIN_SERVICE and mail: mail.send('active') if timer5 > 9: ### 5 minute polling tasks timer5 = 0 if sabnzbd.cfg.web_watchdog() and not is_sabnzbd_running('%s/api?tickleme=1' % sabnzbd.BROWSER_URL, 120): autorestarted = True cherrypy.engine.execv = True else: timer5 += 1 else: timer += 1 ### 3 sec polling tasks # Check for auto-restart request if cherrypy.engine.execv: if sabnzbd.SCHED_RESTART: scheduler.abort() sabnzbd.halt() else: scheduler.stop() sabnzbd.halt() cherrypy.engine.exit() sabnzbd.SABSTOP = True if sabnzbd.downloader.Downloader.do.paused: re_argv.append('-p') if autorestarted: re_argv.append('--autorestarted') sys.argv = re_argv os.chdir(org_dir) if sabnzbd.DARWIN: args = sys.argv[:] args.insert(0, sys.executable) #TO FIX : when executing from sources on osx, after a restart, process is detached from console #If OSX frozen restart of app instead of embedded python if getattr(sys, 'frozen', None) == 'macosx_app': #[[NSProcessInfo processInfo] processIdentifier]] #logging.info("%s" % (NSProcessInfo.processInfo().processIdentifier())) logging.info(os.getpid()) os.system('kill -9 %s && open "%s"' % (os.getpid(),sabnzbd.MY_FULLNAME.replace("/Contents/MacOS/SABnzbd","")) ) else: pid = os.fork() if pid == 0: os.execv(sys.executable, args) elif sabnzbd.WIN_SERVICE and mail: logging.info('Asking the SABHelper service for a restart') mail.send('restart') mail.disconnect() return else: cherrypy.engine._do_execv() config.save_config() if sabnzbd.WINTRAY: sabnzbd.WINTRAY.terminate = True if sabnzbd.WIN_SERVICE and mail: mail.send('stop') if sabnzbd.WIN32: del_connection_info() if sabnzbd.FOUNDATION: sabnzbd.osxmenu.notify("SAB_Shutdown", None) logging.info('Leaving SABnzbd') sys.stderr.flush() sys.stdout.flush() sabnzbd.pid_file() if getattr(sys, 'frozen', None) == 'macosx_app': AppHelper.stopEventLoop() else: growler.send_notification('SABnzbd',T('SABnzbd shutdown finished'), 'startup') os._exit(0) ##################################################################### # # Windows Service Support # if sabnzbd.WIN32: import servicemanager class SABnzbd(win32serviceutil.ServiceFramework): """ Win32 Service Handler """ _svc_name_ = 'SABnzbd' _svc_display_name_ = 'SABnzbd Binary Newsreader' _svc_deps_ = ["EventLog", "Tcpip", "SABHelper"] _svc_description_ = 'Automated downloading from Usenet. ' \ 'Set to "automatic" to start the service at system startup. ' \ 'You may need to login with a real user account when you need ' \ 'access to network shares.' def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) self.overlapped = pywintypes.OVERLAPPED() self.overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None) sabnzbd.WIN_SERVICE = self def SvcDoRun(self): msg = 'SABnzbd-service %s' % sabnzbd.__version__ self.Logger(servicemanager.PYS_SERVICE_STARTED, msg + ' has started') sys.argv = get_serv_parms(self._svc_name_) main() self.Logger(servicemanager.PYS_SERVICE_STOPPED, msg + ' has stopped') def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) win32event.SetEvent(self.hWaitStop) def Logger(self, state, msg): win32evtlogutil.ReportEvent(self._svc_display_name_, state, 0, servicemanager.EVENTLOG_INFORMATION_TYPE, (self._svc_name_, unicoder(msg))) def ErrLogger(self, msg, text): win32evtlogutil.ReportEvent(self._svc_display_name_, servicemanager.PYS_SERVICE_STOPPED, 0, servicemanager.EVENTLOG_ERROR_TYPE, (self._svc_name_, unicoder(msg)), unicoder(text)) def prep_service_parms(args): """ Prepare parameter list for service """ # Must store our original path, because the Python Service launcher # won't give it to us. serv = [os.path.normpath(os.path.abspath(sys.argv[0]))] # Convert the tuples to list for arg in args: serv.append(arg[0]) if arg[1]: serv.append(arg[1]) # Make sure we run in daemon mode serv.append('-d') return serv SERVICE_MSG = """ You may need to set additional Service parameters. Run services.msc from a command prompt. Don't forget to install the Service SABnzbd-helper.exe too! """ def HandleCommandLine(allow_service=True): """ Handle command line for a Windows Service Prescribed name that will be called by Py2Exe. You MUST set 'cmdline_style':'custom' in the package.py! Returns True when any service commands were detected. """ service, sab_opts, serv_opts, upload_nzbs = commandline_handler() if service and not allow_service: # The other frozen apps don't support Services print "For service support, use SABnzbd-service.exe" return True elif service: if service in ('install', 'update'): # In this case check for required parameters path = get_f_option(sab_opts) if not path: print 'The -f parameter is required.\n' \ 'Use: -f %s' % service return True # First run the service installed, because this will # set the service key in the Registry win32serviceutil.HandleCommandLine(SABnzbd, argv=serv_opts) # Add our own parameter to the Registry sab_opts = prep_service_parms(sab_opts) if set_serv_parms(SABnzbd._svc_name_, sab_opts): print SERVICE_MSG else: print 'Cannot set required Registry info.' else: # Other service commands need no manipulation win32serviceutil.HandleCommandLine(SABnzbd) return bool(service) ##################################################################### # # Platform specific startup code # if __name__ == '__main__': args = [] for txt in sys.argv: if ' ' in txt: txt = '"%s"' % latin1(txt) else: txt = latin1(txt) args.append(txt) sabnzbd.CMDLINE = ' '.join(args) if sabnzbd.WIN32: if not HandleCommandLine(allow_service=not hasattr(sys, "frozen")): main() elif getattr(sys, 'frozen', None) == 'macosx_app': # OSX binary try: from PyObjCTools import AppHelper from sabnzbd.osxmenu import SABnzbdDelegate class startApp(Thread): def __init__(self): logging.info('[osx] sabApp Starting - starting main thread') Thread.__init__(self) def run(self): main() logging.info('[osx] sabApp Stopping - main thread quit ') AppHelper.stopEventLoop() def stop(self): logging.info('[osx] sabApp Quit - stopping main thread ') sabnzbd.halt() cherrypy.engine.exit() sabnzbd.SABSTOP = True logging.info('[osx] sabApp Quit - main thread stopped') sabApp = startApp() sabApp.start() AppHelper.runEventLoop() except: main() else: main() SABnzbd-0.7.20/Sample-PostProc.cmd0000644000000000000000000000072012433712601016700 0ustar00usergroup00000000000000@echo off rem Example of a post processing script for SABnzbd echo. echo Running in directory "%~d0%~p0" echo. echo The first parameter (result-dir) = %1 echo The second parameter (nzb-name) = %2 echo The third parameter (nice name) = %3 echo The fourth parameter (newzbin #) = %4 echo The fifth parameter (category) = %5 echo The sixth parameter (group) = %6 echo The seventh parameter (status) = %7 echo The eigth parameter (failure_url)= %8 echo. SABnzbd-0.7.20/Sample-PostProc.sh0000755000000000000000000000074112433712601016555 0ustar00usergroup00000000000000#!/bin/sh # Example of a post processing script for SABnzbd echo echo Started as $0 echo echo "The first parameter (result-dir) =" "$1" echo "The second parameter (nzb-name) =" "$2" echo "The third parameter (nice name) =" "$3" echo "The fourth parameter (newzbin-id) =" "$4" echo "The fifth parameter (category) =" "$5" echo "The sixth parameter (group) =" "$6" echo "The seventh parameter (status) =" "$7" echo "The eigth parameter (failure_url) =" "$8" echo SABnzbd-0.7.20/cherrypy/cherryd0000644000000000000000000000644112433712535016467 0ustar00usergroup00000000000000#! /usr/bin/env python """The CherryPy daemon.""" import sys import cherrypy from cherrypy.process import plugins, servers def start(configfiles=None, daemonize=False, environment=None, fastcgi=False, scgi=False, pidfile=None, imports=None): """Subscribe all engine plugins and start the engine.""" sys.path = [''] + sys.path for i in imports or []: exec "import %s" % i for c in configfiles or []: cherrypy.config.update(c) engine = cherrypy.engine if environment is not None: cherrypy.config.update({'environment': environment}) # Only daemonize if asked to. if daemonize: # Don't print anything to stdout/sterr. cherrypy.config.update({'log.screen': False}) plugins.Daemonizer(engine).subscribe() if pidfile: plugins.PIDFile(engine, pidfile).subscribe() if hasattr(engine, "signal_handler"): engine.signal_handler.subscribe() if hasattr(engine, "console_control_handler"): engine.console_control_handler.subscribe() if fastcgi and scgi: # fastcgi and scgi aren't allowed together. cherrypy.log.error("fastcgi and scgi aren't allowed together.", 'ENGINE') sys.exit(1) elif fastcgi or scgi: # Turn off autoreload when using fastcgi or scgi. cherrypy.config.update({'engine.autoreload_on': False}) # Turn off the default HTTP server (which is subscribed by default). cherrypy.server.unsubscribe() addr = cherrypy.server.bind_addr if fastcgi: f = servers.FlupFCGIServer(application=cherrypy.tree, bindAddress=addr) else: f = servers.FlupSCGIServer(application=cherrypy.tree, bindAddress=addr) s = servers.ServerAdapter(engine, httpserver=f, bind_addr=addr) s.subscribe() # Always start the engine; this will start all other services try: engine.start() except: # Assume the error has been logged already via bus.log. sys.exit(1) else: engine.block() if __name__ == '__main__': from optparse import OptionParser p = OptionParser() p.add_option('-c', '--config', action="append", dest='config', help="specify config file(s)") p.add_option('-d', action="store_true", dest='daemonize', help="run the server as a daemon") p.add_option('-e', '--environment', dest='environment', default=None, help="apply the given config environment") p.add_option('-f', action="store_true", dest='fastcgi', help="start a fastcgi server instead of the default HTTP server") p.add_option('-s', action="store_true", dest='scgi', help="start a scgi server instead of the default HTTP server") p.add_option('-i', '--import', action="append", dest='imports', help="specify modules to import") p.add_option('-p', '--pidfile', dest='pidfile', default=None, help="store the process id in the given file") options, args = p.parse_args() start(options.config, options.daemonize, options.environment, options.fastcgi, options.scgi, options.pidfile, options.imports) SABnzbd-0.7.20/cherrypy/favicon.ico0000644000000000000000000000217612433712535017226 0ustar00usergroup00000000000000 h(  !?[a]Gg 1G|4J=X1H-A8Q):oi],A& oV (;e278PU&4fkkgp"0,lqqqv !/D=V:T:T:T:T;U?Z+=(SABnzbd-0.7.20/cherrypy/LICENSE.txt0000644000000000000000000000302512433712602016715 0ustar00usergroup00000000000000Copyright (c) 2004-2007, CherryPy Team (team@cherrypy.org) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the CherryPy Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SABnzbd-0.7.20/cherrypy/VERSION.txt0000644000000000000000000000005612433712602016761 0ustar00usergroup00000000000000This CherryPy Rev 2138 patched with Rev 2272. SABnzbd-0.7.20/cherrypy/_cpcgifs.py0000644000000000000000000000464512433712602017232 0ustar00usergroup00000000000000import cgi import cherrypy class FieldStorage(cgi.FieldStorage): def __init__(self, *args, **kwds): try: cgi.FieldStorage.__init__(self, *args, **kwds) except ValueError, ex: if str(ex) == 'Maximum content length exceeded': raise cherrypy.HTTPError(status=413) else: raise ex def read_lines_to_eof(self): """Internal: read lines until EOF.""" while 1: line = self.fp.readline(1<<16) if not line: self.done = -1 break self.__write(line) def read_lines_to_outerboundary(self): """Internal: read lines until outerboundary.""" next = "--" + self.outerboundary last = next + "--" delim = "" last_line_lfend = True while 1: line = self.fp.readline(1<<16) if not line: self.done = -1 break if line[:2] == "--" and last_line_lfend: strippedline = line.strip() if strippedline == next: break if strippedline == last: self.done = 1 break odelim = delim if line[-2:] == "\r\n": delim = "\r\n" line = line[:-2] last_line_lfend = True elif line[-1] == "\n": delim = "\n" line = line[:-1] last_line_lfend = True else: delim = "" last_line_lfend = False self.__write(odelim + line) def skip_lines(self): """Internal: skip lines until outer boundary if defined.""" if not self.outerboundary or self.done: return next = "--" + self.outerboundary last = next + "--" last_line_lfend = True while 1: line = self.fp.readline(1<<16) if not line: self.done = -1 break if line[:2] == "--" and last_line_lfend: strippedline = line.strip() if strippedline == next: break if strippedline == last: self.done = 1 break if line.endswith('\n'): last_line_lfend = True else: last_line_lfend = False SABnzbd-0.7.20/cherrypy/_cpchecker.py0000644000000000000000000003037312433712602017540 0ustar00usergroup00000000000000import os import warnings import cherrypy class Checker(object): """A checker for CherryPy sites and their mounted applications. on: set this to False to turn off the checker completely. When this object is called at engine startup, it executes each of its own methods whose names start with "check_". If you wish to disable selected checks, simply add a line in your global config which sets the appropriate method to False: [global] checker.check_skipped_app_config = False You may also dynamically add or replace check_* methods in this way. """ on = True def __init__(self): self._populate_known_types() def __call__(self): """Run all check_* methods.""" if self.on: oldformatwarning = warnings.formatwarning warnings.formatwarning = self.formatwarning try: for name in dir(self): if name.startswith("check_"): method = getattr(self, name) if method and callable(method): method() finally: warnings.formatwarning = oldformatwarning def formatwarning(self, message, category, filename, lineno, line=None): """Function to format a warning.""" return "CherryPy Checker:\n%s\n\n" % message # This value should be set inside _cpconfig. global_config_contained_paths = False def check_app_config_entries_dont_start_with_script_name(self): for sn, app in cherrypy.tree.apps.iteritems(): if not isinstance(app, cherrypy.Application): continue if not app.config: continue if sn == '': continue sn_atoms = sn.strip("/").split("/") for key in app.config.keys(): key_atoms = key.strip("/").split("/") if key_atoms[:len(sn_atoms)] == sn_atoms: warnings.warn( "The application mounted at %r has config " \ "entries that start with its script name: %r" % (sn, key)) def check_skipped_app_config(self): for sn, app in cherrypy.tree.apps.iteritems(): if not isinstance(app, cherrypy.Application): continue if not app.config: msg = "The Application mounted at %r has an empty config." % sn if self.global_config_contained_paths: msg += (" It looks like the config you passed to " "cherrypy.config.update() contains application-" "specific sections. You must explicitly pass " "application config via " "cherrypy.tree.mount(..., config=app_config)") warnings.warn(msg) return def check_static_paths(self): # Use the dummy Request object in the main thread. request = cherrypy.request for sn, app in cherrypy.tree.apps.iteritems(): if not isinstance(app, cherrypy.Application): continue request.app = app for section in app.config: # get_resource will populate request.config request.get_resource(section + "/dummy.html") conf = request.config.get if conf("tools.staticdir.on", False): msg = "" root = conf("tools.staticdir.root") dir = conf("tools.staticdir.dir") if dir is None: msg = "tools.staticdir.dir is not set." else: fulldir = "" if os.path.isabs(dir): fulldir = dir if root: msg = ("dir is an absolute path, even " "though a root is provided.") testdir = os.path.join(root, dir[1:]) if os.path.exists(testdir): msg += ("\nIf you meant to serve the " "filesystem folder at %r, remove " "the leading slash from dir." % testdir) else: if not root: msg = "dir is a relative path and no root provided." else: fulldir = os.path.join(root, dir) if not os.path.isabs(fulldir): msg = "%r is not an absolute path." % fulldir if fulldir and not os.path.exists(fulldir): if msg: msg += "\n" msg += ("%r (root + dir) is not an existing " "filesystem path." % fulldir) if msg: warnings.warn("%s\nsection: [%s]\nroot: %r\ndir: %r" % (msg, section, root, dir)) # -------------------------- Compatibility -------------------------- # obsolete = { 'server.default_content_type': 'tools.response_headers.headers', 'log_access_file': 'log.access_file', 'log_config_options': None, 'log_file': 'log.error_file', 'log_file_not_found': None, 'log_request_headers': 'tools.log_headers.on', 'log_to_screen': 'log.screen', 'show_tracebacks': 'request.show_tracebacks', 'throw_errors': 'request.throw_errors', 'profiler.on': ('cherrypy.tree.mount(profiler.make_app(' 'cherrypy.Application(Root())))'), } deprecated = {} def _compat(self, config): """Process config and warn on each obsolete or deprecated entry.""" for section, conf in config.iteritems(): if isinstance(conf, dict): for k, v in conf.iteritems(): if k in self.obsolete: warnings.warn("%r is obsolete. Use %r instead.\n" "section: [%s]" % (k, self.obsolete[k], section)) elif k in self.deprecated: warnings.warn("%r is deprecated. Use %r instead.\n" "section: [%s]" % (k, self.deprecated[k], section)) else: if section in self.obsolete: warnings.warn("%r is obsolete. Use %r instead." % (section, self.obsolete[section])) elif section in self.deprecated: warnings.warn("%r is deprecated. Use %r instead." % (section, self.deprecated[section])) def check_compatibility(self): """Process config and warn on each obsolete or deprecated entry.""" self._compat(cherrypy.config) for sn, app in cherrypy.tree.apps.iteritems(): if not isinstance(app, cherrypy.Application): continue self._compat(app.config) # ------------------------ Known Namespaces ------------------------ # extra_config_namespaces = [] def _known_ns(self, app): ns = ["wsgi"] ns.extend(app.toolboxes.keys()) ns.extend(app.namespaces.keys()) ns.extend(app.request_class.namespaces.keys()) ns.extend(cherrypy.config.namespaces.keys()) ns += self.extra_config_namespaces for section, conf in app.config.iteritems(): is_path_section = section.startswith("/") if is_path_section and isinstance(conf, dict): for k, v in conf.iteritems(): atoms = k.split(".") if len(atoms) > 1: if atoms[0] not in ns: # Spit out a special warning if a known # namespace is preceded by "cherrypy." if (atoms[0] == "cherrypy" and atoms[1] in ns): msg = ("The config entry %r is invalid; " "try %r instead.\nsection: [%s]" % (k, ".".join(atoms[1:]), section)) else: msg = ("The config entry %r is invalid, because " "the %r config namespace is unknown.\n" "section: [%s]" % (k, atoms[0], section)) warnings.warn(msg) elif atoms[0] == "tools": if atoms[1] not in dir(cherrypy.tools): msg = ("The config entry %r may be invalid, " "because the %r tool was not found.\n" "section: [%s]" % (k, atoms[1], section)) warnings.warn(msg) def check_config_namespaces(self): """Process config and warn on each unknown config namespace.""" for sn, app in cherrypy.tree.apps.iteritems(): if not isinstance(app, cherrypy.Application): continue self._known_ns(app) # -------------------------- Config Types -------------------------- # known_config_types = {} def _populate_known_types(self): import __builtin__ builtins = [x for x in vars(__builtin__).values() if type(x) is type(str)] def traverse(obj, namespace): for name in dir(obj): vtype = type(getattr(obj, name, None)) if vtype in builtins: self.known_config_types[namespace + "." + name] = vtype traverse(cherrypy.request, "request") traverse(cherrypy.response, "response") traverse(cherrypy.server, "server") traverse(cherrypy.engine, "engine") traverse(cherrypy.log, "log") def _known_types(self, config): msg = ("The config entry %r in section %r is of type %r, " "which does not match the expected type %r.") for section, conf in config.iteritems(): if isinstance(conf, dict): for k, v in conf.iteritems(): if v is not None: expected_type = self.known_config_types.get(k, None) vtype = type(v) if expected_type and vtype != expected_type: warnings.warn(msg % (k, section, vtype.__name__, expected_type.__name__)) else: k, v = section, conf if v is not None: expected_type = self.known_config_types.get(k, None) vtype = type(v) if expected_type and vtype != expected_type: warnings.warn(msg % (k, section, vtype.__name__, expected_type.__name__)) def check_config_types(self): """Assert that config values are of the same type as default values.""" self._known_types(cherrypy.config) for sn, app in cherrypy.tree.apps.iteritems(): if not isinstance(app, cherrypy.Application): continue self._known_types(app.config) # -------------------- Specific config warnings -------------------- # def check_localhost(self): """Warn if any socket_host is 'localhost'. See #711.""" for k, v in cherrypy.config.iteritems(): if k == 'server.socket_host' and v == 'localhost': warnings.warn("The use of 'localhost' as a socket host can " "cause problems on newer systems, since 'localhost' can " "map to either an IPv4 or an IPv6 address. You should " "use '127.0.0.1' or '[::1]' instead.") SABnzbd-0.7.20/cherrypy/_cpconfig.py0000644000000000000000000003531112433712602017376 0ustar00usergroup00000000000000"""Configuration system for CherryPy. Configuration in CherryPy is implemented via dictionaries. Keys are strings which name the mapped value, which may be of any type. Architecture ------------ CherryPy Requests are part of an Application, which runs in a global context, and configuration data may apply to any of those three scopes: Global: configuration entries which apply everywhere are stored in cherrypy.config. Application: entries which apply to each mounted application are stored on the Application object itself, as 'app.config'. This is a two-level dict where each key is a path, or "relative URL" (for example, "/" or "/path/to/my/page"), and each value is a config dict. Usually, this data is provided in the call to tree.mount(root(), config=conf), although you may also use app.merge(conf). Request: each Request object possesses a single 'Request.config' dict. Early in the request process, this dict is populated by merging global config entries, Application entries (whose path equals or is a parent of Request.path_info), and any config acquired while looking up the page handler (see next). Declaration ----------- Configuration data may be supplied as a Python dictionary, as a filename, or as an open file object. When you supply a filename or file, CherryPy uses Python's builtin ConfigParser; you declare Application config by writing each path as a section header: [/path/to/my/page] request.stream = True To declare global configuration entries, place them in a [global] section. You may also declare config entries directly on the classes and methods (page handlers) that make up your CherryPy application via the '_cp_config' attribute. For example: class Demo: _cp_config = {'tools.gzip.on': True} def index(self): return "Hello world" index.exposed = True index._cp_config = {'request.show_tracebacks': False} Note, however, that this behavior is only guaranteed for the default dispatcher. Other dispatchers may have different restrictions on where you can attach _cp_config attributes. Namespaces ---------- Configuration keys are separated into namespaces by the first "." in the key. Current namespaces: engine: Controls the 'application engine', including autoreload. These can only be declared in the global config. tree: Grafts cherrypy.Application objects onto cherrypy.tree. These can only be declared in the global config. hooks: Declares additional request-processing functions. log: Configures the logging for each application. These can only be declared in the global or / config. request: Adds attributes to each Request. response: Adds attributes to each Response. server: Controls the default HTTP server via cherrypy.server. These can only be declared in the global config. tools: Runs and configures additional request-processing packages. wsgi: Adds WSGI middleware to an Application's "pipeline". These can only be declared in the app's root config ("/"). checker: Controls the 'checker', which looks for common errors in app state (including config) when the engine starts. Global config only. The only key that does not exist in a namespace is the "environment" entry. This special entry 'imports' other config entries from a template stored in cherrypy._cpconfig.environments[environment]. It only applies to the global config, and only when you use cherrypy.config.update. You can define your own namespaces to be called at the Global, Application, or Request level, by adding a named handler to cherrypy.config.namespaces, app.namespaces, or app.request_class.namespaces. The name can be any string, and the handler must be either a callable or a (Python 2.5 style) context manager. """ import ConfigParser try: set except NameError: from sets import Set as set import sys import cherrypy environments = { "staging": { 'engine.autoreload_on': False, 'checker.on': False, 'tools.log_headers.on': False, 'request.show_tracebacks': False, 'request.show_mismatched_params': False, }, "production": { 'engine.autoreload_on': False, 'checker.on': False, 'tools.log_headers.on': False, 'request.show_tracebacks': False, 'request.show_mismatched_params': False, 'log.screen': False, }, "embedded": { # For use with CherryPy embedded in another deployment stack. 'engine.autoreload_on': False, 'checker.on': False, 'tools.log_headers.on': False, 'request.show_tracebacks': False, 'request.show_mismatched_params': False, 'log.screen': False, 'engine.SIGHUP': None, 'engine.SIGTERM': None, }, "test_suite": { 'engine.autoreload_on': False, 'checker.on': False, 'tools.log_headers.on': False, 'request.show_tracebacks': True, 'request.show_mismatched_params': True, 'log.screen': False, }, } def as_dict(config): """Return a dict from 'config' whether it is a dict, file, or filename.""" if isinstance(config, basestring): config = _Parser().dict_from_file(config) elif hasattr(config, 'read'): config = _Parser().dict_from_file(config) return config def merge(base, other): """Merge one app config (from a dict, file, or filename) into another. If the given config is a filename, it will be appended to the list of files to monitor for "autoreload" changes. """ if isinstance(other, basestring): cherrypy.engine.autoreload.files.add(other) # Load other into base for section, value_map in as_dict(other).iteritems(): base.setdefault(section, {}).update(value_map) class NamespaceSet(dict): """A dict of config namespace names and handlers. Each config entry should begin with a namespace name; the corresponding namespace handler will be called once for each config entry in that namespace, and will be passed two arguments: the config key (with the namespace removed) and the config value. Namespace handlers may be any Python callable; they may also be Python 2.5-style 'context managers', in which case their __enter__ method should return a callable to be used as the handler. See cherrypy.tools (the Toolbox class) for an example. """ def __call__(self, config): """Iterate through config and pass it to each namespace handler. 'config' should be a flat dict, where keys use dots to separate namespaces, and values are arbitrary. The first name in each config key is used to look up the corresponding namespace handler. For example, a config entry of {'tools.gzip.on': v} will call the 'tools' namespace handler with the args: ('gzip.on', v) """ # Separate the given config into namespaces ns_confs = {} for k in config: if "." in k: ns, name = k.split(".", 1) bucket = ns_confs.setdefault(ns, {}) bucket[name] = config[k] # I chose __enter__ and __exit__ so someday this could be # rewritten using Python 2.5's 'with' statement: # for ns, handler in self.iteritems(): # with handler as callable: # for k, v in ns_confs.get(ns, {}).iteritems(): # callable(k, v) for ns, handler in self.iteritems(): exit = getattr(handler, "__exit__", None) if exit: callable = handler.__enter__() no_exc = True try: try: for k, v in ns_confs.get(ns, {}).iteritems(): callable(k, v) except: # The exceptional case is handled here no_exc = False if exit is None: raise if not exit(*sys.exc_info()): raise # The exception is swallowed if exit() returns true finally: # The normal and non-local-goto cases are handled here if no_exc and exit: exit(None, None, None) else: for k, v in ns_confs.get(ns, {}).iteritems(): handler(k, v) def __repr__(self): return "%s.%s(%s)" % (self.__module__, self.__class__.__name__, dict.__repr__(self)) def __copy__(self): newobj = self.__class__() newobj.update(self) return newobj copy = __copy__ class Config(dict): """The 'global' configuration data for the entire CherryPy process.""" defaults = { 'tools.log_tracebacks.on': True, 'tools.log_headers.on': True, 'tools.trailing_slash.on': True, } namespaces = NamespaceSet( **{"log": lambda k, v: setattr(cherrypy.log, k, v), "checker": lambda k, v: setattr(cherrypy.checker, k, v), }) def __init__(self): self.reset() def reset(self): """Reset self to default values.""" self.clear() dict.update(self, self.defaults) def update(self, config): """Update self from a dict, file or filename.""" if isinstance(config, basestring): # Filename cherrypy.engine.autoreload.files.add(config) config = _Parser().dict_from_file(config) elif hasattr(config, 'read'): # Open file object config = _Parser().dict_from_file(config) else: config = config.copy() if isinstance(config.get("global", None), dict): if len(config) > 1: cherrypy.checker.global_config_contained_paths = True config = config["global"] which_env = config.get('environment') if which_env: env = environments[which_env] for k in env: if k not in config: config[k] = env[k] if 'tools.staticdir.dir' in config: config['tools.staticdir.section'] = "global" dict.update(self, config) self.namespaces(config) def __setitem__(self, k, v): dict.__setitem__(self, k, v) self.namespaces({k: v}) def _server_namespace_handler(k, v): """Config handler for the "server" namespace.""" atoms = k.split(".", 1) if len(atoms) > 1: # Special-case config keys of the form 'server.servername.socket_port' # to configure additional HTTP servers. if not hasattr(cherrypy, "servers"): cherrypy.servers = {} servername, k = atoms if servername not in cherrypy.servers: from cherrypy import _cpserver cherrypy.servers[servername] = _cpserver.Server() # On by default, but 'on = False' can unsubscribe it (see below). cherrypy.servers[servername].subscribe() if k == 'on': if v: cherrypy.servers[servername].subscribe() else: cherrypy.servers[servername].unsubscribe() else: setattr(cherrypy.servers[servername], k, v) else: setattr(cherrypy.server, k, v) Config.namespaces["server"] = _server_namespace_handler def _engine_namespace_handler(k, v): """Backward compatibility handler for the "engine" namespace.""" engine = cherrypy.engine if k == 'autoreload_on': if v: engine.autoreload.subscribe() else: engine.autoreload.unsubscribe() elif k == 'autoreload_frequency': engine.autoreload.frequency = v elif k == 'autoreload_match': engine.autoreload.match = v elif k == 'reload_files': engine.autoreload.files = set(v) elif k == 'deadlock_poll_freq': engine.timeout_monitor.frequency = v elif k == 'SIGHUP': engine.listeners['SIGHUP'] = set([v]) elif k == 'SIGTERM': engine.listeners['SIGTERM'] = set([v]) elif "." in k: plugin, attrname = k.split(".", 1) plugin = getattr(engine, plugin) if attrname == 'on': if v and callable(getattr(plugin, 'subscribe', None)): plugin.subscribe() return elif (not v) and callable(getattr(plugin, 'unsubscribe', None)): plugin.unsubscribe() return setattr(plugin, attrname, v) else: setattr(engine, k, v) Config.namespaces["engine"] = _engine_namespace_handler def _tree_namespace_handler(k, v): """Namespace handler for the 'tree' config namespace.""" cherrypy.tree.graft(v, v.script_name) cherrypy.engine.log("Mounted: %s on %s" % (v, v.script_name or "/")) Config.namespaces["tree"] = _tree_namespace_handler class _Parser(ConfigParser.ConfigParser): """Sub-class of ConfigParser that keeps the case of options and that raises an exception if the file cannot be read. """ def optionxform(self, optionstr): return optionstr def read(self, filenames): if isinstance(filenames, basestring): filenames = [filenames] for filename in filenames: # try: # fp = open(filename) # except IOError: # continue fp = open(filename) try: self._read(fp, filename) finally: fp.close() def as_dict(self, raw=False, vars=None): """Convert an INI file to a dictionary""" # Load INI file into a dict from cherrypy.lib import unrepr result = {} for section in self.sections(): if section not in result: result[section] = {} for option in self.options(section): value = self.get(section, option, raw, vars) try: value = unrepr(value) except Exception, x: msg = ("Config error in section: %r, option: %r, " "value: %r. Config values must be valid Python." % (section, option, value)) raise ValueError(msg, x.__class__.__name__, x.args) result[section][option] = value return result def dict_from_file(self, file): if hasattr(file, 'read'): self.readfp(file) else: self.read(file) return self.as_dict() del ConfigParser SABnzbd-0.7.20/cherrypy/_cpdispatch.py0000644000000000000000000005160212433712602017731 0ustar00usergroup00000000000000"""CherryPy dispatchers. A 'dispatcher' is the object which looks up the 'page handler' callable and collects config for the current request based on the path_info, other request attributes, and the application architecture. The core calls the dispatcher as early as possible, passing it a 'path_info' argument. The default dispatcher discovers the page handler by matching path_info to a hierarchical arrangement of objects, starting at request.app.root. """ import cherrypy class PageHandler(object): """Callable which sets response.body.""" def __init__(self, callable, *args, **kwargs): self.callable = callable self.args = args self.kwargs = kwargs def __call__(self): try: return self.callable(*self.args, **self.kwargs) except TypeError, x: try: test_callable_spec(self.callable, self.args, self.kwargs) except cherrypy.HTTPError, error: raise error except: raise x raise def test_callable_spec(callable, callable_args, callable_kwargs): """ Inspect callable and test to see if the given args are suitable for it. When an error occurs during the handler's invoking stage there are 2 erroneous cases: 1. Too many parameters passed to a function which doesn't define one of *args or **kwargs. 2. Too little parameters are passed to the function. There are 3 sources of parameters to a cherrypy handler. 1. query string parameters are passed as keyword parameters to the handler. 2. body parameters are also passed as keyword parameters. 3. when partial matching occurs, the final path atoms are passed as positional args. Both the query string and path atoms are part of the URI. If they are incorrect, then a 404 Not Found should be raised. Conversely the body parameters are part of the request; if they are invalid a 400 Bad Request. """ show_mismatched_params = getattr(cherrypy.request, 'show_mismatched_params', False) try: (args, varargs, varkw, defaults) = inspect.getargspec(callable) except TypeError: if isinstance(callable, object) and hasattr(callable, '__call__'): (args, varargs, varkw, defaults) = inspect.getargspec(callable.__call__) else: # If it wasn't one of our own types, re-raise # the original error raise if args and args[0] == 'self': args = args[1:] arg_usage = dict([(arg, 0,) for arg in args]) vararg_usage = 0 varkw_usage = 0 extra_kwargs = set() for i, value in enumerate(callable_args): try: arg_usage[args[i]] += 1 except IndexError: vararg_usage += 1 for key in callable_kwargs.keys(): try: arg_usage[key] += 1 except KeyError: varkw_usage += 1 extra_kwargs.add(key) for i, val in enumerate(defaults or []): # Defaults take effect only when the arg hasn't been used yet. if arg_usage[args[i]] == 0: arg_usage[args[i]] += 1 missing_args = [] multiple_args = [] for key, usage in arg_usage.iteritems(): if usage == 0: missing_args.append(key) elif usage > 1: multiple_args.append(key) if missing_args: # In the case where the method allows body arguments # there are 3 potential errors: # 1. not enough query string parameters -> 404 # 2. not enough body parameters -> 400 # 3. not enough path parts (partial matches) -> 404 # # We can't actually tell which case it is, # so I'm raising a 404 because that covers 2/3 of the # possibilities # # In the case where the method does not allow body # arguments it's definitely a 404. message = None if show_mismatched_params: message="Missing parameters: %s" % ",".join(missing_args) raise cherrypy.HTTPError(404, message=message) # the extra positional arguments come from the path - 404 Not Found if not varargs and vararg_usage > 0: raise cherrypy.HTTPError(404) body_params = cherrypy.request.body_params or {} body_params = set(body_params.keys()) qs_params = set(callable_kwargs.keys()) - body_params if multiple_args: if qs_params.intersection(set(multiple_args)): # If any of the multiple parameters came from the query string then # it's a 404 Not Found error = 404 else: # Otherwise it's a 400 Bad Request error = 400 message = None if show_mismatched_params: message="Multiple values for parameters: "\ "%s" % ",".join(multiple_args) raise cherrypy.HTTPError(error, message=message) if not varkw and varkw_usage > 0: # If there were extra query string parameters, it's a 404 Not Found extra_qs_params = set(qs_params).intersection(extra_kwargs) if extra_qs_params: message = None if show_mismatched_params: message="Unexpected query string "\ "parameters: %s" % ", ".join(extra_qs_params) raise cherrypy.HTTPError(404, message=message) # If there were any extra body parameters, it's a 400 Not Found extra_body_params = set(body_params).intersection(extra_kwargs) if extra_body_params: message = None if show_mismatched_params: message="Unexpected body parameters: "\ "%s" % ", ".join(extra_body_params) raise cherrypy.HTTPError(400, message=message) try: import inspect except ImportError: test_callable_spec = lambda callable, args, kwargs: None class LateParamPageHandler(PageHandler): """When passing cherrypy.request.params to the page handler, we do not want to capture that dict too early; we want to give tools like the decoding tool a chance to modify the params dict in-between the lookup of the handler and the actual calling of the handler. This subclass takes that into account, and allows request.params to be 'bound late' (it's more complicated than that, but that's the effect). """ def _get_kwargs(self): kwargs = cherrypy.request.params.copy() if self._kwargs: kwargs.update(self._kwargs) return kwargs def _set_kwargs(self, kwargs): self._kwargs = kwargs kwargs = property(_get_kwargs, _set_kwargs, doc='page handler kwargs (with ' 'cherrypy.request.params copied in)') class Dispatcher(object): """CherryPy Dispatcher which walks a tree of objects to find a handler. The tree is rooted at cherrypy.request.app.root, and each hierarchical component in the path_info argument is matched to a corresponding nested attribute of the root object. Matching handlers must have an 'exposed' attribute which evaluates to True. The special method name "index" matches a URI which ends in a slash ("/"). The special method name "default" may match a portion of the path_info (but only when no longer substring of the path_info matches some other object). This is the default, built-in dispatcher for CherryPy. """ __metaclass__ = cherrypy._AttributeDocstrings dispatch_method_name = '_cp_dispatch' dispatch_method_name__doc = """ The name of the dispatch method that nodes may optionally implement to provide their own dynamic dispatch algorithm. """ def __init__(self, dispatch_method_name = None): if dispatch_method_name: self.dispatch_method_name = dispatch_method_name def __call__(self, path_info): """Set handler and config for the current request.""" request = cherrypy.request func, vpath = self.find_handler(path_info) if func: # Decode any leftover %2F in the virtual_path atoms. vpath = [x.replace("%2F", "/") for x in vpath] request.handler = LateParamPageHandler(func, *vpath) else: request.handler = cherrypy.NotFound() def find_handler(self, path): """Return the appropriate page handler, plus any virtual path. This will return two objects. The first will be a callable, which can be used to generate page output. Any parameters from the query string or request body will be sent to that callable as keyword arguments. The callable is found by traversing the application's tree, starting from cherrypy.request.app.root, and matching path components to successive objects in the tree. For example, the URL "/path/to/handler" might return root.path.to.handler. The second object returned will be a list of names which are 'virtual path' components: parts of the URL which are dynamic, and were not used when looking up the handler. These virtual path components are passed to the handler as positional arguments. """ request = cherrypy.request app = request.app root = app.root dispatch_name = self.dispatch_method_name # Get config for the root object/path. curpath = "" nodeconf = {} if hasattr(root, "_cp_config"): nodeconf.update(root._cp_config) if "/" in app.config: nodeconf.update(app.config["/"]) object_trail = [['root', root, nodeconf, curpath]] node = root names = [x for x in path.strip('/').split('/') if x] + ['index'] iternames = names[:] while iternames: name = iternames[0] # map to legal Python identifiers (replace '.' with '_') objname = name.replace('.', '_') nodeconf = {} subnode = getattr(node, objname, None) if subnode is None: dispatch = getattr(node, dispatch_name, None) if dispatch and callable(dispatch) and not \ getattr(dispatch, 'exposed', False): subnode = dispatch(vpath=iternames) name = iternames.pop(0) node = subnode if node is not None: # Get _cp_config attached to this node. if hasattr(node, "_cp_config"): nodeconf.update(node._cp_config) # Mix in values from app.config for this path. curpath = "/".join((curpath, name)) if curpath in app.config: nodeconf.update(app.config[curpath]) object_trail.append([name, node, nodeconf, curpath]) def set_conf(): """Collapse all object_trail config into cherrypy.request.config.""" base = cherrypy.config.copy() # Note that we merge the config from each node # even if that node was None. for name, obj, conf, curpath in object_trail: base.update(conf) if 'tools.staticdir.dir' in conf: base['tools.staticdir.section'] = curpath return base # Try successive objects (reverse order) num_candidates = len(object_trail) - 1 for i in xrange(num_candidates, -1, -1): name, candidate, nodeconf, curpath = object_trail[i] if candidate is None: continue # Try a "default" method on the current leaf. if hasattr(candidate, "default"): defhandler = candidate.default if getattr(defhandler, 'exposed', False): # Insert any extra _cp_config from the default handler. conf = getattr(defhandler, "_cp_config", {}) object_trail.insert(i+1, ["default", defhandler, conf, curpath]) request.config = set_conf() # See http://www.cherrypy.org/ticket/613 request.is_index = path.endswith("/") return defhandler, names[i:-1] # Uncomment the next line to restrict positional params to "default". # if i < num_candidates - 2: continue # Try the current leaf. if getattr(candidate, 'exposed', False): request.config = set_conf() if i == num_candidates: # We found the extra ".index". Mark request so tools # can redirect if path_info has no trailing slash. request.is_index = True else: # We're not at an 'index' handler. Mark request so tools # can redirect if path_info has NO trailing slash. # Note that this also includes handlers which take # positional parameters (virtual paths). request.is_index = False return candidate, names[i:-1] # We didn't find anything request.config = set_conf() return None, [] class MethodDispatcher(Dispatcher): """Additional dispatch based on cherrypy.request.method.upper(). Methods named GET, POST, etc will be called on an exposed class. The method names must be all caps; the appropriate Allow header will be output showing all capitalized method names as allowable HTTP verbs. Note that the containing class must be exposed, not the methods. """ def __call__(self, path_info): """Set handler and config for the current request.""" request = cherrypy.request resource, vpath = self.find_handler(path_info) if resource: # Set Allow header avail = [m for m in dir(resource) if m.isupper()] if "GET" in avail and "HEAD" not in avail: avail.append("HEAD") avail.sort() cherrypy.response.headers['Allow'] = ", ".join(avail) # Find the subhandler meth = request.method.upper() func = getattr(resource, meth, None) if func is None and meth == "HEAD": func = getattr(resource, "GET", None) if func: # Decode any leftover %2F in the virtual_path atoms. vpath = [x.replace("%2F", "/") for x in vpath] request.handler = LateParamPageHandler(func, *vpath) else: request.handler = cherrypy.HTTPError(405) else: request.handler = cherrypy.NotFound() class RoutesDispatcher(object): """A Routes based dispatcher for CherryPy.""" def __init__(self, full_result=False): """ Routes dispatcher Set full_result to True if you wish the controller and the action to be passed on to the page handler parameters. By default they won't be. """ import routes self.full_result = full_result self.controllers = {} self.mapper = routes.Mapper() self.mapper.controller_scan = self.controllers.keys def connect(self, name, route, controller, **kwargs): self.controllers[name] = controller self.mapper.connect(name, route, controller=name, **kwargs) def redirect(self, url): raise cherrypy.HTTPRedirect(url) def __call__(self, path_info): """Set handler and config for the current request.""" func = self.find_handler(path_info) if func: cherrypy.request.handler = LateParamPageHandler(func) else: cherrypy.request.handler = cherrypy.NotFound() def find_handler(self, path_info): """Find the right page handler, and set request.config.""" import routes request = cherrypy.request config = routes.request_config() config.mapper = self.mapper if hasattr(cherrypy.request, 'wsgi_environ'): config.environ = cherrypy.request.wsgi_environ config.host = request.headers.get('Host', None) config.protocol = request.scheme config.redirect = self.redirect result = self.mapper.match(path_info) config.mapper_dict = result params = {} if result: params = result.copy() if not self.full_result: params.pop('controller', None) params.pop('action', None) request.params.update(params) # Get config for the root object/path. request.config = base = cherrypy.config.copy() curpath = "" def merge(nodeconf): if 'tools.staticdir.dir' in nodeconf: nodeconf['tools.staticdir.section'] = curpath or "/" base.update(nodeconf) app = request.app root = app.root if hasattr(root, "_cp_config"): merge(root._cp_config) if "/" in app.config: merge(app.config["/"]) # Mix in values from app.config. atoms = [x for x in path_info.split("/") if x] if atoms: last = atoms.pop() else: last = None for atom in atoms: curpath = "/".join((curpath, atom)) if curpath in app.config: merge(app.config[curpath]) handler = None if result: controller = result.get('controller', None) controller = self.controllers.get(controller) if controller: # Get config from the controller. if hasattr(controller, "_cp_config"): merge(controller._cp_config) action = result.get('action', None) if action is not None: handler = getattr(controller, action, None) # Get config from the handler if hasattr(handler, "_cp_config"): merge(handler._cp_config) # Do the last path atom here so it can # override the controller's _cp_config. if last: curpath = "/".join((curpath, last)) if curpath in app.config: merge(app.config[curpath]) return handler def XMLRPCDispatcher(next_dispatcher=Dispatcher()): from cherrypy.lib import xmlrpc def xmlrpc_dispatch(path_info): path_info = xmlrpc.patched_path(path_info) return next_dispatcher(path_info) return xmlrpc_dispatch def VirtualHost(next_dispatcher=Dispatcher(), use_x_forwarded_host=True, **domains): """Select a different handler based on the Host header. This can be useful when running multiple sites within one CP server. It allows several domains to point to different parts of a single website structure. For example: http://www.domain.example -> root http://www.domain2.example -> root/domain2/ http://www.domain2.example:443 -> root/secure can be accomplished via the following config: [/] request.dispatch = cherrypy.dispatch.VirtualHost( **{'www.domain2.example': '/domain2', 'www.domain2.example:443': '/secure', }) next_dispatcher: the next dispatcher object in the dispatch chain. The VirtualHost dispatcher adds a prefix to the URL and calls another dispatcher. Defaults to cherrypy.dispatch.Dispatcher(). use_x_forwarded_host: if True (the default), any "X-Forwarded-Host" request header will be used instead of the "Host" header. This is commonly added by HTTP servers (such as Apache) when proxying. **domains: a dict of {host header value: virtual prefix} pairs. The incoming "Host" request header is looked up in this dict, and, if a match is found, the corresponding "virtual prefix" value will be prepended to the URL path before calling the next dispatcher. Note that you often need separate entries for "example.com" and "www.example.com". In addition, "Host" headers may contain the port number. """ from cherrypy.lib import http def vhost_dispatch(path_info): header = cherrypy.request.headers.get domain = header('Host', '') if use_x_forwarded_host: domain = header("X-Forwarded-Host", domain) prefix = domains.get(domain, "") if prefix: path_info = http.urljoin(prefix, path_info) result = next_dispatcher(path_info) # Touch up staticdir config. See http://www.cherrypy.org/ticket/614. section = cherrypy.request.config.get('tools.staticdir.section') if section: section = section[len(prefix):] cherrypy.request.config['tools.staticdir.section'] = section return result return vhost_dispatch SABnzbd-0.7.20/cherrypy/_cperror.py0000644000000000000000000003415412433712602017266 0ustar00usergroup00000000000000"""Error classes for CherryPy.""" from cgi import escape as _escape from sys import exc_info as _exc_info from traceback import format_exception as _format_exception from urlparse import urljoin as _urljoin from cherrypy.lib import http as _http class CherryPyException(Exception): pass class TimeoutError(CherryPyException): """Exception raised when Response.timed_out is detected.""" pass class InternalRedirect(CherryPyException): """Exception raised to switch to the handler for a different URL. Any request.params must be supplied in a query string. """ def __init__(self, path): import cherrypy request = cherrypy.request self.query_string = "" if "?" in path: # Separate any params included in the path path, self.query_string = path.split("?", 1) # Note that urljoin will "do the right thing" whether url is: # 1. a URL relative to root (e.g. "/dummy") # 2. a URL relative to the current path # Note that any query string will be discarded. path = _urljoin(request.path_info, path) # Set a 'path' member attribute so that code which traps this # error can have access to it. self.path = path CherryPyException.__init__(self, path, self.query_string) class HTTPRedirect(CherryPyException): """Exception raised when the request should be redirected. The new URL must be passed as the first argument to the Exception, e.g., HTTPRedirect(newUrl). Multiple URLs are allowed. If a URL is absolute, it will be used as-is. If it is relative, it is assumed to be relative to the current cherrypy.request.path_info. """ def __init__(self, urls, status=None): import cherrypy request = cherrypy.request if isinstance(urls, basestring): urls = [urls] abs_urls = [] for url in urls: # Note that urljoin will "do the right thing" whether url is: # 1. a complete URL with host (e.g. "http://www.example.com/test") # 2. a URL relative to root (e.g. "/dummy") # 3. a URL relative to the current path # Note that any query string in cherrypy.request is discarded. url = _urljoin(cherrypy.url(), url) abs_urls.append(url) self.urls = abs_urls # RFC 2616 indicates a 301 response code fits our goal; however, # browser support for 301 is quite messy. Do 302/303 instead. See # http://www.alanflavell.org.uk/www/post-redirect.html if status is None: if request.protocol >= (1, 1): status = 303 else: status = 302 else: status = int(status) if status < 300 or status > 399: raise ValueError("status must be between 300 and 399.") self.status = status CherryPyException.__init__(self, abs_urls, status) def set_response(self): """Modify cherrypy.response status, headers, and body to represent self. CherryPy uses this internally, but you can also use it to create an HTTPRedirect object and set its output without *raising* the exception. """ import cherrypy response = cherrypy.response response.status = status = self.status if status in (300, 301, 302, 303, 307): response.headers['Content-Type'] = "text/html" # "The ... URI SHOULD be given by the Location field # in the response." response.headers['Location'] = self.urls[0] # "Unless the request method was HEAD, the entity of the response # SHOULD contain a short hypertext note with a hyperlink to the # new URI(s)." msg = {300: "This resource can be found at %s.", 301: "This resource has permanently moved to %s.", 302: "This resource resides temporarily at %s.", 303: "This resource can be found at %s.", 307: "This resource has moved temporarily to %s.", }[status] response.body = "
\n".join([msg % (u, u) for u in self.urls]) # Previous code may have set C-L, so we have to reset it # (allow finalize to set it). response.headers.pop('Content-Length', None) elif status == 304: # Not Modified. # "The response MUST include the following header fields: # Date, unless its omission is required by section 14.18.1" # The "Date" header should have been set in Response.__init__ # "...the response SHOULD NOT include other entity-headers." for key in ('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-Location', 'Content-MD5', 'Content-Range', 'Content-Type', 'Expires', 'Last-Modified'): if key in response.headers: del response.headers[key] # "The 304 response MUST NOT contain a message-body." response.body = None # Previous code may have set C-L, so we have to reset it. response.headers.pop('Content-Length', None) elif status == 305: # Use Proxy. # self.urls[0] should be the URI of the proxy. response.headers['Location'] = self.urls[0] response.body = None # Previous code may have set C-L, so we have to reset it. response.headers.pop('Content-Length', None) else: raise ValueError("The %s status code is unknown." % status) def __call__(self): """Use this exception as a request.handler (raise self).""" raise self def clean_headers(status): """Remove any headers which should not apply to an error response.""" import cherrypy response = cherrypy.response # Remove headers which applied to the original content, # but do not apply to the error page. respheaders = response.headers for key in ["Accept-Ranges", "Age", "ETag", "Location", "Retry-After", "Vary", "Content-Encoding", "Content-Length", "Expires", "Content-Location", "Content-MD5", "Last-Modified"]: if respheaders.has_key(key): del respheaders[key] if status != 416: # A server sending a response with status code 416 (Requested # range not satisfiable) SHOULD include a Content-Range field # with a byte-range-resp-spec of "*". The instance-length # specifies the current length of the selected resource. # A response with status code 206 (Partial Content) MUST NOT # include a Content-Range field with a byte-range- resp-spec of "*". if respheaders.has_key("Content-Range"): del respheaders["Content-Range"] class HTTPError(CherryPyException): """ Exception used to return an HTTP error code (4xx-5xx) to the client. This exception will automatically set the response status and body. A custom message (a long description to display in the browser) can be provided in place of the default. """ def __init__(self, status=500, message=None): self.status = status try: self.code, self.reason, defaultmsg = _http.valid_status(status) except ValueError, x: raise cherrypy.HTTPError(500, x.args[0]) if self.code < 400 or self.code > 599: raise ValueError("status must be between 400 and 599.") # See http://www.python.org/dev/peps/pep-0352/ # self.message = message self._message = message or defaultmsg CherryPyException.__init__(self, status, message) def set_response(self): """Modify cherrypy.response status, headers, and body to represent self. CherryPy uses this internally, but you can also use it to create an HTTPError object and set its output without *raising* the exception. """ import cherrypy response = cherrypy.response clean_headers(self.code) # In all cases, finalize will be called after this method, # so don't bother cleaning up response values here. response.status = self.status tb = None if cherrypy.request.show_tracebacks: tb = format_exc() response.headers['Content-Type'] = "text/html" content = self.get_error_page(self.status, traceback=tb, message=self._message) response.body = content response.headers['Content-Length'] = len(content) _be_ie_unfriendly(self.code) def get_error_page(self, *args, **kwargs): return get_error_page(*args, **kwargs) def __call__(self): """Use this exception as a request.handler (raise self).""" raise self class NotFound(HTTPError): """Exception raised when a URL could not be mapped to any handler (404).""" def __init__(self, path=None): if path is None: import cherrypy path = cherrypy.request.script_name + cherrypy.request.path_info self.args = (path,) HTTPError.__init__(self, 404, "The path %r was not found." % path) _HTTPErrorTemplate = ''' %(status)s

%(status)s

%(message)s

%(traceback)s
''' def get_error_page(status, **kwargs): """Return an HTML page, containing a pretty error response. status should be an int or a str. kwargs will be interpolated into the page template. """ import cherrypy try: code, reason, message = _http.valid_status(status) except ValueError, x: raise cherrypy.HTTPError(500, x.args[0]) # We can't use setdefault here, because some # callers send None for kwarg values. if kwargs.get('status') is None: kwargs['status'] = "%s %s" % (code, reason) if kwargs.get('message') is None: kwargs['message'] = message if kwargs.get('traceback') is None: kwargs['traceback'] = '' if kwargs.get('version') is None: kwargs['version'] = cherrypy.__version__ for k, v in kwargs.iteritems(): if v is None: kwargs[k] = "" else: kwargs[k] = _escape(kwargs[k]) # Use a custom template or callable for the error page? pages = cherrypy.request.error_page error_page = pages.get(code) or pages.get('default') if error_page: try: if callable(error_page): return error_page(**kwargs) else: return file(error_page, 'rb').read() % kwargs except: e = _format_exception(*_exc_info())[-1] m = kwargs['message'] if m: m += "
" m += "In addition, the custom error page failed:\n
%s" % e kwargs['message'] = m return _HTTPErrorTemplate % kwargs _ie_friendly_error_sizes = { 400: 512, 403: 256, 404: 512, 405: 256, 406: 512, 408: 512, 409: 512, 410: 256, 500: 512, 501: 512, 505: 512, } def _be_ie_unfriendly(status): import cherrypy response = cherrypy.response # For some statuses, Internet Explorer 5+ shows "friendly error # messages" instead of our response.body if the body is smaller # than a given size. Fix this by returning a body over that size # (by adding whitespace). # See http://support.microsoft.com/kb/q218155/ s = _ie_friendly_error_sizes.get(status, 0) if s: s += 1 # Since we are issuing an HTTP error status, we assume that # the entity is short, and we should just collapse it. content = response.collapse_body() l = len(content) if l and l < s: # IN ADDITION: the response must be written to IE # in one chunk or it will still get replaced! Bah. content = content + (" " * (s - l)) response.body = content response.headers['Content-Length'] = len(content) def format_exc(exc=None): """Return exc (or sys.exc_info if None), formatted.""" if exc is None: exc = _exc_info() if exc == (None, None, None): return "" import traceback return "".join(traceback.format_exception(*exc)) def bare_error(extrabody=None): """Produce status, headers, body for a critical error. Returns a triple without calling any other questionable functions, so it should be as error-free as possible. Call it from an HTTP server if you get errors outside of the request. If extrabody is None, a friendly but rather unhelpful error message is set in the body. If extrabody is a string, it will be appended as-is to the body. """ # The whole point of this function is to be a last line-of-defense # in handling errors. That is, it must not raise any errors itself; # it cannot be allowed to fail. Therefore, don't add to it! # In particular, don't call any other CP functions. body = "Unrecoverable error in the server." if extrabody is not None: body += "\n" + extrabody return ("500 Internal Server Error", [('Content-Type', 'text/plain'), ('Content-Length', str(len(body)))], [body]) SABnzbd-0.7.20/cherrypy/_cplogging.py0000644000000000000000000002141012433712602017552 0ustar00usergroup00000000000000"""CherryPy logging.""" import datetime import logging # Silence the no-handlers "warning" (stderr write!) in stdlib logging logging.Logger.manager.emittedNoHandlerWarning = 1 logfmt = logging.Formatter("%(message)s") import os import rfc822 import sys import cherrypy from cherrypy import _cperror class LogManager(object): appid = None error_log = None access_log = None access_log_format = \ '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"' def __init__(self, appid=None, logger_root="cherrypy"): self.logger_root = logger_root self.appid = appid if appid is None: self.error_log = logging.getLogger("%s.error" % logger_root) self.access_log = logging.getLogger("%s.access" % logger_root) else: self.error_log = logging.getLogger("%s.error.%s" % (logger_root, appid)) self.access_log = logging.getLogger("%s.access.%s" % (logger_root, appid)) self.error_log.setLevel(logging.DEBUG) self.access_log.setLevel(logging.INFO) cherrypy.engine.subscribe('graceful', self.reopen_files) def reopen_files(self): """Close and reopen all file handlers.""" for log in (self.error_log, self.access_log): for h in log.handlers: if isinstance(h, logging.FileHandler): h.acquire() h.stream.close() h.stream = open(h.baseFilename, h.mode) h.release() def error(self, msg='', context='', severity=logging.INFO, traceback=False): """Write to the error log. This is not just for errors! Applications may call this at any time to log application-specific information. """ if traceback: msg += _cperror.format_exc() self.error_log.log(severity, ' '.join((self.time(), context, msg))) def __call__(self, *args, **kwargs): """Write to the error log. This is not just for errors! Applications may call this at any time to log application-specific information. """ return self.error(*args, **kwargs) def access(self): """Write to the access log (in Apache/NCSA Combined Log format). Like Apache started doing in 2.0.46, non-printable and other special characters in %r (and we expand that to all parts) are escaped using \\xhh sequences, where hh stands for the hexadecimal representation of the raw byte. Exceptions from this rule are " and \\, which are escaped by prepending a backslash, and all whitespace characters, which are written in their C-style notation (\\n, \\t, etc). """ request = cherrypy.request remote = request.remote response = cherrypy.response outheaders = response.headers inheaders = request.headers atoms = {'h': remote.name or remote.ip, 'l': '-', 'u': getattr(request, "login", None) or "-", 't': self.time(), 'r': request.request_line, 's': response.status.split(" ", 1)[0], 'b': outheaders.get('Content-Length', '') or "-", 'f': inheaders.get('Referer', ''), 'a': inheaders.get('User-Agent', ''), } for k, v in atoms.items(): if isinstance(v, unicode): v = v.encode('utf8') elif not isinstance(v, str): v = str(v) # Fortunately, repr(str) escapes unprintable chars, \n, \t, etc # and backslash for us. All we have to do is strip the quotes. v = repr(v)[1:-1] # Escape double-quote. atoms[k] = v.replace('"', '\\"') try: self.access_log.log(logging.INFO, self.access_log_format % atoms) except: self(traceback=True) def time(self): """Return now() in Apache Common Log Format (no timezone).""" now = datetime.datetime.now() month = rfc822._monthnames[now.month - 1].capitalize() return ('[%02d/%s/%04d:%02d:%02d:%02d]' % (now.day, month, now.year, now.hour, now.minute, now.second)) def _get_builtin_handler(self, log, key): for h in log.handlers: if getattr(h, "_cpbuiltin", None) == key: return h # ------------------------- Screen handlers ------------------------- # def _set_screen_handler(self, log, enable, stream=None): h = self._get_builtin_handler(log, "screen") if enable: if not h: if stream is None: stream=sys.stderr h = logging.StreamHandler(stream) h.setFormatter(logfmt) h._cpbuiltin = "screen" log.addHandler(h) elif h: log.handlers.remove(h) def _get_screen(self): h = self._get_builtin_handler has_h = h(self.error_log, "screen") or h(self.access_log, "screen") return bool(has_h) def _set_screen(self, newvalue): self._set_screen_handler(self.error_log, newvalue, stream=sys.stderr) self._set_screen_handler(self.access_log, newvalue, stream=sys.stdout) screen = property(_get_screen, _set_screen, doc="If True, error and access will print to stderr.") # -------------------------- File handlers -------------------------- # def _add_builtin_file_handler(self, log, fname): h = logging.FileHandler(fname) h.setFormatter(logfmt) h._cpbuiltin = "file" log.addHandler(h) def _set_file_handler(self, log, filename): h = self._get_builtin_handler(log, "file") if filename: if h: if h.baseFilename != os.path.abspath(filename): h.close() log.handlers.remove(h) self._add_builtin_file_handler(log, filename) else: self._add_builtin_file_handler(log, filename) else: if h: h.close() log.handlers.remove(h) def _get_error_file(self): h = self._get_builtin_handler(self.error_log, "file") if h: return h.baseFilename return '' def _set_error_file(self, newvalue): self._set_file_handler(self.error_log, newvalue) error_file = property(_get_error_file, _set_error_file, doc="The filename for self.error_log.") def _get_access_file(self): h = self._get_builtin_handler(self.access_log, "file") if h: return h.baseFilename return '' def _set_access_file(self, newvalue): self._set_file_handler(self.access_log, newvalue) access_file = property(_get_access_file, _set_access_file, doc="The filename for self.access_log.") # ------------------------- WSGI handlers ------------------------- # def _set_wsgi_handler(self, log, enable): h = self._get_builtin_handler(log, "wsgi") if enable: if not h: h = WSGIErrorHandler() h.setFormatter(logfmt) h._cpbuiltin = "wsgi" log.addHandler(h) elif h: log.handlers.remove(h) def _get_wsgi(self): return bool(self._get_builtin_handler(self.error_log, "wsgi")) def _set_wsgi(self, newvalue): self._set_wsgi_handler(self.error_log, newvalue) wsgi = property(_get_wsgi, _set_wsgi, doc="If True, error messages will be sent to wsgi.errors.") class WSGIErrorHandler(logging.Handler): "A handler class which writes logging records to environ['wsgi.errors']." def flush(self): """Flushes the stream.""" try: stream = cherrypy.request.wsgi_environ.get('wsgi.errors') except (AttributeError, KeyError): pass else: stream.flush() def emit(self, record): """Emit a record.""" try: stream = cherrypy.request.wsgi_environ.get('wsgi.errors') except (AttributeError, KeyError): pass else: try: msg = self.format(record) fs = "%s\n" import types if not hasattr(types, "UnicodeType"): #if no unicode support... stream.write(fs % msg) else: try: stream.write(fs % msg) except UnicodeError: stream.write(fs % msg.encode("UTF-8")) self.flush() except: self.handleError(record) SABnzbd-0.7.20/cherrypy/_cpmodpy.py0000644000000000000000000002463212433712602017265 0ustar00usergroup00000000000000"""Native adapter for serving CherryPy via mod_python Basic usage: ########################################## # Application in a module called myapp.py ########################################## import cherrypy class Root: @cherrypy.expose def index(self): return 'Hi there, Ho there, Hey there' # We will use this method from the mod_python configuration # as the entry point to our application def setup_server(): cherrypy.tree.mount(Root()) cherrypy.config.update({'environment': 'production', 'log.screen': False, 'show_tracebacks': False}) ########################################## # mod_python settings for apache2 # This should reside in your httpd.conf # or a file that will be loaded at # apache startup ########################################## # Start DocumentRoot "/" Listen 8080 LoadModule python_module /usr/lib/apache2/modules/mod_python.so PythonPath "sys.path+['/path/to/my/application']" SetHandler python-program PythonHandler cherrypy._cpmodpy::handler PythonOption cherrypy.setup myapp::setup_server PythonDebug On # End The actual path to your mod_python.so is dependent on your environment. In this case we suppose a global mod_python installation on a Linux distribution such as Ubuntu. We do set the PythonPath configuration setting so that your application can be found by from the user running the apache2 instance. Of course if your application resides in the global site-package this won't be needed. Then restart apache2 and access http://127.0.0.1:8080 """ import logging import StringIO import cherrypy from cherrypy._cperror import format_exc, bare_error from cherrypy.lib import http # ------------------------------ Request-handling def setup(req): from mod_python import apache # Run any setup function defined by a "PythonOption cherrypy.setup" directive. options = req.get_options() if 'cherrypy.setup' in options: atoms = options['cherrypy.setup'].split('::', 1) if len(atoms) == 1: mod = __import__(atoms[0], globals(), locals()) else: modname, fname = atoms mod = __import__(modname, globals(), locals(), [fname]) func = getattr(mod, fname) func() cherrypy.config.update({'log.screen': False, "tools.ignore_headers.on": True, "tools.ignore_headers.headers": ['Range'], }) engine = cherrypy.engine if hasattr(engine, "signal_handler"): engine.signal_handler.unsubscribe() if hasattr(engine, "console_control_handler"): engine.console_control_handler.unsubscribe() engine.autoreload.unsubscribe() cherrypy.server.unsubscribe() def _log(msg, level): newlevel = apache.APLOG_ERR if logging.DEBUG >= level: newlevel = apache.APLOG_DEBUG elif logging.INFO >= level: newlevel = apache.APLOG_INFO elif logging.WARNING >= level: newlevel = apache.APLOG_WARNING # On Windows, req.server is required or the msg will vanish. See # http://www.modpython.org/pipermail/mod_python/2003-October/014291.html. # Also, "When server is not specified...LogLevel does not apply..." apache.log_error(msg, newlevel, req.server) engine.subscribe('log', _log) engine.start() def cherrypy_cleanup(data): engine.exit() try: # apache.register_cleanup wasn't available until 3.1.4. apache.register_cleanup(cherrypy_cleanup) except AttributeError: req.server.register_cleanup(req, cherrypy_cleanup) class _ReadOnlyRequest: expose = ('read', 'readline', 'readlines') def __init__(self, req): for method in self.expose: self.__dict__[method] = getattr(req, method) recursive = False _isSetUp = False def handler(req): from mod_python import apache try: global _isSetUp if not _isSetUp: setup(req) _isSetUp = True # Obtain a Request object from CherryPy local = req.connection.local_addr local = http.Host(local[0], local[1], req.connection.local_host or "") remote = req.connection.remote_addr remote = http.Host(remote[0], remote[1], req.connection.remote_host or "") scheme = req.parsed_uri[0] or 'http' req.get_basic_auth_pw() try: # apache.mpm_query only became available in mod_python 3.1 q = apache.mpm_query threaded = q(apache.AP_MPMQ_IS_THREADED) forked = q(apache.AP_MPMQ_IS_FORKED) except AttributeError: bad_value = ("You must provide a PythonOption '%s', " "either 'on' or 'off', when running a version " "of mod_python < 3.1") threaded = options.get('multithread', '').lower() if threaded == 'on': threaded = True elif threaded == 'off': threaded = False else: raise ValueError(bad_value % "multithread") forked = options.get('multiprocess', '').lower() if forked == 'on': forked = True elif forked == 'off': forked = False else: raise ValueError(bad_value % "multiprocess") sn = cherrypy.tree.script_name(req.uri or "/") if sn is None: send_response(req, '404 Not Found', [], '') else: app = cherrypy.tree.apps[sn] method = req.method path = req.uri qs = req.args or "" reqproto = req.protocol headers = req.headers_in.items() rfile = _ReadOnlyRequest(req) prev = None try: redirections = [] while True: request, response = app.get_serving(local, remote, scheme, "HTTP/1.1") request.login = req.user request.multithread = bool(threaded) request.multiprocess = bool(forked) request.app = app request.prev = prev # Run the CherryPy Request object and obtain the response try: request.run(method, path, qs, reqproto, headers, rfile) break except cherrypy.InternalRedirect, ir: app.release_serving() prev = request if not recursive: if ir.path in redirections: raise RuntimeError("InternalRedirector visited the " "same URL twice: %r" % ir.path) else: # Add the *previous* path_info + qs to redirections. if qs: qs = "?" + qs redirections.append(sn + path + qs) # Munge environment and try again. method = "GET" path = ir.path qs = ir.query_string rfile = StringIO.StringIO() send_response(req, response.status, response.header_list, response.body, response.stream) finally: app.release_serving() except: tb = format_exc() cherrypy.log(tb, 'MOD_PYTHON', severity=logging.ERROR) s, h, b = bare_error() send_response(req, s, h, b) return apache.OK def send_response(req, status, headers, body, stream=False): # Set response status req.status = int(status[:3]) # Set response headers req.content_type = "text/plain" for header, value in headers: if header.lower() == 'content-type': req.content_type = value continue req.headers_out.add(header, value) if stream: # Flush now so the status and headers are sent immediately. req.flush() # Set response body if isinstance(body, basestring): req.write(body) else: for seg in body: req.write(seg) # --------------- Startup tools for CherryPy + mod_python --------------- # import os import re def read_process(cmd, args=""): pipein, pipeout = os.popen4("%s %s" % (cmd, args)) try: firstline = pipeout.readline() if (re.search(r"(not recognized|No such file|not found)", firstline, re.IGNORECASE)): raise IOError('%s must be on your system path.' % cmd) output = firstline + pipeout.read() finally: pipeout.close() return output class ModPythonServer(object): template = """ # Apache2 server configuration file for running CherryPy with mod_python. DocumentRoot "/" Listen %(port)s LoadModule python_module modules/mod_python.so SetHandler python-program PythonHandler %(handler)s PythonDebug On %(opts)s """ def __init__(self, loc="/", port=80, opts=None, apache_path="apache", handler="cherrypy._cpmodpy::handler"): self.loc = loc self.port = port self.opts = opts self.apache_path = apache_path self.handler = handler def start(self): opts = "".join([" PythonOption %s %s\n" % (k, v) for k, v in self.opts]) conf_data = self.template % {"port": self.port, "loc": self.loc, "opts": opts, "handler": self.handler, } mpconf = os.path.join(os.path.dirname(__file__), "cpmodpy.conf") f = open(mpconf, 'wb') try: f.write(conf_data) finally: f.close() response = read_process(self.apache_path, "-k start -f %s" % mpconf) self.ready = True return response def stop(self): os.popen("apache -k stop") self.ready = False SABnzbd-0.7.20/cherrypy/_cprequest.py0000644000000000000000000010777712433712602017641 0ustar00usergroup00000000000000 import Cookie import os import sys import time import types import cherrypy from cherrypy import _cpcgifs, _cpconfig from cherrypy._cperror import format_exc, bare_error from cherrypy.lib import http, file_generator class Hook(object): """A callback and its metadata: failsafe, priority, and kwargs.""" __metaclass__ = cherrypy._AttributeDocstrings callback = None callback__doc = """ The bare callable that this Hook object is wrapping, which will be called when the Hook is called.""" failsafe = False failsafe__doc = """ If True, the callback is guaranteed to run even if other callbacks from the same call point raise exceptions.""" priority = 50 priority__doc = """ Defines the order of execution for a list of Hooks. Priority numbers should be limited to the closed interval [0, 100], but values outside this range are acceptable, as are fractional values.""" kwargs = {} kwargs__doc = """ A set of keyword arguments that will be passed to the callable on each call.""" def __init__(self, callback, failsafe=None, priority=None, **kwargs): self.callback = callback if failsafe is None: failsafe = getattr(callback, "failsafe", False) self.failsafe = failsafe if priority is None: priority = getattr(callback, "priority", 50) self.priority = priority self.kwargs = kwargs def __cmp__(self, other): return cmp(self.priority, other.priority) def __call__(self): """Run self.callback(**self.kwargs).""" return self.callback(**self.kwargs) def __repr__(self): cls = self.__class__ return ("%s.%s(callback=%r, failsafe=%r, priority=%r, %s)" % (cls.__module__, cls.__name__, self.callback, self.failsafe, self.priority, ", ".join(['%s=%r' % (k, v) for k, v in self.kwargs.iteritems()]))) class HookMap(dict): """A map of call points to lists of callbacks (Hook objects).""" def __new__(cls, points=None): d = dict.__new__(cls) for p in points or []: d[p] = [] return d def __init__(self, *a, **kw): pass def attach(self, point, callback, failsafe=None, priority=None, **kwargs): """Append a new Hook made from the supplied arguments.""" self[point].append(Hook(callback, failsafe, priority, **kwargs)) def run(self, point): """Execute all registered Hooks (callbacks) for the given point.""" exc = None hooks = self[point] hooks.sort() for hook in hooks: # Some hooks are guaranteed to run even if others at # the same hookpoint fail. We will still log the failure, # but proceed on to the next hook. The only way # to stop all processing from one of these hooks is # to raise SystemExit and stop the whole server. if exc is None or hook.failsafe: try: hook() except (KeyboardInterrupt, SystemExit): raise except (cherrypy.HTTPError, cherrypy.HTTPRedirect, cherrypy.InternalRedirect): exc = sys.exc_info()[1] except: exc = sys.exc_info()[1] cherrypy.log(traceback=True, severity=40) if exc: raise def __copy__(self): newmap = self.__class__() # We can't just use 'update' because we want copies of the # mutable values (each is a list) as well. for k, v in self.iteritems(): newmap[k] = v[:] return newmap copy = __copy__ def __repr__(self): cls = self.__class__ return "%s.%s(points=%r)" % (cls.__module__, cls.__name__, self.keys()) # Config namespace handlers def hooks_namespace(k, v): """Attach bare hooks declared in config.""" # Use split again to allow multiple hooks for a single # hookpoint per path (e.g. "hooks.before_handler.1"). # Little-known fact you only get from reading source ;) hookpoint = k.split(".", 1)[0] if isinstance(v, basestring): v = cherrypy.lib.attributes(v) if not isinstance(v, Hook): v = Hook(v) cherrypy.request.hooks[hookpoint].append(v) def request_namespace(k, v): """Attach request attributes declared in config.""" setattr(cherrypy.request, k, v) def response_namespace(k, v): """Attach response attributes declared in config.""" setattr(cherrypy.response, k, v) def error_page_namespace(k, v): """Attach error pages declared in config.""" if k != 'default': k = int(k) cherrypy.request.error_page[k] = v hookpoints = ['on_start_resource', 'before_request_body', 'before_handler', 'before_finalize', 'on_end_resource', 'on_end_request', 'before_error_response', 'after_error_response'] class Request(object): """An HTTP request. This object represents the metadata of an HTTP request message; that is, it contains attributes which describe the environment in which the request URL, headers, and body were sent (if you want tools to interpret the headers and body, those are elsewhere, mostly in Tools). This 'metadata' consists of socket data, transport characteristics, and the Request-Line. This object also contains data regarding the configuration in effect for the given URL, and the execution plan for generating a response. """ __metaclass__ = cherrypy._AttributeDocstrings prev = None prev__doc = """ The previous Request object (if any). This should be None unless we are processing an InternalRedirect.""" # Conversation/connection attributes local = http.Host("127.0.0.1", 80) local__doc = \ "An http.Host(ip, port, hostname) object for the server socket." remote = http.Host("127.0.0.1", 1111) remote__doc = \ "An http.Host(ip, port, hostname) object for the client socket." scheme = "http" scheme__doc = """ The protocol used between client and server. In most cases, this will be either 'http' or 'https'.""" server_protocol = "HTTP/1.1" server_protocol__doc = """ The HTTP version for which the HTTP server is at least conditionally compliant.""" base = "" base__doc = """The (scheme://host) portion of the requested URL. In some cases (e.g. when proxying via mod_rewrite), this may contain path segments which cherrypy.url uses when constructing url's, but which otherwise are ignored by CherryPy. Regardless, this value MUST NOT end in a slash.""" # Request-Line attributes request_line = "" request_line__doc = """ The complete Request-Line received from the client. This is a single string consisting of the request method, URI, and protocol version (joined by spaces). Any final CRLF is removed.""" method = "GET" method__doc = """ Indicates the HTTP method to be performed on the resource identified by the Request-URI. Common methods include GET, HEAD, POST, PUT, and DELETE. CherryPy allows any extension method; however, various HTTP servers and gateways may restrict the set of allowable methods. CherryPy applications SHOULD restrict the set (on a per-URI basis).""" query_string = "" query_string__doc = """ The query component of the Request-URI, a string of information to be interpreted by the resource. The query portion of a URI follows the path component, and is separated by a '?'. For example, the URI 'http://www.cherrypy.org/wiki?a=3&b=4' has the query component, 'a=3&b=4'.""" protocol = (1, 1) protocol__doc = """The HTTP protocol version corresponding to the set of features which should be allowed in the response. If BOTH the client's request message AND the server's level of HTTP compliance is HTTP/1.1, this attribute will be the tuple (1, 1). If either is 1.0, this attribute will be the tuple (1, 0). Lower HTTP protocol versions are not explicitly supported.""" params = {} params__doc = """ A dict which combines query string (GET) and request entity (POST) variables. This is populated in two stages: GET params are added before the 'on_start_resource' hook, and POST params are added between the 'before_request_body' and 'before_handler' hooks.""" # Message attributes header_list = [] header_list__doc = """ A list of the HTTP request headers as (name, value) tuples. In general, you should use request.headers (a dict) instead.""" headers = http.HeaderMap() headers__doc = """ A dict-like object containing the request headers. Keys are header names (in Title-Case format); however, you may get and set them in a case-insensitive manner. That is, headers['Content-Type'] and headers['content-type'] refer to the same value. Values are header values (decoded according to RFC 2047 if necessary). See also: http.HeaderMap, http.HeaderElement.""" cookie = Cookie.SimpleCookie() cookie__doc = """See help(Cookie).""" rfile = None rfile__doc = """ If the request included an entity (body), it will be available as a stream in this attribute. However, the rfile will normally be read for you between the 'before_request_body' hook and the 'before_handler' hook, and the resulting string is placed into either request.params or the request.body attribute. You may disable the automatic consumption of the rfile by setting request.process_request_body to False, either in config for the desired path, or in an 'on_start_resource' or 'before_request_body' hook. WARNING: In almost every case, you should not attempt to read from the rfile stream after CherryPy's automatic mechanism has read it. If you turn off the automatic parsing of rfile, you should read exactly the number of bytes specified in request.headers['Content-Length']. Ignoring either of these warnings may result in a hung request thread or in corruption of the next (pipelined) request. """ process_request_body = True process_request_body__doc = """ If True, the rfile (if any) is automatically read and parsed, and the result placed into request.params or request.body.""" methods_with_bodies = ("POST", "PUT") methods_with_bodies__doc = """ A sequence of HTTP methods for which CherryPy will automatically attempt to read a body from the rfile.""" body = None body__doc = """ If the request Content-Type is 'application/x-www-form-urlencoded' or multipart, this will be None. Otherwise, this will contain the request entity body as a string; this value is set between the 'before_request_body' and 'before_handler' hooks (assuming that process_request_body is True).""" body_params = None body_params__doc = """ If the request Content-Type is 'application/x-www-form-urlencoded' or multipart, this will be a dict of the params pulled from the entity body; that is, it will be the portion of request.params that come from the message body (sometimes called "POST params", although they can be sent with various HTTP method verbs). This value is set between the 'before_request_body' and 'before_handler' hooks (assuming that process_request_body is True).""" # Dispatch attributes dispatch = cherrypy.dispatch.Dispatcher() dispatch__doc = """ The object which looks up the 'page handler' callable and collects config for the current request based on the path_info, other request attributes, and the application architecture. The core calls the dispatcher as early as possible, passing it a 'path_info' argument. The default dispatcher discovers the page handler by matching path_info to a hierarchical arrangement of objects, starting at request.app.root. See help(cherrypy.dispatch) for more information.""" script_name = "" script_name__doc = """ The 'mount point' of the application which is handling this request. This attribute MUST NOT end in a slash. If the script_name refers to the root of the URI, it MUST be an empty string (not "/"). """ path_info = "/" path_info__doc = """ The 'relative path' portion of the Request-URI. This is relative to the script_name ('mount point') of the application which is handling this request.""" login = None login__doc = """ When authentication is used during the request processing this is set to 'False' if it failed and to the 'username' value if it succeeded. The default 'None' implies that no authentication happened.""" # Note that cherrypy.url uses "if request.app:" to determine whether # the call is during a real HTTP request or not. So leave this None. app = None app__doc = \ """The cherrypy.Application object which is handling this request.""" handler = None handler__doc = """ The function, method, or other callable which CherryPy will call to produce the response. The discovery of the handler and the arguments it will receive are determined by the request.dispatch object. By default, the handler is discovered by walking a tree of objects starting at request.app.root, and is then passed all HTTP params (from the query string and POST body) as keyword arguments.""" toolmaps = {} toolmaps__doc = """ A nested dict of all Toolboxes and Tools in effect for this request, of the form: {Toolbox.namespace: {Tool.name: config dict}}.""" config = None config__doc = """ A flat dict of all configuration entries which apply to the current request. These entries are collected from global config, application config (based on request.path_info), and from handler config (exactly how is governed by the request.dispatch object in effect for this request; by default, handler config can be attached anywhere in the tree between request.app.root and the final handler, and inherits downward).""" is_index = None is_index__doc = """ This will be True if the current request is mapped to an 'index' resource handler (also, a 'default' handler if path_info ends with a slash). The value may be used to automatically redirect the user-agent to a 'more canonical' URL which either adds or removes the trailing slash. See cherrypy.tools.trailing_slash.""" hooks = HookMap(hookpoints) hooks__doc = """ A HookMap (dict-like object) of the form: {hookpoint: [hook, ...]}. Each key is a str naming the hook point, and each value is a list of hooks which will be called at that hook point during this request. The list of hooks is generally populated as early as possible (mostly from Tools specified in config), but may be extended at any time. See also: _cprequest.Hook, _cprequest.HookMap, and cherrypy.tools.""" error_response = cherrypy.HTTPError(500).set_response error_response__doc = """ The no-arg callable which will handle unexpected, untrapped errors during request processing. This is not used for expected exceptions (like NotFound, HTTPError, or HTTPRedirect) which are raised in response to expected conditions (those should be customized either via request.error_page or by overriding HTTPError.set_response). By default, error_response uses HTTPError(500) to return a generic error response to the user-agent.""" error_page = {} error_page__doc = """ A dict of {error code: response filename or callable} pairs. The error code must be an int representing a given HTTP error code, or the string 'default', which will be used if no matching entry is found for a given numeric code. If a filename is provided, the file should contain a Python string- formatting template, and can expect by default to receive format values with the mapping keys %(status)s, %(message)s, %(traceback)s, and %(version)s. The set of format mappings can be extended by overriding HTTPError.set_response. If a callable is provided, it will be called by default with keyword arguments 'status', 'message', 'traceback', and 'version', as for a string-formatting template. The callable must return a string which will be set to response.body. It may also override headers or perform any other processing. If no entry is given for an error code, and no 'default' entry exists, a default template will be used. """ show_tracebacks = True show_tracebacks__doc = """ If True, unexpected errors encountered during request processing will include a traceback in the response body.""" show_mismatched_params = True show_mismatched_params__doc = """ If True, mismatched parameters encountered during PageHandler invocation processing will be included in the response body.""" throws = (KeyboardInterrupt, SystemExit, cherrypy.InternalRedirect) throws__doc = \ """The sequence of exceptions which Request.run does not trap.""" throw_errors = False throw_errors__doc = """ If True, Request.run will not trap any errors (except HTTPRedirect and HTTPError, which are more properly called 'exceptions', not errors).""" closed = False closed__doc = """ True once the close method has been called, False otherwise.""" stage = None stage__doc = """ A string containing the stage reached in the request-handling process. This is useful when debugging a live server with hung requests.""" namespaces = _cpconfig.NamespaceSet( **{"hooks": hooks_namespace, "request": request_namespace, "response": response_namespace, "error_page": error_page_namespace, "tools": cherrypy.tools, }) def __init__(self, local_host, remote_host, scheme="http", server_protocol="HTTP/1.1"): """Populate a new Request object. local_host should be an http.Host object with the server info. remote_host should be an http.Host object with the client info. scheme should be a string, either "http" or "https". """ self.local = local_host self.remote = remote_host self.scheme = scheme self.server_protocol = server_protocol self.closed = False # Put a *copy* of the class error_page into self. self.error_page = self.error_page.copy() # Put a *copy* of the class namespaces into self. self.namespaces = self.namespaces.copy() self.stage = None def close(self): """Run cleanup code. (Core)""" if not self.closed: self.closed = True self.stage = 'on_end_request' self.hooks.run('on_end_request') self.stage = 'close' def run(self, method, path, query_string, req_protocol, headers, rfile): """Process the Request. (Core) method, path, query_string, and req_protocol should be pulled directly from the Request-Line (e.g. "GET /path?key=val HTTP/1.0"). path should be %XX-unquoted, but query_string should not be. headers should be a list of (name, value) tuples. rfile should be a file-like object containing the HTTP request entity. When run() is done, the returned object should have 3 attributes: status, e.g. "200 OK" header_list, a list of (name, value) tuples body, an iterable yielding strings Consumer code (HTTP servers) should then access these response attributes to build the outbound stream. """ self.stage = 'run' try: self.error_response = cherrypy.HTTPError(500).set_response self.method = method path = path or "/" self.query_string = query_string or '' # Compare request and server HTTP protocol versions, in case our # server does not support the requested protocol. Limit our output # to min(req, server). We want the following output: # request server actual written supported response # protocol protocol response protocol feature set # a 1.0 1.0 1.0 1.0 # b 1.0 1.1 1.1 1.0 # c 1.1 1.0 1.0 1.0 # d 1.1 1.1 1.1 1.1 # Notice that, in (b), the response will be "HTTP/1.1" even though # the client only understands 1.0. RFC 2616 10.5.6 says we should # only return 505 if the _major_ version is different. rp = int(req_protocol[5]), int(req_protocol[7]) sp = int(self.server_protocol[5]), int(self.server_protocol[7]) self.protocol = min(rp, sp) # Rebuild first line of the request (e.g. "GET /path HTTP/1.0"). url = path if query_string: url += '?' + query_string self.request_line = '%s %s %s' % (method, url, req_protocol) self.header_list = list(headers) self.rfile = rfile self.headers = http.HeaderMap() self.cookie = Cookie.SimpleCookie() self.handler = None # path_info should be the path from the # app root (script_name) to the handler. self.script_name = self.app.script_name self.path_info = pi = path[len(self.script_name):] self.stage = 'respond' self.respond(pi) except self.throws: raise except: if self.throw_errors: raise else: # Failure in setup, error handler or finalize. Bypass them. # Can't use handle_error because we may not have hooks yet. cherrypy.log(traceback=True, severity=40) if self.show_tracebacks: body = format_exc() else: body = "" r = bare_error(body) response = cherrypy.response response.status, response.header_list, response.body = r if self.method == "HEAD": # HEAD requests MUST NOT return a message-body in the response. cherrypy.response.body = [] try: cherrypy.log.access() except: cherrypy.log.error(traceback=True) if cherrypy.response.timed_out: raise cherrypy.TimeoutError() return cherrypy.response def respond(self, path_info): """Generate a response for the resource at self.path_info. (Core)""" try: try: try: if self.app is None: raise cherrypy.NotFound() # Get the 'Host' header, so we can HTTPRedirect properly. self.stage = 'process_headers' self.process_headers() # Make a copy of the class hooks self.hooks = self.__class__.hooks.copy() self.toolmaps = {} self.stage = 'get_resource' self.get_resource(path_info) self.namespaces(self.config) self.stage = 'on_start_resource' self.hooks.run('on_start_resource') if self.process_request_body: if self.method not in self.methods_with_bodies: self.process_request_body = False self.stage = 'before_request_body' self.hooks.run('before_request_body') if self.process_request_body: self.process_body() self.stage = 'before_handler' self.hooks.run('before_handler') if self.handler: self.stage = 'handler' cherrypy.response.body = self.handler() self.stage = 'before_finalize' self.hooks.run('before_finalize') cherrypy.response.finalize() except (cherrypy.HTTPRedirect, cherrypy.HTTPError), inst: inst.set_response() self.stage = 'before_finalize (HTTPError)' self.hooks.run('before_finalize') cherrypy.response.finalize() finally: self.stage = 'on_end_resource' self.hooks.run('on_end_resource') except self.throws: raise except: if self.throw_errors: raise self.handle_error() def process_headers(self): """Parse HTTP header data into Python structures. (Core)""" self.params = http.parse_query_string(self.query_string) # Process the headers into self.headers headers = self.headers for name, value in self.header_list: # Call title() now (and use dict.__method__(headers)) # so title doesn't have to be called twice. name = name.title() value = value.strip() # Warning: if there is more than one header entry for cookies (AFAIK, # only Konqueror does that), only the last one will remain in headers # (but they will be correctly stored in request.cookie). if "=?" in value: dict.__setitem__(headers, name, http.decode_TEXT(value)) else: dict.__setitem__(headers, name, value) # Handle cookies differently because on Konqueror, multiple # cookies come on different lines with the same key if name == 'Cookie': try: self.cookie.load(value) except: pass if not dict.__contains__(headers, 'Host'): # All Internet-based HTTP/1.1 servers MUST respond with a 400 # (Bad Request) status code to any HTTP/1.1 request message # which lacks a Host header field. if self.protocol >= (1, 1): msg = "HTTP/1.1 requires a 'Host' request header." raise cherrypy.HTTPError(400, msg) host = dict.get(headers, 'Host') if not host: host = self.local.name or self.local.ip self.base = "%s://%s" % (self.scheme, host) def get_resource(self, path): """Call a dispatcher (which sets self.handler and .config). (Core)""" dispatch = self.dispatch # First, see if there is a custom dispatch at this URI. Custom # dispatchers can only be specified in app.config, not in _cp_config # (since custom dispatchers may not even have an app.root). trail = path or "/" while trail: nodeconf = self.app.config.get(trail, {}) d = nodeconf.get("request.dispatch") if d: dispatch = d break lastslash = trail.rfind("/") if lastslash == -1: break elif lastslash == 0 and trail != "/": trail = "/" else: trail = trail[:lastslash] # dispatch() should set self.handler and self.config dispatch(path) def process_body(self): """Convert request.rfile into request.params (or request.body). (Core)""" if not self.headers.get("Content-Length", ""): # No Content-Length header supplied (or it's 0). # If we went ahead and called cgi.FieldStorage, it would hang, # since it cannot determine when to stop reading from the socket. # See http://www.cherrypy.org/ticket/493. # See also http://www.cherrypy.org/ticket/650. # Note also that we expect any HTTP server to have decoded # any message-body that had a transfer-coding, and we expect # the HTTP server to have supplied a Content-Length header # which is valid for the decoded entity-body. raise cherrypy.HTTPError(411) # If the headers are missing "Content-Type" then add one # with an empty value. This ensures that FieldStorage # won't parse the request body for params if the client # didn't provide a "Content-Type" header. if 'Content-Type' not in self.headers: h = http.HeaderMap(self.headers.items()) h['Content-Type'] = '' else: h = self.headers try: forms = _cpcgifs.FieldStorage(fp=self.rfile, headers=h, # FieldStorage only recognizes POST. environ={'REQUEST_METHOD': "POST"}, keep_blank_values=1) except Exception, e: if e.__class__.__name__ == 'MaxSizeExceeded': # Post data is too big raise cherrypy.HTTPError(413) else: raise # Note that, if headers['Content-Type'] is multipart/*, # then forms.file will not exist; instead, each form[key] # item will be its own file object, and will be handled # by params_from_CGI_form. if forms.file: # request body was a content-type other than multipart. self.body = forms.file else: self.body_params = p = http.params_from_CGI_form(forms) self.params.update(p) def handle_error(self): """Handle the last unanticipated exception. (Core)""" try: self.hooks.run("before_error_response") if self.error_response: self.error_response() self.hooks.run("after_error_response") cherrypy.response.finalize() except cherrypy.HTTPRedirect, inst: inst.set_response() cherrypy.response.finalize() class Body(object): """The body of the HTTP response (the response entity).""" def __get__(self, obj, objclass=None): if obj is None: # When calling on the class instead of an instance... return self else: return obj._body def __set__(self, obj, value): # Convert the given value to an iterable object. if isinstance(value, basestring): # strings get wrapped in a list because iterating over a single # item list is much faster than iterating over every character # in a long string. if value: value = [value] else: # [''] doesn't evaluate to False, so replace it with []. value = [] elif isinstance(value, types.FileType): value = file_generator(value) elif value is None: value = [] obj._body = value class Response(object): """An HTTP Response, including status, headers, and body. Application developers should use Response.headers (a dict) to set or modify HTTP response headers. When the response is finalized, Response.headers is transformed into Response.header_list as (key, value) tuples. """ __metaclass__ = cherrypy._AttributeDocstrings # Class attributes for dev-time introspection. status = "" status__doc = """The HTTP Status-Code and Reason-Phrase.""" header_list = [] header_list__doc = """ A list of the HTTP response headers as (name, value) tuples. In general, you should use response.headers (a dict) instead.""" headers = http.HeaderMap() headers__doc = """ A dict-like object containing the response headers. Keys are header names (in Title-Case format); however, you may get and set them in a case-insensitive manner. That is, headers['Content-Type'] and headers['content-type'] refer to the same value. Values are header values (decoded according to RFC 2047 if necessary). See also: http.HeaderMap, http.HeaderElement.""" cookie = Cookie.SimpleCookie() cookie__doc = """See help(Cookie).""" body = Body() body__doc = """The body (entity) of the HTTP response.""" time = None time__doc = """The value of time.time() when created. Use in HTTP dates.""" timeout = 300 timeout__doc = """Seconds after which the response will be aborted.""" timed_out = False timed_out__doc = """ Flag to indicate the response should be aborted, because it has exceeded its timeout.""" stream = False stream__doc = """If False, buffer the response body.""" def __init__(self): self.status = None self.header_list = None self._body = [] self.time = time.time() self.headers = http.HeaderMap() # Since we know all our keys are titled strings, we can # bypass HeaderMap.update and get a big speed boost. dict.update(self.headers, { "Content-Type": 'text/html', "Server": "CherryPy/" + cherrypy.__version__, "Date": http.HTTPDate(self.time), }) self.cookie = Cookie.SimpleCookie() def collapse_body(self): """Collapse self.body to a single string; replace it and return it.""" newbody = ''.join([chunk for chunk in self.body]) self.body = newbody return newbody def finalize(self): """Transform headers (and cookies) into self.header_list. (Core)""" try: code, reason, _ = http.valid_status(self.status) except ValueError, x: raise cherrypy.HTTPError(500, x.args[0]) self.status = "%s %s" % (code, reason) headers = self.headers if self.stream: # The upshot: wsgiserver will chunk the response if # you pop Content-Length (or set it explicitly to None). # Note that lib.static sets C-L to the file's st_size. if dict.get(headers, 'Content-Length') is None: dict.pop(headers, 'Content-Length', None) elif code < 200 or code in (204, 205, 304): # "All 1xx (informational), 204 (no content), # and 304 (not modified) responses MUST NOT # include a message-body." dict.pop(headers, 'Content-Length', None) self.body = "" else: # Responses which are not streamed should have a Content-Length, # but allow user code to set Content-Length if desired. if dict.get(headers, 'Content-Length') is None: content = self.collapse_body() dict.__setitem__(headers, 'Content-Length', len(content)) # Transform our header dict into a list of tuples. self.header_list = h = headers.output(cherrypy.request.protocol) cookie = self.cookie.output() if cookie: for line in cookie.split("\n"): if line.endswith("\r"): # Python 2.4 emits cookies joined by LF but 2.5+ by CRLF. line = line[:-1] name, value = line.split(": ", 1) h.append((name, value)) def check_timeout(self): """If now > self.time + self.timeout, set self.timed_out. This purposefully sets a flag, rather than raising an error, so that a monitor thread can interrupt the Response thread. """ if time.time() > self.time + self.timeout: self.timed_out = True SABnzbd-0.7.20/cherrypy/_cpserver.py0000644000000000000000000001163512433712602017442 0ustar00usergroup00000000000000"""Manage HTTP servers with CherryPy.""" import warnings import cherrypy from cherrypy.lib import attributes # We import * because we want to export check_port # et al as attributes of this module. from cherrypy.process.servers import * class Server(ServerAdapter): """An adapter for an HTTP server. You can set attributes (like socket_host and socket_port) on *this* object (which is probably cherrypy.server), and call quickstart. For example: cherrypy.server.socket_port = 80 cherrypy.quickstart() """ socket_port = 8080 _socket_host = '127.0.0.1' def _get_socket_host(self): return self._socket_host def _set_socket_host(self, value): if value == '': raise ValueError("The empty string ('') is not an allowed value. " "Use '0.0.0.0' instead to listen on all active " "interfaces (INADDR_ANY).") self._socket_host = value socket_host = property(_get_socket_host, _set_socket_host, doc="""The hostname or IP address on which to listen for connections. Host values may be any IPv4 or IPv6 address, or any valid hostname. The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if your hosts file prefers IPv6). The string '0.0.0.0' is a special IPv4 entry meaning "any active interface" (INADDR_ANY), and '::' is the similar IN6ADDR_ANY for IPv6. The empty string or None are not allowed.""") socket_file = None socket_queue_size = 5 socket_timeout = 10 shutdown_timeout = 5 protocol_version = 'HTTP/1.1' reverse_dns = False thread_pool = 10 thread_pool_max = -1 max_request_header_size = 500 * 1024 max_request_body_size = 100 * 1024 * 1024 instance = None ssl_context = None ssl_certificate = None ssl_certificate_chain = None ssl_private_key = None nodelay = True def __init__(self): self.bus = cherrypy.engine self.httpserver = None self.interrupt = None self.running = False def quickstart(self, server=None): """This does nothing now and will be removed in 3.2.""" warnings.warn('quickstart does nothing now and will be removed in ' '3.2. Call cherrypy.engine.start() instead.', DeprecationWarning) def httpserver_from_self(self, httpserver=None): """Return a (httpserver, bind_addr) pair based on self attributes.""" if httpserver is None: httpserver = self.instance if httpserver is None: from cherrypy import _cpwsgi_server httpserver = _cpwsgi_server.CPWSGIServer(self) if isinstance(httpserver, basestring): # Is anyone using this? Can I add an arg? httpserver = attributes(httpserver)(self) return httpserver, self.bind_addr def start(self): """Start the HTTP server.""" if not self.httpserver: self.httpserver, self.bind_addr = self.httpserver_from_self() ServerAdapter.start(self) start.priority = 75 def _get_bind_addr(self): if self.socket_file: return self.socket_file if self.socket_host is None and self.socket_port is None: return None return (self.socket_host, self.socket_port) def _set_bind_addr(self, value): if value is None: self.socket_file = None self.socket_host = None self.socket_port = None elif isinstance(value, basestring): self.socket_file = value self.socket_host = None self.socket_port = None else: try: self.socket_host, self.socket_port = value self.socket_file = None except ValueError: raise ValueError("bind_addr must be a (host, port) tuple " "(for TCP sockets) or a string (for Unix " "domain sockets), not %r" % value) bind_addr = property(_get_bind_addr, _set_bind_addr) def base(self): """Return the base (scheme://host[:port] or sock file) for this server.""" if self.socket_file: return self.socket_file host = self.socket_host if host in ('0.0.0.0', '::'): # 0.0.0.0 is INADDR_ANY and :: is IN6ADDR_ANY. # Look up the host name, which should be the # safest thing to spit out in a URL. import socket host = socket.gethostname() port = self.socket_port if self.ssl_certificate: scheme = "https" if port != 443: host += ":%s" % port else: scheme = "http" if port != 80: host += ":%s" % port return "%s://%s" % (scheme, host) SABnzbd-0.7.20/cherrypy/_cpthreadinglocal.py0000644000000000000000000001473012433712602021113 0ustar00usergroup00000000000000# This is a backport of Python-2.4's threading.local() implementation """Thread-local objects (Note that this module provides a Python version of thread threading.local class. Depending on the version of Python you're using, there may be a faster one available. You should always import the local class from threading.) Thread-local objects support the management of thread-local data. If you have data that you want to be local to a thread, simply create a thread-local object and use its attributes: >>> mydata = local() >>> mydata.number = 42 >>> mydata.number 42 You can also access the local-object's dictionary: >>> mydata.__dict__ {'number': 42} >>> mydata.__dict__.setdefault('widgets', []) [] >>> mydata.widgets [] What's important about thread-local objects is that their data are local to a thread. If we access the data in a different thread: >>> log = [] >>> def f(): ... items = mydata.__dict__.items() ... items.sort() ... log.append(items) ... mydata.number = 11 ... log.append(mydata.number) >>> import threading >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() >>> log [[], 11] we get different data. Furthermore, changes made in the other thread don't affect data seen in this thread: >>> mydata.number 42 Of course, values you get from a local object, including a __dict__ attribute, are for whatever thread was current at the time the attribute was read. For that reason, you generally don't want to save these values across threads, as they apply only to the thread they came from. You can create custom local objects by subclassing the local class: >>> class MyLocal(local): ... number = 2 ... initialized = False ... def __init__(self, **kw): ... if self.initialized: ... raise SystemError('__init__ called too many times') ... self.initialized = True ... self.__dict__.update(kw) ... def squared(self): ... return self.number ** 2 This can be useful to support default values, methods and initialization. Note that if you define an __init__ method, it will be called each time the local object is used in a separate thread. This is necessary to initialize each thread's dictionary. Now if we create a local object: >>> mydata = MyLocal(color='red') Now we have a default number: >>> mydata.number 2 an initial color: >>> mydata.color 'red' >>> del mydata.color And a method that operates on the data: >>> mydata.squared() 4 As before, we can access the data in a separate thread: >>> log = [] >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() >>> log [[('color', 'red'), ('initialized', True)], 11] without affecting this thread's data: >>> mydata.number 2 >>> mydata.color Traceback (most recent call last): ... AttributeError: 'MyLocal' object has no attribute 'color' Note that subclasses can define slots, but they are not thread local. They are shared across threads: >>> class MyLocal(local): ... __slots__ = 'number' >>> mydata = MyLocal() >>> mydata.number = 42 >>> mydata.color = 'red' So, the separate thread: >>> thread = threading.Thread(target=f) >>> thread.start() >>> thread.join() affects what we see: >>> mydata.number 11 >>> del mydata """ # Threading import is at end class _localbase(object): __slots__ = '_local__key', '_local__args', '_local__lock' def __new__(cls, *args, **kw): self = object.__new__(cls) key = 'thread.local.' + str(id(self)) object.__setattr__(self, '_local__key', key) object.__setattr__(self, '_local__args', (args, kw)) object.__setattr__(self, '_local__lock', RLock()) if args or kw and (cls.__init__ is object.__init__): raise TypeError("Initialization arguments are not supported") # We need to create the thread dict in anticipation of # __init__ being called, to make sure we don't call it # again ourselves. dict = object.__getattribute__(self, '__dict__') currentThread().__dict__[key] = dict return self def _patch(self): key = object.__getattribute__(self, '_local__key') d = currentThread().__dict__.get(key) if d is None: d = {} currentThread().__dict__[key] = d object.__setattr__(self, '__dict__', d) # we have a new instance dict, so call out __init__ if we have # one cls = type(self) if cls.__init__ is not object.__init__: args, kw = object.__getattribute__(self, '_local__args') cls.__init__(self, *args, **kw) else: object.__setattr__(self, '__dict__', d) class local(_localbase): def __getattribute__(self, name): lock = object.__getattribute__(self, '_local__lock') lock.acquire() try: _patch(self) return object.__getattribute__(self, name) finally: lock.release() def __setattr__(self, name, value): lock = object.__getattribute__(self, '_local__lock') lock.acquire() try: _patch(self) return object.__setattr__(self, name, value) finally: lock.release() def __delattr__(self, name): lock = object.__getattribute__(self, '_local__lock') lock.acquire() try: _patch(self) return object.__delattr__(self, name) finally: lock.release() def __del__(): threading_enumerate = enumerate __getattribute__ = object.__getattribute__ def __del__(self): key = __getattribute__(self, '_local__key') try: threads = list(threading_enumerate()) except: # if enumerate fails, as it seems to do during # shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up return for thread in threads: try: __dict__ = thread.__dict__ except AttributeError: # Thread is dying, rest in peace continue if key in __dict__: try: del __dict__[key] except KeyError: pass # didn't have anything in this thread return __del__ __del__ = __del__() from threading import currentThread, enumerate, RLock SABnzbd-0.7.20/cherrypy/_cptools.py0000644000000000000000000004434212433712602017275 0ustar00usergroup00000000000000"""CherryPy tools. A "tool" is any helper, adapted to CP. Tools are usually designed to be used in a variety of ways (although some may only offer one if they choose): Library calls: All tools are callables that can be used wherever needed. The arguments are straightforward and should be detailed within the docstring. Function decorators: All tools, when called, may be used as decorators which configure individual CherryPy page handlers (methods on the CherryPy tree). That is, "@tools.anytool()" should "turn on" the tool via the decorated function's _cp_config attribute. CherryPy config: If a tool exposes a "_setup" callable, it will be called once per Request (if the feature is "turned on" via config). Tools may be implemented as any object with a namespace. The builtins are generally either modules or instances of the tools.Tool class. """ import cherrypy def _getargs(func): """Return the names of all static arguments to the given function.""" # Use this instead of importing inspect for less mem overhead. import types if isinstance(func, types.MethodType): func = func.im_func co = func.func_code return co.co_varnames[:co.co_argcount] class Tool(object): """A registered function for use with CherryPy request-processing hooks. help(tool.callable) should give you more information about this Tool. """ namespace = "tools" def __init__(self, point, callable, name=None, priority=50): self._point = point self.callable = callable self._name = name self._priority = priority self.__doc__ = self.callable.__doc__ self._setargs() def _setargs(self): """Copy func parameter names to obj attributes.""" try: for arg in _getargs(self.callable): setattr(self, arg, None) except (TypeError, AttributeError): if hasattr(self.callable, "__call__"): for arg in _getargs(self.callable.__call__): setattr(self, arg, None) # IronPython 1.0 raises NotImplementedError because # inspect.getargspec tries to access Python bytecode # in co_code attribute. except NotImplementedError: pass # IronPython 1B1 may raise IndexError in some cases, # but if we trap it here it doesn't prevent CP from working. except IndexError: pass def _merged_args(self, d=None): """Return a dict of configuration entries for this Tool.""" if d: conf = d.copy() else: conf = {} tm = cherrypy.request.toolmaps[self.namespace] if self._name in tm: conf.update(tm[self._name]) if "on" in conf: del conf["on"] return conf def __call__(self, *args, **kwargs): """Compile-time decorator (turn on the tool in config). For example: @tools.proxy() def whats_my_base(self): return cherrypy.request.base whats_my_base.exposed = True """ if args: raise TypeError("The %r Tool does not accept positional " "arguments; you must use keyword arguments." % self._name) def tool_decorator(f): if not hasattr(f, "_cp_config"): f._cp_config = {} subspace = self.namespace + "." + self._name + "." f._cp_config[subspace + "on"] = True for k, v in kwargs.iteritems(): f._cp_config[subspace + k] = v return f return tool_decorator def _setup(self): """Hook this tool into cherrypy.request. The standard CherryPy request object will automatically call this method when the tool is "turned on" in config. """ conf = self._merged_args() p = conf.pop("priority", None) if p is None: p = getattr(self.callable, "priority", self._priority) cherrypy.request.hooks.attach(self._point, self.callable, priority=p, **conf) class HandlerTool(Tool): """Tool which is called 'before main', that may skip normal handlers. If the tool successfully handles the request (by setting response.body), if should return True. This will cause CherryPy to skip any 'normal' page handler. If the tool did not handle the request, it should return False to tell CherryPy to continue on and call the normal page handler. If the tool is declared AS a page handler (see the 'handler' method), returning False will raise NotFound. """ def __init__(self, callable, name=None): Tool.__init__(self, 'before_handler', callable, name) def handler(self, *args, **kwargs): """Use this tool as a CherryPy page handler. For example: class Root: nav = tools.staticdir.handler(section="/nav", dir="nav", root=absDir) """ def handle_func(*a, **kw): handled = self.callable(*args, **self._merged_args(kwargs)) if not handled: raise cherrypy.NotFound() return cherrypy.response.body handle_func.exposed = True return handle_func def _wrapper(self, **kwargs): if self.callable(**kwargs): cherrypy.request.handler = None def _setup(self): """Hook this tool into cherrypy.request. The standard CherryPy request object will automatically call this method when the tool is "turned on" in config. """ conf = self._merged_args() p = conf.pop("priority", None) if p is None: p = getattr(self.callable, "priority", self._priority) cherrypy.request.hooks.attach(self._point, self._wrapper, priority=p, **conf) class HandlerWrapperTool(Tool): """Tool which wraps request.handler in a provided wrapper function. The 'newhandler' arg must be a handler wrapper function that takes a 'next_handler' argument, plus *args and **kwargs. Like all page handler functions, it must return an iterable for use as cherrypy.response.body. For example, to allow your 'inner' page handlers to return dicts which then get interpolated into a template: def interpolator(next_handler, *args, **kwargs): filename = cherrypy.request.config.get('template') cherrypy.response.template = env.get_template(filename) response_dict = next_handler(*args, **kwargs) return cherrypy.response.template.render(**response_dict) cherrypy.tools.jinja = HandlerWrapperTool(interpolator) """ def __init__(self, newhandler, point='before_handler', name=None, priority=50): self.newhandler = newhandler self._point = point self._name = name self._priority = priority def callable(self): innerfunc = cherrypy.request.handler def wrap(*args, **kwargs): return self.newhandler(innerfunc, *args, **kwargs) cherrypy.request.handler = wrap class ErrorTool(Tool): """Tool which is used to replace the default request.error_response.""" def __init__(self, callable, name=None): Tool.__init__(self, None, callable, name) def _wrapper(self): self.callable(**self._merged_args()) def _setup(self): """Hook this tool into cherrypy.request. The standard CherryPy request object will automatically call this method when the tool is "turned on" in config. """ cherrypy.request.error_response = self._wrapper # Builtin tools # from cherrypy.lib import cptools, encoding, auth, static, tidy from cherrypy.lib import sessions as _sessions, xmlrpc as _xmlrpc from cherrypy.lib import caching as _caching, wsgiapp as _wsgiapp class SessionTool(Tool): """Session Tool for CherryPy. sessions.locking: When 'implicit' (the default), the session will be locked for you, just before running the page handler. When 'early', the session will be locked before reading the request body. This is off by default for safety reasons; for example, a large upload would block the session, denying an AJAX progress meter (see http://www.cherrypy.org/ticket/630). When 'explicit' (or any other value), you need to call cherrypy.session.acquire_lock() yourself before using session data. """ def __init__(self): # _sessions.init must be bound after headers are read Tool.__init__(self, 'before_request_body', _sessions.init) def _lock_session(self): cherrypy.serving.session.acquire_lock() def _setup(self): """Hook this tool into cherrypy.request. The standard CherryPy request object will automatically call this method when the tool is "turned on" in config. """ hooks = cherrypy.request.hooks conf = self._merged_args() p = conf.pop("priority", None) if p is None: p = getattr(self.callable, "priority", self._priority) hooks.attach(self._point, self.callable, priority=p, **conf) locking = conf.pop('locking', 'implicit') if locking == 'implicit': hooks.attach('before_handler', self._lock_session) elif locking == 'early': # Lock before the request body (but after _sessions.init runs!) hooks.attach('before_request_body', self._lock_session, priority=60) else: # Don't lock pass hooks.attach('before_finalize', _sessions.save) hooks.attach('on_end_request', _sessions.close) def regenerate(self): """Drop the current session and make a new one (with a new id).""" sess = cherrypy.serving.session sess.regenerate() # Grab cookie-relevant tool args conf = dict([(k, v) for k, v in self._merged_args().iteritems() if k in ('path', 'path_header', 'name', 'timeout', 'domain', 'secure')]) _sessions.set_response_cookie(**conf) class XMLRPCController(object): """A Controller (page handler collection) for XML-RPC. To use it, have your controllers subclass this base class (it will turn on the tool for you). You can also supply the following optional config entries: tools.xmlrpc.encoding: 'utf-8' tools.xmlrpc.allow_none: 0 XML-RPC is a rather discontinuous layer over HTTP; dispatching to the appropriate handler must first be performed according to the URL, and then a second dispatch step must take place according to the RPC method specified in the request body. It also allows a superfluous "/RPC2" prefix in the URL, supplies its own handler args in the body, and requires a 200 OK "Fault" response instead of 404 when the desired method is not found. Therefore, XML-RPC cannot be implemented for CherryPy via a Tool alone. This Controller acts as the dispatch target for the first half (based on the URL); it then reads the RPC method from the request body and does its own second dispatch step based on that method. It also reads body params, and returns a Fault on error. The XMLRPCDispatcher strips any /RPC2 prefix; if you aren't using /RPC2 in your URL's, you can safely skip turning on the XMLRPCDispatcher. Otherwise, you need to use declare it in config: request.dispatch: cherrypy.dispatch.XMLRPCDispatcher() """ # Note we're hard-coding this into the 'tools' namespace. We could do # a huge amount of work to make it relocatable, but the only reason why # would be if someone actually disabled the default_toolbox. Meh. _cp_config = {'tools.xmlrpc.on': True} def default(self, *vpath, **params): rpcparams, rpcmethod = _xmlrpc.process_body() subhandler = self for attr in str(rpcmethod).split('.'): subhandler = getattr(subhandler, attr, None) if subhandler and getattr(subhandler, "exposed", False): body = subhandler(*(vpath + rpcparams), **params) else: # http://www.cherrypy.org/ticket/533 # if a method is not found, an xmlrpclib.Fault should be returned # raising an exception here will do that; see # cherrypy.lib.xmlrpc.on_error raise Exception, 'method "%s" is not supported' % attr conf = cherrypy.request.toolmaps['tools'].get("xmlrpc", {}) _xmlrpc.respond(body, conf.get('encoding', 'utf-8'), conf.get('allow_none', 0)) return cherrypy.response.body default.exposed = True class WSGIAppTool(HandlerTool): """A tool for running any WSGI middleware/application within CP. Here are the parameters: wsgi_app - any wsgi application callable env_update - a dictionary with arbitrary keys and values to be merged with the WSGI environ dictionary. Example: class Whatever: _cp_config = {'tools.wsgiapp.on': True, 'tools.wsgiapp.app': some_app, 'tools.wsgiapp.env': app_environ, } """ def _setup(self): # Keep request body intact so the wsgi app can have its way with it. cherrypy.request.process_request_body = False HandlerTool._setup(self) class SessionAuthTool(HandlerTool): def _setargs(self): for name in dir(cptools.SessionAuth): if not name.startswith("__"): setattr(self, name, None) class CachingTool(Tool): """Caching Tool for CherryPy.""" def _wrapper(self, invalid_methods=("POST", "PUT", "DELETE"), **kwargs): request = cherrypy.request if not hasattr(cherrypy, "_cache"): # Make a process-wide Cache object. cherrypy._cache = kwargs.pop("cache_class", _caching.MemoryCache)() # Take all remaining kwargs and set them on the Cache object. for k, v in kwargs.iteritems(): setattr(cherrypy._cache, k, v) if _caching.get(invalid_methods=invalid_methods): request.handler = None else: if request.cacheable: # Note the devious technique here of adding hooks on the fly request.hooks.attach('before_finalize', _caching.tee_output, priority = 90) _wrapper.priority = 20 def _setup(self): """Hook caching into cherrypy.request.""" conf = self._merged_args() p = conf.pop("priority", None) cherrypy.request.hooks.attach('before_handler', self._wrapper, priority=p, **conf) class Toolbox(object): """A collection of Tools. This object also functions as a config namespace handler for itself. Custom toolboxes should be added to each Application's toolboxes dict. """ def __init__(self, namespace): self.namespace = namespace def __setattr__(self, name, value): # If the Tool._name is None, supply it from the attribute name. if isinstance(value, Tool): if value._name is None: value._name = name value.namespace = self.namespace object.__setattr__(self, name, value) def __enter__(self): """Populate request.toolmaps from tools specified in config.""" cherrypy.request.toolmaps[self.namespace] = map = {} def populate(k, v): toolname, arg = k.split(".", 1) bucket = map.setdefault(toolname, {}) bucket[arg] = v return populate def __exit__(self, exc_type, exc_val, exc_tb): """Run tool._setup() for each tool in our toolmap.""" map = cherrypy.request.toolmaps.get(self.namespace) if map: for name, settings in map.items(): if settings.get("on", False): tool = getattr(self, name) tool._setup() default_toolbox = _d = Toolbox("tools") _d.session_auth = SessionAuthTool(cptools.session_auth) _d.proxy = Tool('before_request_body', cptools.proxy, priority=30) _d.response_headers = Tool('on_start_resource', cptools.response_headers) _d.log_tracebacks = Tool('before_error_response', cptools.log_traceback) _d.log_headers = Tool('before_error_response', cptools.log_request_headers) _d.log_hooks = Tool('on_end_request', cptools.log_hooks, priority=100) _d.err_redirect = ErrorTool(cptools.redirect) _d.etags = Tool('before_finalize', cptools.validate_etags, priority=75) _d.decode = Tool('before_handler', encoding.decode) # the order of encoding, gzip, caching is important _d.encode = Tool('before_finalize', encoding.encode, priority=70) _d.gzip = Tool('before_finalize', encoding.gzip, priority=80) _d.staticdir = HandlerTool(static.staticdir) _d.staticfile = HandlerTool(static.staticfile) _d.sessions = SessionTool() _d.xmlrpc = ErrorTool(_xmlrpc.on_error) _d.wsgiapp = WSGIAppTool(_wsgiapp.run) _d.caching = CachingTool('before_handler', _caching.get, 'caching') _d.expires = Tool('before_finalize', _caching.expires) _d.tidy = Tool('before_finalize', tidy.tidy) _d.nsgmls = Tool('before_finalize', tidy.nsgmls) _d.ignore_headers = Tool('before_request_body', cptools.ignore_headers) _d.referer = Tool('before_request_body', cptools.referer) _d.basic_auth = Tool('on_start_resource', auth.basic_auth) _d.digest_auth = Tool('on_start_resource', auth.digest_auth) _d.trailing_slash = Tool('before_handler', cptools.trailing_slash, priority=60) _d.flatten = Tool('before_finalize', cptools.flatten) _d.accept = Tool('on_start_resource', cptools.accept) _d.redirect = Tool('on_start_resource', cptools.redirect) del _d, cptools, encoding, auth, static, tidy SABnzbd-0.7.20/cherrypy/_cptree.py0000644000000000000000000002252112433712602017067 0ustar00usergroup00000000000000"""CherryPy Application and Tree objects.""" import os import cherrypy from cherrypy import _cpconfig, _cplogging, _cprequest, _cpwsgi, tools from cherrypy.lib import http as _http class Application(object): """A CherryPy Application. Servers and gateways should not instantiate Request objects directly. Instead, they should ask an Application object for a request object. An instance of this class may also be used as a WSGI callable (WSGI application object) for itself. """ __metaclass__ = cherrypy._AttributeDocstrings root = None root__doc = """ The top-most container of page handlers for this app. Handlers should be arranged in a hierarchy of attributes, matching the expected URI hierarchy; the default dispatcher then searches this hierarchy for a matching handler. When using a dispatcher other than the default, this value may be None.""" config = {} config__doc = """ A dict of {path: pathconf} pairs, where 'pathconf' is itself a dict of {key: value} pairs.""" namespaces = _cpconfig.NamespaceSet() toolboxes = {'tools': cherrypy.tools} log = None log__doc = """A LogManager instance. See _cplogging.""" wsgiapp = None wsgiapp__doc = """A CPWSGIApp instance. See _cpwsgi.""" request_class = _cprequest.Request response_class = _cprequest.Response relative_urls = False def __init__(self, root, script_name="", config=None): self.log = _cplogging.LogManager(id(self), cherrypy.log.logger_root) self.root = root self.script_name = script_name self.wsgiapp = _cpwsgi.CPWSGIApp(self) self.namespaces = self.namespaces.copy() self.namespaces["log"] = lambda k, v: setattr(self.log, k, v) self.namespaces["wsgi"] = self.wsgiapp.namespace_handler self.config = self.__class__.config.copy() if config: self.merge(config) def __repr__(self): return "%s.%s(%r, %r)" % (self.__module__, self.__class__.__name__, self.root, self.script_name) script_name__doc = """ The URI "mount point" for this app. A mount point is that portion of the URI which is constant for all URIs that are serviced by this application; it does not include scheme, host, or proxy ("virtual host") portions of the URI. For example, if script_name is "/my/cool/app", then the URL "http://www.example.com/my/cool/app/page1" might be handled by a "page1" method on the root object. The value of script_name MUST NOT end in a slash. If the script_name refers to the root of the URI, it MUST be an empty string (not "/"). If script_name is explicitly set to None, then the script_name will be provided for each call from request.wsgi_environ['SCRIPT_NAME']. """ def _get_script_name(self): if self._script_name is None: # None signals that the script name should be pulled from WSGI environ. return cherrypy.request.wsgi_environ['SCRIPT_NAME'].rstrip("/") return self._script_name def _set_script_name(self, value): if value: value = value.rstrip("/") self._script_name = value script_name = property(fget=_get_script_name, fset=_set_script_name, doc=script_name__doc) def merge(self, config): """Merge the given config into self.config.""" _cpconfig.merge(self.config, config) # Handle namespaces specified in config. self.namespaces(self.config.get("/", {})) def get_serving(self, local, remote, scheme, sproto): """Create and return a Request and Response object.""" req = self.request_class(local, remote, scheme, sproto) req.app = self for name, toolbox in self.toolboxes.iteritems(): req.namespaces[name] = toolbox resp = self.response_class() cherrypy.serving.load(req, resp) cherrypy.engine.timeout_monitor.acquire() cherrypy.engine.publish('acquire_thread') return req, resp def release_serving(self): """Release the current serving (request and response).""" req = cherrypy.serving.request cherrypy.engine.timeout_monitor.release() try: req.close() except: cherrypy.log(traceback=True, severity=40) cherrypy.serving.clear() def __call__(self, environ, start_response): return self.wsgiapp(environ, start_response) class Tree(object): """A registry of CherryPy applications, mounted at diverse points. An instance of this class may also be used as a WSGI callable (WSGI application object), in which case it dispatches to all mounted apps. """ apps = {} apps__doc = """ A dict of the form {script name: application}, where "script name" is a string declaring the URI mount point (no trailing slash), and "application" is an instance of cherrypy.Application (or an arbitrary WSGI callable if you happen to be using a WSGI server).""" def __init__(self): self.apps = {} def mount(self, root, script_name="", config=None): """Mount a new app from a root object, script_name, and config. root: an instance of a "controller class" (a collection of page handler methods) which represents the root of the application. This may also be an Application instance, or None if using a dispatcher other than the default. script_name: a string containing the "mount point" of the application. This should start with a slash, and be the path portion of the URL at which to mount the given root. For example, if root.index() will handle requests to "http://www.example.com:8080/dept/app1/", then the script_name argument would be "/dept/app1". It MUST NOT end in a slash. If the script_name refers to the root of the URI, it MUST be an empty string (not "/"). config: a file or dict containing application config. """ if script_name is None: raise TypeError( "The 'script_name' argument may not be None. Application " "objects may, however, possess a script_name of None (in " "order to inpect the WSGI environ for SCRIPT_NAME upon each " "request). You cannot mount such Applications on this Tree; " "you must pass them to a WSGI server interface directly.") # Next line both 1) strips trailing slash and 2) maps "/" -> "". script_name = script_name.rstrip("/") if isinstance(root, Application): app = root if script_name != "" and script_name != app.script_name: raise ValueError, "Cannot specify a different script name and pass an Application instance to cherrypy.mount" script_name = app.script_name else: app = Application(root, script_name) # If mounted at "", add favicon.ico if (script_name == "" and root is not None and not hasattr(root, "favicon_ico")): favicon = os.path.join(os.getcwd(), os.path.dirname(__file__), "favicon.ico") root.favicon_ico = tools.staticfile.handler(favicon) if config: app.merge(config) self.apps[script_name] = app return app def graft(self, wsgi_callable, script_name=""): """Mount a wsgi callable at the given script_name.""" # Next line both 1) strips trailing slash and 2) maps "/" -> "". script_name = script_name.rstrip("/") self.apps[script_name] = wsgi_callable def script_name(self, path=None): """The script_name of the app at the given path, or None. If path is None, cherrypy.request is used. """ if path is None: try: path = _http.urljoin(cherrypy.request.script_name, cherrypy.request.path_info) except AttributeError: return None while True: if path in self.apps: return path if path == "": return None # Move one node up the tree and try again. path = path[:path.rfind("/")] def __call__(self, environ, start_response): # If you're calling this, then you're probably setting SCRIPT_NAME # to '' (some WSGI servers always set SCRIPT_NAME to ''). # Try to look up the app using the full path. path = _http.urljoin(environ.get('SCRIPT_NAME', ''), environ.get('PATH_INFO', '')) sn = self.script_name(path or "/") if sn is None: start_response('404 Not Found', []) return [] app = self.apps[sn] # Correct the SCRIPT_NAME and PATH_INFO environ entries. environ = environ.copy() environ['SCRIPT_NAME'] = sn environ['PATH_INFO'] = path[len(sn.rstrip("/")):] return app(environ, start_response) SABnzbd-0.7.20/cherrypy/_cpwsgi.py0000644000000000000000000003212012433712602017075 0ustar00usergroup00000000000000"""WSGI interface (see PEP 333).""" import StringIO as _StringIO import sys as _sys import cherrypy as _cherrypy from cherrypy import _cperror from cherrypy.lib import http as _http class VirtualHost(object): """Select a different WSGI application based on the Host header. This can be useful when running multiple sites within one CP server. It allows several domains to point to different applications. For example: root = Root() RootApp = cherrypy.Application(root) Domain2App = cherrypy.Application(root) SecureApp = cherrypy.Application(Secure()) vhost = cherrypy._cpwsgi.VirtualHost(RootApp, domains={'www.domain2.example': Domain2App, 'www.domain2.example:443': SecureApp, }) cherrypy.tree.graft(vhost) default: required. The default WSGI application. use_x_forwarded_host: if True (the default), any "X-Forwarded-Host" request header will be used instead of the "Host" header. This is commonly added by HTTP servers (such as Apache) when proxying. domains: a dict of {host header value: application} pairs. The incoming "Host" request header is looked up in this dict, and, if a match is found, the corresponding WSGI application will be called instead of the default. Note that you often need separate entries for "example.com" and "www.example.com". In addition, "Host" headers may contain the port number. """ def __init__(self, default, domains=None, use_x_forwarded_host=True): self.default = default self.domains = domains or {} self.use_x_forwarded_host = use_x_forwarded_host def __call__(self, environ, start_response): domain = environ.get('HTTP_HOST', '') if self.use_x_forwarded_host: domain = environ.get("HTTP_X_FORWARDED_HOST", domain) nextapp = self.domains.get(domain) if nextapp is None: nextapp = self.default return nextapp(environ, start_response) # WSGI-to-CP Adapter # class AppResponse(object): throws = (KeyboardInterrupt, SystemExit) request = None def __init__(self, environ, start_response, cpapp, recursive=False): self.redirections = [] self.recursive = recursive self.environ = environ self.start_response = start_response self.cpapp = cpapp self.setapp() def setapp(self): try: self.request = self.get_request() s, h, b = self.get_response() self.iter_response = iter(b) self.write = self.start_response(s, h) except self.throws: self.close() raise except _cherrypy.InternalRedirect, ir: self.environ['cherrypy.previous_request'] = _cherrypy.serving.request self.close() self.iredirect(ir.path, ir.query_string) return except: if getattr(self.request, "throw_errors", False): self.close() raise tb = _cperror.format_exc() _cherrypy.log(tb, severity=40) if not getattr(self.request, "show_tracebacks", True): tb = "" s, h, b = _cperror.bare_error(tb) self.iter_response = iter(b) try: self.start_response(s, h, _sys.exc_info()) except: # "The application must not trap any exceptions raised by # start_response, if it called start_response with exc_info. # Instead, it should allow such exceptions to propagate # back to the server or gateway." # But we still log and call close() to clean up ourselves. _cherrypy.log(traceback=True, severity=40) self.close() raise def iredirect(self, path, query_string): """Doctor self.environ and perform an internal redirect. When cherrypy.InternalRedirect is raised, this method is called. It rewrites the WSGI environ using the new path and query_string, and calls a new CherryPy Request object. Because the wsgi.input stream may have already been consumed by the next application, the redirected call will always be of HTTP method "GET"; therefore, any params must be passed in the query_string argument, which is formed from InternalRedirect.query_string when using that exception. If you need something more complicated, make and raise your own exception and write your own AppResponse subclass to trap it. ;) It would be a bad idea to redirect after you've already yielded response content, although an enterprising soul could choose to abuse this. """ env = self.environ if not self.recursive: sn = env.get('SCRIPT_NAME', '') qs = query_string if qs: qs = "?" + qs if sn + path + qs in self.redirections: raise RuntimeError("InternalRedirector visited the " "same URL twice: %r + %r + %r" % (sn, path, qs)) else: # Add the *previous* path_info + qs to redirections. p = env.get('PATH_INFO', '') qs = env.get('QUERY_STRING', '') if qs: qs = "?" + qs self.redirections.append(sn + p + qs) # Munge environment and try again. env['REQUEST_METHOD'] = "GET" env['PATH_INFO'] = path env['QUERY_STRING'] = query_string env['wsgi.input'] = _StringIO.StringIO() env['CONTENT_LENGTH'] = "0" self.setapp() def __iter__(self): return self def next(self): try: chunk = self.iter_response.next() # WSGI requires all data to be of type "str". This coercion should # not take any time at all if chunk is already of type "str". # If it's unicode, it could be a big performance hit (x ~500). if not isinstance(chunk, str): chunk = chunk.encode("ISO-8859-1") return chunk except self.throws: self.close() raise except _cherrypy.InternalRedirect, ir: self.environ['cherrypy.previous_request'] = _cherrypy.serving.request self.close() self.iredirect(ir.path, ir.query_string) except StopIteration: raise except: if getattr(self.request, "throw_errors", False): self.close() raise tb = _cperror.format_exc() _cherrypy.log(tb, severity=40) if not getattr(self.request, "show_tracebacks", True): tb = "" s, h, b = _cperror.bare_error(tb) # Empty our iterable (so future calls raise StopIteration) self.iter_response = iter([]) try: self.start_response(s, h, _sys.exc_info()) except: # "The application must not trap any exceptions raised by # start_response, if it called start_response with exc_info. # Instead, it should allow such exceptions to propagate # back to the server or gateway." # But we still log and call close() to clean up ourselves. _cherrypy.log(traceback=True, severity=40) self.close() raise return "".join(b) def close(self): """Close and de-reference the current request and response. (Core)""" self.cpapp.release_serving() def get_response(self): """Run self.request and return its response.""" meth = self.environ['REQUEST_METHOD'] path = _http.urljoin(self.environ.get('SCRIPT_NAME', ''), self.environ.get('PATH_INFO', '')) qs = self.environ.get('QUERY_STRING', '') rproto = self.environ.get('SERVER_PROTOCOL') headers = self.translate_headers(self.environ) rfile = self.environ['wsgi.input'] response = self.request.run(meth, path, qs, rproto, headers, rfile) return response.status, response.header_list, response.body def get_request(self): """Create a Request object using environ.""" env = self.environ.get local = _http.Host('', int(env('SERVER_PORT', 80)), env('SERVER_NAME', '')) remote = _http.Host(env('REMOTE_ADDR', ''), int(env('REMOTE_PORT', -1)), env('REMOTE_HOST', '')) scheme = env('wsgi.url_scheme') sproto = env('ACTUAL_SERVER_PROTOCOL', "HTTP/1.1") request, resp = self.cpapp.get_serving(local, remote, scheme, sproto) # LOGON_USER is served by IIS, and is the name of the # user after having been mapped to a local account. # Both IIS and Apache set REMOTE_USER, when possible. request.login = env('LOGON_USER') or env('REMOTE_USER') or None request.multithread = self.environ['wsgi.multithread'] request.multiprocess = self.environ['wsgi.multiprocess'] request.wsgi_environ = self.environ request.prev = env('cherrypy.previous_request', None) return request headerNames = {'HTTP_CGI_AUTHORIZATION': 'Authorization', 'CONTENT_LENGTH': 'Content-Length', 'CONTENT_TYPE': 'Content-Type', 'REMOTE_HOST': 'Remote-Host', 'REMOTE_ADDR': 'Remote-Addr', } def translate_headers(self, environ): """Translate CGI-environ header names to HTTP header names.""" for cgiName in environ: # We assume all incoming header keys are uppercase already. if cgiName in self.headerNames: yield self.headerNames[cgiName], environ[cgiName] elif cgiName[:5] == "HTTP_": # Hackish attempt at recovering original header names. translatedHeader = cgiName[5:].replace("_", "-") yield translatedHeader, environ[cgiName] class CPWSGIApp(object): """A WSGI application object for a CherryPy Application. pipeline: a list of (name, wsgiapp) pairs. Each 'wsgiapp' MUST be a constructor that takes an initial, positional 'nextapp' argument, plus optional keyword arguments, and returns a WSGI application (that takes environ and start_response arguments). The 'name' can be any you choose, and will correspond to keys in self.config. head: rather than nest all apps in the pipeline on each call, it's only done the first time, and the result is memoized into self.head. Set this to None again if you change self.pipeline after calling self. config: a dict whose keys match names listed in the pipeline. Each value is a further dict which will be passed to the corresponding named WSGI callable (from the pipeline) as keyword arguments. """ pipeline = [] head = None config = {} response_class = AppResponse def __init__(self, cpapp, pipeline=None): self.cpapp = cpapp self.pipeline = self.pipeline[:] if pipeline: self.pipeline.extend(pipeline) self.config = self.config.copy() def tail(self, environ, start_response): """WSGI application callable for the actual CherryPy application. You probably shouldn't call this; call self.__call__ instead, so that any WSGI middleware in self.pipeline can run first. """ return self.response_class(environ, start_response, self.cpapp) def __call__(self, environ, start_response): head = self.head if head is None: # Create and nest the WSGI apps in our pipeline (in reverse order). # Then memoize the result in self.head. head = self.tail for name, callable in self.pipeline[::-1]: conf = self.config.get(name, {}) head = callable(head, **conf) self.head = head return head(environ, start_response) def namespace_handler(self, k, v): """Config handler for the 'wsgi' namespace.""" if k == "pipeline": # Note this allows multiple 'wsgi.pipeline' config entries # (but each entry will be processed in a 'random' order). # It should also allow developers to set default middleware # in code (passed to self.__init__) that deployers can add to # (but not remove) via config. self.pipeline.extend(v) elif k == "response_class": self.response_class = v else: name, arg = k.split(".", 1) bucket = self.config.setdefault(name, {}) bucket[arg] = v SABnzbd-0.7.20/cherrypy/_cpwsgi_server.py0000644000000000000000000000554112433712602020472 0ustar00usergroup00000000000000"""WSGI server interface (see PEP 333). This adds some CP-specific bits to the framework-agnostic wsgiserver package. """ import cherrypy from cherrypy import wsgiserver class CPHTTPRequest(wsgiserver.HTTPRequest): def __init__(self, sendall, environ, wsgi_app): s = cherrypy.server self.max_request_header_size = s.max_request_header_size or 0 self.max_request_body_size = s.max_request_body_size or 0 wsgiserver.HTTPRequest.__init__(self, sendall, environ, wsgi_app) class CPHTTPConnection(wsgiserver.HTTPConnection): RequestHandlerClass = CPHTTPRequest class CPWSGIServer(wsgiserver.CherryPyWSGIServer): """Wrapper for wsgiserver.CherryPyWSGIServer. wsgiserver has been designed to not reference CherryPy in any way, so that it can be used in other frameworks and applications. Therefore, we wrap it here, so we can set our own mount points from cherrypy.tree and apply some attributes from config -> cherrypy.server -> wsgiserver. """ ConnectionClass = CPHTTPConnection def __init__(self, server_adapter=cherrypy.server): self.server_adapter = server_adapter # We have to make custom subclasses of wsgiserver internals here # so that our server.* attributes get applied to every request. class _CPHTTPRequest(wsgiserver.HTTPRequest): def __init__(self, sendall, environ, wsgi_app): s = server_adapter self.max_request_header_size = s.max_request_header_size or 0 self.max_request_body_size = s.max_request_body_size or 0 wsgiserver.HTTPRequest.__init__(self, sendall, environ, wsgi_app) class _CPHTTPConnection(wsgiserver.HTTPConnection): RequestHandlerClass = _CPHTTPRequest self.ConnectionClass = _CPHTTPConnection server_name = (self.server_adapter.socket_host or self.server_adapter.socket_file or None) s = wsgiserver.CherryPyWSGIServer s.__init__(self, server_adapter.bind_addr, cherrypy.tree, self.server_adapter.thread_pool, server_name, max = self.server_adapter.thread_pool_max, request_queue_size = self.server_adapter.socket_queue_size, timeout = self.server_adapter.socket_timeout, shutdown_timeout = self.server_adapter.shutdown_timeout, ) self.protocol = self.server_adapter.protocol_version self.nodelay = self.server_adapter.nodelay self.ssl_context = self.server_adapter.ssl_context self.ssl_certificate = self.server_adapter.ssl_certificate self.ssl_certificate_chain = self.server_adapter.ssl_certificate_chain self.ssl_private_key = self.server_adapter.ssl_private_key SABnzbd-0.7.20/cherrypy/__init__.py0000644000000000000000000004561112433712602017212 0ustar00usergroup00000000000000"""CherryPy is a pythonic, object-oriented HTTP framework. CherryPy consists of not one, but four separate API layers. The APPLICATION LAYER is the simplest. CherryPy applications are written as a tree of classes and methods, where each branch in the tree corresponds to a branch in the URL path. Each method is a 'page handler', which receives GET and POST params as keyword arguments, and returns or yields the (HTML) body of the response. The special method name 'index' is used for paths that end in a slash, and the special method name 'default' is used to handle multiple paths via a single handler. This layer also includes: * the 'exposed' attribute (and cherrypy.expose) * cherrypy.quickstart() * _cp_config attributes * cherrypy.tools (including cherrypy.session) * cherrypy.url() The ENVIRONMENT LAYER is used by developers at all levels. It provides information about the current request and response, plus the application and server environment, via a (default) set of top-level objects: * cherrypy.request * cherrypy.response * cherrypy.engine * cherrypy.server * cherrypy.tree * cherrypy.config * cherrypy.thread_data * cherrypy.log * cherrypy.HTTPError, NotFound, and HTTPRedirect * cherrypy.lib The EXTENSION LAYER allows advanced users to construct and share their own plugins. It consists of: * Hook API * Tool API * Toolbox API * Dispatch API * Config Namespace API Finally, there is the CORE LAYER, which uses the core API's to construct the default components which are available at higher layers. You can think of the default components as the 'reference implementation' for CherryPy. Megaframeworks (and advanced users) may replace the default components with customized or extended components. The core API's are: * Application API * Engine API * Request API * Server API * WSGI API These API's are described in the CherryPy specification: http://www.cherrypy.org/wiki/CherryPySpec """ __version__ = "3.2.0" from urlparse import urljoin as _urljoin class _AttributeDocstrings(type): """Metaclass for declaring docstrings for class attributes.""" # The full docstring for this type is down in the __init__ method so # that it doesn't show up in help() for every consumer class. def __init__(cls, name, bases, dct): '''Metaclass for declaring docstrings for class attributes. Base Python doesn't provide any syntax for setting docstrings on 'data attributes' (non-callables). This metaclass allows class definitions to follow the declaration of a data attribute with a docstring for that attribute; the attribute docstring will be popped from the class dict and folded into the class docstring. The naming convention for attribute docstrings is: + "__doc". For example: class Thing(object): """A thing and its properties.""" __metaclass__ = cherrypy._AttributeDocstrings height = 50 height__doc = """The height of the Thing in inches.""" In which case, help(Thing) starts like this: >>> help(mod.Thing) Help on class Thing in module pkg.mod: class Thing(__builtin__.object) | A thing and its properties. | | height [= 50]: | The height of the Thing in inches. | The benefits of this approach over hand-edited class docstrings: 1. Places the docstring nearer to the attribute declaration. 2. Makes attribute docs more uniform ("name (default): doc"). 3. Reduces mismatches of attribute _names_ between the declaration and the documentation. 4. Reduces mismatches of attribute default _values_ between the declaration and the documentation. The benefits of a metaclass approach over other approaches: 1. Simpler ("less magic") than interface-based solutions. 2. __metaclass__ can be specified at the module global level for classic classes. For various formatting reasons, you should write multiline docs with a leading newline and not a trailing one: response__doc = """ The response object for the current thread. In the main thread, and any threads which are not HTTP requests, this is None.""" The type of the attribute is intentionally not included, because that's not How Python Works. Quack. ''' newdoc = [cls.__doc__ or ""] dctnames = dct.keys() dctnames.sort() for name in dctnames: if name.endswith("__doc"): # Remove the magic doc attribute. if hasattr(cls, name): delattr(cls, name) # Make a uniformly-indented docstring from it. val = '\n'.join([' ' + line.strip() for line in dct[name].split('\n')]) # Get the default value. attrname = name[:-5] try: attrval = getattr(cls, attrname) except AttributeError: attrval = "missing" # Add the complete attribute docstring to our list. newdoc.append("%s [= %r]:\n%s" % (attrname, attrval, val)) # Add our list of new docstrings to the class docstring. cls.__doc__ = "\n\n".join(newdoc) from cherrypy._cperror import HTTPError, HTTPRedirect, InternalRedirect from cherrypy._cperror import NotFound, CherryPyException, TimeoutError from cherrypy import _cpdispatch as dispatch from cherrypy import _cptools tools = _cptools.default_toolbox Tool = _cptools.Tool from cherrypy import _cprequest from cherrypy.lib import http as _http from cherrypy import _cptree tree = _cptree.Tree() from cherrypy._cptree import Application from cherrypy import _cpwsgi as wsgi from cherrypy import process try: from cherrypy.process import win32 engine = win32.Win32Bus() engine.console_control_handler = win32.ConsoleCtrlHandler(engine) del win32 except ImportError: engine = process.bus # Timeout monitor class _TimeoutMonitor(process.plugins.Monitor): def __init__(self, bus): self.servings = [] process.plugins.Monitor.__init__(self, bus, self.run) def acquire(self): self.servings.append((serving.request, serving.response)) def release(self): try: self.servings.remove((serving.request, serving.response)) except ValueError: pass def run(self): """Check timeout on all responses. (Internal)""" for req, resp in self.servings: resp.check_timeout() engine.timeout_monitor = _TimeoutMonitor(engine) engine.timeout_monitor.subscribe() engine.autoreload = process.plugins.Autoreloader(engine) engine.autoreload.subscribe() engine.thread_manager = process.plugins.ThreadManager(engine) engine.thread_manager.subscribe() engine.signal_handler = process.plugins.SignalHandler(engine) from cherrypy import _cpserver server = _cpserver.Server() server.subscribe() def quickstart(root=None, script_name="", config=None): """Mount the given root, start the builtin server (and engine), then block. root: an instance of a "controller class" (a collection of page handler methods) which represents the root of the application. script_name: a string containing the "mount point" of the application. This should start with a slash, and be the path portion of the URL at which to mount the given root. For example, if root.index() will handle requests to "http://www.example.com:8080/dept/app1/", then the script_name argument would be "/dept/app1". It MUST NOT end in a slash. If the script_name refers to the root of the URI, it MUST be an empty string (not "/"). config: a file or dict containing application config. If this contains a [global] section, those entries will be used in the global (site-wide) config. """ if config: _global_conf_alias.update(config) if root is not None: tree.mount(root, script_name, config) if hasattr(engine, "signal_handler"): engine.signal_handler.subscribe() if hasattr(engine, "console_control_handler"): engine.console_control_handler.subscribe() engine.start() engine.block() try: from threading import local as _local except ImportError: from cherrypy._cpthreadinglocal import local as _local class _Serving(_local): """An interface for registering request and response objects. Rather than have a separate "thread local" object for the request and the response, this class works as a single threadlocal container for both objects (and any others which developers wish to define). In this way, we can easily dump those objects when we stop/start a new HTTP conversation, yet still refer to them as module-level globals in a thread-safe way. """ __metaclass__ = _AttributeDocstrings request = _cprequest.Request(_http.Host("127.0.0.1", 80), _http.Host("127.0.0.1", 1111)) request__doc = """ The request object for the current thread. In the main thread, and any threads which are not receiving HTTP requests, this is None.""" response = _cprequest.Response() response__doc = """ The response object for the current thread. In the main thread, and any threads which are not receiving HTTP requests, this is None.""" def load(self, request, response): self.request = request self.response = response def clear(self): """Remove all attributes of self.""" self.__dict__.clear() serving = _Serving() class _ThreadLocalProxy(object): __slots__ = ['__attrname__', '__dict__'] def __init__(self, attrname): self.__attrname__ = attrname def __getattr__(self, name): child = getattr(serving, self.__attrname__) return getattr(child, name) def __setattr__(self, name, value): if name in ("__attrname__", ): object.__setattr__(self, name, value) else: child = getattr(serving, self.__attrname__) setattr(child, name, value) def __delattr__(self, name): child = getattr(serving, self.__attrname__) delattr(child, name) def _get_dict(self): child = getattr(serving, self.__attrname__) d = child.__class__.__dict__.copy() d.update(child.__dict__) return d __dict__ = property(_get_dict) def __getitem__(self, key): child = getattr(serving, self.__attrname__) return child[key] def __setitem__(self, key, value): child = getattr(serving, self.__attrname__) child[key] = value def __delitem__(self, key): child = getattr(serving, self.__attrname__) del child[key] def __contains__(self, key): child = getattr(serving, self.__attrname__) return key in child def __len__(self): child = getattr(serving, self.__attrname__) return len(child) def __nonzero__(self): child = getattr(serving, self.__attrname__) return bool(child) # Create request and response object (the same objects will be used # throughout the entire life of the webserver, but will redirect # to the "serving" object) request = _ThreadLocalProxy('request') response = _ThreadLocalProxy('response') # Create thread_data object as a thread-specific all-purpose storage class _ThreadData(_local): """A container for thread-specific data.""" thread_data = _ThreadData() # Monkeypatch pydoc to allow help() to go through the threadlocal proxy. # Jan 2007: no Googleable examples of anyone else replacing pydoc.resolve. # The only other way would be to change what is returned from type(request) # and that's not possible in pure Python (you'd have to fake ob_type). def _cherrypy_pydoc_resolve(thing, forceload=0): """Given an object or a path to an object, get the object and its name.""" if isinstance(thing, _ThreadLocalProxy): thing = getattr(serving, thing.__attrname__) return _pydoc._builtin_resolve(thing, forceload) try: import pydoc as _pydoc _pydoc._builtin_resolve = _pydoc.resolve _pydoc.resolve = _cherrypy_pydoc_resolve except ImportError: pass from cherrypy import _cplogging class _GlobalLogManager(_cplogging.LogManager): def __call__(self, *args, **kwargs): try: log = request.app.log except AttributeError: log = self return log.error(*args, **kwargs) def access(self): try: return request.app.log.access() except AttributeError: return _cplogging.LogManager.access(self) log = _GlobalLogManager() # Set a default screen handler on the global log. log.screen = True log.error_file = '' # Using an access file makes CP about 10% slower. Leave off by default. log.access_file = '' def _buslog(msg, level): log.error(msg, 'ENGINE', severity=level) engine.subscribe('log', _buslog) # Helper functions for CP apps # def expose(func=None, alias=None): """Expose the function, optionally providing an alias or set of aliases.""" def expose_(func): func.exposed = True if alias is not None: if isinstance(alias, basestring): parents[alias.replace(".", "_")] = func else: for a in alias: parents[a.replace(".", "_")] = func return func import sys, types if isinstance(func, (types.FunctionType, types.MethodType)): if alias is None: # @expose func.exposed = True return func else: # func = expose(func, alias) parents = sys._getframe(1).f_locals return expose_(func) elif func is None: if alias is None: # @expose() parents = sys._getframe(1).f_locals return expose_ else: # @expose(alias="alias") or # @expose(alias=["alias1", "alias2"]) parents = sys._getframe(1).f_locals return expose_ else: # @expose("alias") or # @expose(["alias1", "alias2"]) parents = sys._getframe(1).f_locals alias = func return expose_ def url(path="", qs="", script_name=None, base=None, relative=None): """Create an absolute URL for the given path. If 'path' starts with a slash ('/'), this will return (base + script_name + path + qs). If it does not start with a slash, this returns (base + script_name [+ request.path_info] + path + qs). If script_name is None, cherrypy.request will be used to find a script_name, if available. If base is None, cherrypy.request.base will be used (if available). Note that you can use cherrypy.tools.proxy to change this. Finally, note that this function can be used to obtain an absolute URL for the current request path (minus the querystring) by passing no args. If you call url(qs=cherrypy.request.query_string), you should get the original browser URL (assuming no internal redirections). If relative is None or not provided, request.app.relative_urls will be used (if available, else False). If False, the output will be an absolute URL (including the scheme, host, vhost, and script_name). If True, the output will instead be a URL that is relative to the current request path, perhaps including '..' atoms. If relative is the string 'server', the output will instead be a URL that is relative to the server root; i.e., it will start with a slash. """ if qs: qs = '?' + qs if request.app: if not path.startswith("/"): # Append/remove trailing slash from path_info as needed # (this is to support mistyped URL's without redirecting; # if you want to redirect, use tools.trailing_slash). pi = request.path_info if request.is_index is True: if not pi.endswith('/'): pi = pi + '/' elif request.is_index is False: if pi.endswith('/') and pi != '/': pi = pi[:-1] if path == "": path = pi else: path = _urljoin(pi, path) if script_name is None: script_name = request.script_name if base is None: base = request.base newurl = base + script_name + path + qs else: # No request.app (we're being called outside a request). # We'll have to guess the base from server.* attributes. # This will produce very different results from the above # if you're using vhosts or tools.proxy. if base is None: base = server.base() path = (script_name or "") + path newurl = base + path + qs if './' in newurl: # Normalize the URL by removing ./ and ../ atoms = [] for atom in newurl.split('/'): if atom == '.': pass elif atom == '..': atoms.pop() else: atoms.append(atom) newurl = '/'.join(atoms) # At this point, we should have a fully-qualified absolute URL. if relative is None: relative = getattr(request.app, "relative_urls", False) # See http://www.ietf.org/rfc/rfc2396.txt if relative == 'server': # "A relative reference beginning with a single slash character is # termed an absolute-path reference, as defined by ..." # This is also sometimes called "server-relative". newurl = '/' + '/'.join(newurl.split('/', 3)[3:]) elif relative: # "A relative reference that does not begin with a scheme name # or a slash character is termed a relative-path reference." old = url().split('/')[:-1] new = newurl.split('/') while old and new: a, b = old[0], new[0] if a != b: break old.pop(0) new.pop(0) new = (['..'] * len(old)) + new newurl = '/'.join(new) return newurl # import _cpconfig last so it can reference other top-level objects from cherrypy import _cpconfig # Use _global_conf_alias so quickstart can use 'config' as an arg # without shadowing cherrypy.config. config = _global_conf_alias = _cpconfig.Config() from cherrypy import _cpchecker checker = _cpchecker.Checker() engine.subscribe('start', checker) SABnzbd-0.7.20/cherrypy/lib/auth.py0000644000000000000000000000604412433712602017157 0ustar00usergroup00000000000000import logging import cherrypy from cherrypy.lib import httpauth def check_auth(users, encrypt=None, realm=None): """If an authorization header contains credentials, return True, else False.""" if 'authorization' in cherrypy.request.headers: # make sure the provided credentials are correctly set ah = httpauth.parseAuthorization(cherrypy.request.headers['authorization']) if ah is None: raise cherrypy.HTTPError(400, 'Bad Request') if not encrypt: encrypt = httpauth.DIGEST_AUTH_ENCODERS[httpauth.MD5] if callable(users): try: # backward compatibility users = users() # expect it to return a dictionary if not isinstance(users, dict): raise ValueError, "Authentication users must be a dictionary" # fetch the user password password = users.get(ah["username"], None) except TypeError: # returns a password (encrypted or clear text) password = users(ah["username"]) else: if not isinstance(users, dict): raise ValueError, "Authentication users must be a dictionary" # fetch the user password password = users.get(ah["username"], None) # validate the authorization by re-computing it here # and compare it with what the user-agent provided if httpauth.checkResponse(ah, password, method=cherrypy.request.method, encrypt=encrypt, realm=realm): cherrypy.request.login = ah["username"] return True if ah.get('username') or ah.get('password'): logging.info('Attempt to login with wrong credentials from %s', cherrypy.request.headers['Remote-Addr']) cherrypy.request.login = False return False def basic_auth(realm, users, encrypt=None): """If auth fails, raise 401 with a basic authentication header. realm: a string containing the authentication realm. users: a dict of the form: {username: password} or a callable returning a dict. encrypt: callable used to encrypt the password returned from the user-agent. if None it defaults to a md5 encryption. """ if check_auth(users, encrypt): return # inform the user-agent this path is protected cherrypy.response.headers['www-authenticate'] = httpauth.basicAuth(realm) raise cherrypy.HTTPError(401, "You are not authorized to access that resource") def digest_auth(realm, users): """If auth fails, raise 401 with a digest authentication header. realm: a string containing the authentication realm. users: a dict of the form: {username: password} or a callable returning a dict. """ if check_auth(users, realm=realm): return # inform the user-agent this path is protected cherrypy.response.headers['www-authenticate'] = httpauth.digestAuth(realm) raise cherrypy.HTTPError(401, "You are not authorized to access that resource") SABnzbd-0.7.20/cherrypy/lib/caching.py0000644000000000000000000002202212433712602017604 0ustar00usergroup00000000000000import datetime import threading import time import cherrypy from cherrypy.lib import cptools, http class MemoryCache: maxobjects = 1000 maxobj_size = 100000 maxsize = 10000000 delay = 600 def __init__(self): self.clear() t = threading.Thread(target=self.expire_cache, name='expire_cache') self.expiration_thread = t if hasattr(threading.Thread, "daemon"): # Python 2.6+ t.daemon = True else: t.setDaemon(True) t.start() def clear(self): """Reset the cache to its initial, empty state.""" self.cache = {} self.expirations = {} self.tot_puts = 0 self.tot_gets = 0 self.tot_hist = 0 self.tot_expires = 0 self.tot_non_modified = 0 self.cursize = 0 def key(self): return cherrypy.url(qs=cherrypy.request.query_string) def expire_cache(self): # expire_cache runs in a separate thread which the servers are # not aware of. It's possible that "time" will be set to None # arbitrarily, so we check "while time" to avoid exceptions. # See tickets #99 and #180 for more information. while time: now = time.time() for expiration_time, objects in self.expirations.items(): if expiration_time <= now: for obj_size, obj_key in objects: try: del self.cache[obj_key] self.tot_expires += 1 self.cursize -= obj_size except KeyError: # the key may have been deleted elsewhere pass del self.expirations[expiration_time] time.sleep(0.1) def get(self): """Return the object if in the cache, else None.""" self.tot_gets += 1 cache_item = self.cache.get(self.key(), None) if cache_item: self.tot_hist += 1 return cache_item else: return None def put(self, obj): if len(self.cache) < self.maxobjects: # Size check no longer includes header length obj_size = len(obj[2]) total_size = self.cursize + obj_size # checks if there's space for the object if (obj_size < self.maxobj_size and total_size < self.maxsize): # add to the expirations list and cache expiration_time = cherrypy.response.time + self.delay obj_key = self.key() bucket = self.expirations.setdefault(expiration_time, []) bucket.append((obj_size, obj_key)) self.cache[obj_key] = obj self.tot_puts += 1 self.cursize = total_size def delete(self): self.cache.pop(self.key(), None) def get(invalid_methods=("POST", "PUT", "DELETE"), **kwargs): """Try to obtain cached output. If fresh enough, raise HTTPError(304). If POST, PUT, or DELETE: * invalidates (deletes) any cached response for this resource * sets request.cached = False * sets request.cacheable = False else if a cached copy exists: * sets request.cached = True * sets request.cacheable = False * sets response.headers to the cached values * checks the cached Last-Modified response header against the current If-(Un)Modified-Since request headers; raises 304 if necessary. * sets response.status and response.body to the cached values * returns True otherwise: * sets request.cached = False * sets request.cacheable = True * returns False """ request = cherrypy.request # POST, PUT, DELETE should invalidate (delete) the cached copy. # See http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10. if request.method in invalid_methods: cherrypy._cache.delete() request.cached = False request.cacheable = False return False cache_data = cherrypy._cache.get() request.cached = c = bool(cache_data) request.cacheable = not c if c: response = cherrypy.response s, h, b, create_time, original_req_headers = cache_data # Check 'Vary' selecting headers. If any headers mentioned in "Vary" # differ between the cached and current request, bail out and # let the rest of CP handle the request. This should properly # mimic the behavior of isolated caches as RFC 2616 assumes: # "If the selecting request header fields for the cached entry # do not match the selecting request header fields of the new # request, then the cache MUST NOT use a cached entry to satisfy # the request unless it first relays the new request to the origin # server in a conditional request and the server responds with # 304 (Not Modified), including an entity tag or Content-Location # that indicates the entity to be used. # TODO: can we store multiple variants based on Vary'd headers? for header_element in h.elements('Vary'): key = header_element.value if original_req_headers[key] != request.headers.get(key, 'missing'): request.cached = False request.cacheable = True return False # Copy the response headers. See http://www.cherrypy.org/ticket/721. response.headers = rh = http.HeaderMap() for k in h: dict.__setitem__(rh, k, dict.__getitem__(h, k)) # Add the required Age header response.headers["Age"] = str(int(response.time - create_time)) try: # Note that validate_since depends on a Last-Modified header; # this was put into the cached copy, and should have been # resurrected just above (response.headers = cache_data[1]). cptools.validate_since() except cherrypy.HTTPRedirect, x: if x.status == 304: cherrypy._cache.tot_non_modified += 1 raise # serve it & get out from the request response.status = s response.body = b return c def tee_output(): def tee(body): """Tee response.body into a list.""" output = [] for chunk in body: output.append(chunk) yield chunk # Might as well do this here; why cache if the body isn't consumed? if response.headers.get('Pragma', None) != 'no-cache': # save the cache data body = ''.join(output) vary = [he.value for he in cherrypy.response.headers.elements('Vary')] if vary: sel_headers = dict([(k, v) for k, v in cherrypy.request.headers.iteritems() if k in vary]) else: sel_headers = {} cherrypy._cache.put((response.status, response.headers or {}, body, response.time, sel_headers)) response = cherrypy.response response.body = tee(response.body) def expires(secs=0, force=False): """Tool for influencing cache mechanisms using the 'Expires' header. 'secs' must be either an int or a datetime.timedelta, and indicates the number of seconds between response.time and when the response should expire. The 'Expires' header will be set to (response.time + secs). If 'secs' is zero, the 'Expires' header is set one year in the past, and the following "cache prevention" headers are also set: 'Pragma': 'no-cache' 'Cache-Control': 'no-cache, must-revalidate' If 'force' is False (the default), the following headers are checked: 'Etag', 'Last-Modified', 'Age', 'Expires'. If any are already present, none of the above response headers are set. """ response = cherrypy.response headers = response.headers cacheable = False if not force: # some header names that indicate that the response can be cached for indicator in ('Etag', 'Last-Modified', 'Age', 'Expires'): if indicator in headers: cacheable = True break if not cacheable: if isinstance(secs, datetime.timedelta): secs = (86400 * secs.days) + secs.seconds if secs == 0: if force or "Pragma" not in headers: headers["Pragma"] = "no-cache" if cherrypy.request.protocol >= (1, 1): if force or "Cache-Control" not in headers: headers["Cache-Control"] = "no-cache, must-revalidate" # Set an explicit Expires date in the past. expiry = http.HTTPDate(1169942400.0) else: expiry = http.HTTPDate(response.time + secs) if force or "Expires" not in headers: headers["Expires"] = expiry SABnzbd-0.7.20/cherrypy/lib/covercp.py0000644000000000000000000002542612433712602017664 0ustar00usergroup00000000000000"""Code-coverage tools for CherryPy. To use this module, or the coverage tools in the test suite, you need to download 'coverage.py', either Gareth Rees' original implementation: http://www.garethrees.org/2001/12/04/python-coverage/ or Ned Batchelder's enhanced version: http://www.nedbatchelder.com/code/modules/coverage.html To turn on coverage tracing, use the following code: cherrypy.engine.subscribe('start', covercp.start) cherrypy.engine.subscribe('start_thread', covercp.start) Run your code, then use the covercp.serve() function to browse the results in a web browser. If you run this module from the command line, it will call serve() for you. """ import re import sys import cgi import urllib import os, os.path localFile = os.path.join(os.path.dirname(__file__), "coverage.cache") try: import cStringIO as StringIO except ImportError: import StringIO try: from coverage import the_coverage as coverage def start(threadid=None): coverage.start() except ImportError: # Setting coverage to None will raise errors # that need to be trapped downstream. coverage = None import warnings warnings.warn("No code coverage will be performed; coverage.py could not be imported.") def start(threadid=None): pass start.priority = 20 # Guess initial depth to hide FIXME this doesn't work for non-cherrypy stuff import cherrypy initial_base = os.path.dirname(cherrypy.__file__) TEMPLATE_MENU = """ CherryPy Coverage Menu

CherryPy Coverage

""" TEMPLATE_FORM = """
Show percentages
Hide files over %%
Exclude files matching

""" TEMPLATE_FRAMESET = """ CherryPy coverage data """ % initial_base.lower() TEMPLATE_COVERAGE = """ Coverage for %(name)s

%(name)s

%(fullpath)s

Coverage: %(pc)s%%

""" TEMPLATE_LOC_COVERED = """ %s  %s \n""" TEMPLATE_LOC_NOT_COVERED = """ %s  %s \n""" TEMPLATE_LOC_EXCLUDED = """ %s  %s \n""" TEMPLATE_ITEM = "%s%s%s\n" def _percent(statements, missing): s = len(statements) e = s - len(missing) if s > 0: return int(round(100.0 * e / s)) return 0 def _show_branch(root, base, path, pct=0, showpct=False, exclude=""): # Show the directory name and any of our children dirs = [k for k, v in root.iteritems() if v] dirs.sort() for name in dirs: newpath = os.path.join(path, name) if newpath.lower().startswith(base): relpath = newpath[len(base):] yield "| " * relpath.count(os.sep) yield "%s\n" % \ (newpath, urllib.quote_plus(exclude), name) for chunk in _show_branch(root[name], base, newpath, pct, showpct, exclude): yield chunk # Now list the files if path.lower().startswith(base): relpath = path[len(base):] files = [k for k, v in root.iteritems() if not v] files.sort() for name in files: newpath = os.path.join(path, name) pc_str = "" if showpct: try: _, statements, _, missing, _ = coverage.analysis2(newpath) except: # Yes, we really want to pass on all errors. pass else: pc = _percent(statements, missing) pc_str = ("%3d%% " % pc).replace(' ',' ') if pc < float(pct) or pc == -1: pc_str = "%s" % pc_str else: pc_str = "%s" % pc_str yield TEMPLATE_ITEM % ("| " * (relpath.count(os.sep) + 1), pc_str, newpath, name) def _skip_file(path, exclude): if exclude: return bool(re.search(exclude, path)) def _graft(path, tree): d = tree p = path atoms = [] while True: p, tail = os.path.split(p) if not tail: break atoms.append(tail) atoms.append(p) if p != "/": atoms.append("/") atoms.reverse() for node in atoms: if node: d = d.setdefault(node, {}) def get_tree(base, exclude): """Return covered module names as a nested dict.""" tree = {} coverage.get_ready() runs = coverage.cexecuted.keys() if runs: for path in runs: if not _skip_file(path, exclude) and not os.path.isdir(path): _graft(path, tree) return tree class CoverStats(object): def index(self): return TEMPLATE_FRAMESET index.exposed = True def menu(self, base="/", pct="50", showpct="", exclude=r'python\d\.\d|test|tut\d|tutorial'): # The coverage module uses all-lower-case names. base = base.lower().rstrip(os.sep) yield TEMPLATE_MENU yield TEMPLATE_FORM % locals() # Start by showing links for parent paths yield "
" path = "" atoms = base.split(os.sep) atoms.pop() for atom in atoms: path += atom + os.sep yield ("%s %s" % (path, urllib.quote_plus(exclude), atom, os.sep)) yield "
" yield "
" # Then display the tree tree = get_tree(base, exclude) if not tree: yield "

No modules covered.

" else: for chunk in _show_branch(tree, base, "/", pct, showpct=='checked', exclude): yield chunk yield "
" yield "" menu.exposed = True def annotated_file(self, filename, statements, excluded, missing): source = open(filename, 'r') buffer = [] for lineno, line in enumerate(source.readlines()): lineno += 1 line = line.strip("\n\r") empty_the_buffer = True if lineno in excluded: template = TEMPLATE_LOC_EXCLUDED elif lineno in missing: template = TEMPLATE_LOC_NOT_COVERED elif lineno in statements: template = TEMPLATE_LOC_COVERED else: empty_the_buffer = False buffer.append((lineno, line)) if empty_the_buffer: for lno, pastline in buffer: yield template % (lno, cgi.escape(pastline)) buffer = [] yield template % (lineno, cgi.escape(line)) def report(self, name): coverage.get_ready() filename, statements, excluded, missing, _ = coverage.analysis2(name) pc = _percent(statements, missing) yield TEMPLATE_COVERAGE % dict(name=os.path.basename(name), fullpath=name, pc=pc) yield '\n' for line in self.annotated_file(filename, statements, excluded, missing): yield line yield '
' yield '' yield '' report.exposed = True def serve(path=localFile, port=8080): if coverage is None: raise ImportError("The coverage module could not be imported.") coverage.cache_default = path import cherrypy cherrypy.config.update({'server.socket_port': port, 'server.thread_pool': 10, 'environment': "production", }) cherrypy.quickstart(CoverStats()) if __name__ == "__main__": serve(*tuple(sys.argv[1:])) SABnzbd-0.7.20/cherrypy/lib/cptools.py0000644000000000000000000003750312433712602017705 0ustar00usergroup00000000000000"""Functions for builtin CherryPy tools.""" import logging try: # Python 2.5+ from hashlib import md5 except ImportError: from md5 import new as md5 import re import cherrypy from cherrypy.lib import http as _http # Conditional HTTP request support # def validate_etags(autotags=False): """Validate the current ETag against If-Match, If-None-Match headers. If autotags is True, an ETag response-header value will be provided from an MD5 hash of the response body (unless some other code has already provided an ETag header). If False (the default), the ETag will not be automatic. WARNING: the autotags feature is not designed for URL's which allow methods other than GET. For example, if a POST to the same URL returns no content, the automatic ETag will be incorrect, breaking a fundamental use for entity tags in a possibly destructive fashion. Likewise, if you raise 304 Not Modified, the response body will be empty, the ETag hash will be incorrect, and your application will break. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24 """ response = cherrypy.response # Guard against being run twice. if hasattr(response, "ETag"): return status, reason, msg = _http.valid_status(response.status) etag = response.headers.get('ETag') # Automatic ETag generation. See warning in docstring. if (not etag) and autotags: if status == 200: etag = response.collapse_body() etag = '"%s"' % md5(etag).hexdigest() response.headers['ETag'] = etag response.ETag = etag # "If the request would, without the If-Match header field, result in # anything other than a 2xx or 412 status, then the If-Match header # MUST be ignored." if status >= 200 and status <= 299: request = cherrypy.request conditions = request.headers.elements('If-Match') or [] conditions = [str(x) for x in conditions] if conditions and not (conditions == ["*"] or etag in conditions): raise cherrypy.HTTPError(412, "If-Match failed: ETag %r did " "not match %r" % (etag, conditions)) conditions = request.headers.elements('If-None-Match') or [] conditions = [str(x) for x in conditions] if conditions == ["*"] or etag in conditions: if request.method in ("GET", "HEAD"): raise cherrypy.HTTPRedirect([], 304) else: raise cherrypy.HTTPError(412, "If-None-Match failed: ETag %r " "matched %r" % (etag, conditions)) def validate_since(): """Validate the current Last-Modified against If-Modified-Since headers. If no code has set the Last-Modified response header, then no validation will be performed. """ response = cherrypy.response lastmod = response.headers.get('Last-Modified') if lastmod: status, reason, msg = _http.valid_status(response.status) request = cherrypy.request since = request.headers.get('If-Unmodified-Since') if since and since != lastmod: if (status >= 200 and status <= 299) or status == 412: raise cherrypy.HTTPError(412) since = request.headers.get('If-Modified-Since') if since and since == lastmod: if (status >= 200 and status <= 299) or status == 304: if request.method in ("GET", "HEAD"): raise cherrypy.HTTPRedirect([], 304) else: raise cherrypy.HTTPError(412) # Tool code # def proxy(base=None, local='X-Forwarded-Host', remote='X-Forwarded-For', scheme='X-Forwarded-Proto'): """Change the base URL (scheme://host[:port][/path]). For running a CP server behind Apache, lighttpd, or other HTTP server. If you want the new request.base to include path info (not just the host), you must explicitly set base to the full base path, and ALSO set 'local' to '', so that the X-Forwarded-Host request header (which never includes path info) does not override it. Regardless, the value for 'base' MUST NOT end in a slash. cherrypy.request.remote.ip (the IP address of the client) will be rewritten if the header specified by the 'remote' arg is valid. By default, 'remote' is set to 'X-Forwarded-For'. If you do not want to rewrite remote.ip, set the 'remote' arg to an empty string. """ request = cherrypy.request if scheme: s = request.headers.get(scheme, None) if s == 'on' and 'ssl' in scheme.lower(): # This handles e.g. webfaction's 'X-Forwarded-Ssl: on' header scheme = 'https' else: # This is for lighttpd/pound/Mongrel's 'X-Forwarded-Proto: https' scheme = s if not scheme: scheme = request.base[:request.base.find("://")] if local: base = request.headers.get(local, base) if not base: port = cherrypy.request.local.port if port == 80: base = '127.0.0.1' else: base = '127.0.0.1:%s' % port if base.find("://") == -1: # add http:// or https:// if needed base = scheme + "://" + base request.base = base if remote: xff = request.headers.get(remote) if xff: if remote == 'X-Forwarded-For': # See http://bob.pythonmac.org/archives/2005/09/23/apache-x-forwarded-for-caveat/ xff = xff.split(',')[-1].strip() request.remote.ip = xff def ignore_headers(headers=('Range',)): """Delete request headers whose field names are included in 'headers'. This is a useful tool for working behind certain HTTP servers; for example, Apache duplicates the work that CP does for 'Range' headers, and will doubly-truncate the response. """ request = cherrypy.request for name in headers: if name in request.headers: del request.headers[name] def response_headers(headers=None): """Set headers on the response.""" for name, value in (headers or []): cherrypy.response.headers[name] = value response_headers.failsafe = True def referer(pattern, accept=True, accept_missing=False, error=403, message='Forbidden Referer header.'): """Raise HTTPError if Referer header does/does not match the given pattern. pattern: a regular expression pattern to test against the Referer. accept: if True, the Referer must match the pattern; if False, the Referer must NOT match the pattern. accept_missing: if True, permit requests with no Referer header. error: the HTTP error code to return to the client on failure. message: a string to include in the response body on failure. """ try: match = bool(re.match(pattern, cherrypy.request.headers['Referer'])) if accept == match: return except KeyError: if accept_missing: return raise cherrypy.HTTPError(error, message) class SessionAuth(object): """Assert that the user is logged in.""" session_key = "username" def check_username_and_password(self, username, password): pass def anonymous(self): """Provide a temporary user name for anonymous users.""" pass def on_login(self, username): pass def on_logout(self, username): pass def on_check(self, username): pass def login_screen(self, from_page='..', username='', error_msg='', **kwargs): return """ Message: %(error_msg)s
Login:
Password:

""" % {'from_page': from_page, 'username': username, 'error_msg': error_msg} def do_login(self, username, password, from_page='..', **kwargs): """Login. May raise redirect, or return True if request handled.""" error_msg = self.check_username_and_password(username, password) if error_msg: body = self.login_screen(from_page, username, error_msg) cherrypy.response.body = body if cherrypy.response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del cherrypy.response.headers["Content-Length"] return True else: cherrypy.session[self.session_key] = cherrypy.request.login = username self.on_login(username) raise cherrypy.HTTPRedirect(from_page or "/") def do_logout(self, from_page='..', **kwargs): """Logout. May raise redirect, or return True if request handled.""" sess = cherrypy.session username = sess.get(self.session_key) sess[self.session_key] = None if username: cherrypy.request.login = None self.on_logout(username) raise cherrypy.HTTPRedirect(from_page) def do_check(self): """Assert username. May raise redirect, or return True if request handled.""" sess = cherrypy.session request = cherrypy.request username = sess.get(self.session_key) if not username: sess[self.session_key] = username = self.anonymous() if not username: cherrypy.response.body = self.login_screen(cherrypy.url(qs=request.query_string)) if cherrypy.response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del cherrypy.response.headers["Content-Length"] return True cherrypy.request.login = username self.on_check(username) def run(self): request = cherrypy.request path = request.path_info if path.endswith('login_screen'): return self.login_screen(**request.params) elif path.endswith('do_login'): return self.do_login(**request.params) elif path.endswith('do_logout'): return self.do_logout(**request.params) else: return self.do_check() def session_auth(**kwargs): sa = SessionAuth() for k, v in kwargs.iteritems(): setattr(sa, k, v) return sa.run() session_auth.__doc__ = """Session authentication hook. Any attribute of the SessionAuth class may be overridden via a keyword arg to this function: """ + "\n".join(["%s: %s" % (k, type(getattr(SessionAuth, k)).__name__) for k in dir(SessionAuth) if not k.startswith("__")]) def log_traceback(severity=logging.DEBUG): """Write the last error's traceback to the cherrypy error log.""" cherrypy.log("", "HTTP", severity=severity, traceback=True) def log_request_headers(): """Write request headers to the cherrypy error log.""" h = [" %s: %s" % (k, v) for k, v in cherrypy.request.header_list] cherrypy.log('\nRequest Headers:\n' + '\n'.join(h), "HTTP") def log_hooks(): """Write request.hooks to the cherrypy error log.""" msg = [] # Sort by the standard points if possible. from cherrypy import _cprequest points = _cprequest.hookpoints for k in cherrypy.request.hooks.keys(): if k not in points: points.append(k) for k in points: msg.append(" %s:" % k) v = cherrypy.request.hooks.get(k, []) v.sort() for h in v: msg.append(" %r" % h) cherrypy.log('\nRequest Hooks for ' + cherrypy.url() + ':\n' + '\n'.join(msg), "HTTP") def redirect(url='', internal=True): """Raise InternalRedirect or HTTPRedirect to the given url.""" if internal: raise cherrypy.InternalRedirect(url) else: raise cherrypy.HTTPRedirect(url) def trailing_slash(missing=True, extra=False): """Redirect if path_info has (missing|extra) trailing slash.""" request = cherrypy.request pi = request.path_info if request.is_index is True: if missing: if not pi.endswith('/'): new_url = cherrypy.url(pi + '/', request.query_string) raise cherrypy.HTTPRedirect(new_url) elif request.is_index is False: if extra: # If pi == '/', don't redirect to ''! if pi.endswith('/') and pi != '/': new_url = cherrypy.url(pi[:-1], request.query_string) raise cherrypy.HTTPRedirect(new_url) def flatten(): """Wrap response.body in a generator that recursively iterates over body. This allows cherrypy.response.body to consist of 'nested generators'; that is, a set of generators that yield generators. """ import types def flattener(input): for x in input: if not isinstance(x, types.GeneratorType): yield x else: for y in flattener(x): yield y response = cherrypy.response response.body = flattener(response.body) def accept(media=None): """Return the client's preferred media-type (from the given Content-Types). If 'media' is None (the default), no test will be performed. If 'media' is provided, it should be the Content-Type value (as a string) or values (as a list or tuple of strings) which the current request can emit. The client's acceptable media ranges (as declared in the Accept request header) will be matched in order to these Content-Type values; the first such string is returned. That is, the return value will always be one of the strings provided in the 'media' arg (or None if 'media' is None). If no match is found, then HTTPError 406 (Not Acceptable) is raised. Note that most web browsers send */* as a (low-quality) acceptable media range, which should match any Content-Type. In addition, "...if no Accept header field is present, then it is assumed that the client accepts all media types." Matching types are checked in order of client preference first, and then in the order of the given 'media' values. Note that this function does not honor accept-params (other than "q"). """ if not media: return if isinstance(media, basestring): media = [media] # Parse the Accept request header, and try to match one # of the requested media-ranges (in order of preference). ranges = cherrypy.request.headers.elements('Accept') if not ranges: # Any media type is acceptable. return media[0] else: # Note that 'ranges' is sorted in order of preference for element in ranges: if element.qvalue > 0: if element.value == "*/*": # Matches any type or subtype return media[0] elif element.value.endswith("/*"): # Matches any subtype mtype = element.value[:-1] # Keep the slash for m in media: if m.startswith(mtype): return m else: # Matches exact value if element.value in media: return element.value # No suitable media-range found. ah = cherrypy.request.headers.get('Accept') if ah is None: msg = "Your client did not send an Accept header." else: msg = "Your client sent this Accept header: %s." % ah msg += (" But this resource only emits these media types: %s." % ", ".join(media)) raise cherrypy.HTTPError(406, msg) SABnzbd-0.7.20/cherrypy/lib/encoding.py0000644000000000000000000002373312433712602020010 0ustar00usergroup00000000000000import struct import time import cherrypy def decode(encoding=None, default_encoding='utf-8'): """Decode cherrypy.request.params from str to unicode objects.""" if not encoding: ct = cherrypy.request.headers.elements("Content-Type") if ct: ct = ct[0] encoding = ct.params.get("charset", None) if (not encoding) and ct.value.lower().startswith("text/"): # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7.1 # When no explicit charset parameter is provided by the # sender, media subtypes of the "text" type are defined # to have a default charset value of "ISO-8859-1" when # received via HTTP. encoding = "ISO-8859-1" if not encoding: encoding = default_encoding try: decode_params(encoding) except UnicodeDecodeError: # IE and Firefox don't supply a charset when submitting form # params with a CT of application/x-www-form-urlencoded. # So after all our guessing, it could *still* be wrong. # Start over with ISO-8859-1, since that seems to be preferred. decode_params("ISO-8859-1") def decode_params(encoding): decoded_params = {} for key, value in cherrypy.request.params.items(): if not hasattr(value, 'file'): # Skip the value if it is an uploaded file if isinstance(value, list): # value is a list: decode each element value = [v.decode(encoding) for v in value] elif isinstance(value, str): # value is a regular string: decode it value = value.decode(encoding) decoded_params[key] = value # Decode all or nothing, so we can try again on error. cherrypy.request.params = decoded_params # Encoding def encode(encoding=None, errors='strict', text_only=True, add_charset=True): # Guard against running twice if getattr(cherrypy.request, "_encoding_attempted", False): return cherrypy.request._encoding_attempted = True ct = cherrypy.response.headers.elements("Content-Type") if ct: ct = ct[0] if (not text_only) or ct.value.lower().startswith("text/"): # Set "charset=..." param on response Content-Type header ct.params['charset'] = find_acceptable_charset(encoding, errors=errors) if add_charset: cherrypy.response.headers["Content-Type"] = str(ct) def encode_stream(encoding, errors='strict'): """Encode a streaming response body. Use a generator wrapper, and just pray it works as the stream is being written out. """ def encoder(body): for chunk in body: if isinstance(chunk, unicode): chunk = chunk.encode(encoding, errors) yield chunk cherrypy.response.body = encoder(cherrypy.response.body) return True def encode_string(encoding, errors='strict'): """Encode a buffered response body.""" try: body = [] for chunk in cherrypy.response.body: if isinstance(chunk, unicode): chunk = chunk.encode(encoding, errors) body.append(chunk) cherrypy.response.body = body except (LookupError, UnicodeError): return False else: return True def find_acceptable_charset(encoding=None, default_encoding='utf-8', errors='strict'): response = cherrypy.response if cherrypy.response.stream: encoder = encode_stream else: response.collapse_body() encoder = encode_string if response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. # Encoded strings may be of different lengths from their # unicode equivalents, and even from each other. For example: # >>> t = u"\u7007\u3040" # >>> len(t) # 2 # >>> len(t.encode("UTF-8")) # 6 # >>> len(t.encode("utf7")) # 8 del response.headers["Content-Length"] # Parse the Accept-Charset request header, and try to provide one # of the requested charsets (in order of user preference). encs = cherrypy.request.headers.elements('Accept-Charset') charsets = [enc.value.lower() for enc in encs] attempted_charsets = [] if encoding is not None: # If specified, force this encoding to be used, or fail. encoding = encoding.lower() if (not charsets) or "*" in charsets or encoding in charsets: if encoder(encoding, errors): return encoding else: if not encs: # Any character-set is acceptable. if encoder(default_encoding, errors): return default_encoding else: raise cherrypy.HTTPError(500, failmsg % default_encoding) else: if "*" not in charsets: # If no "*" is present in an Accept-Charset field, then all # character sets not explicitly mentioned get a quality # value of 0, except for ISO-8859-1, which gets a quality # value of 1 if not explicitly mentioned. iso = 'iso-8859-1' if iso not in charsets: attempted_charsets.append(iso) if encoder(iso, errors): return iso for element in encs: if element.qvalue > 0: if element.value == "*": # Matches any charset. Try our default. if default_encoding not in attempted_charsets: attempted_charsets.append(default_encoding) if encoder(default_encoding, errors): return default_encoding else: encoding = element.value if encoding not in attempted_charsets: attempted_charsets.append(encoding) if encoder(encoding, errors): return encoding # No suitable encoding found. ac = cherrypy.request.headers.get('Accept-Charset') if ac is None: msg = "Your client did not send an Accept-Charset header." else: msg = "Your client sent this Accept-Charset header: %s." % ac msg += " We tried these charsets: %s." % ", ".join(attempted_charsets) raise cherrypy.HTTPError(406, msg) # GZIP def compress(body, compress_level): """Compress 'body' at the given compress_level.""" import zlib yield '\037\213' # magic header yield '\010' # compression method yield '\0' yield struct.pack(" 0 is present * The 'identity' value is given with a qvalue > 0. """ response = cherrypy.response if not response.body: # Response body is empty (might be a 304 for instance) return # If returning cached content (which should already have been gzipped), # don't re-zip. if getattr(cherrypy.request, "cached", False): return acceptable = cherrypy.request.headers.elements('Accept-Encoding') if not acceptable: # If no Accept-Encoding field is present in a request, # the server MAY assume that the client will accept any # content coding. In this case, if "identity" is one of # the available content-codings, then the server SHOULD use # the "identity" content-coding, unless it has additional # information that a different content-coding is meaningful # to the client. return ct = response.headers.get('Content-Type', '').split(';')[0] for coding in acceptable: if coding.value == 'identity' and coding.qvalue != 0: return if coding.value in ('gzip', 'x-gzip'): if coding.qvalue == 0: return if ct in mime_types: # Return a generator that compresses the page varies = response.headers.get("Vary", "") varies = [x.strip() for x in varies.split(",") if x.strip()] if "Accept-Encoding" not in varies: varies.append("Accept-Encoding") response.headers['Vary'] = ", ".join(varies) response.headers['Content-Encoding'] = 'gzip' response.body = compress(response.body, compress_level) if response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del response.headers["Content-Length"] return cherrypy.HTTPError(406, "identity, gzip").set_response() SABnzbd-0.7.20/cherrypy/lib/http.py0000644000000000000000000003352612433712602017202 0ustar00usergroup00000000000000"""HTTP library functions.""" # This module contains functions for building an HTTP application # framework: any one, not just one whose name starts with "Ch". ;) If you # reference any modules from some popular framework inside *this* module, # FuManChu will personally hang you up by your thumbs and submit you # to a public caning. from BaseHTTPServer import BaseHTTPRequestHandler response_codes = BaseHTTPRequestHandler.responses.copy() # From http://www.cherrypy.org/ticket/361 response_codes[500] = ('Internal Server Error', 'The server encountered an unexpected condition ' 'which prevented it from fulfilling the request.') response_codes[503] = ('Service Unavailable', 'The server is currently unable to handle the ' 'request due to a temporary overloading or ' 'maintenance of the server.') import cgi import re from rfc822 import formatdate as HTTPDate def urljoin(*atoms): """Return the given path *atoms, joined into a single URL. This will correctly join a SCRIPT_NAME and PATH_INFO into the original URL, even if either atom is blank. """ url = "/".join([x for x in atoms if x]) while "//" in url: url = url.replace("//", "/") # Special-case the final url of "", and return "/" instead. return url or "/" def protocol_from_http(protocol_str): """Return a protocol tuple from the given 'HTTP/x.y' string.""" return int(protocol_str[5]), int(protocol_str[7]) def get_ranges(headervalue, content_length): """Return a list of (start, stop) indices from a Range header, or None. Each (start, stop) tuple will be composed of two ints, which are suitable for use in a slicing operation. That is, the header "Range: bytes=3-6", if applied against a Python string, is requesting resource[3:7]. This function will return the list [(3, 7)]. If this function returns an empty list, you should return HTTP 416. """ if not headervalue: return None result = [] bytesunit, byteranges = headervalue.split("=", 1) for brange in byteranges.split(","): start, stop = [x.strip() for x in brange.split("-", 1)] if start: if not stop: stop = content_length - 1 start, stop = map(int, (start, stop)) if start >= content_length: # From rfc 2616 sec 14.16: # "If the server receives a request (other than one # including an If-Range request-header field) with an # unsatisfiable Range request-header field (that is, # all of whose byte-range-spec values have a first-byte-pos # value greater than the current length of the selected # resource), it SHOULD return a response code of 416 # (Requested range not satisfiable)." continue if stop < start: # From rfc 2616 sec 14.16: # "If the server ignores a byte-range-spec because it # is syntactically invalid, the server SHOULD treat # the request as if the invalid Range header field # did not exist. (Normally, this means return a 200 # response containing the full entity)." return None result.append((start, stop + 1)) else: if not stop: # See rfc quote above. return None # Negative subscript (last N bytes) result.append((content_length - int(stop), content_length)) return result class HeaderElement(object): """An element (with parameters) from an HTTP header's element list.""" def __init__(self, value, params=None): self.value = value if params is None: params = {} self.params = params def __unicode__(self): p = [";%s=%s" % (k, v) for k, v in self.params.iteritems()] return u"%s%s" % (self.value, "".join(p)) def __str__(self): return str(self.__unicode__()) def parse(elementstr): """Transform 'token;key=val' to ('token', {'key': 'val'}).""" # Split the element into a value and parameters. The 'value' may # be of the form, "token=token", but we don't split that here. atoms = [x.strip() for x in elementstr.split(";") if x.strip()] initial_value = atoms.pop(0).strip() params = {} for atom in atoms: atom = [x.strip() for x in atom.split("=", 1) if x.strip()] key = atom.pop(0) if atom: val = atom[0] else: val = "" params[key] = val return initial_value, params parse = staticmethod(parse) def from_str(cls, elementstr): """Construct an instance from a string of the form 'token;key=val'.""" ival, params = cls.parse(elementstr) return cls(ival, params) from_str = classmethod(from_str) q_separator = re.compile(r'; *q *=') class AcceptElement(HeaderElement): """An element (with parameters) from an Accept* header's element list. AcceptElement objects are comparable; the more-preferred object will be "less than" the less-preferred object. They are also therefore sortable; if you sort a list of AcceptElement objects, they will be listed in priority order; the most preferred value will be first. Yes, it should have been the other way around, but it's too late to fix now. """ def from_str(cls, elementstr): qvalue = None # The first "q" parameter (if any) separates the initial # media-range parameter(s) (if any) from the accept-params. atoms = q_separator.split(elementstr, 1) media_range = atoms.pop(0).strip() if atoms: # The qvalue for an Accept header can have extensions. The other # headers cannot, but it's easier to parse them as if they did. qvalue = HeaderElement.from_str(atoms[0].strip()) media_type, params = cls.parse(media_range) if qvalue is not None: params["q"] = qvalue return cls(media_type, params) from_str = classmethod(from_str) def qvalue(self): val = self.params.get("q", "1") if isinstance(val, HeaderElement): val = val.value return float(val) qvalue = property(qvalue, doc="The qvalue, or priority, of this value.") def __cmp__(self, other): diff = cmp(other.qvalue, self.qvalue) if diff == 0: diff = cmp(str(other), str(self)) return diff def header_elements(fieldname, fieldvalue): """Return a HeaderElement list from a comma-separated header str.""" if not fieldvalue: return None headername = fieldname.lower() result = [] for element in fieldvalue.split(","): if headername.startswith("accept") or headername == 'te': hv = AcceptElement.from_str(element) else: hv = HeaderElement.from_str(element) result.append(hv) result.sort() return result def decode_TEXT(value): """Decode RFC-2047 TEXT (e.g. "=?utf-8?q?f=C3=BCr?=" -> u"f\xfcr").""" from email.Header import decode_header atoms = decode_header(value) decodedvalue = "" for atom, charset in atoms: if charset is not None: atom = atom.decode(charset) decodedvalue += atom return decodedvalue def valid_status(status): """Return legal HTTP status Code, Reason-phrase and Message. The status arg must be an int, or a str that begins with an int. If status is an int, or a str and no reason-phrase is supplied, a default reason-phrase will be provided. """ if not status: status = 200 status = str(status) parts = status.split(" ", 1) if len(parts) == 1: # No reason supplied. code, = parts reason = None else: code, reason = parts reason = reason.strip() try: code = int(code) except ValueError: raise ValueError("Illegal response status from server " "(%s is non-numeric)." % repr(code)) if code < 100 or code > 599: raise ValueError("Illegal response status from server " "(%s is out of range)." % repr(code)) if code not in response_codes: # code is unknown but not illegal default_reason, message = "", "" else: default_reason, message = response_codes[code] if reason is None: reason = default_reason return code, reason, message image_map_pattern = re.compile(r"[0-9]+,[0-9]+") def parse_query_string(query_string, keep_blank_values=True): """Build a params dictionary from a query_string. Duplicate key/value pairs in the provided query_string will be returned as {'key': [val1, val2, ...]}. Single key/values will be returned as strings: {'key': 'value'}. """ if image_map_pattern.match(query_string): # Server-side image map. Map the coords to 'x' and 'y' # (like CGI::Request does). pm = query_string.split(",") pm = {'x': int(pm[0]), 'y': int(pm[1])} else: pm = cgi.parse_qs(query_string, keep_blank_values) for key, val in pm.items(): if len(val) == 1: pm[key] = val[0] return pm def params_from_CGI_form(form): params = {} for key in form.keys(): value_list = form[key] if key is None: # multipart/* message parts that have no Content-Disposition # have a .name of None, but Python kwarg keys must be strings. # See http://www.cherrypy.org/ticket/890. key = 'parts' if isinstance(value_list, list): params[key] = [] for item in value_list: if item.filename is not None: value = item # It's a file upload else: value = item.value # It's a regular field params[key].append(value) else: if value_list.filename is not None: value = value_list # It's a file upload else: value = value_list.value # It's a regular field params[key] = value return params class CaseInsensitiveDict(dict): """A case-insensitive dict subclass. Each key is changed on entry to str(key).title(). """ def __getitem__(self, key): return dict.__getitem__(self, str(key).title()) def __setitem__(self, key, value): dict.__setitem__(self, str(key).title(), value) def __delitem__(self, key): dict.__delitem__(self, str(key).title()) def __contains__(self, key): return dict.__contains__(self, str(key).title()) def get(self, key, default=None): return dict.get(self, str(key).title(), default) def has_key(self, key): return dict.has_key(self, str(key).title()) def update(self, E): for k in E.keys(): self[str(k).title()] = E[k] def fromkeys(cls, seq, value=None): newdict = cls() for k in seq: newdict[str(k).title()] = value return newdict fromkeys = classmethod(fromkeys) def setdefault(self, key, x=None): key = str(key).title() try: return self[key] except KeyError: self[key] = x return x def pop(self, key, default): return dict.pop(self, str(key).title(), default) class HeaderMap(CaseInsensitiveDict): """A dict subclass for HTTP request and response headers. Each key is changed on entry to str(key).title(). This allows headers to be case-insensitive and avoid duplicates. Values are header values (decoded according to RFC 2047 if necessary). """ def elements(self, key): """Return a list of HeaderElements for the given header (or None).""" key = str(key).title() h = self.get(key) if h is None: return [] return header_elements(key, h) def output(self, protocol=(1, 1)): """Transform self into a list of (name, value) tuples.""" header_list = [] for key, v in self.iteritems(): if isinstance(v, unicode): # HTTP/1.0 says, "Words of *TEXT may contain octets # from character sets other than US-ASCII." and # "Recipients of header field TEXT containing octets # outside the US-ASCII character set may assume that # they represent ISO-8859-1 characters." try: v = v.encode("iso-8859-1") except UnicodeEncodeError: if protocol >= (1, 1): # Encode RFC-2047 TEXT # (e.g. u"\u8200" -> "=?utf-8?b?6IiA?="). from email.Header import Header v = Header(v, 'utf-8').encode() else: raise else: # This coercion should not take any time at all # if value is already of type "str". v = str(v) header_list.append((key, v)) return header_list class Host(object): """An internet address. name should be the client's host name. If not available (because no DNS lookup is performed), the IP address should be used instead. """ ip = "0.0.0.0" port = 80 name = "unknown.tld" def __init__(self, ip, port, name=None): self.ip = ip self.port = port if name is None: name = ip self.name = name def __repr__(self): return "http.Host(%r, %r, %r)" % (self.ip, self.port, self.name) SABnzbd-0.7.20/cherrypy/lib/httpauth.py0000644000000000000000000003124112433712602020054 0ustar00usergroup00000000000000""" httpauth modules defines functions to implement HTTP Digest Authentication (RFC 2617). This has full compliance with 'Digest' and 'Basic' authentication methods. In 'Digest' it supports both MD5 and MD5-sess algorithms. Usage: First use 'doAuth' to request the client authentication for a certain resource. You should send an httplib.UNAUTHORIZED response to the client so he knows he has to authenticate itself. Then use 'parseAuthorization' to retrieve the 'auth_map' used in 'checkResponse'. To use 'checkResponse' you must have already verified the password associated with the 'username' key in 'auth_map' dict. Then you use the 'checkResponse' function to verify if the password matches the one sent by the client. SUPPORTED_ALGORITHM - list of supported 'Digest' algorithms SUPPORTED_QOP - list of supported 'Digest' 'qop'. """ __version__ = 1, 0, 1 __author__ = "Tiago Cogumbreiro " __credits__ = """ Peter van Kampen for its recipe which implement most of Digest authentication: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/302378 """ __license__ = """ Copyright (c) 2005, Tiago Cogumbreiro All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Sylvain Hellegouarch nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ __all__ = ("digestAuth", "basicAuth", "doAuth", "checkResponse", "parseAuthorization", "SUPPORTED_ALGORITHM", "md5SessionKey", "calculateNonce", "SUPPORTED_QOP") ################################################################################ try: # Python 2.5+ from hashlib import md5 except ImportError: from md5 import new as md5 import time import base64 import urllib2 MD5 = "MD5" MD5_SESS = "MD5-sess" AUTH = "auth" AUTH_INT = "auth-int" SUPPORTED_ALGORITHM = (MD5, MD5_SESS) SUPPORTED_QOP = (AUTH, AUTH_INT) ################################################################################ # doAuth # DIGEST_AUTH_ENCODERS = { MD5: lambda val: md5(val).hexdigest(), MD5_SESS: lambda val: md5(val).hexdigest(), # SHA: lambda val: sha.new (val).hexdigest (), } def calculateNonce (realm, algorithm = MD5): """This is an auxaliary function that calculates 'nonce' value. It is used to handle sessions.""" global SUPPORTED_ALGORITHM, DIGEST_AUTH_ENCODERS assert algorithm in SUPPORTED_ALGORITHM try: encoder = DIGEST_AUTH_ENCODERS[algorithm] except KeyError: raise NotImplementedError ("The chosen algorithm (%s) does not have "\ "an implementation yet" % algorithm) return encoder ("%d:%s" % (time.time(), realm)) def digestAuth (realm, algorithm = MD5, nonce = None, qop = AUTH): """Challenges the client for a Digest authentication.""" global SUPPORTED_ALGORITHM, DIGEST_AUTH_ENCODERS, SUPPORTED_QOP assert algorithm in SUPPORTED_ALGORITHM assert qop in SUPPORTED_QOP if nonce is None: nonce = calculateNonce (realm, algorithm) return 'Digest realm="%s", nonce="%s", algorithm="%s", qop="%s"' % ( realm, nonce, algorithm, qop ) def basicAuth (realm): """Challengenes the client for a Basic authentication.""" assert '"' not in realm, "Realms cannot contain the \" (quote) character." return 'Basic realm="%s"' % realm def doAuth (realm): """'doAuth' function returns the challenge string b giving priority over Digest and fallback to Basic authentication when the browser doesn't support the first one. This should be set in the HTTP header under the key 'WWW-Authenticate'.""" return digestAuth (realm) + " " + basicAuth (realm) ################################################################################ # Parse authorization parameters # def _parseDigestAuthorization (auth_params): # Convert the auth params to a dict items = urllib2.parse_http_list (auth_params) params = urllib2.parse_keqv_list (items) # Now validate the params # Check for required parameters required = ["username", "realm", "nonce", "uri", "response"] for k in required: if not params.has_key(k): return None # If qop is sent then cnonce and nc MUST be present if params.has_key("qop") and not (params.has_key("cnonce") \ and params.has_key("nc")): return None # If qop is not sent, neither cnonce nor nc can be present if (params.has_key("cnonce") or params.has_key("nc")) and \ not params.has_key("qop"): return None return params def _parseBasicAuthorization (auth_params): username, password = base64.decodestring (auth_params).split (":", 1) return {"username": username, "password": password} AUTH_SCHEMES = { "basic": _parseBasicAuthorization, "digest": _parseDigestAuthorization, } def parseAuthorization (credentials): """parseAuthorization will convert the value of the 'Authorization' key in the HTTP header to a map itself. If the parsing fails 'None' is returned. """ global AUTH_SCHEMES auth_scheme, auth_params = credentials.split(" ", 1) auth_scheme = auth_scheme.lower () parser = AUTH_SCHEMES[auth_scheme] params = parser (auth_params) if params is None: return assert "auth_scheme" not in params params["auth_scheme"] = auth_scheme return params ################################################################################ # Check provided response for a valid password # def md5SessionKey (params, password): """ If the "algorithm" directive's value is "MD5-sess", then A1 [the session key] is calculated only once - on the first request by the client following receipt of a WWW-Authenticate challenge from the server. This creates a 'session key' for the authentication of subsequent requests and responses which is different for each "authentication session", thus limiting the amount of material hashed with any one key. Because the server need only use the hash of the user credentials in order to create the A1 value, this construction could be used in conjunction with a third party authentication service so that the web server would not need the actual password value. The specification of such a protocol is beyond the scope of this specification. """ keys = ("username", "realm", "nonce", "cnonce") params_copy = {} for key in keys: params_copy[key] = params[key] params_copy["algorithm"] = MD5_SESS return _A1 (params_copy, password) def _A1(params, password): algorithm = params.get ("algorithm", MD5) H = DIGEST_AUTH_ENCODERS[algorithm] if algorithm == MD5: # If the "algorithm" directive's value is "MD5" or is # unspecified, then A1 is: # A1 = unq(username-value) ":" unq(realm-value) ":" passwd return "%s:%s:%s" % (params["username"], params["realm"], password) elif algorithm == MD5_SESS: # This is A1 if qop is set # A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd ) # ":" unq(nonce-value) ":" unq(cnonce-value) h_a1 = H ("%s:%s:%s" % (params["username"], params["realm"], password)) return "%s:%s:%s" % (h_a1, params["nonce"], params["cnonce"]) def _A2(params, method, kwargs): # If the "qop" directive's value is "auth" or is unspecified, then A2 is: # A2 = Method ":" digest-uri-value qop = params.get ("qop", "auth") if qop == "auth": return method + ":" + params["uri"] elif qop == "auth-int": # If the "qop" value is "auth-int", then A2 is: # A2 = Method ":" digest-uri-value ":" H(entity-body) entity_body = kwargs.get ("entity_body", "") H = kwargs["H"] return "%s:%s:%s" % ( method, params["uri"], H(entity_body) ) else: raise NotImplementedError ("The 'qop' method is unknown: %s" % qop) def _computeDigestResponse(auth_map, password, method = "GET", A1 = None,**kwargs): """ Generates a response respecting the algorithm defined in RFC 2617 """ params = auth_map algorithm = params.get ("algorithm", MD5) H = DIGEST_AUTH_ENCODERS[algorithm] KD = lambda secret, data: H(secret + ":" + data) qop = params.get ("qop", None) H_A2 = H(_A2(params, method, kwargs)) if algorithm == MD5_SESS and A1 is not None: H_A1 = H(A1) else: H_A1 = H(_A1(params, password)) if qop in ("auth", "auth-int"): # If the "qop" value is "auth" or "auth-int": # request-digest = <"> < KD ( H(A1), unq(nonce-value) # ":" nc-value # ":" unq(cnonce-value) # ":" unq(qop-value) # ":" H(A2) # ) <"> request = "%s:%s:%s:%s:%s" % ( params["nonce"], params["nc"], params["cnonce"], params["qop"], H_A2, ) elif qop is None: # If the "qop" directive is not present (this construction is # for compatibility with RFC 2069): # request-digest = # <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> request = "%s:%s" % (params["nonce"], H_A2) return KD(H_A1, request) def _checkDigestResponse(auth_map, password, method = "GET", A1 = None, **kwargs): """This function is used to verify the response given by the client when he tries to authenticate. Optional arguments: entity_body - when 'qop' is set to 'auth-int' you MUST provide the raw data you are going to send to the client (usually the HTML page. request_uri - the uri from the request line compared with the 'uri' directive of the authorization map. They must represent the same resource (unused at this time). """ if auth_map['realm'] != kwargs.get('realm', None): return False response = _computeDigestResponse(auth_map, password, method, A1,**kwargs) return response == auth_map["response"] def _checkBasicResponse (auth_map, password, method='GET', encrypt=None, **kwargs): # Note that the Basic response doesn't provide the realm value so we cannot # test it try: return encrypt(auth_map["password"], auth_map["username"]) == password except TypeError: return encrypt(auth_map["password"]) == password AUTH_RESPONSES = { "basic": _checkBasicResponse, "digest": _checkDigestResponse, } def checkResponse (auth_map, password, method = "GET", encrypt=None, **kwargs): """'checkResponse' compares the auth_map with the password and optionally other arguments that each implementation might need. If the response is of type 'Basic' then the function has the following signature: checkBasicResponse (auth_map, password) -> bool If the response is of type 'Digest' then the function has the following signature: checkDigestResponse (auth_map, password, method = 'GET', A1 = None) -> bool The 'A1' argument is only used in MD5_SESS algorithm based responses. Check md5SessionKey() for more info. """ global AUTH_RESPONSES checker = AUTH_RESPONSES[auth_map["auth_scheme"]] return checker (auth_map, password, method=method, encrypt=encrypt, **kwargs) SABnzbd-0.7.20/cherrypy/lib/profiler.py0000644000000000000000000001363312433712602020042 0ustar00usergroup00000000000000"""Profiler tools for CherryPy. CherryPy users ============== You can profile any of your pages as follows: from cherrypy.lib import profiler class Root: p = profile.Profiler("/path/to/profile/dir") def index(self): self.p.run(self._index) index.exposed = True def _index(self): return "Hello, world!" cherrypy.tree.mount(Root()) You can also turn on profiling for all requests using the make_app function as WSGI middleware. CherryPy developers =================== This module can be used whenever you make changes to CherryPy, to get a quick sanity-check on overall CP performance. Use the "--profile" flag when running the test suite. Then, use the serve() function to browse the results in a web browser. If you run this module from the command line, it will call serve() for you. """ # Make profiler output more readable by adding __init__ modules' parents. def new_func_strip_path(func_name): filename, line, name = func_name if filename.endswith("__init__.py"): return os.path.basename(filename[:-12]) + filename[-12:], line, name return os.path.basename(filename), line, name try: import profile import pstats pstats.func_strip_path = new_func_strip_path except ImportError: profile = None pstats = None import warnings msg = ("Your installation of Python does not have a profile module. " "If you're on Debian, try `sudo apt-get install python-profiler`. " "See http://www.cherrypy.org/wiki/ProfilingOnDebian for details.") warnings.warn(msg) import os, os.path import sys try: import cStringIO as StringIO except ImportError: import StringIO _count = 0 class Profiler(object): def __init__(self, path=None): if not path: path = os.path.join(os.path.dirname(__file__), "profile") self.path = path if not os.path.exists(path): os.makedirs(path) def run(self, func, *args, **params): """Dump profile data into self.path.""" global _count c = _count = _count + 1 path = os.path.join(self.path, "cp_%04d.prof" % c) prof = profile.Profile() result = prof.runcall(func, *args, **params) prof.dump_stats(path) return result def statfiles(self): """statfiles() -> list of available profiles.""" return [f for f in os.listdir(self.path) if f.startswith("cp_") and f.endswith(".prof")] def stats(self, filename, sortby='cumulative'): """stats(index) -> output of print_stats() for the given profile.""" sio = StringIO.StringIO() if sys.version_info >= (2, 5): s = pstats.Stats(os.path.join(self.path, filename), stream=sio) s.strip_dirs() s.sort_stats(sortby) s.print_stats() else: # pstats.Stats before Python 2.5 didn't take a 'stream' arg, # but just printed to stdout. So re-route stdout. s = pstats.Stats(os.path.join(self.path, filename)) s.strip_dirs() s.sort_stats(sortby) oldout = sys.stdout try: sys.stdout = sio s.print_stats() finally: sys.stdout = oldout response = sio.getvalue() sio.close() return response def index(self): return """ CherryPy profile data """ index.exposed = True def menu(self): yield "

Profiling runs

" yield "

Click on one of the runs below to see profiling data.

" runs = self.statfiles() runs.sort() for i in runs: yield "%s
" % (i, i) menu.exposed = True def report(self, filename): import cherrypy cherrypy.response.headers['Content-Type'] = 'text/plain' return self.stats(filename) report.exposed = True class ProfileAggregator(Profiler): def __init__(self, path=None): Profiler.__init__(self, path) global _count self.count = _count = _count + 1 self.profiler = profile.Profile() def run(self, func, *args): path = os.path.join(self.path, "cp_%04d.prof" % self.count) result = self.profiler.runcall(func, *args) self.profiler.dump_stats(path) return result class make_app: def __init__(self, nextapp, path=None, aggregate=False): """Make a WSGI middleware app which wraps 'nextapp' with profiling. nextapp: the WSGI application to wrap, usually an instance of cherrypy.Application. path: where to dump the profiling output. aggregate: if True, profile data for all HTTP requests will go in a single file. If False (the default), each HTTP request will dump its profile data into a separate file. """ self.nextapp = nextapp self.aggregate = aggregate if aggregate: self.profiler = ProfileAggregator(path) else: self.profiler = Profiler(path) def __call__(self, environ, start_response): def gather(): result = [] for line in self.nextapp(environ, start_response): result.append(line) return result return self.profiler.run(gather) def serve(path=None, port=8080): import cherrypy cherrypy.config.update({'server.socket_port': int(port), 'server.thread_pool': 10, 'environment': "production", }) cherrypy.quickstart(Profiler(path)) if __name__ == "__main__": serve(*tuple(sys.argv[1:])) SABnzbd-0.7.20/cherrypy/lib/safemime.py0000644000000000000000000001045312433712602020003 0ustar00usergroup00000000000000import cherrypy class MultipartWrapper(object): """Wraps a file-like object, returning '' when Content-Length is reached. The cgi module's logic for reading multipart MIME messages doesn't allow the parts to know when the Content-Length for the entire message has been reached, and doesn't allow for multipart-MIME messages that omit the trailing CRLF (Flash 8's FileReference.upload(url), for example, does this). The read_lines_to_outerboundary function gets stuck in a loop until the socket times out. This rfile wrapper simply monitors the incoming stream. When a read is attempted past the Content-Length, it returns an empty string rather than timing out (of course, if the last read *overlaps* the C-L, you'll get the last bit of data up to C-L, and then the next read will return an empty string). """ def __init__(self, rfile, clen): self.rfile = rfile self.clen = clen self.bytes_read = 0 def read(self, size = None): if self.clen: # Return '' if we've read all the data. if self.bytes_read >= self.clen: return '' # Reduce 'size' if it's over our limit. new_bytes_read = self.bytes_read + size if new_bytes_read > self.clen: size = self.clen - self.bytes_read data = self.rfile.read(size) self.bytes_read += len(data) return data def readline(self, size = None): if size is not None: if self.clen: # Return '' if we've read all the data. if self.bytes_read >= self.clen: return '' # Reduce 'size' if it's over our limit. new_bytes_read = self.bytes_read + size if new_bytes_read > self.clen: size = self.clen - self.bytes_read data = self.rfile.readline(size) self.bytes_read += len(data) return data # User didn't specify a size ... # We read the line in chunks to make sure it's not a 100MB line ! res = [] size = 256 while True: if self.clen: # Return if we've read all the data. if self.bytes_read >= self.clen: return ''.join(res) # Reduce 'size' if it's over our limit. new_bytes_read = self.bytes_read + size if new_bytes_read > self.clen: size = self.clen - self.bytes_read data = self.rfile.readline(size) self.bytes_read += len(data) res.append(data) # See http://www.cherrypy.org/ticket/421 if len(data) < size or data[-1:] == "\n": return ''.join(res) def readlines(self, sizehint = 0): # Shamelessly stolen from StringIO total = 0 lines = [] line = self.readline() while line: lines.append(line) total += len(line) if 0 < sizehint <= total: break line = self.readline() return lines def close(self): self.rfile.close() def __iter__(self): return self.rfile def next(self): if self.clen: # Return '' if we've read all the data. if self.bytes_read >= self.clen: return '' data = self.rfile.next() self.bytes_read += len(data) return data def safe_multipart(flash_only=False): """Wrap request.rfile in a reader that won't crash on no trailing CRLF.""" h = cherrypy.request.headers if not h.get('Content-Type','').startswith('multipart/'): return if flash_only and not 'Shockwave Flash' in h.get('User-Agent', ''): return clen = h.get('Content-Length', '0') try: clen = int(clen) except ValueError: return cherrypy.request.rfile = MultipartWrapper(cherrypy.request.rfile, clen) def init(): """Create a Tool for safe_multipart and add it to cherrypy.tools.""" cherrypy.tools.safe_multipart = cherrypy.Tool('before_request_body', safe_multipart) SABnzbd-0.7.20/cherrypy/lib/sessions.py0000644000000000000000000006001312433712602020060 0ustar00usergroup00000000000000"""Session implementation for CherryPy. We use cherrypy.request to store some convenient variables as well as data about the session for the current request. Instead of polluting cherrypy.request we use a Session object bound to cherrypy.session to store these variables. """ import datetime import os try: import cPickle as pickle except ImportError: import pickle import random try: # Python 2.5+ from hashlib import sha1 as sha except ImportError: from sha import new as sha import time import threading import types from warnings import warn import cherrypy from cherrypy.lib import http missing = object() class Session(object): """A CherryPy dict-like Session object (one per request).""" __metaclass__ = cherrypy._AttributeDocstrings _id = None id_observers = None id_observers__doc = "A list of callbacks to which to pass new id's." id__doc = "The current session ID." def _get_id(self): return self._id def _set_id(self, value): self._id = value for o in self.id_observers: o(value) id = property(_get_id, _set_id, doc=id__doc) timeout = 60 timeout__doc = "Number of minutes after which to delete session data." locked = False locked__doc = """ If True, this session instance has exclusive read/write access to session data.""" loaded = False loaded__doc = """ If True, data has been retrieved from storage. This should happen automatically on the first attempt to access session data.""" clean_thread = None clean_thread__doc = "Class-level Monitor which calls self.clean_up." clean_freq = 5 clean_freq__doc = "The poll rate for expired session cleanup in minutes." def __init__(self, id=None, **kwargs): self.id_observers = [] self._data = {} for k, v in kwargs.iteritems(): setattr(self, k, v) if id is None: self.regenerate() else: self.id = id if not self._exists(): # Expired or malicious session. Make a new one. # See http://www.cherrypy.org/ticket/709. self.id = None self.regenerate() def regenerate(self): """Replace the current session (with a new id).""" if self.id is not None: self.delete() old_session_was_locked = self.locked if old_session_was_locked: self.release_lock() self.id = None while self.id is None: self.id = self.generate_id() # Assert that the generated id is not already stored. if self._exists(): self.id = None if old_session_was_locked: self.acquire_lock() def clean_up(self): """Clean up expired sessions.""" pass try: os.urandom(20) except (AttributeError, NotImplementedError): # os.urandom not available until Python 2.4. Fall back to random.random. def generate_id(self): """Return a new session id.""" return sha('%s' % random.random()).hexdigest() else: def generate_id(self): """Return a new session id.""" return os.urandom(20).encode('hex') def save(self): """Save session data.""" try: # If session data has never been loaded then it's never been # accessed: no need to save it if self.loaded: t = datetime.timedelta(seconds = self.timeout * 60) expiration_time = datetime.datetime.now() + t self._save(expiration_time) finally: if self.locked: # Always release the lock if the user didn't release it self.release_lock() def load(self): """Copy stored session data into this session instance.""" data = self._load() # data is either None or a tuple (session_data, expiration_time) if data is None or data[1] < datetime.datetime.now(): # Expired session: flush session data self._data = {} else: self._data = data[0] self.loaded = True # Stick the clean_thread in the class, not the instance. # The instances are created and destroyed per-request. cls = self.__class__ if self.clean_freq and not cls.clean_thread: # clean_up is in instancemethod and not a classmethod, # so that tool config can be accessed inside the method. t = cherrypy.process.plugins.Monitor( cherrypy.engine, self.clean_up, self.clean_freq * 60) t.subscribe() cls.clean_thread = t t.start() def delete(self): """Delete stored session data.""" self._delete() def __getitem__(self, key): if not self.loaded: self.load() return self._data[key] def __setitem__(self, key, value): if not self.loaded: self.load() self._data[key] = value def __delitem__(self, key): if not self.loaded: self.load() del self._data[key] def pop(self, key, default=missing): """Remove the specified key and return the corresponding value. If key is not found, default is returned if given, otherwise KeyError is raised. """ if not self.loaded: self.load() if default is missing: return self._data.pop(key) else: return self._data.pop(key, default) def __contains__(self, key): if not self.loaded: self.load() return key in self._data def has_key(self, key): """D.has_key(k) -> True if D has a key k, else False.""" if not self.loaded: self.load() return self._data.has_key(key) def get(self, key, default=None): """D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.""" if not self.loaded: self.load() return self._data.get(key, default) def update(self, d): """D.update(E) -> None. Update D from E: for k in E: D[k] = E[k].""" if not self.loaded: self.load() self._data.update(d) def setdefault(self, key, default=None): """D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D.""" if not self.loaded: self.load() return self._data.setdefault(key, default) def clear(self): """D.clear() -> None. Remove all items from D.""" if not self.loaded: self.load() self._data.clear() def keys(self): """D.keys() -> list of D's keys.""" if not self.loaded: self.load() return self._data.keys() def items(self): """D.items() -> list of D's (key, value) pairs, as 2-tuples.""" if not self.loaded: self.load() return self._data.items() def values(self): """D.values() -> list of D's values.""" if not self.loaded: self.load() return self._data.values() class RamSession(Session): # Class-level objects. Don't rebind these! cache = {} locks = {} def clean_up(self): """Clean up expired sessions.""" now = datetime.datetime.now() for id, (data, expiration_time) in self.cache.items(): if expiration_time < now: try: del self.cache[id] except KeyError: pass try: del self.locks[id] except KeyError: pass def _exists(self): return self.id in self.cache def _load(self): return self.cache.get(self.id) def _save(self, expiration_time): self.cache[self.id] = (self._data, expiration_time) def _delete(self): del self.cache[self.id] def acquire_lock(self): """Acquire an exclusive lock on the currently-loaded session data.""" self.locked = True self.locks.setdefault(self.id, threading.RLock()).acquire() def release_lock(self): """Release the lock on the currently-loaded session data.""" self.locks[self.id].release() self.locked = False def __len__(self): """Return the number of active sessions.""" return len(self.cache) class FileSession(Session): """Implementation of the File backend for sessions storage_path: the folder where session data will be saved. Each session will be saved as pickle.dump(data, expiration_time) in its own file; the filename will be self.SESSION_PREFIX + self.id. """ SESSION_PREFIX = 'session-' LOCK_SUFFIX = '.lock' pickle_protocol = pickle.HIGHEST_PROTOCOL def __init__(self, id=None, **kwargs): # The 'storage_path' arg is required for file-based sessions. kwargs['storage_path'] = os.path.abspath(kwargs['storage_path']) Session.__init__(self, id=id, **kwargs) def setup(cls, **kwargs): """Set up the storage system for file-based sessions. This should only be called once per process; this will be done automatically when using sessions.init (as the built-in Tool does). """ # The 'storage_path' arg is required for file-based sessions. kwargs['storage_path'] = os.path.abspath(kwargs['storage_path']) for k, v in kwargs.iteritems(): setattr(cls, k, v) # Warn if any lock files exist at startup. lockfiles = [fname for fname in os.listdir(cls.storage_path) if (fname.startswith(cls.SESSION_PREFIX) and fname.endswith(cls.LOCK_SUFFIX))] if lockfiles: plural = ('', 's')[len(lockfiles) > 1] warn("%s session lockfile%s found at startup. If you are " "only running one process, then you may need to " "manually delete the lockfiles found at %r." % (len(lockfiles), plural, cls.storage_path)) setup = classmethod(setup) def _get_file_path(self): f = os.path.join(self.storage_path, self.SESSION_PREFIX + self.id) if not os.path.abspath(f).startswith(self.storage_path): raise cherrypy.HTTPError(400, "Invalid session id in cookie.") return f def _exists(self): path = self._get_file_path() return os.path.exists(path) def _load(self, path=None): if path is None: path = self._get_file_path() try: f = open(path, "rb") try: return pickle.load(f) finally: f.close() except (IOError, EOFError): return None def _save(self, expiration_time): f = open(self._get_file_path(), "wb") try: pickle.dump((self._data, expiration_time), f, self.pickle_protocol) finally: f.close() def _delete(self): try: os.unlink(self._get_file_path()) except OSError: pass def acquire_lock(self, path=None): """Acquire an exclusive lock on the currently-loaded session data.""" if path is None: path = self._get_file_path() path += self.LOCK_SUFFIX while True: try: lockfd = os.open(path, os.O_CREAT|os.O_WRONLY|os.O_EXCL) except OSError: time.sleep(0.1) else: os.close(lockfd) break self.locked = True def release_lock(self, path=None): """Release the lock on the currently-loaded session data.""" if path is None: path = self._get_file_path() os.unlink(path + self.LOCK_SUFFIX) self.locked = False def clean_up(self): """Clean up expired sessions.""" now = datetime.datetime.now() # Iterate over all session files in self.storage_path for fname in os.listdir(self.storage_path): if (fname.startswith(self.SESSION_PREFIX) and not fname.endswith(self.LOCK_SUFFIX)): # We have a session file: lock and load it and check # if it's expired. If it fails, nevermind. path = os.path.join(self.storage_path, fname) self.acquire_lock(path) try: contents = self._load(path) # _load returns None on IOError if contents is not None: data, expiration_time = contents if expiration_time < now: # Session expired: deleting it os.unlink(path) finally: self.release_lock(path) def __len__(self): """Return the number of active sessions.""" return len([fname for fname in os.listdir(self.storage_path) if (fname.startswith(self.SESSION_PREFIX) and not fname.endswith(self.LOCK_SUFFIX))]) class PostgresqlSession(Session): """ Implementation of the PostgreSQL backend for sessions. It assumes a table like this: create table session ( id varchar(40), data text, expiration_time timestamp ) You must provide your own get_db function. """ pickle_protocol = pickle.HIGHEST_PROTOCOL def __init__(self, id=None, **kwargs): Session.__init__(self, id, **kwargs) self.cursor = self.db.cursor() def setup(cls, **kwargs): """Set up the storage system for Postgres-based sessions. This should only be called once per process; this will be done automatically when using sessions.init (as the built-in Tool does). """ for k, v in kwargs.iteritems(): setattr(cls, k, v) self.db = self.get_db() setup = classmethod(setup) def __del__(self): if self.cursor: self.cursor.close() self.db.commit() def _exists(self): # Select session data from table self.cursor.execute('select data, expiration_time from session ' 'where id=%s', (self.id,)) rows = self.cursor.fetchall() return bool(rows) def _load(self): # Select session data from table self.cursor.execute('select data, expiration_time from session ' 'where id=%s', (self.id,)) rows = self.cursor.fetchall() if not rows: return None pickled_data, expiration_time = rows[0] data = pickle.loads(pickled_data) return data, expiration_time def _save(self, expiration_time): pickled_data = pickle.dumps(self._data, self.pickle_protocol) self.cursor.execute('update session set data = %s, ' 'expiration_time = %s where id = %s', (pickled_data, expiration_time, self.id)) def _delete(self): self.cursor.execute('delete from session where id=%s', (self.id,)) def acquire_lock(self): """Acquire an exclusive lock on the currently-loaded session data.""" # We use the "for update" clause to lock the row self.locked = True self.cursor.execute('select id from session where id=%s for update', (self.id,)) def release_lock(self): """Release the lock on the currently-loaded session data.""" # We just close the cursor and that will remove the lock # introduced by the "for update" clause self.cursor.close() self.locked = False def clean_up(self): """Clean up expired sessions.""" self.cursor.execute('delete from session where expiration_time < %s', (datetime.datetime.now(),)) class MemcachedSession(Session): # The most popular memcached client for Python isn't thread-safe. # Wrap all .get and .set operations in a single lock. mc_lock = threading.RLock() # This is a seperate set of locks per session id. locks = {} servers = ['127.0.0.1:11211'] def setup(cls, **kwargs): """Set up the storage system for memcached-based sessions. This should only be called once per process; this will be done automatically when using sessions.init (as the built-in Tool does). """ for k, v in kwargs.iteritems(): setattr(cls, k, v) import memcache cls.cache = memcache.Client(cls.servers) setup = classmethod(setup) def _exists(self): self.mc_lock.acquire() try: return bool(self.cache.get(self.id)) finally: self.mc_lock.release() def _load(self): self.mc_lock.acquire() try: return self.cache.get(self.id) finally: self.mc_lock.release() def _save(self, expiration_time): # Send the expiration time as "Unix time" (seconds since 1/1/1970) td = int(time.mktime(expiration_time.timetuple())) self.mc_lock.acquire() try: if not self.cache.set(self.id, (self._data, expiration_time), td): raise AssertionError("Session data for id %r not set." % self.id) finally: self.mc_lock.release() def _delete(self): self.cache.delete(self.id) def acquire_lock(self): """Acquire an exclusive lock on the currently-loaded session data.""" self.locked = True self.locks.setdefault(self.id, threading.RLock()).acquire() def release_lock(self): """Release the lock on the currently-loaded session data.""" self.locks[self.id].release() self.locked = False def __len__(self): """Return the number of active sessions.""" raise NotImplementedError # Hook functions (for CherryPy tools) def save(): """Save any changed session data.""" if not hasattr(cherrypy.serving, "session"): return # Guard against running twice if hasattr(cherrypy.request, "_sessionsaved"): return cherrypy.request._sessionsaved = True if cherrypy.response.stream: # If the body is being streamed, we have to save the data # *after* the response has been written out cherrypy.request.hooks.attach('on_end_request', cherrypy.session.save) else: # If the body is not being streamed, we save the data now # (so we can release the lock). if isinstance(cherrypy.response.body, types.GeneratorType): cherrypy.response.collapse_body() cherrypy.session.save() save.failsafe = True def close(): """Close the session object for this request.""" sess = getattr(cherrypy.serving, "session", None) if getattr(sess, "locked", False): # If the session is still locked we release the lock sess.release_lock() close.failsafe = True close.priority = 90 def init(storage_type='ram', path=None, path_header=None, name='session_id', timeout=60, domain=None, secure=False, clean_freq=5, persistent=True, **kwargs): """Initialize session object (using cookies). storage_type: one of 'ram', 'file', 'postgresql'. This will be used to look up the corresponding class in cherrypy.lib.sessions globals. For example, 'file' will use the FileSession class. path: the 'path' value to stick in the response cookie metadata. path_header: if 'path' is None (the default), then the response cookie 'path' will be pulled from request.headers[path_header]. name: the name of the cookie. timeout: the expiration timeout (in minutes) for the stored session data. If 'persistent' is True (the default), this is also the timeout for the cookie. domain: the cookie domain. secure: if False (the default) the cookie 'secure' value will not be set. If True, the cookie 'secure' value will be set (to 1). clean_freq (minutes): the poll rate for expired session cleanup. persistent: if True (the default), the 'timeout' argument will be used to expire the cookie. If False, the cookie will not have an expiry, and the cookie will be a "session cookie" which expires when the browser is closed. Any additional kwargs will be bound to the new Session instance, and may be specific to the storage type. See the subclass of Session you're using for more information. """ request = cherrypy.request # Guard against running twice if hasattr(request, "_session_init_flag"): return request._session_init_flag = True # Check if request came with a session ID id = None if name in request.cookie: id = request.cookie[name].value # Find the storage class and call setup (first time only). storage_class = storage_type.title() + 'Session' storage_class = globals()[storage_class] if not hasattr(cherrypy, "session"): if hasattr(storage_class, "setup"): storage_class.setup(**kwargs) # Create and attach a new Session instance to cherrypy.serving. # It will possess a reference to (and lock, and lazily load) # the requested session data. kwargs['timeout'] = timeout kwargs['clean_freq'] = clean_freq cherrypy.serving.session = sess = storage_class(id, **kwargs) def update_cookie(id): """Update the cookie every time the session id changes.""" cherrypy.response.cookie[name] = id sess.id_observers.append(update_cookie) # Create cherrypy.session which will proxy to cherrypy.serving.session if not hasattr(cherrypy, "session"): cherrypy.session = cherrypy._ThreadLocalProxy('session') if persistent: cookie_timeout = timeout else: # See http://support.microsoft.com/kb/223799/EN-US/ # and http://support.mozilla.com/en-US/kb/Cookies cookie_timeout = None set_response_cookie(path=path, path_header=path_header, name=name, timeout=cookie_timeout, domain=domain, secure=secure) def set_response_cookie(path=None, path_header=None, name='session_id', timeout=60, domain=None, secure=False): """Set a response cookie for the client. path: the 'path' value to stick in the response cookie metadata. path_header: if 'path' is None (the default), then the response cookie 'path' will be pulled from request.headers[path_header]. name: the name of the cookie. timeout: the expiration timeout for the cookie. If 0 or other boolean False, no 'expires' param will be set, and the cookie will be a "session cookie" which expires when the browser is closed. domain: the cookie domain. secure: if False (the default) the cookie 'secure' value will not be set. If True, the cookie 'secure' value will be set (to 1). """ # Set response cookie cookie = cherrypy.response.cookie cookie[name] = cherrypy.serving.session.id cookie[name]['path'] = (path or cherrypy.request.headers.get(path_header) or '/') # We'd like to use the "max-age" param as indicated in # http://www.faqs.org/rfcs/rfc2109.html but IE doesn't # save it to disk and the session is lost if people close # the browser. So we have to use the old "expires" ... sigh ... ## cookie[name]['max-age'] = timeout * 60 if timeout: cookie[name]['expires'] = http.HTTPDate(time.time() + (timeout * 60)) if domain is not None: cookie[name]['domain'] = domain if secure: cookie[name]['secure'] = 1 def expire(): """Expire the current session cookie.""" name = cherrypy.request.config.get('tools.sessions.name', 'session_id') one_year = 60 * 60 * 24 * 365 exp = time.gmtime(time.time() - one_year) t = time.strftime("%a, %d-%b-%Y %H:%M:%S GMT", exp) cherrypy.response.cookie[name]['expires'] = t SABnzbd-0.7.20/cherrypy/lib/static.py0000644000000000000000000002207012433712602017502 0ustar00usergroup00000000000000import mimetypes mimetypes.init() mimetypes.types_map['.dwg']='image/x-dwg' mimetypes.types_map['.ico']='image/x-icon' import os import re import stat import time import urllib import cherrypy from cherrypy.lib import cptools, http, file_generator_limited def serve_file(path, content_type=None, disposition=None, name=None): """Set status, headers, and body in order to serve the given file. The Content-Type header will be set to the content_type arg, if provided. If not provided, the Content-Type will be guessed by the file extension of the 'path' argument. If disposition is not None, the Content-Disposition header will be set to "; filename=". If name is None, it will be set to the basename of path. If disposition is None, no Content-Disposition header will be written. """ response = cherrypy.response # If path is relative, users should fix it by making path absolute. # That is, CherryPy should not guess where the application root is. # It certainly should *not* use cwd (since CP may be invoked from a # variety of paths). If using tools.staticdir, you can make your relative # paths become absolute by supplying a value for "tools.staticdir.root". if not os.path.isabs(path): raise ValueError("'%s' is not an absolute path." % path) try: st = os.stat(path) except OSError: raise cherrypy.NotFound() # Check if path is a directory. if stat.S_ISDIR(st.st_mode): # Let the caller deal with it as they like. raise cherrypy.NotFound() # Set the Last-Modified response header, so that # modified-since validation code can work. response.headers['Last-Modified'] = http.HTTPDate(st.st_mtime) cptools.validate_since() if content_type is None: # Set content-type based on filename extension ext = "" i = path.rfind('.') if i != -1: ext = path[i:].lower() content_type = mimetypes.types_map.get(ext, "text/plain") response.headers['Content-Type'] = content_type if disposition is not None: if name is None: name = os.path.basename(path) cd = '%s; filename="%s"' % (disposition, name) response.headers["Content-Disposition"] = cd # Set Content-Length and use an iterable (file object) # this way CP won't load the whole file in memory c_len = st.st_size bodyfile = open(path, 'rb') # HTTP/1.0 didn't have Range/Accept-Ranges headers, or the 206 code if cherrypy.request.protocol >= (1, 1): response.headers["Accept-Ranges"] = "bytes" r = http.get_ranges(cherrypy.request.headers.get('Range'), c_len) if r == []: response.headers['Content-Range'] = "bytes */%s" % c_len message = "Invalid Range (first-byte-pos greater than Content-Length)" raise cherrypy.HTTPError(416, message) if r: if len(r) == 1: # Return a single-part response. start, stop = r[0] if stop > c_len: stop = c_len r_len = stop - start response.status = "206 Partial Content" response.headers['Content-Range'] = ("bytes %s-%s/%s" % (start, stop - 1, c_len)) response.headers['Content-Length'] = r_len bodyfile.seek(start) response.body = file_generator_limited(bodyfile, r_len) else: # Return a multipart/byteranges response. response.status = "206 Partial Content" import mimetools boundary = mimetools.choose_boundary() ct = "multipart/byteranges; boundary=%s" % boundary response.headers['Content-Type'] = ct if response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del response.headers["Content-Length"] def file_ranges(): # Apache compatibility: yield "\r\n" for start, stop in r: yield "--" + boundary yield "\r\nContent-type: %s" % content_type yield ("\r\nContent-range: bytes %s-%s/%s\r\n\r\n" % (start, stop - 1, c_len)) bodyfile.seek(start) for chunk in file_generator_limited(bodyfile, stop-start): yield chunk yield "\r\n" # Final boundary yield "--" + boundary + "--" # Apache compatibility: yield "\r\n" response.body = file_ranges() return response.body response.headers['Content-Length'] = c_len response.body = bodyfile return response.body def serve_download(path, name=None): """Serve 'path' as an application/x-download attachment.""" # This is such a common idiom I felt it deserved its own wrapper. return serve_file(path, "application/x-download", "attachment", name) def _attempt(filename, content_types): try: # you can set the content types for a # complete directory per extension content_type = None if content_types: r, ext = os.path.splitext(filename) content_type = content_types.get(ext[1:], None) serve_file(filename, content_type=content_type) return True except cherrypy.NotFound: # If we didn't find the static file, continue handling the # request. We might find a dynamic handler instead. return False def staticdir(section, dir, root="", match="", content_types=None, index=""): """Serve a static resource from the given (root +) dir. If 'match' is given, request.path_info will be searched for the given regular expression before attempting to serve static content. If content_types is given, it should be a Python dictionary of {file-extension: content-type} pairs, where 'file-extension' is a string (e.g. "gif") and 'content-type' is the value to write out in the Content-Type response header (e.g. "image/gif"). If 'index' is provided, it should be the (relative) name of a file to serve for directory requests. For example, if the dir argument is '/home/me', the Request-URI is 'myapp', and the index arg is 'index.html', the file '/home/me/myapp/index.html' will be sought. """ if match and not re.search(match, cherrypy.request.path_info): return False # Allow the use of '~' to refer to a user's home directory. dir = os.path.expanduser(dir) # If dir is relative, make absolute using "root". if not os.path.isabs(dir): if not root: msg = "Static dir requires an absolute dir (or root)." raise ValueError(msg) dir = os.path.join(root, dir) # Determine where we are in the object tree relative to 'section' # (where the static tool was defined). if section == 'global': section = "/" section = section.rstrip(r"\/") branch = cherrypy.request.path_info[len(section) + 1:] branch = urllib.unquote(branch.lstrip(r"\/")) # If branch is "", filename will end in a slash filename = os.path.join(dir, branch) # There's a chance that the branch pulled from the URL might # have ".." or similar uplevel attacks in it. Check that the final # filename is a child of dir. if not os.path.normpath(filename).startswith(os.path.normpath(dir)): raise cherrypy.HTTPError(403) # Forbidden handled = _attempt(filename, content_types) if not handled: # Check for an index file if a folder was requested. if index: handled = _attempt(os.path.join(filename, index), content_types) if handled: cherrypy.request.is_index = filename[-1] in (r"\/") return handled def staticfile(filename, root=None, match="", content_types=None): """Serve a static resource from the given (root +) filename. If 'match' is given, request.path_info will be searched for the given regular expression before attempting to serve static content. If content_types is given, it should be a Python dictionary of {file-extension: content-type} pairs, where 'file-extension' is a string (e.g. "gif") and 'content-type' is the value to write out in the Content-Type response header (e.g. "image/gif"). """ if match and not re.search(match, cherrypy.request.path_info): return False # If filename is relative, make absolute using "root". if not os.path.isabs(filename): if not root: msg = "Static tool requires an absolute filename (got '%s')." % filename raise ValueError(msg) filename = os.path.join(root, filename) return _attempt(filename, content_types) SABnzbd-0.7.20/cherrypy/lib/tidy.py0000644000000000000000000001523312433712602017167 0ustar00usergroup00000000000000"""Functions to run cherrypy.response through Tidy or NSGML.""" import cgi import os import StringIO import traceback import cherrypy def tidy(temp_dir, tidy_path, strict_xml=False, errors_to_ignore=None, indent=False, wrap=False, warnings=True): """Run cherrypy.response through Tidy. If either 'indent' or 'wrap' are specified, then response.body will be set to the output of tidy. Otherwise, only errors (including warnings, if warnings is True) will change the body. Note that we use the standalone Tidy tool rather than the python mxTidy module. This is because this module does not seem to be stable and it crashes on some HTML pages (which means that the server would also crash) """ response = cherrypy.response # the tidy tool, by its very nature it's not generator friendly, # so we just collapse the body and work with it. orig_body = response.collapse_body() fct = response.headers.get('Content-Type', '') ct = fct.split(';')[0] encoding = '' i = fct.find('charset=') if i != -1: encoding = fct[i + 8:] if ct == 'text/html': page_file = os.path.join(temp_dir, 'page.html') open(page_file, 'wb').write(orig_body) out_file = os.path.join(temp_dir, 'tidy.out') err_file = os.path.join(temp_dir, 'tidy.err') tidy_enc = encoding.replace('-', '') if tidy_enc: tidy_enc = '-' + tidy_enc strict_xml = ("", " -xml")[bool(strict_xml)] if indent: indent = ' -indent' else: indent = '' if wrap is False: wrap = '' else: try: wrap = ' -wrap %d' % int(tidyWrap) except: wrap = '' result = os.system('"%s" %s%s%s%s -f %s -o %s %s' % (tidy_path, tidy_enc, strict_xml, indent, wrap, err_file, out_file, page_file)) use_output = bool(indent or wrap) and not result if use_output: output = open(out_file, 'rb').read() new_errs = [] for err in open(err_file, 'rb').read().splitlines(): if (err.find('Error') != -1 or (warnings and err.find('Warning') != -1)): ignore = 0 for err_ign in errors_to_ignore or []: if err.find(err_ign) != -1: ignore = 1 break if not ignore: new_errs.append(err) if new_errs: response.body = wrong_content('
'.join(new_errs), orig_body) if response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del response.headers["Content-Length"] return elif strict_xml: # The HTML is OK, but is it valid XML? # Use elementtree to parse XML from elementtree.ElementTree import parse tag_list = ['nbsp', 'quot'] for tag in tag_list: orig_body = orig_body.replace('&' + tag + ';', tag.upper()) if encoding: enctag = '' % encoding orig_body = enctag + orig_body f = StringIO.StringIO(orig_body) try: tree = parse(f) except: # Wrong XML body_file = StringIO.StringIO() traceback.print_exc(file = body_file) body_file = '
'.join(body_file.getvalue()) response.body = wrong_content(body_file, orig_body, "XML") if response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del response.headers["Content-Length"] return if use_output: response.body = [output] if response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del response.headers["Content-Length"] def html_space(text): """Escape text, replacing space with nbsp and tab with 4 nbsp's.""" return cgi.escape(text).replace('\t', ' ').replace(' ', ' ') def html_break(text): """Escape text, replacing newline with HTML br element.""" return cgi.escape(text).replace('\n', '
') def wrong_content(header, body, content_type="HTML"): output = ["Wrong %s:
%s
" % (content_type, html_break(header))] for i, line in enumerate(body.splitlines()): output.append("%03d - %s" % (i + 1, html_space(line))) return "
".join(output) def nsgmls(temp_dir, nsgmls_path, catalog_path, errors_to_ignore=None): response = cherrypy.response # the tidy tool, by its very nature it's not generator friendly, # so we just collect the body and work with it. orig_body = response.collapse_body() fct = response.headers.get('Content-Type', '') ct = fct.split(';')[0] encoding = '' i = fct.find('charset=') if i != -1: encoding = fct[i + 8:] if ct == 'text/html': # Remove bits of Javascript (nsgmls doesn't seem to handle # them correctly (for instance, if ', i) if j == -1: break orig_body = orig_body[:i] + orig_body[j+9:] page_file = os.path.join(temp_dir, 'page.html') open(page_file, 'wb').write(orig_body) err_file = os.path.join(temp_dir, 'nsgmls.err') command = ('%s -c%s -f%s -s -E10 %s' % (nsgmls_path, catalog_path, err_file, page_file)) command = command.replace('\\', '/') os.system(command) errs = open(err_file, 'rb').read() new_errs = [] for err in errs.splitlines(): ignore = False for err_ign in errors_to_ignore or []: if err.find(err_ign) != -1: ignore = True break if not ignore: new_errs.append(err) if new_errs: response.body = wrong_content('
'.join(new_errs), orig_body) if response.headers.has_key("Content-Length"): # Delete Content-Length header so finalize() recalcs it. del response.headers["Content-Length"] SABnzbd-0.7.20/cherrypy/lib/wsgiapp.py0000644000000000000000000000474512433712602017676 0ustar00usergroup00000000000000"""A CherryPy tool for hosting a foreign WSGI application.""" import sys import warnings import cherrypy # is this sufficient for start_response? def start_response(status, response_headers, exc_info=None): cherrypy.response.status = status headers_dict = dict(response_headers) cherrypy.response.headers.update(headers_dict) def make_environ(): """grabbed some of below from wsgiserver.py for hosting WSGI apps in non-WSGI environments (yikes!) """ request = cherrypy.request # create and populate the wsgi environ environ = dict() environ["wsgi.version"] = (1,0) environ["wsgi.url_scheme"] = request.scheme environ["wsgi.input"] = request.rfile environ["wsgi.errors"] = sys.stderr environ["wsgi.multithread"] = True environ["wsgi.multiprocess"] = False environ["wsgi.run_once"] = False environ["REQUEST_METHOD"] = request.method environ["SCRIPT_NAME"] = request.script_name environ["PATH_INFO"] = request.path_info environ["QUERY_STRING"] = request.query_string environ["SERVER_PROTOCOL"] = request.protocol environ["SERVER_NAME"] = request.local.name environ["SERVER_PORT"] = request.local.port environ["REMOTE_HOST"] = request.remote.name environ["REMOTE_ADDR"] = request.remote.ip environ["REMOTE_PORT"] = request.remote.port # then all the http headers headers = request.headers environ["CONTENT_TYPE"] = headers.get("Content-type", "") environ["CONTENT_LENGTH"] = headers.get("Content-length", "") for (k, v) in headers.iteritems(): envname = "HTTP_" + k.upper().replace("-","_") environ[envname] = v return environ def run(app, env=None): """Run the given WSGI app and set response.body to its output.""" warnings.warn("This module is deprecated and will be removed in " "Cherrypy 3.2. See http://www.cherrypy.org/ticket/700 " "for more information.") try: environ = cherrypy.request.wsgi_environ.copy() environ['SCRIPT_NAME'] = cherrypy.request.script_name environ['PATH_INFO'] = cherrypy.request.path_info except AttributeError: environ = make_environ() if env: environ.update(env) # run the wsgi app and have it set response.body response = app(environ, start_response) try: cherrypy.response.body = [x for x in response] finally: if hasattr(response, "close"): response.close() return True SABnzbd-0.7.20/cherrypy/lib/xmlrpc.py0000644000000000000000000000261512433712602017523 0ustar00usergroup00000000000000import sys import cherrypy def process_body(): """Return (params, method) from request body.""" try: import xmlrpclib return xmlrpclib.loads(cherrypy.request.body.read()) except Exception: return ('ERROR PARAMS', ), 'ERRORMETHOD' def patched_path(path): """Return 'path', doctored for RPC.""" if not path.endswith('/'): path += '/' if path.startswith('/RPC2/'): # strip the first /rpc2 path = path[5:] return path def _set_response(body): # The XML-RPC spec (http://www.xmlrpc.com/spec) says: # "Unless there's a lower-level error, always return 200 OK." # Since Python's xmlrpclib interprets a non-200 response # as a "Protocol Error", we'll just return 200 every time. response = cherrypy.response response.status = '200 OK' response.body = body response.headers['Content-Type'] = 'text/xml' response.headers['Content-Length'] = len(body) def respond(body, encoding='utf-8', allow_none=0): import xmlrpclib if not isinstance(body, xmlrpclib.Fault): body = (body,) _set_response(xmlrpclib.dumps(body, methodresponse=1, encoding=encoding, allow_none=allow_none)) def on_error(*args, **kwargs): body = str(sys.exc_info()[1]) import xmlrpclib _set_response(xmlrpclib.dumps(xmlrpclib.Fault(1, body))) SABnzbd-0.7.20/cherrypy/lib/__init__.py0000644000000000000000000001106712433712602017756 0ustar00usergroup00000000000000"""CherryPy Library""" import sys as _sys def modules(modulePath): """Load a module and retrieve a reference to that module.""" try: mod = _sys.modules[modulePath] if mod is None: raise KeyError() except KeyError: # The last [''] is important. mod = __import__(modulePath, globals(), locals(), ['']) return mod def attributes(full_attribute_name): """Load a module and retrieve an attribute of that module.""" # Parse out the path, module, and attribute last_dot = full_attribute_name.rfind(u".") attr_name = full_attribute_name[last_dot + 1:] mod_path = full_attribute_name[:last_dot] mod = modules(mod_path) # Let an AttributeError propagate outward. try: attr = getattr(mod, attr_name) except AttributeError: raise AttributeError("'%s' object has no attribute '%s'" % (mod_path, attr_name)) # Return a reference to the attribute. return attr # public domain "unrepr" implementation, found on the web and then improved. class _Builder: def build(self, o): m = getattr(self, 'build_' + o.__class__.__name__, None) if m is None: raise TypeError("unrepr does not recognize %s" % repr(o.__class__.__name__)) return m(o) def build_Subscript(self, o): expr, flags, subs = o.getChildren() expr = self.build(expr) subs = self.build(subs) return expr[subs] def build_CallFunc(self, o): children = map(self.build, o.getChildren()) callee = children.pop(0) kwargs = children.pop() or {} starargs = children.pop() or () args = tuple(children) + tuple(starargs) return callee(*args, **kwargs) def build_List(self, o): return map(self.build, o.getChildren()) def build_Const(self, o): return o.value def build_Dict(self, o): d = {} i = iter(map(self.build, o.getChildren())) for el in i: d[el] = i.next() return d def build_Tuple(self, o): return tuple(self.build_List(o)) def build_Name(self, o): if o.name == 'None': return None if o.name == 'True': return True if o.name == 'False': return False # See if the Name is a package or module. If it is, import it. try: return modules(o.name) except ImportError: pass # See if the Name is in __builtin__. try: import __builtin__ return getattr(__builtin__, o.name) except AttributeError: pass raise TypeError("unrepr could not resolve the name %s" % repr(o.name)) def build_Add(self, o): left, right = map(self.build, o.getChildren()) return left + right def build_Getattr(self, o): parent = self.build(o.expr) return getattr(parent, o.attrname) def build_NoneType(self, o): return None def build_UnarySub(self, o): return -self.build(o.getChildren()[0]) def build_UnaryAdd(self, o): return self.build(o.getChildren()[0]) def unrepr(s): """Return a Python object compiled from a string.""" if not s: return s try: import compiler except ImportError: # Fallback to eval when compiler package is not available, # e.g. IronPython 1.0. return eval(s) p = compiler.parse("__tempvalue__ = " + s) obj = p.getChildren()[1].getChildren()[0].getChildren()[1] return _Builder().build(obj) class file_generator(object): """Yield the given input (a file object) in chunks (default 64k). (Core)""" def __init__(self, input, chunkSize=65536): self.input = input self.chunkSize = chunkSize def __iter__(self): return self def next(self): chunk = self.input.read(self.chunkSize) if chunk: return chunk else: self.input.close() raise StopIteration() def file_generator_limited(fileobj, count, chunk_size=65536): """Yield the given file object in chunks, stopping after `count` bytes has been emitted. Default chunk size is 64kB. (Core) """ remaining = count while remaining > 0: chunk = fileobj.read(min(chunk_size, remaining)) chunklen = len(chunk) if chunklen == 0: return remaining -= chunklen yield chunk SABnzbd-0.7.20/cherrypy/process/plugins.py0000644000000000000000000004470112433712602020611 0ustar00usergroup00000000000000"""Site services for use with a Web Site Process Bus.""" import os import re try: set except NameError: from sets import Set as set import signal as _signal import sys import time import threading class SimplePlugin(object): """Plugin base class which auto-subscribes methods for known channels.""" def __init__(self, bus): self.bus = bus def subscribe(self): """Register this object as a (multi-channel) listener on the bus.""" for channel in self.bus.listeners: # Subscribe self.start, self.exit, etc. if present. method = getattr(self, channel, None) if method is not None: self.bus.subscribe(channel, method) def unsubscribe(self): """Unregister this object as a listener on the bus.""" for channel in self.bus.listeners: # Unsubscribe self.start, self.exit, etc. if present. method = getattr(self, channel, None) if method is not None: self.bus.unsubscribe(channel, method) class SignalHandler(object): """Register bus channels (and listeners) for system signals. By default, instantiating this object subscribes the following signals and listeners: TERM: bus.exit HUP : bus.restart USR1: bus.graceful """ # Map from signal numbers to names signals = {} for k, v in vars(_signal).items(): if k.startswith('SIG') and not k.startswith('SIG_'): signals[v] = k del k, v def __init__(self, bus): self.bus = bus # Set default handlers self.handlers = {'SIGTERM': self.bus.exit, 'SIGHUP': self.handle_SIGHUP, 'SIGUSR1': self.bus.graceful, } self._previous_handlers = {} def subscribe(self): for sig, func in self.handlers.iteritems(): try: self.set_handler(sig, func) except ValueError: pass def unsubscribe(self): for signum, handler in self._previous_handlers.iteritems(): signame = self.signals[signum] if handler is None: self.bus.log("Restoring %s handler to SIG_DFL." % signame) handler = _signal.SIG_DFL else: self.bus.log("Restoring %s handler %r." % (signame, handler)) try: our_handler = _signal.signal(signum, handler) if our_handler is None: self.bus.log("Restored old %s handler %r, but our " "handler was not registered." % (signame, handler), level=30) except ValueError: self.bus.log("Unable to restore %s handler %r." % (signame, handler), level=40, traceback=True) def set_handler(self, signal, listener=None): """Subscribe a handler for the given signal (number or name). If the optional 'listener' argument is provided, it will be subscribed as a listener for the given signal's channel. If the given signal name or number is not available on the current platform, ValueError is raised. """ if isinstance(signal, basestring): signum = getattr(_signal, signal, None) if signum is None: raise ValueError("No such signal: %r" % signal) signame = signal else: try: signame = self.signals[signal] except KeyError: raise ValueError("No such signal: %r" % signal) signum = signal prev = _signal.signal(signum, self._handle_signal) self._previous_handlers[signum] = prev if listener is not None: self.bus.log("Listening for %s." % signame) self.bus.subscribe(signame, listener) def _handle_signal(self, signum=None, frame=None): """Python signal handler (self.set_handler subscribes it for you).""" signame = self.signals[signum] self.bus.log("Caught signal %s." % signame) self.bus.publish(signame) def handle_SIGHUP(self): if os.isatty(sys.stdin.fileno()): # not daemonized (may be foreground or background) self.bus.log("SIGHUP caught but not daemonized. Exiting.") self.bus.exit() else: self.bus.log("SIGHUP caught while daemonized. Restarting.") self.bus.restart() try: import pwd, grp except ImportError: pwd, grp = None, None class DropPrivileges(SimplePlugin): """Drop privileges. uid/gid arguments not available on Windows. Special thanks to Gavin Baker: http://antonym.org/node/100. """ def __init__(self, bus, umask=None, uid=None, gid=None): SimplePlugin.__init__(self, bus) self.finalized = False self.uid = uid self.gid = gid self.umask = umask def _get_uid(self): return self._uid def _set_uid(self, val): if val is not None: if pwd is None: self.bus.log("pwd module not available; ignoring uid.", level=30) val = None elif isinstance(val, basestring): val = pwd.getpwnam(val)[2] self._uid = val uid = property(_get_uid, _set_uid, doc="The uid under which to run.") def _get_gid(self): return self._gid def _set_gid(self, val): if val is not None: if grp is None: self.bus.log("grp module not available; ignoring gid.", level=30) val = None elif isinstance(val, basestring): val = grp.getgrnam(val)[2] self._gid = val gid = property(_get_gid, _set_gid, doc="The gid under which to run.") def _get_umask(self): return self._umask def _set_umask(self, val): if val is not None: try: os.umask except AttributeError: self.bus.log("umask function not available; ignoring umask.", level=30) val = None self._umask = val umask = property(_get_umask, _set_umask, doc="The umask under which to run.") def start(self): # uid/gid def current_ids(): """Return the current (uid, gid) if available.""" name, group = None, None if pwd: name = pwd.getpwuid(os.getuid())[0] if grp: group = grp.getgrgid(os.getgid())[0] return name, group if self.finalized: if not (self.uid is None and self.gid is None): self.bus.log('Already running as uid: %r gid: %r' % current_ids()) else: if self.uid is None and self.gid is None: if pwd or grp: self.bus.log('uid/gid not set', level=30) else: self.bus.log('Started as uid: %r gid: %r' % current_ids()) if self.gid is not None: os.setgid(self.gid) if self.uid is not None: os.setuid(self.uid) self.bus.log('Running as uid: %r gid: %r' % current_ids()) # umask if self.finalized: if self.umask is not None: self.bus.log('umask already set to: %03o' % self.umask) else: if self.umask is None: self.bus.log('umask not set', level=30) else: old_umask = os.umask(self.umask) self.bus.log('umask old: %03o, new: %03o' % (old_umask, self.umask)) self.finalized = True # This is slightly higher than the priority for server.start # in order to facilitate the most common use: starting on a low # port (which requires root) and then dropping to another user. start.priority = 77 class Daemonizer(SimplePlugin): """Daemonize the running script. Use this with a Web Site Process Bus via: Daemonizer(bus).subscribe() When this component finishes, the process is completely decoupled from the parent environment. Please note that when this component is used, the return code from the parent process will still be 0 if a startup error occurs in the forked children. Errors in the initial daemonizing process still return proper exit codes. Therefore, if you use this plugin to daemonize, don't use the return code as an accurate indicator of whether the process fully started. In fact, that return code only indicates if the process succesfully finished the first fork. """ def __init__(self, bus, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): SimplePlugin.__init__(self, bus) self.stdin = stdin self.stdout = stdout self.stderr = stderr self.finalized = False def start(self): if self.finalized: self.bus.log('Already deamonized.') # forking has issues with threads: # http://www.opengroup.org/onlinepubs/000095399/functions/fork.html # "The general problem with making fork() work in a multi-threaded # world is what to do with all of the threads..." # So we check for active threads: if threading.activeCount() != 1: self.bus.log('There are %r active threads. ' 'Daemonizing now may cause strange failures.' % threading.enumerate(), level=30) # See http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 # (or http://www.faqs.org/faqs/unix-faq/programmer/faq/ section 1.7) # and http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012 # Finish up with the current stdout/stderr sys.stdout.flush() sys.stderr.flush() # Do first fork. try: pid = os.fork() if pid == 0: # This is the child process. Continue. pass else: # This is the first parent. Exit, now that we've forked. self.bus.log('Forking once.') os._exit(0) except OSError, exc: # Python raises OSError rather than returning negative numbers. sys.exit("%s: fork #1 failed: (%d) %s\n" % (sys.argv[0], exc.errno, exc.strerror)) os.setsid() # Do second fork try: pid = os.fork() if pid > 0: self.bus.log('Forking twice.') os._exit(0) # Exit second parent except OSError, exc: sys.exit("%s: fork #2 failed: (%d) %s\n" % (sys.argv[0], exc.errno, exc.strerror)) os.chdir("/") os.umask(0) si = open(self.stdin, "r") so = open(self.stdout, "a+") se = open(self.stderr, "a+", 0) # os.dup2(fd, fd2) will close fd2 if necessary, # so we don't explicitly close stdin/out/err. # See http://docs.python.org/lib/os-fd-ops.html os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) self.bus.log('Daemonized to PID: %s' % os.getpid()) self.finalized = True start.priority = 65 class PIDFile(SimplePlugin): """Maintain a PID file via a WSPBus.""" def __init__(self, bus, pidfile): SimplePlugin.__init__(self, bus) self.pidfile = pidfile self.finalized = False def start(self): pid = os.getpid() if self.finalized: self.bus.log('PID %r already written to %r.' % (pid, self.pidfile)) else: open(self.pidfile, "wb").write(str(pid)) self.bus.log('PID %r written to %r.' % (pid, self.pidfile)) self.finalized = True start.priority = 70 def exit(self): try: os.remove(self.pidfile) self.bus.log('PID file removed: %r.' % self.pidfile) except (KeyboardInterrupt, SystemExit): raise except: pass class PerpetualTimer(threading._Timer): """A subclass of threading._Timer whose run() method repeats.""" def run(self): while True: self.finished.wait(self.interval) if self.finished.isSet(): return self.function(*self.args, **self.kwargs) class Monitor(SimplePlugin): """WSPBus listener to periodically run a callback in its own thread. bus: a Web Site Process Bus object. callback: the function to call at intervals. frequency: the time in seconds between callback runs. """ frequency = 60 def __init__(self, bus, callback, frequency=60): SimplePlugin.__init__(self, bus) self.callback = callback self.frequency = frequency self.thread = None def start(self): """Start our callback in its own perpetual timer thread.""" if self.frequency > 0: threadname = self.__class__.__name__ if self.thread is None: self.thread = PerpetualTimer(self.frequency, self.callback) self.thread.setName(threadname) self.thread.start() self.bus.log("Started monitor thread %r." % threadname) else: self.bus.log("Monitor thread %r already started." % threadname) start.priority = 70 def stop(self): """Stop our callback's perpetual timer thread.""" if self.thread is None: self.bus.log("No thread running for %s." % self.__class__.__name__) else: if self.thread is not threading.currentThread(): name = self.thread.getName() self.thread.cancel() self.thread.join() self.bus.log("Stopped thread %r." % name) self.thread = None def graceful(self): """Stop the callback's perpetual timer thread and restart it.""" self.stop() self.start() class Autoreloader(Monitor): """Monitor which re-executes the process when files change.""" frequency = 1 match = '.*' def __init__(self, bus, frequency=1, match='.*'): self.mtimes = {} self.files = set() self.match = match Monitor.__init__(self, bus, self.run, frequency) def start(self): """Start our own perpetual timer thread for self.run.""" if self.thread is None: self.mtimes = {} Monitor.start(self) start.priority = 70 def run(self): """Reload the process if registered files have been modified.""" sysfiles = set() for k, m in sys.modules.items(): if re.match(self.match, k): if hasattr(m, '__loader__'): if hasattr(m.__loader__, 'archive'): k = m.__loader__.archive k = getattr(m, '__file__', None) sysfiles.add(k) for filename in sysfiles | self.files: if filename: if filename.endswith('.pyc'): filename = filename[:-1] oldtime = self.mtimes.get(filename, 0) if oldtime is None: # Module with no .py file. Skip it. continue try: mtime = os.stat(filename).st_mtime except OSError: # Either a module with no .py file, or it's been deleted. mtime = None if filename not in self.mtimes: # If a module has no .py file, this will be None. self.mtimes[filename] = mtime else: if mtime is None or mtime > oldtime: # The file has been deleted or modified. self.bus.log("Restarting because %s changed." % filename) self.thread.cancel() self.bus.log("Stopped thread %r." % self.thread.getName()) self.bus.restart() return class ThreadManager(SimplePlugin): """Manager for HTTP request threads. If you have control over thread creation and destruction, publish to the 'acquire_thread' and 'release_thread' channels (for each thread). This will register/unregister the current thread and publish to 'start_thread' and 'stop_thread' listeners in the bus as needed. If threads are created and destroyed by code you do not control (e.g., Apache), then, at the beginning of every HTTP request, publish to 'acquire_thread' only. You should not publish to 'release_thread' in this case, since you do not know whether the thread will be re-used or not. The bus will call 'stop_thread' listeners for you when it stops. """ def __init__(self, bus): self.threads = {} SimplePlugin.__init__(self, bus) self.bus.listeners.setdefault('acquire_thread', set()) self.bus.listeners.setdefault('release_thread', set()) def acquire_thread(self): """Run 'start_thread' listeners for the current thread. If the current thread has already been seen, any 'start_thread' listeners will not be run again. """ thread_ident = threading._get_ident() if thread_ident not in self.threads: # We can't just use _get_ident as the thread ID # because some platforms reuse thread ID's. i = len(self.threads) + 1 self.threads[thread_ident] = i self.bus.publish('start_thread', i) def release_thread(self): """Release the current thread and run 'stop_thread' listeners.""" thread_ident = threading._get_ident() i = self.threads.pop(thread_ident, None) if i is not None: self.bus.publish('stop_thread', i) def stop(self): """Release all threads and run all 'stop_thread' listeners.""" for thread_ident, i in self.threads.iteritems(): self.bus.publish('stop_thread', i) self.threads.clear() graceful = stop SABnzbd-0.7.20/cherrypy/process/servers.py0000644000000000000000000002343512433712602020622 0ustar00usergroup00000000000000"""Adapt an HTTP server.""" import time class ServerAdapter(object): """Adapter for an HTTP server. If you need to start more than one HTTP server (to serve on multiple ports, or protocols, etc.), you can manually register each one and then start them all with bus.start: s1 = ServerAdapter(bus, MyWSGIServer(host='0.0.0.0', port=80)) s2 = ServerAdapter(bus, another.HTTPServer(host='127.0.0.1', SSL=True)) s1.subscribe() s2.subscribe() bus.start() """ def __init__(self, bus, httpserver=None, bind_addr=None): self.bus = bus self.httpserver = httpserver self.bind_addr = bind_addr self.interrupt = None self.running = False def subscribe(self): self.bus.subscribe('start', self.start) self.bus.subscribe('stop', self.stop) def unsubscribe(self): self.bus.unsubscribe('start', self.start) self.bus.unsubscribe('stop', self.stop) def start(self): """Start the HTTP server.""" if self.bind_addr is None: on_what = "unknown interface (dynamic?)" elif isinstance(self.bind_addr, tuple): host, port = self.bind_addr on_what = "%s:%s" % (host, port) else: on_what = "socket file: %s" % self.bind_addr if self.running: self.bus.log("Already serving on %s" % on_what) return self.interrupt = None if not self.httpserver: raise ValueError("No HTTP server has been created.") # Start the httpserver in a new thread. if isinstance(self.bind_addr, tuple): wait_for_free_port(*self.bind_addr) import threading t = threading.Thread(target=self._start_http_thread) t.setName("HTTPServer " + t.getName()) t.start() self.wait() self.running = True self.bus.log("Serving on %s" % on_what) start.priority = 75 def _start_http_thread(self): """HTTP servers MUST be running in new threads, so that the main thread persists to receive KeyboardInterrupt's. If an exception is raised in the httpserver's thread then it's trapped here, and the bus (and therefore our httpserver) are shut down. """ try: self.httpserver.start() except KeyboardInterrupt, exc: self.bus.log(" hit: shutting down HTTP server") self.interrupt = exc self.bus.exit() except SystemExit, exc: self.bus.log("SystemExit raised: shutting down HTTP server") self.interrupt = exc self.bus.exit() raise except: import sys self.interrupt = sys.exc_info()[1] self.bus.log("Error in HTTP server: shutting down", traceback=True, level=40) self.bus.exit() raise def wait(self): """Wait until the HTTP server is ready to receive requests.""" while not getattr(self.httpserver, "ready", False): if self.interrupt: raise self.interrupt time.sleep(.1) # Wait for port to be occupied if isinstance(self.bind_addr, tuple): host, port = self.bind_addr wait_for_occupied_port(host, port) def stop(self): """Stop the HTTP server.""" if self.running: # stop() MUST block until the server is *truly* stopped. self.httpserver.stop() # Wait for the socket to be truly freed. if isinstance(self.bind_addr, tuple): wait_for_free_port(*self.bind_addr) self.running = False self.bus.log("HTTP Server %s shut down" % self.httpserver) else: self.bus.log("HTTP Server %s already shut down" % self.httpserver) stop.priority = 25 def restart(self): """Restart the HTTP server.""" self.stop() self.start() class FlupFCGIServer(object): """Adapter for a flup.server.fcgi.WSGIServer.""" def __init__(self, *args, **kwargs): if kwargs.get('bindAddress', None) is None: import socket if not hasattr(socket.socket, 'fromfd'): raise ValueError( 'Dynamic FCGI server not available on this platform. ' 'You must use a static or external one by providing a ' 'legal bindAddress.') self.args = args self.kwargs = kwargs self.ready = False def start(self): """Start the FCGI server.""" # We have to instantiate the server class here because its __init__ # starts a threadpool. If we do it too early, daemonize won't work. from flup.server.fcgi import WSGIServer self.fcgiserver = WSGIServer(*self.args, **self.kwargs) # TODO: report this bug upstream to flup. # If we don't set _oldSIGs on Windows, we get: # File "C:\Python24\Lib\site-packages\flup\server\threadedserver.py", # line 108, in run # self._restoreSignalHandlers() # File "C:\Python24\Lib\site-packages\flup\server\threadedserver.py", # line 156, in _restoreSignalHandlers # for signum,handler in self._oldSIGs: # AttributeError: 'WSGIServer' object has no attribute '_oldSIGs' self.fcgiserver._installSignalHandlers = lambda: None self.fcgiserver._oldSIGs = [] self.ready = True self.fcgiserver.run() def stop(self): """Stop the HTTP server.""" # Forcibly stop the fcgi server main event loop. self.fcgiserver._keepGoing = False # Force all worker threads to die off. self.fcgiserver._threadPool.maxSpare = self.fcgiserver._threadPool._idleCount self.ready = False class FlupSCGIServer(object): """Adapter for a flup.server.scgi.WSGIServer.""" def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs self.ready = False def start(self): """Start the SCGI server.""" # We have to instantiate the server class here because its __init__ # starts a threadpool. If we do it too early, daemonize won't work. from flup.server.scgi import WSGIServer self.scgiserver = WSGIServer(*self.args, **self.kwargs) # TODO: report this bug upstream to flup. # If we don't set _oldSIGs on Windows, we get: # File "C:\Python24\Lib\site-packages\flup\server\threadedserver.py", # line 108, in run # self._restoreSignalHandlers() # File "C:\Python24\Lib\site-packages\flup\server\threadedserver.py", # line 156, in _restoreSignalHandlers # for signum,handler in self._oldSIGs: # AttributeError: 'WSGIServer' object has no attribute '_oldSIGs' self.scgiserver._installSignalHandlers = lambda: None self.scgiserver._oldSIGs = [] self.ready = True self.scgiserver.run() def stop(self): """Stop the HTTP server.""" self.ready = False # Forcibly stop the scgi server main event loop. self.scgiserver._keepGoing = False # Force all worker threads to die off. self.scgiserver._threadPool.maxSpare = 0 def client_host(server_host): """Return the host on which a client can connect to the given listener.""" if server_host == '0.0.0.0': # 0.0.0.0 is INADDR_ANY, which should answer on localhost. return '127.0.0.1' if server_host == '::': # :: is IN6ADDR_ANY, which should answer on localhost. return '::1' return server_host def check_port(host, port, timeout=1.0): """Raise an error if the given port is not free on the given host.""" if not host: raise ValueError("Host values of '' or None are not allowed.") host = client_host(host) port = int(port) import socket # AF_INET or AF_INET6 socket # Get the correct address family for our host (allows IPv6 addresses) for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res s = None try: s = socket.socket(af, socktype, proto) # See http://groups.google.com/group/cherrypy-users/ # browse_frm/thread/bbfe5eb39c904fe0 s.settimeout(timeout) s.connect((host, port)) s.close() raise IOError("Port %s is in use on %s; perhaps the previous " "httpserver did not shut down properly." % (repr(port), repr(host))) except socket.error: if s: s.close() def wait_for_free_port(host, port): """Wait for the specified port to become free (drop requests).""" if not host: raise ValueError("Host values of '' or None are not allowed.") for trial in xrange(50): try: # we are expecting a free port, so reduce the timeout check_port(host, port, timeout=0.1) except IOError: # Give the old server thread time to free the port. time.sleep(0.1) else: return raise IOError("Port %r not free on %r" % (port, host)) def wait_for_occupied_port(host, port): """Wait for the specified port to become active (receive requests).""" if not host: raise ValueError("Host values of '' or None are not allowed.") for trial in xrange(50): try: check_port(host, port) except IOError: return else: time.sleep(.1) raise IOError("Port %r not bound on %r" % (port, host)) SABnzbd-0.7.20/cherrypy/process/win32.py0000644000000000000000000001336312433712602020072 0ustar00usergroup00000000000000"""Windows service. Requires pywin32.""" import os import thread import win32api import win32con import win32event import win32service import win32serviceutil from cherrypy.process import wspbus, plugins class ConsoleCtrlHandler(plugins.SimplePlugin): """A WSPBus plugin for handling Win32 console events (like Ctrl-C).""" def __init__(self, bus): self.is_set = False plugins.SimplePlugin.__init__(self, bus) def start(self): if self.is_set: self.bus.log('Handler for console events already set.', level=40) return result = win32api.SetConsoleCtrlHandler(self.handle, 1) if result == 0: self.bus.log('Could not SetConsoleCtrlHandler (error %r)' % win32api.GetLastError(), level=40) else: self.bus.log('Set handler for console events.', level=40) self.is_set = True def stop(self): if not self.is_set: self.bus.log('Handler for console events already off.', level=40) return try: result = win32api.SetConsoleCtrlHandler(self.handle, 0) except ValueError: # "ValueError: The object has not been registered" result = 1 if result == 0: self.bus.log('Could not remove SetConsoleCtrlHandler (error %r)' % win32api.GetLastError(), level=40) else: self.bus.log('Removed handler for console events.', level=40) self.is_set = False def handle(self, event): """Handle console control events (like Ctrl-C).""" if event in (win32con.CTRL_C_EVENT, win32con.CTRL_LOGOFF_EVENT, win32con.CTRL_BREAK_EVENT, win32con.CTRL_SHUTDOWN_EVENT, win32con.CTRL_CLOSE_EVENT): self.bus.log('Console event %s: shutting down bus' % event) # Remove self immediately so repeated Ctrl-C doesn't re-call it. try: self.stop() except ValueError: pass self.bus.exit() # 'First to return True stops the calls' return 1 return 0 class Win32Bus(wspbus.Bus): """A Web Site Process Bus implementation for Win32. Instead of time.sleep, this bus blocks using native win32event objects. """ def __init__(self): self.events = {} wspbus.Bus.__init__(self) def _get_state_event(self, state): """Return a win32event for the given state (creating it if needed).""" try: return self.events[state] except KeyError: event = win32event.CreateEvent(None, 0, 0, u"WSPBus %s Event (pid=%r)" % (state.name, os.getpid())) self.events[state] = event return event def _get_state(self): return self._state def _set_state(self, value): self._state = value event = self._get_state_event(value) win32event.PulseEvent(event) state = property(_get_state, _set_state) def wait(self, state, interval=0.1): """Wait for the given state(s), KeyboardInterrupt or SystemExit. Since this class uses native win32event objects, the interval argument is ignored. """ if isinstance(state, (tuple, list)): # Don't wait for an event that beat us to the punch ;) if self.state not in state: events = tuple([self._get_state_event(s) for s in state]) win32event.WaitForMultipleObjects(events, 0, win32event.INFINITE) else: # Don't wait for an event that beat us to the punch ;) if self.state != state: event = self._get_state_event(state) win32event.WaitForSingleObject(event, win32event.INFINITE) class _ControlCodes(dict): """Control codes used to "signal" a service via ControlService. User-defined control codes are in the range 128-255. We generally use the standard Python value for the Linux signal and add 128. Example: >>> signal.SIGUSR1 10 control_codes['graceful'] = 128 + 10 """ def key_for(self, obj): """For the given value, return its corresponding key.""" for key, val in self.iteritems(): if val is obj: return key raise ValueError("The given object could not be found: %r" % obj) control_codes = _ControlCodes({'graceful': 138}) def signal_child(service, command): if command == 'stop': win32serviceutil.StopService(service) elif command == 'restart': win32serviceutil.RestartService(service) else: win32serviceutil.ControlService(service, control_codes[command]) class PyWebService(win32serviceutil.ServiceFramework): """Python Web Service.""" _svc_name_ = "Python Web Service" _svc_display_name_ = "Python Web Service" _svc_deps_ = None # sequence of service names on which this depends _exe_name_ = "pywebsvc" _exe_args_ = None # Default to no arguments # Only exists on Windows 2000 or later, ignored on windows NT _svc_description_ = "Python Web Service" def SvcDoRun(self): from cherrypy import process process.bus.start() process.bus.block() def SvcStop(self): from cherrypy import process self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) process.bus.exit() def SvcOther(self, control): process.bus.publish(control_codes.key_for(control)) if __name__ == '__main__': win32serviceutil.HandleCommandLine(PyWebService) SABnzbd-0.7.20/cherrypy/process/wspbus.py0000644000000000000000000003071712433712602020455 0ustar00usergroup00000000000000"""An implementation of the Web Site Process Bus. This module is completely standalone, depending only on the stdlib. Web Site Process Bus -------------------- A Bus object is used to contain and manage site-wide behavior: daemonization, HTTP server start/stop, process reload, signal handling, drop privileges, PID file management, logging for all of these, and many more. In addition, a Bus object provides a place for each web framework to register code that runs in response to site-wide events (like process start and stop), or which controls or otherwise interacts with the site-wide components mentioned above. For example, a framework which uses file-based templates would add known template filenames to an autoreload component. Ideally, a Bus object will be flexible enough to be useful in a variety of invocation scenarios: 1. The deployer starts a site from the command line via a framework- neutral deployment script; applications from multiple frameworks are mixed in a single site. Command-line arguments and configuration files are used to define site-wide components such as the HTTP server, WSGI component graph, autoreload behavior, signal handling, etc. 2. The deployer starts a site via some other process, such as Apache; applications from multiple frameworks are mixed in a single site. Autoreload and signal handling (from Python at least) are disabled. 3. The deployer starts a site via a framework-specific mechanism; for example, when running tests, exploring tutorials, or deploying single applications from a single framework. The framework controls which site-wide components are enabled as it sees fit. The Bus object in this package uses topic-based publish-subscribe messaging to accomplish all this. A few topic channels are built in ('start', 'stop', 'exit', and 'graceful'). Frameworks and site containers are free to define their own. If a message is sent to a channel that has not been defined or has no listeners, there is no effect. In general, there should only ever be a single Bus object per process. Frameworks and site containers share a single Bus object by publishing messages and subscribing listeners. The Bus object works as a finite state machine which models the current state of the process. Bus methods move it from one state to another; those methods then publish to subscribed listeners on the channel for the new state. O | V STOPPING --> STOPPED --> EXITING -> X A A | | \___ | | \ | | V V STARTED <-- STARTING """ import atexit import os try: set except NameError: from sets import Set as set import sys import threading import time import traceback as _traceback import warnings # Use a flag to indicate the state of the bus. class _StateEnum(object): class State(object): name = None def __repr__(self): return "states.%s" % self.name def __setattr__(self, key, value): if isinstance(value, self.State): value.name = key object.__setattr__(self, key, value) states = _StateEnum() states.STOPPED = states.State() states.STARTING = states.State() states.STARTED = states.State() states.STOPPING = states.State() states.EXITING = states.State() class Bus(object): """Process state-machine and messenger for HTTP site deployment. All listeners for a given channel are guaranteed to be called even if others at the same channel fail. Each failure is logged, but execution proceeds on to the next listener. The only way to stop all processing from inside a listener is to raise SystemExit and stop the whole server. """ states = states state = states.STOPPED execv = False def __init__(self): self.execv = False self.state = states.STOPPED self.listeners = dict( [(channel, set()) for channel in ('start', 'stop', 'exit', 'graceful', 'log')]) self._priorities = {} def subscribe(self, channel, callback, priority=None): """Add the given callback at the given channel (if not present).""" if channel not in self.listeners: self.listeners[channel] = set() self.listeners[channel].add(callback) if priority is None: priority = getattr(callback, 'priority', 50) self._priorities[(channel, callback)] = priority def unsubscribe(self, channel, callback): """Discard the given callback (if present).""" listeners = self.listeners.get(channel) if listeners and callback in listeners: listeners.discard(callback) del self._priorities[(channel, callback)] def publish(self, channel, *args, **kwargs): """Return output of all subscribers for the given channel.""" if channel not in self.listeners: return [] exc = None output = [] items = [(self._priorities[(channel, listener)], listener) for listener in self.listeners[channel]] items.sort() for priority, listener in items: try: output.append(listener(*args, **kwargs)) except KeyboardInterrupt: raise except SystemExit, e: # If we have previous errors ensure the exit code is non-zero if exc and e.code == 0: e.code = 1 raise except: exc = sys.exc_info()[1] if channel == 'log': # Assume any further messages to 'log' will fail. pass else: self.log("Error in %r listener %r" % (channel, listener), level=40, traceback=True) if exc: raise return output def _clean_exit(self): """An atexit handler which asserts the Bus is not running.""" if self.state != states.EXITING: warnings.warn( "The main thread is exiting, but the Bus is in the %r state; " "shutting it down automatically now. You must either call " "bus.block() after start(), or call bus.exit() before the " "main thread exits." % self.state, RuntimeWarning) self.exit() def start(self): """Start all services.""" atexit.register(self._clean_exit) self.state = states.STARTING self.log('Bus STARTING') try: self.publish('start') self.state = states.STARTED self.log('Bus STARTED') except (KeyboardInterrupt, SystemExit): raise except: self.log("Shutting down due to error in start listener:", level=40, traceback=True) e_info = sys.exc_info() try: self.exit() except: # Any stop/exit errors will be logged inside publish(). pass raise e_info[0], e_info[1], e_info[2] def exit(self): """Stop all services and prepare to exit the process.""" try: self.stop() self.state = states.EXITING self.log('Bus EXITING') self.publish('exit') # This isn't strictly necessary, but it's better than seeing # "Waiting for child threads to terminate..." and then nothing. self.log('Bus EXITED') except: # This method is often called asynchronously (whether thread, # signal handler, console handler, or atexit handler), so we # can't just let exceptions propagate out unhandled. # Assume it's been logged and just die. os._exit(70) # EX_SOFTWARE def restart(self): """Restart the process (may close connections). This method does not restart the process from the calling thread; instead, it stops the bus and asks the main thread to call execv. """ self.execv = True self.exit() def graceful(self): """Advise all services to reload.""" self.log('Bus graceful') self.publish('graceful') def block(self, interval=0.1): """Wait for the EXITING state, KeyboardInterrupt or SystemExit. This function is intended to be called only by the main thread. After waiting for the EXITING state, it also waits for all threads to terminate, and then calls os.execv if self.execv is True. This design allows another thread to call bus.restart, yet have the main thread perform the actual execv call (required on some platforms). """ try: self.wait(states.EXITING, interval=interval) except (KeyboardInterrupt, IOError): # The time.sleep call might raise # "IOError: [Errno 4] Interrupted function call" on KBInt. self.log('Keyboard Interrupt: shutting down bus') self.exit() except SystemExit: self.log('SystemExit raised: shutting down bus') self.exit() raise # Waiting for ALL child threads to finish is necessary on OS X. # See http://www.cherrypy.org/ticket/581. # It's also good to let them all shut down before allowing # the main thread to call atexit handlers. # See http://www.cherrypy.org/ticket/751. self.log("Waiting for child threads to terminate...") for t in threading.enumerate(): if t != threading.currentThread() and t.isAlive(): # Note that any dummy (external) threads are always daemonic. if hasattr(threading.Thread, "daemon"): # Python 2.6+ d = t.daemon else: d = t.isDaemon() if not d: t.join() if self.execv: self._do_execv() def wait(self, state, interval=0.1): """Wait for the given state(s).""" if isinstance(state, (tuple, list)): states = state else: states = [state] def _wait(): while self.state not in states: time.sleep(interval) # From http://psyco.sourceforge.net/psycoguide/bugs.html: # "The compiled machine code does not include the regular polling # done by Python, meaning that a KeyboardInterrupt will not be # detected before execution comes back to the regular Python # interpreter. Your program cannot be interrupted if caught # into an infinite Psyco-compiled loop." try: sys.modules['psyco'].cannotcompile(_wait) except (KeyError, AttributeError): pass _wait() def _do_execv(self): """Re-execute the current process. This must be called from the main thread, because certain platforms (OS X) don't allow execv to be called in a child thread very well. """ args = sys.argv[:] self.log('Re-spawning %s' % ' '.join(args)) args.insert(0, sys.executable) if sys.platform == 'win32': args = ['"%s"' % arg for arg in args] os.execv(sys.executable, args) def stop(self): """Stop all services.""" self.state = states.STOPPING self.log('Bus STOPPING') self.publish('stop') self.state = states.STOPPED self.log('Bus STOPPED') def start_with_callback(self, func, args=None, kwargs=None): """Start 'func' in a new thread T, then start self (and return T).""" if args is None: args = () if kwargs is None: kwargs = {} args = (func,) + args def _callback(func, *a, **kw): self.wait(states.STARTED) func(*a, **kw) t = threading.Thread(target=_callback, args=args, kwargs=kwargs) t.setName('Bus Callback ' + t.getName()) t.start() self.start() return t def log(self, msg="", level=20, traceback=False): """Log the given message. Append the last traceback if requested.""" if traceback: exc = sys.exc_info() msg += "\n" + "".join(_traceback.format_exception(*exc)) self.publish('log', msg, level) bus = Bus() SABnzbd-0.7.20/cherrypy/process/__init__.py0000644000000000000000000000103012433712602020653 0ustar00usergroup00000000000000"""Site container for an HTTP server. A Web Site Process Bus object is used to connect applications, servers, and frameworks with site-wide services such as daemonization, process reload, signal handling, drop privileges, PID file management, logging for all of these, and many more. The 'plugins' module defines a few abstract and concrete services for use with the bus. Some use tool-specific channels; see the documentation for each class. """ from cherrypy.process.wspbus import bus from cherrypy.process import plugins, servers SABnzbd-0.7.20/cherrypy/wsgiserver/__init__.py0000644000000000000000000021645112433712602021414 0ustar00usergroup00000000000000"""A high-speed, production ready, thread pooled, generic WSGI server. Simplest example on how to use this module directly (without using CherryPy's application machinery): from cherrypy import wsgiserver def my_crazy_app(environ, start_response): status = '200 OK' response_headers = [('Content-type','text/plain')] start_response(status, response_headers) return ['Hello world!\n'] server = wsgiserver.CherryPyWSGIServer( ('0.0.0.0', 8070), my_crazy_app, server_name='www.cherrypy.example') The CherryPy WSGI server can serve as many WSGI applications as you want in one instance by using a WSGIPathInfoDispatcher: d = WSGIPathInfoDispatcher({'/': my_crazy_app, '/blog': my_blog_app}) server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 80), d) Want SSL support? Just set these attributes: server.ssl_certificate = server.ssl_private_key = if __name__ == '__main__': try: server.start() except KeyboardInterrupt: server.stop() This won't call the CherryPy engine (application side) at all, only the WSGI server, which is independant from the rest of CherryPy. Don't let the name "CherryPyWSGIServer" throw you; the name merely reflects its origin, not its coupling. For those of you wanting to understand internals of this module, here's the basic call flow. The server's listening thread runs a very tight loop, sticking incoming connections onto a Queue: server = CherryPyWSGIServer(...) server.start() while True: tick() # This blocks until a request comes in: child = socket.accept() conn = HTTPConnection(child, ...) server.requests.put(conn) Worker threads are kept in a pool and poll the Queue, popping off and then handling each connection in turn. Each connection can consist of an arbitrary number of requests and their responses, so we run a nested loop: while True: conn = server.requests.get() conn.communicate() -> while True: req = HTTPRequest(...) req.parse_request() -> # Read the Request-Line, e.g. "GET /page HTTP/1.1" req.rfile.readline() req.read_headers() req.respond() -> response = wsgi_app(...) try: for chunk in response: if chunk: req.write(chunk) finally: if hasattr(response, "close"): response.close() if req.close_connection: return """ import base64 import os import Queue import re quoted_slash = re.compile("(?i)%2F") import rfc822 import socket try: import cStringIO as StringIO except ImportError: import StringIO REDIRECT_URL = None # Application can write it's HTTP-->HTTPS redirection URL here _fileobject_uses_str_type = isinstance(socket._fileobject(None)._rbuf, basestring) import sys import threading import time from traceback import format_exc from urllib import unquote from urlparse import urlparse import warnings try: from OpenSSL import SSL from OpenSSL import crypto except ImportError: SSL = None import errno def plat_specific_errors(*errnames): """Return error numbers for all errors in errnames on this platform. The 'errno' module contains different global constants depending on the specific platform (OS). This function will return the list of numeric values for a given list of potential names. """ errno_names = dir(errno) nums = [getattr(errno, k) for k in errnames if k in errno_names] # de-dupe the list return dict.fromkeys(nums).keys() socket_error_eintr = plat_specific_errors("EINTR", "WSAEINTR") socket_errors_to_ignore = plat_specific_errors( "EPIPE", "EBADF", "WSAEBADF", "ENOTSOCK", "WSAENOTSOCK", "ETIMEDOUT", "WSAETIMEDOUT", "ECONNREFUSED", "WSAECONNREFUSED", "ECONNRESET", "WSAECONNRESET", "ECONNABORTED", "WSAECONNABORTED", "ENETRESET", "WSAENETRESET", "EHOSTDOWN", "EHOSTUNREACH", ) socket_errors_to_ignore.append("timed out") socket_errors_nonblocking = plat_specific_errors( 'EAGAIN', 'EWOULDBLOCK', 'WSAEWOULDBLOCK') comma_separated_headers = ['ACCEPT', 'ACCEPT-CHARSET', 'ACCEPT-ENCODING', 'ACCEPT-LANGUAGE', 'ACCEPT-RANGES', 'ALLOW', 'CACHE-CONTROL', 'CONNECTION', 'CONTENT-ENCODING', 'CONTENT-LANGUAGE', 'EXPECT', 'IF-MATCH', 'IF-NONE-MATCH', 'PRAGMA', 'PROXY-AUTHENTICATE', 'TE', 'TRAILER', 'TRANSFER-ENCODING', 'UPGRADE', 'VARY', 'VIA', 'WARNING', 'WWW-AUTHENTICATE'] class WSGIPathInfoDispatcher(object): """A WSGI dispatcher for dispatch based on the PATH_INFO. apps: a dict or list of (path_prefix, app) pairs. """ def __init__(self, apps): try: apps = apps.items() except AttributeError: pass # Sort the apps by len(path), descending apps.sort() apps.reverse() # The path_prefix strings must start, but not end, with a slash. # Use "" instead of "/". self.apps = [(p.rstrip("/"), a) for p, a in apps] def __call__(self, environ, start_response): path = environ["PATH_INFO"] or "/" for p, app in self.apps: # The apps list should be sorted by length, descending. if path.startswith(p + "/") or path == p: environ = environ.copy() environ["SCRIPT_NAME"] = environ["SCRIPT_NAME"] + p environ["PATH_INFO"] = path[len(p):] return app(environ, start_response) start_response('404 Not Found', [('Content-Type', 'text/plain'), ('Content-Length', '0')]) return [''] class MaxSizeExceeded(Exception): pass class SizeCheckWrapper(object): """Wraps a file-like object, raising MaxSizeExceeded if too large.""" def __init__(self, rfile, maxlen): self.rfile = rfile self.maxlen = maxlen self.bytes_read = 0 def _check_length(self): if self.maxlen and self.bytes_read > self.maxlen: raise MaxSizeExceeded() def read(self, size=None): data = self.rfile.read(size) self.bytes_read += len(data) self._check_length() return data def readline(self, size=None): if size is not None: data = self.rfile.readline(size) self.bytes_read += len(data) self._check_length() return data # User didn't specify a size ... # We read the line in chunks to make sure it's not a 100MB line ! res = [] while True: data = self.rfile.readline(256) self.bytes_read += len(data) self._check_length() res.append(data) # See http://www.cherrypy.org/ticket/421 if len(data) < 256 or data[-1:] == "\n": return ''.join(res) def readlines(self, sizehint=0): # Shamelessly stolen from StringIO total = 0 lines = [] line = self.readline() while line: lines.append(line) total += len(line) if 0 < sizehint <= total: break line = self.readline() return lines def close(self): self.rfile.close() def __iter__(self): return self def next(self): data = self.rfile.next() self.bytes_read += len(data) self._check_length() return data class HTTPRequest(object): """An HTTP Request (and response). A single HTTP connection may consist of multiple request/response pairs. send: the 'send' method from the connection's socket object. wsgi_app: the WSGI application to call. environ: a partial WSGI environ (server and connection entries). The caller MUST set the following entries: * All wsgi.* entries, including .input * SERVER_NAME and SERVER_PORT * Any SSL_* entries * Any custom entries like REMOTE_ADDR and REMOTE_PORT * SERVER_SOFTWARE: the value to write in the "Server" response header. * ACTUAL_SERVER_PROTOCOL: the value to write in the Status-Line of the response. From RFC 2145: "An HTTP server SHOULD send a response version equal to the highest version for which the server is at least conditionally compliant, and whose major version is less than or equal to the one received in the request. An HTTP server MUST NOT send a version for which it is not at least conditionally compliant." outheaders: a list of header tuples to write in the response. ready: when True, the request has been parsed and is ready to begin generating the response. When False, signals the calling Connection that the response should not be generated and the connection should close. close_connection: signals the calling Connection that the request should close. This does not imply an error! The client and/or server may each request that the connection be closed. chunked_write: if True, output will be encoded with the "chunked" transfer-coding. This value is set automatically inside send_headers. """ max_request_header_size = 0 max_request_body_size = 0 def __init__(self, wfile, environ, wsgi_app): self.rfile = environ['wsgi.input'] self.wfile = wfile self.environ = environ.copy() self.wsgi_app = wsgi_app self.ready = False self.started_request = False self.started_response = False self.status = "" self.outheaders = [] self.sent_headers = False self.close_connection = False self.chunked_write = False def parse_request(self): """Parse the next HTTP request start-line and message-headers.""" self.rfile.maxlen = self.max_request_header_size self.rfile.bytes_read = 0 try: self._parse_request() except MaxSizeExceeded: self.simple_response("413 Request Entity Too Large") return def _parse_request(self): # HTTP/1.1 connections are persistent by default. If a client # requests a page, then idles (leaves the connection open), # then rfile.readline() will raise socket.error("timed out"). # Note that it does this based on the value given to settimeout(), # and doesn't need the client to request or acknowledge the close # (although your TCP stack might suffer for it: cf Apache's history # with FIN_WAIT_2). request_line = self.rfile.readline() # Set started_request to True so communicate() knows to send 408 # from here on out. self.started_request = True if not request_line: # Force self.ready = False so the connection will close. self.ready = False return if request_line == "\r\n": # RFC 2616 sec 4.1: "...if the server is reading the protocol # stream at the beginning of a message and receives a CRLF # first, it should ignore the CRLF." # But only ignore one leading line! else we enable a DoS. request_line = self.rfile.readline() if not request_line: self.ready = False return if not request_line.endswith('\r\n'): self.simple_response(400, "HTTP requires CRLF terminators") return environ = self.environ try: method, path, req_protocol = request_line.strip().split(" ", 2) except ValueError: self.simple_response(400, "Malformed Request-Line") return environ["REQUEST_URI"] = path environ["REQUEST_METHOD"] = method # path may be an abs_path (including "http://host.domain.tld"); scheme, location, path, params, qs, frag = urlparse(path) if frag: self.simple_response("400 Bad Request", "Illegal #fragment in Request-URI.") return if scheme: environ["wsgi.url_scheme"] = scheme if params: path = path + ";" + params environ["SCRIPT_NAME"] = "" # Unquote the path+params (e.g. "/this%20path" -> "this path"). # http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2 # # But note that "...a URI must be separated into its components # before the escaped characters within those components can be # safely decoded." http://www.ietf.org/rfc/rfc2396.txt, sec 2.4.2 atoms = [unquote(x) for x in quoted_slash.split(path)] path = "%2F".join(atoms) environ["PATH_INFO"] = path # Note that, like wsgiref and most other WSGI servers, # we unquote the path but not the query string. environ["QUERY_STRING"] = qs # Compare request and server HTTP protocol versions, in case our # server does not support the requested protocol. Limit our output # to min(req, server). We want the following output: # request server actual written supported response # protocol protocol response protocol feature set # a 1.0 1.0 1.0 1.0 # b 1.0 1.1 1.1 1.0 # c 1.1 1.0 1.0 1.0 # d 1.1 1.1 1.1 1.1 # Notice that, in (b), the response will be "HTTP/1.1" even though # the client only understands 1.0. RFC 2616 10.5.6 says we should # only return 505 if the _major_ version is different. rp = int(req_protocol[5]), int(req_protocol[7]) server_protocol = environ["ACTUAL_SERVER_PROTOCOL"] sp = int(server_protocol[5]), int(server_protocol[7]) if sp[0] != rp[0]: self.simple_response("505 HTTP Version Not Supported") return # Bah. "SERVER_PROTOCOL" is actually the REQUEST protocol. environ["SERVER_PROTOCOL"] = req_protocol self.response_protocol = "HTTP/%s.%s" % min(rp, sp) # then all the http headers try: self.read_headers() except ValueError, ex: self.simple_response("400 Bad Request", ex.args[0]) return mrbs = self.max_request_body_size if mrbs and int(environ.get("CONTENT_LENGTH", 0)) > mrbs: self.simple_response("413 Request Entity Too Large") return # Persistent connection support if self.response_protocol == "HTTP/1.1": # Both server and client are HTTP/1.1 if environ.get("HTTP_CONNECTION", "") == "close": self.close_connection = True else: # Either the server or client (or both) are HTTP/1.0 if environ.get("HTTP_CONNECTION", "") != "Keep-Alive": self.close_connection = True # Transfer-Encoding support te = None if self.response_protocol == "HTTP/1.1": te = environ.get("HTTP_TRANSFER_ENCODING") if te: te = [x.strip().lower() for x in te.split(",") if x.strip()] self.chunked_read = False if te: for enc in te: if enc == "chunked": self.chunked_read = True else: # Note that, even if we see "chunked", we must reject # if there is an extension we don't recognize. self.simple_response("501 Unimplemented") self.close_connection = True return # From PEP 333: # "Servers and gateways that implement HTTP 1.1 must provide # transparent support for HTTP 1.1's "expect/continue" mechanism. # This may be done in any of several ways: # 1. Respond to requests containing an Expect: 100-continue request # with an immediate "100 Continue" response, and proceed normally. # 2. Proceed with the request normally, but provide the application # with a wsgi.input stream that will send the "100 Continue" # response if/when the application first attempts to read from # the input stream. The read request must then remain blocked # until the client responds. # 3. Wait until the client decides that the server does not support # expect/continue, and sends the request body on its own. # (This is suboptimal, and is not recommended.) # # We used to do 3, but are now doing 1. Maybe we'll do 2 someday, # but it seems like it would be a big slowdown for such a rare case. if environ.get("HTTP_EXPECT", "") == "100-continue": self.simple_response(100) self.ready = True def read_headers(self): """Read header lines from the incoming stream.""" environ = self.environ while True: line = self.rfile.readline() if not line: # No more data--illegal end of headers raise ValueError("Illegal end of headers.") if line == '\r\n': # Normal end of headers break if not line.endswith('\r\n'): raise ValueError("HTTP requires CRLF terminators") if line[0] in ' \t': # It's a continuation line. v = line.strip() else: k, v = line.split(":", 1) k, v = k.strip().upper(), v.strip() envname = "HTTP_" + k.replace("-", "_") if k in comma_separated_headers: existing = environ.get(envname) if existing: v = ", ".join((existing, v)) environ[envname] = v ct = environ.pop("HTTP_CONTENT_TYPE", None) if ct is not None: environ["CONTENT_TYPE"] = ct cl = environ.pop("HTTP_CONTENT_LENGTH", None) if cl is not None: environ["CONTENT_LENGTH"] = cl def decode_chunked(self): """Decode the 'chunked' transfer coding.""" cl = 0 data = StringIO.StringIO() while True: line = self.rfile.readline().strip().split(";", 1) chunk_size = int(line.pop(0), 16) if chunk_size <= 0: break ## if line: chunk_extension = line[0] cl += chunk_size data.write(self.rfile.read(chunk_size)) crlf = self.rfile.read(2) if crlf != "\r\n": self.simple_response("400 Bad Request", "Bad chunked transfer coding " "(expected '\\r\\n', got %r)" % crlf) return # Grab any trailer headers self.read_headers() data.seek(0) self.environ["wsgi.input"] = data self.environ["CONTENT_LENGTH"] = str(cl) or "" return True def respond(self): """Call the appropriate WSGI app and write its iterable output.""" # Set rfile.maxlen to ensure we don't read past Content-Length. # This will also be used to read the entire request body if errors # are raised before the app can read the body. if self.chunked_read: # If chunked, Content-Length will be 0. self.rfile.maxlen = self.max_request_body_size else: cl = int(self.environ.get("CONTENT_LENGTH", 0)) if self.max_request_body_size: self.rfile.maxlen = min(cl, self.max_request_body_size) else: self.rfile.maxlen = cl self.rfile.bytes_read = 0 try: self._respond() except MaxSizeExceeded: if not self.sent_headers: self.simple_response("413 Request Entity Too Large") return def _respond(self): if self.chunked_read: if not self.decode_chunked(): self.close_connection = True return response = self.wsgi_app(self.environ, self.start_response) try: for chunk in response: # "The start_response callable must not actually transmit # the response headers. Instead, it must store them for the # server or gateway to transmit only after the first # iteration of the application return value that yields # a NON-EMPTY string, or upon the application's first # invocation of the write() callable." (PEP 333) if chunk: self.write(chunk) finally: if hasattr(response, "close"): response.close() if (self.ready and not self.sent_headers): self.sent_headers = True self.send_headers() if self.chunked_write: self.wfile.sendall("0\r\n\r\n") def simple_response(self, status, msg=""): """Write a simple response back to the client. For status "301 ...", the msg is the redirect URL. """ status = str(status) if status[:3] == "301": buf = ["%s %s\r\n" % (self.environ['ACTUAL_SERVER_PROTOCOL'], status), "Location: %s\r\n" % msg, "Content-Length: 0\r\n", "Content-Type: text/plain\r\n"] else: buf = ["%s %s\r\n" % (self.environ['ACTUAL_SERVER_PROTOCOL'], status), "Content-Length: %s\r\n" % len(msg), "Content-Type: text/plain\r\n"] if status[:3] == "413" and self.response_protocol == 'HTTP/1.1': # Request Entity Too Large self.close_connection = True buf.append("Connection: close\r\n") buf.append("\r\n") if msg: buf.append(msg) try: self.wfile.sendall("".join(buf)) except socket.error, x: if x.args[0] not in socket_errors_to_ignore: raise def start_response(self, status, headers, exc_info = None): """WSGI callable to begin the HTTP response.""" # "The application may call start_response more than once, # if and only if the exc_info argument is provided." if self.started_response and not exc_info: raise AssertionError("WSGI start_response called a second " "time with no exc_info.") # "if exc_info is provided, and the HTTP headers have already been # sent, start_response must raise an error, and should raise the # exc_info tuple." if self.sent_headers: try: raise exc_info[0], exc_info[1], exc_info[2] finally: exc_info = None self.started_response = True self.status = status self.outheaders.extend(headers) return self.write def write(self, chunk): """WSGI callable to write unbuffered data to the client. This method is also used internally by start_response (to write data from the iterable returned by the WSGI application). """ if not self.started_response: raise AssertionError("WSGI write called before start_response.") if not self.sent_headers: self.sent_headers = True self.send_headers() if self.chunked_write and chunk: buf = [hex(len(chunk))[2:], "\r\n", chunk, "\r\n"] self.wfile.sendall("".join(buf)) else: self.wfile.sendall(chunk) def send_headers(self): """Assert, process, and send the HTTP response message-headers.""" hkeys = [key.lower() for key, value in self.outheaders] status = int(self.status[:3]) if status == 413: # Request Entity Too Large. Close conn to avoid garbage. self.close_connection = True elif "content-length" not in hkeys: # "All 1xx (informational), 204 (no content), # and 304 (not modified) responses MUST NOT # include a message-body." So no point chunking. if status < 200 or status in (204, 205, 304): pass else: if (self.response_protocol == 'HTTP/1.1' and self.environ["REQUEST_METHOD"] != 'HEAD'): # Use the chunked transfer-coding self.chunked_write = True self.outheaders.append(("Transfer-Encoding", "chunked")) else: # Closing the conn is the only way to determine len. self.close_connection = True if "connection" not in hkeys: if self.response_protocol == 'HTTP/1.1': # Both server and client are HTTP/1.1 or better if self.close_connection: self.outheaders.append(("Connection", "close")) else: # Server and/or client are HTTP/1.0 if not self.close_connection: self.outheaders.append(("Connection", "Keep-Alive")) if (not self.close_connection) and (not self.chunked_read): # Read any remaining request body data on the socket. # "If an origin server receives a request that does not include an # Expect request-header field with the "100-continue" expectation, # the request includes a request body, and the server responds # with a final status code before reading the entire request body # from the transport connection, then the server SHOULD NOT close # the transport connection until it has read the entire request, # or until the client closes the connection. Otherwise, the client # might not reliably receive the response message. However, this # requirement is not be construed as preventing a server from # defending itself against denial-of-service attacks, or from # badly broken client implementations." size = self.rfile.maxlen - self.rfile.bytes_read if size > 0: self.rfile.read(size) if "date" not in hkeys: self.outheaders.append(("Date", rfc822.formatdate())) if "server" not in hkeys: self.outheaders.append(("Server", self.environ['SERVER_SOFTWARE'])) buf = [self.environ['ACTUAL_SERVER_PROTOCOL'], " ", self.status, "\r\n"] try: buf += [k + ": " + v + "\r\n" for k, v in self.outheaders] except TypeError: if not isinstance(k, str): raise TypeError("WSGI response header key %r is not a string.") if not isinstance(v, str): raise TypeError("WSGI response header value %r is not a string.") else: raise buf.append("\r\n") self.wfile.sendall("".join(buf)) class NoSSLError(Exception): """Exception raised when a client speaks HTTP to an HTTPS socket.""" pass class FatalSSLAlert(Exception): """Exception raised when the SSL implementation signals a fatal alert.""" pass if not _fileobject_uses_str_type: class CP_fileobject(socket._fileobject): """Faux file object attached to a socket object.""" def sendall(self, data): """Sendall for non-blocking sockets.""" while data: try: bytes_sent = self.send(data) data = data[bytes_sent:] except socket.error, e: if e.args[0] not in socket_errors_nonblocking: raise def send(self, data): return self._sock.send(data) def flush(self): if self._wbuf: buffer = "".join(self._wbuf) self._wbuf = [] self.sendall(buffer) def recv(self, size): while True: try: return self._sock.recv(size) except socket.error, e: if (e.args[0] not in socket_errors_nonblocking and e.args[0] not in socket_error_eintr): raise def read(self, size=-1): # Use max, disallow tiny reads in a loop as they are very inefficient. # We never leave read() with any leftover data from a new recv() call # in our internal buffer. rbufsize = max(self._rbufsize, self.default_bufsize) # Our use of StringIO rather than lists of string objects returned by # recv() minimizes memory usage and fragmentation that occurs when # rbufsize is large compared to the typical return value of recv(). buf = self._rbuf buf.seek(0, 2) # seek end if size < 0: # Read until EOF self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. while True: data = self.recv(rbufsize) if not data: break buf.write(data) return buf.getvalue() else: # Read until size bytes or EOF seen, whichever comes first buf_len = buf.tell() if buf_len >= size: # Already have size bytes in our buffer? Extract and return. buf.seek(0) rv = buf.read(size) self._rbuf = StringIO.StringIO() self._rbuf.write(buf.read()) return rv self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. while True: left = size - buf_len # recv() will malloc the amount of memory given as its # parameter even though it often returns much less data # than that. The returned data string is short lived # as we copy it into a StringIO and free it. This avoids # fragmentation issues on many platforms. data = self.recv(left) if not data: break n = len(data) if n == size and not buf_len: # Shortcut. Avoid buffer data copies when: # - We have no data in our buffer. # AND # - Our call to recv returned exactly the # number of bytes we were asked to read. return data if n == left: buf.write(data) del data # explicit free break assert n <= left, "recv(%d) returned %d bytes" % (left, n) buf.write(data) buf_len += n del data # explicit free #assert buf_len == buf.tell() return buf.getvalue() def readline(self, size=-1): buf = self._rbuf buf.seek(0, 2) # seek end if buf.tell() > 0: # check if we already have it in our buffer buf.seek(0) bline = buf.readline(size) if bline.endswith('\n') or len(bline) == size: self._rbuf = StringIO.StringIO() self._rbuf.write(buf.read()) return bline del bline if size < 0: # Read until \n or EOF, whichever comes first if self._rbufsize <= 1: # Speed up unbuffered case buf.seek(0) buffers = [buf.read()] self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. data = None recv = self.recv while data != "\n": data = recv(1) if not data: break buffers.append(data) return "".join(buffers) buf.seek(0, 2) # seek end self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. while True: data = self.recv(self._rbufsize) if not data: break nl = data.find('\n') if nl >= 0: nl += 1 buf.write(data[:nl]) self._rbuf.write(data[nl:]) del data break buf.write(data) return buf.getvalue() else: # Read until size bytes or \n or EOF seen, whichever comes first buf.seek(0, 2) # seek end buf_len = buf.tell() if buf_len >= size: buf.seek(0) rv = buf.read(size) self._rbuf = StringIO.StringIO() self._rbuf.write(buf.read()) return rv self._rbuf = StringIO.StringIO() # reset _rbuf. we consume it via buf. while True: data = self.recv(self._rbufsize) if not data: break left = size - buf_len # did we just receive a newline? nl = data.find('\n', 0, left) if nl >= 0: nl += 1 # save the excess data to _rbuf self._rbuf.write(data[nl:]) if buf_len: buf.write(data[:nl]) break else: # Shortcut. Avoid data copy through buf when returning # a substring of our first recv(). return data[:nl] n = len(data) if n == size and not buf_len: # Shortcut. Avoid data copy through buf when # returning exactly all of our first recv(). return data if n >= left: buf.write(data[:left]) self._rbuf.write(data[left:]) break buf.write(data) buf_len += n #assert buf_len == buf.tell() return buf.getvalue() else: class CP_fileobject(socket._fileobject): """Faux file object attached to a socket object.""" def sendall(self, data): """Sendall for non-blocking sockets.""" while data: try: bytes_sent = self.send(data) data = data[bytes_sent:] except socket.error, e: if e.args[0] not in socket_errors_nonblocking: raise def send(self, data): return self._sock.send(data) def flush(self): if self._wbuf: buffer = "".join(self._wbuf) self._wbuf = [] self.sendall(buffer) def recv(self, size): while True: try: return self._sock.recv(size) except socket.error, e: if (e.args[0] not in socket_errors_nonblocking and e.args[0] not in socket_error_eintr): raise def read(self, size=-1): if size < 0: # Read until EOF buffers = [self._rbuf] self._rbuf = "" if self._rbufsize <= 1: recv_size = self.default_bufsize else: recv_size = self._rbufsize while True: data = self.recv(recv_size) if not data: break buffers.append(data) return "".join(buffers) else: # Read until size bytes or EOF seen, whichever comes first data = self._rbuf buf_len = len(data) if buf_len >= size: self._rbuf = data[size:] return data[:size] buffers = [] if data: buffers.append(data) self._rbuf = "" while True: left = size - buf_len recv_size = max(self._rbufsize, left) data = self.recv(recv_size) if not data: break buffers.append(data) n = len(data) if n >= left: self._rbuf = data[left:] buffers[-1] = data[:left] break buf_len += n return "".join(buffers) def readline(self, size=-1): data = self._rbuf if size < 0: # Read until \n or EOF, whichever comes first if self._rbufsize <= 1: # Speed up unbuffered case assert data == "" buffers = [] while data != "\n": data = self.recv(1) if not data: break buffers.append(data) return "".join(buffers) nl = data.find('\n') if nl >= 0: nl += 1 self._rbuf = data[nl:] return data[:nl] buffers = [] if data: buffers.append(data) self._rbuf = "" while True: data = self.recv(self._rbufsize) if not data: break buffers.append(data) nl = data.find('\n') if nl >= 0: nl += 1 self._rbuf = data[nl:] buffers[-1] = data[:nl] break return "".join(buffers) else: # Read until size bytes or \n or EOF seen, whichever comes first nl = data.find('\n', 0, size) if nl >= 0: nl += 1 self._rbuf = data[nl:] return data[:nl] buf_len = len(data) if buf_len >= size: self._rbuf = data[size:] return data[:size] buffers = [] if data: buffers.append(data) self._rbuf = "" while True: data = self.recv(self._rbufsize) if not data: break buffers.append(data) left = size - buf_len nl = data.find('\n', 0, left) if nl >= 0: nl += 1 self._rbuf = data[nl:] buffers[-1] = data[:nl] break n = len(data) if n >= left: self._rbuf = data[left:] buffers[-1] = data[:left] break buf_len += n return "".join(buffers) class SSL_fileobject(CP_fileobject): """SSL file object attached to a socket object.""" ssl_timeout = 3 ssl_retry = .01 def _safe_call(self, is_reader, call, *args, **kwargs): """Wrap the given call with SSL error-trapping. is_reader: if False EOF errors will be raised. If True, EOF errors will return "" (to emulate normal sockets). """ start = time.time() while True: try: return call(*args, **kwargs) except SSL.WantReadError: # Sleep and try again. This is dangerous, because it means # the rest of the stack has no way of differentiating # between a "new handshake" error and "client dropped". # Note this isn't an endless loop: there's a timeout below. time.sleep(self.ssl_retry) except SSL.WantWriteError: time.sleep(self.ssl_retry) except SSL.SysCallError, e: if is_reader and e.args == (-1, 'Unexpected EOF'): return "" errnum = e.args[0] if is_reader and errnum in socket_errors_to_ignore: return "" raise socket.error(errnum) except SSL.Error, e: if is_reader and e.args == (-1, 'Unexpected EOF'): return "" thirdarg = None try: thirdarg = e.args[0][0][2] except IndexError: pass if thirdarg == 'http request': # The client is talking HTTP to an HTTPS server. raise NoSSLError() raise FatalSSLAlert(*e.args) except: raise if time.time() - start > self.ssl_timeout: raise socket.timeout("timed out") def recv(self, *args, **kwargs): buf = [] r = super(SSL_fileobject, self).recv while True: data = self._safe_call(True, r, *args, **kwargs) buf.append(data) p = self._sock.pending() if not p: return "".join(buf) def sendall(self, *args, **kwargs): return self._safe_call(False, super(SSL_fileobject, self).sendall, *args, **kwargs) def send(self, *args, **kwargs): return self._safe_call(False, super(SSL_fileobject, self).send, *args, **kwargs) class HTTPConnection(object): """An HTTP connection (active socket). socket: the raw socket object (usually TCP) for this connection. wsgi_app: the WSGI application for this server/connection. environ: a WSGI environ template. This will be copied for each request. rfile: a fileobject for reading from the socket. send: a function for writing (+ flush) to the socket. """ rbufsize = -1 RequestHandlerClass = HTTPRequest environ = {"wsgi.version": (1, 0), "wsgi.url_scheme": "http", "wsgi.multithread": True, "wsgi.multiprocess": False, "wsgi.run_once": False, "wsgi.errors": sys.stderr, } def __init__(self, sock, wsgi_app, environ): self.socket = sock self.wsgi_app = wsgi_app # Copy the class environ into self. self.environ = self.environ.copy() self.environ.update(environ) if SSL and isinstance(sock, SSL.ConnectionType): timeout = sock.gettimeout() self.rfile = SSL_fileobject(sock, "rb", self.rbufsize) self.rfile.ssl_timeout = timeout self.wfile = SSL_fileobject(sock, "wb", -1) self.wfile.ssl_timeout = timeout else: self.rfile = CP_fileobject(sock, "rb", self.rbufsize) self.wfile = CP_fileobject(sock, "wb", -1) # Wrap wsgi.input but not HTTPConnection.rfile itself. # We're also not setting maxlen yet; we'll do that separately # for headers and body for each iteration of self.communicate # (if maxlen is 0 the wrapper doesn't check length). self.environ["wsgi.input"] = SizeCheckWrapper(self.rfile, 0) def communicate(self): """Read each request and respond appropriately.""" request_seen = False try: while True: # (re)set req to None so that if something goes wrong in # the RequestHandlerClass constructor, the error doesn't # get written to the previous request. req = None req = self.RequestHandlerClass(self.wfile, self.environ, self.wsgi_app) # This order of operations should guarantee correct pipelining. req.parse_request() if not req.ready: # Something went wrong in the parsing (and the server has # probably already made a simple_response). Return and # let the conn close. return request_seen = True req.respond() if req.close_connection: return except socket.error, e: errnum = e.args[0] if errnum == 'timed out': # Don't error if we're between requests; only error # if 1) no request has been started at all, or 2) we're # in the middle of a request. # See http://www.cherrypy.org/ticket/853 if (not request_seen) or (req and req.started_request): # Don't bother writing the 408 if the response # has already started being written. if req and not req.sent_headers: req.simple_response("408 Request Timeout") elif errnum not in socket_errors_to_ignore: if req and not req.sent_headers: req.simple_response("500 Internal Server Error", format_exc()) return except (KeyboardInterrupt, SystemExit): raise except FatalSSLAlert, e: # Close the connection. return except NoSSLError: if req and not req.sent_headers: # Unwrap our wfile req.wfile = CP_fileobject(self.socket._sock, "wb", -1) if REDIRECT_URL: req.simple_response("301 Moved Permanently", REDIRECT_URL) else: req.simple_response("400 Bad Request", "The client sent a plain HTTP request, but " "this server only speaks HTTPS on this port.") self.linger = True except Exception, e: if req and not req.sent_headers: req.simple_response("500 Internal Server Error", format_exc()) linger = False def close(self): """Close the socket underlying this connection.""" self.rfile.close() if not self.linger: # Python's socket module does NOT call close on the kernel socket # when you call socket.close(). We do so manually here because we # want this server to send a FIN TCP segment immediately. Note this # must be called *before* calling socket.close(), because the latter # drops its reference to the kernel socket. self.socket._sock.close() self.socket.close() else: # On the other hand, sometimes we want to hang around for a bit # to make sure the client has a chance to read our entire # response. Skipping the close() calls here delays the FIN # packet until the socket object is garbage-collected later. # Someday, perhaps, we'll do the full lingering_close that # Apache does, but not today. pass _SHUTDOWNREQUEST = None class WorkerThread(threading.Thread): """Thread which continuously polls a Queue for Connection objects. server: the HTTP Server which spawned this thread, and which owns the Queue and is placing active connections into it. ready: a simple flag for the calling server to know when this thread has begun polling the Queue. Due to the timing issues of polling a Queue, a WorkerThread does not check its own 'ready' flag after it has started. To stop the thread, it is necessary to stick a _SHUTDOWNREQUEST object onto the Queue (one for each running WorkerThread). """ conn = None def __init__(self, server): self.ready = False self.server = server threading.Thread.__init__(self) def run(self): try: self.ready = True while True: conn = self.server.requests.get() if conn is _SHUTDOWNREQUEST: return self.conn = conn try: conn.communicate() finally: conn.close() self.conn = None except (KeyboardInterrupt, SystemExit), exc: self.server.interrupt = exc class ThreadPool(object): """A Request Queue for the CherryPyWSGIServer which pools threads. ThreadPool objects must provide min, get(), put(obj), start() and stop(timeout) attributes. """ def __init__(self, server, min=10, max=-1): self.server = server self.min = min self.max = max self._threads = [] self._queue = Queue.Queue() self.get = self._queue.get def start(self): """Start the pool of threads.""" for i in xrange(self.min): self._threads.append(WorkerThread(self.server)) for worker in self._threads: worker.setName("CP WSGIServer " + worker.getName()) worker.start() for worker in self._threads: while not worker.ready: time.sleep(.1) def _get_idle(self): """Number of worker threads which are idle. Read-only.""" return len([t for t in self._threads if t.conn is None]) idle = property(_get_idle, doc=_get_idle.__doc__) def put(self, obj): self._queue.put(obj) if obj is _SHUTDOWNREQUEST: return def grow(self, amount): """Spawn new worker threads (not above self.max).""" for i in xrange(amount): if self.max > 0 and len(self._threads) >= self.max: break worker = WorkerThread(self.server) worker.setName("CP WSGIServer " + worker.getName()) self._threads.append(worker) worker.start() def shrink(self, amount): """Kill off worker threads (not below self.min).""" # Grow/shrink the pool if necessary. # Remove any dead threads from our list for t in self._threads: if not t.isAlive(): self._threads.remove(t) amount -= 1 if amount > 0: for i in xrange(min(amount, len(self._threads) - self.min)): # Put a number of shutdown requests on the queue equal # to 'amount'. Once each of those is processed by a worker, # that worker will terminate and be culled from our list # in self.put. self._queue.put(_SHUTDOWNREQUEST) def stop(self, timeout=5): # Must shut down threads here so the code that calls # this method can know when all threads are stopped. for worker in self._threads: self._queue.put(_SHUTDOWNREQUEST) # Don't join currentThread (when stop is called inside a request). current = threading.currentThread() while self._threads: worker = self._threads.pop() if worker is not current and worker.isAlive(): try: if timeout is None or timeout < 0: worker.join() else: worker.join(timeout) if worker.isAlive(): # We exhausted the timeout. # Forcibly shut down the socket. c = worker.conn if c and not c.rfile.closed: if SSL and isinstance(c.socket, SSL.ConnectionType): # pyOpenSSL.socket.shutdown takes no args c.socket.shutdown() else: c.socket.shutdown(socket.SHUT_RD) worker.join() except (AssertionError, # Ignore repeated Ctrl-C. # See http://www.cherrypy.org/ticket/691. KeyboardInterrupt), exc1: pass class SSLConnection: """A thread-safe wrapper for an SSL.Connection. *args: the arguments to create the wrapped SSL.Connection(*args). """ def __init__(self, *args): self._ssl_conn = SSL.Connection(*args) self._lock = threading.RLock() for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read', 'renegotiate', 'bind', 'listen', 'connect', 'accept', 'setblocking', 'fileno', 'shutdown', 'close', 'get_cipher_list', 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', 'makefile', 'get_app_data', 'set_app_data', 'state_string', 'sock_shutdown', 'get_peer_certificate', 'want_read', 'want_write', 'set_connect_state', 'set_accept_state', 'connect_ex', 'sendall', 'settimeout'): exec """def %s(self, *args): self._lock.acquire() try: return self._ssl_conn.%s(*args) finally: self._lock.release() """ % (f, f) try: import fcntl except ImportError: try: from ctypes import windll, WinError except ImportError: def prevent_socket_inheritance(sock): """Dummy function, since neither fcntl nor ctypes are available.""" pass else: def prevent_socket_inheritance(sock): """Mark the given socket fd as non-inheritable (Windows).""" if not windll.kernel32.SetHandleInformation(sock.fileno(), 1, 0): raise WinError() else: def prevent_socket_inheritance(sock): """Mark the given socket fd as non-inheritable (POSIX).""" fd = sock.fileno() old_flags = fcntl.fcntl(fd, fcntl.F_GETFD) fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC) class CherryPyWSGIServer(object): """An HTTP server for WSGI. bind_addr: The interface on which to listen for connections. For TCP sockets, a (host, port) tuple. Host values may be any IPv4 or IPv6 address, or any valid hostname. The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if your hosts file prefers IPv6). The string '0.0.0.0' is a special IPv4 entry meaning "any active interface" (INADDR_ANY), and '::' is the similar IN6ADDR_ANY for IPv6. The empty string or None are not allowed. For UNIX sockets, supply the filename as a string. wsgi_app: the WSGI 'application callable'; multiple WSGI applications may be passed as (path_prefix, app) pairs. numthreads: the number of worker threads to create (default 10). server_name: the string to set for WSGI's SERVER_NAME environ entry. Defaults to socket.gethostname(). max: the maximum number of queued requests (defaults to -1 = no limit). request_queue_size: the 'backlog' argument to socket.listen(); specifies the maximum number of queued connections (default 5). timeout: the timeout in seconds for accepted connections (default 10). nodelay: if True (the default since 3.1), sets the TCP_NODELAY socket option. protocol: the version string to write in the Status-Line of all HTTP responses. For example, "HTTP/1.1" (the default). This also limits the supported features used in the response. SSL/HTTPS --------- The OpenSSL module must be importable for SSL functionality. You can obtain it from http://pyopenssl.sourceforge.net/ There are two ways to use SSL: Method One: ssl_context: an instance of SSL.Context. If this is not None, it is assumed to be an SSL.Context instance, and will be passed to SSL.Connection on bind(). The developer is responsible for forming a valid Context object. This approach is to be preferred for more flexibility, e.g. if the cert and key are streams instead of files, or need decryption, or SSL.SSLv3_METHOD is desired instead of the default SSL.SSLv23_METHOD, etc. Consult the pyOpenSSL documentation for complete options. Method Two (shortcut): ssl_certificate: the filename of the server SSL certificate. ssl_privatekey: the filename of the server's private key file. Both are None by default. If ssl_context is None, but ssl_privatekey and ssl_certificate are both given and valid, they will be read on server start, and self.ssl_context will be automatically created from them. ssl_certificate_chain: (optional) the filename of CA's intermediate certificate bundle. This is needed for cheaper "chained root" SSL certificates, and should be left as None if not required. """ protocol = "HTTP/1.1" _bind_addr = "127.0.0.1" version = "CherryPy/3.2.0" ready = False _interrupt = None nodelay = True ConnectionClass = HTTPConnection environ = {} # An SSL.Context instance... ssl_context = None # ...or paths to certificate and private key files ssl_certificate = None ssl_certificate_chain = None ssl_private_key = None def __init__(self, bind_addr, wsgi_app, numthreads=10, server_name=None, max=-1, request_queue_size=5, timeout=10, shutdown_timeout=5): self.requests = ThreadPool(self, min=numthreads or 1, max=max) self.environ = self.environ.copy() if callable(wsgi_app): # We've been handed a single wsgi_app, in CP-2.1 style. # Assume it's mounted at "". self.wsgi_app = wsgi_app else: # We've been handed a list of (path_prefix, wsgi_app) tuples, # so that the server can call different wsgi_apps, and also # correctly set SCRIPT_NAME. warnings.warn("The ability to pass multiple apps is deprecated " "and will be removed in 3.2. You should explicitly " "include a WSGIPathInfoDispatcher instead.", DeprecationWarning) self.wsgi_app = WSGIPathInfoDispatcher(wsgi_app) self.bind_addr = bind_addr if not server_name: server_name = socket.gethostname() self.server_name = server_name self.request_queue_size = request_queue_size self.timeout = timeout self.shutdown_timeout = shutdown_timeout def _get_numthreads(self): return self.requests.min def _set_numthreads(self, value): self.requests.min = value numthreads = property(_get_numthreads, _set_numthreads) def __str__(self): return "%s.%s(%r)" % (self.__module__, self.__class__.__name__, self.bind_addr) def _get_bind_addr(self): return self._bind_addr def _set_bind_addr(self, value): if isinstance(value, tuple) and value[0] in ('', None): # Despite the socket module docs, using '' does not # allow AI_PASSIVE to work. Passing None instead # returns '0.0.0.0' like we want. In other words: # host AI_PASSIVE result # '' Y 192.168.x.y # '' N 192.168.x.y # None Y 0.0.0.0 # None N 127.0.0.1 # But since you can get the same effect with an explicit # '0.0.0.0', we deny both the empty string and None as values. raise ValueError("Host values of '' or None are not allowed. " "Use '0.0.0.0' (IPv4) or '::' (IPv6) instead " "to listen on all active interfaces.") self._bind_addr = value bind_addr = property(_get_bind_addr, _set_bind_addr, doc="""The interface on which to listen for connections. For TCP sockets, a (host, port) tuple. Host values may be any IPv4 or IPv6 address, or any valid hostname. The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if your hosts file prefers IPv6). The string '0.0.0.0' is a special IPv4 entry meaning "any active interface" (INADDR_ANY), and '::' is the similar IN6ADDR_ANY for IPv6. The empty string or None are not allowed. For UNIX sockets, supply the filename as a string.""") def start(self): """Run the server forever.""" # We don't have to trap KeyboardInterrupt or SystemExit here, # because cherrpy.server already does so, calling self.stop() for us. # If you're using this server with another framework, you should # trap those exceptions in whatever code block calls start(). self._interrupt = None # Select the appropriate socket if isinstance(self.bind_addr, basestring): # AF_UNIX socket # So we can reuse the socket... try: os.unlink(self.bind_addr) except: pass # So everyone can access the socket... try: os.chmod(self.bind_addr, 0777) except: pass info = [(socket.AF_UNIX, socket.SOCK_STREAM, 0, "", self.bind_addr)] else: # AF_INET or AF_INET6 socket # Get the correct address family for our host (allows IPv6 addresses) host, port = self.bind_addr try: info = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) except socket.gaierror: # Probably a DNS issue. Assume IPv4. info = [(socket.AF_INET, socket.SOCK_STREAM, 0, "", self.bind_addr)] self.socket = None msg = "No socket could be created" for res in info: af, socktype, proto, canonname, sa = res try: self.bind(af, socktype, proto) except socket.error, msg: if self.socket: self.socket.close() self.socket = None continue break if not self.socket: raise socket.error, msg # Timeout so KeyboardInterrupt can be caught on Win32 self.socket.settimeout(1) self.socket.listen(self.request_queue_size) # Create worker threads self.requests.start() self.ready = True while self.ready: self.tick() if self.interrupt: while self.interrupt is True: # Wait for self.stop() to complete. See _set_interrupt. time.sleep(0.1) if self.interrupt: raise self.interrupt def bind(self, family, type, proto=0): """Create (or recreate) the actual socket object.""" self.socket = socket.socket(family, type, proto) prevent_socket_inheritance(self.socket) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) if self.nodelay: self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if (self.ssl_context is None and self.ssl_certificate and self.ssl_private_key): if SSL is None: raise ImportError("You must install pyOpenSSL to use HTTPS.") # See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442473 self.ssl_context = SSL.Context(SSL.SSLv23_METHOD) self.ssl_context.use_privatekey_file(self.ssl_private_key) if self.ssl_certificate_chain: self.ssl_context.load_verify_locations(self.ssl_certificate_chain) self.ssl_context.use_certificate_file(self.ssl_certificate) if self.ssl_context is not None: self.socket = SSLConnection(self.ssl_context, self.socket) self.populate_ssl_environ() # If listening on the IPV6 any address ('::' = IN6ADDR_ANY), # activate dual-stack. See http://www.cherrypy.org/ticket/871. if (not isinstance(self.bind_addr, basestring) and self.bind_addr[0] == '::' and family == socket.AF_INET6): try: self.socket.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) except (AttributeError, socket.error): # Apparently, the socket option is not available in # this machine's TCP stack pass self.socket.bind(self.bind_addr) def tick(self): """Accept a new connection and put it on the Queue.""" try: s, addr = self.socket.accept() prevent_socket_inheritance(s) if not self.ready: return if hasattr(s, 'settimeout'): s.settimeout(self.timeout) environ = self.environ.copy() # SERVER_SOFTWARE is common for IIS. It's also helpful for # us to pass a default value for the "Server" response header. if environ.get("SERVER_SOFTWARE") is None: environ["SERVER_SOFTWARE"] = "%s WSGI Server" % self.version # set a non-standard environ entry so the WSGI app can know what # the *real* server protocol is (and what features to support). # See http://www.faqs.org/rfcs/rfc2145.html. environ["ACTUAL_SERVER_PROTOCOL"] = self.protocol environ["SERVER_NAME"] = self.server_name if isinstance(self.bind_addr, basestring): # AF_UNIX. This isn't really allowed by WSGI, which doesn't # address unix domain sockets. But it's better than nothing. environ["SERVER_PORT"] = "" else: environ["SERVER_PORT"] = str(self.bind_addr[1]) # optional values # Until we do DNS lookups, omit REMOTE_HOST environ["REMOTE_ADDR"] = addr[0] environ["REMOTE_PORT"] = str(addr[1]) conn = self.ConnectionClass(s, self.wsgi_app, environ) self.requests.put(conn) except socket.timeout: # The only reason for the timeout in start() is so we can # notice keyboard interrupts on Win32, which don't interrupt # accept() by default return except socket.error, x: if x.args[0] in socket_error_eintr: # I *think* this is right. EINTR should occur when a signal # is received during the accept() call; all docs say retry # the call, and I *think* I'm reading it right that Python # will then go ahead and poll for and handle the signal # elsewhere. See http://www.cherrypy.org/ticket/707. return if x.args[0] in socket_errors_nonblocking: # Just try again. See http://www.cherrypy.org/ticket/479. return if x.args[0] in socket_errors_to_ignore: # Our socket was closed. # See http://www.cherrypy.org/ticket/686. return raise def _get_interrupt(self): return self._interrupt def _set_interrupt(self, interrupt): self._interrupt = True self.stop() self._interrupt = interrupt interrupt = property(_get_interrupt, _set_interrupt, doc="Set this to an Exception instance to " "interrupt the server.") def stop(self): """Gracefully shutdown a server that is serving forever.""" self.ready = False sock = getattr(self, "socket", None) if sock: if not isinstance(self.bind_addr, basestring): # Touch our own socket to make accept() return immediately. try: host, port = sock.getsockname()[:2] except socket.error, x: if x.args[1] != "Bad file descriptor": raise else: # Note that we're explicitly NOT using AI_PASSIVE, # here, because we want an actual IP to touch. # localhost won't work if we've bound to a public IP, # but it will if we bound to '0.0.0.0' (INADDR_ANY). for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res s = None try: s = socket.socket(af, socktype, proto) # See http://groups.google.com/group/cherrypy-users/ # browse_frm/thread/bbfe5eb39c904fe0 s.settimeout(1.0) s.connect((host, port)) s.close() except socket.error: if s: s.close() if hasattr(sock, "close"): sock.close() self.socket = None self.requests.stop(self.shutdown_timeout) def populate_ssl_environ(self): """Create WSGI environ entries to be merged into each request.""" ssl_environ = { "wsgi.url_scheme": "https", "HTTPS": "on", # pyOpenSSL doesn't provide access to any of these AFAICT ## 'SSL_PROTOCOL': 'SSLv2', ## SSL_CIPHER string The cipher specification name ## SSL_VERSION_INTERFACE string The mod_ssl program version ## SSL_VERSION_LIBRARY string The OpenSSL program version } if self.ssl_certificate: # Server certificate attributes cert = open(self.ssl_certificate, 'rb').read() cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert) ssl_environ.update({ 'SSL_SERVER_M_VERSION': cert.get_version(), 'SSL_SERVER_M_SERIAL': cert.get_serial_number(), ## 'SSL_SERVER_V_START': Validity of server's certificate (start time), ## 'SSL_SERVER_V_END': Validity of server's certificate (end time), }) for prefix, dn in [("I", cert.get_issuer()), ("S", cert.get_subject())]: # X509Name objects don't seem to have a way to get the # complete DN string. Use str() and slice it instead, # because str(dn) == "" dnstr = str(dn)[18:-2] wsgikey = 'SSL_SERVER_%s_DN' % prefix ssl_environ[wsgikey] = dnstr # The DN should be of the form: /k1=v1/k2=v2, but we must allow # for any value to contain slashes itself (in a URL). while dnstr: pos = dnstr.rfind("=") dnstr, value = dnstr[:pos], dnstr[pos + 1:] pos = dnstr.rfind("/") dnstr, key = dnstr[:pos], dnstr[pos + 1:] if key and value: wsgikey = 'SSL_SERVER_%s_DN_%s' % (prefix, key) ssl_environ[wsgikey] = value self.environ.update(ssl_environ) SABnzbd-0.7.20/email/badfetch-da.tmpl0000644000000000000000000000072712433712601017341 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Dårlig URL Fetch E-mail skabelon for SABnzbd ## Dette er en Cheetah skabelon ## Dokumentation: http://sabnzbd.wikidot.com/email-templates ## ## Linjeskift og blanktegn er betydelig! ## ## Dette er email headers To: $to From: $from Date: $date Subject: SABnzbd kunne ikke hente en NZB X-priority: 5 X-MS-priority: 5 ## Efter dette kommer body, den tomme linje kræves! Hej, SABnzbd kunne ikke hente NZB fra $url. Fejl meddelelsen er: $msg Farvel SABnzbd-0.7.20/email/badfetch-de.tmpl0000644000000000000000000000104412433712601017336 0ustar00usergroup00000000000000#encoding UTF-8 ## Translation by Thomas Lucke (Lucky) ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd konnte eine NZB-Datei nicht herunterladen X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hallo, SABnzbd konnte die NZB-Datei von $url nicht herrunterladen. Die Fehlermeldung war: $msg SABnzbd-0.7.20/email/badfetch-en.tmpl0000644000000000000000000000072212433712601017352 0ustar00usergroup00000000000000## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd failed to fetch an NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has failed to retrieve the NZB from $url. The error message was: $msg Bye SABnzbd-0.7.20/email/badfetch-es.tmpl0000644000000000000000000000104512433712601017356 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Plantilla de correo para URLs incorrectas de SABnzbd ## Esta es una plantilla Cheetah ## Documentación: http://sabnzbd.wikidot.com/email-templates ## ## Líneas nuevas y espacios en blanco IMPORTAN! ## ## Estas son las cabeceras del email To: $to From: $from Date: $date Subject: SABnzbd ha encontrado un error al recuperar un NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hola, SABnzbd ha encontrado un error al descargar un NZB desde $url. El error ha sido: $msg Un saludo SABnzbd-0.7.20/email/badfetch-fi.tmpl0000644000000000000000000000103012433712601017337 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Virheellisen URL-noudon sähköpostin pohja SABnzbd ohjelmalle ## Tämä on Cheetah pohja ## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates ## ## Rivinvaihdot ja välilyönnit ovat merkitseviä! ## ## Tässä on sähköpostin otsikkotiedot To: $to From: $from Date: $date Subject: SABnzbd ei voinut hakea NZB tiedostoa X-priority: 5 X-MS-priority: 5 ## Tämän jälkeen tulee viestin sisältö, tyhjä rivi on pakollinen! Hei, SABnzbd ei voinut hakea NZB tiedostoa osoitteesta $url. Virheviesti: $msg SABnzbd-0.7.20/email/badfetch-fr.tmpl0000644000000000000000000000074212433712601017361 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd failed to fetch an NZB X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has failed to retrieve the NZB from $url. The error message was: $msg Bye SABnzbd-0.7.20/email/badfetch-nb.tmpl0000644000000000000000000000075112433712601017351 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd ikke klarte å hente en NZB fil X-priority: 5 X-MS-priority: 5 ## Etter dette kommer meldingen, den tomme linjen er nødvendig! Hei, SABnzbd klarte ikke å hente NZB fra $url. Feilmeldingen var: $msg Hade SABnzbd-0.7.20/email/badfetch-nl.tmpl0000644000000000000000000000100312433712601017352 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Ongeldige URL Ophaal Email sjabloon voor SABnzbd ## Dit is een Cheetah sjabloon ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ## Lege regels en spaties zijn belangrijk! ## ## Dit zijn de email koppen To: $to From: $from Date: $date Subject: Ophalen van NZB door SABnzbd is mislukt X-priority: 5 X-MS-priority: 5 ## Hierna komt het bericht, de lege regel is noodzakelijk! Hi, Het is SABnzbd niet gelukt om een NZB bestand op te halen van $url. De foutmelding was $msg Sorry SABnzbd-0.7.20/email/badfetch-pl.tmpl0000644000000000000000000000077612433712601017374 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Szablon wiadomosci blednego pobierania URL SABnzbd ## To jest szablon Cheetah ## Dokumentacja: http://sabnzbd.wikidot.com/email-templates ## ## Znaki nowego wiersza i biale znaki maja znaczenie! ## ## To sa naglówki wiadomosci To: $to From: $from Date: $date Subject: SABnzbd nie udalo sie pobrac pliku NZB X-priority: 5 X-MS-priority: 5 ## Po tym nastepuje tresc. Pusty wiersz jest wymagany! Czesc, SABnzbd nie udalo sie pobrac pliku NZB z $url. Komunikat bledu: $msg Do uslyszenia. SABnzbd-0.7.20/email/badfetch-pt_BR.tmpl0000644000000000000000000000101312433712601017750 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Template de e-mail de busca em URL ruim para SABnzbd ## Este é um template Cheetah ## Documentação: http://sabnzbd.wikidot.com/email-templates ## ## Novas linhas e espaços em branco são significativos! ## ## Estes são os cabeçalhos de e-mail To: $to From: $from Date: $date Subject: SABnzbd falhou ao buscar um NZB X-priority: 5 X-MS-priority: 5 ## Depois daqui vem o corpo. A linha vazia é necessária! Olá, SABnzbd não conseguiu obter o NZB de $url. A mensagem de erro foi: $msg Tchau! SABnzbd-0.7.20/email/badfetch-ro.tmpl0000644000000000000000000000103612433712601017367 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Adresã URL Gresitã sablon Email pentru SABnybd ## Acesta este un sablon Cheetah ## Documentatie : http://sabnzbd.wikidot.com/email-templates ## ## Liniile noi si spatiile sunt importante! ## ## Acestea sunt headerele email Cãtre: $to De la: $from Datã: $date Subiect: SABnzbd nu a reusit sã descarce un NZB X-priority: 5 X-MS-priority: 5 ## Dupã aceasta urmeazã corpul email, linia goalã e necesarã ! Salut, SABnzbd nu a putut descãrca NZB-ul de la adresa $url. Mesajul de eroare a fost: $msg La revedere! SABnzbd-0.7.20/email/badfetch-sv.tmpl0000644000000000000000000000100512433712601017373 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Bad URL Fetch Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers Till: $to Från: $from Datum: $date Ämne: SABnzbd misslyckades med att hämta en NZB -fil X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hej, SABnzbd har misslyckats med att hämta NZB -filen från $url. Felmeddelandet lyder: $msg Hej då SABnzbd-0.7.20/email/email-da.tmpl0000644000000000000000000000205112433712601016660 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Standard Email skabelon til SABnzbd ## Dette er en Cheetah skabelon ## Dokumentation: http://sabnzbd.wikidot.com/email-templates ## ## Linjeskift og blanktegn er betydelig! ## ## Disse er e-mail-headerne To: $to From: $from Date: $date Subject: SABnzbd har job $name X-priority: 5 X-MS-priority: 5 ## Efter dette kommer body, den tomme linje kræves! Hej, SABnzbd har hentet "$name" SABnzbd kunne ikke hente "$name" Færdig kl. $end_time Hentet $size Resultat af job: Etape $stage $result Output fra bruger script "$script" (Exit code = $script_ret): $script_output Enjoy! Sorry! SABnzbd-0.7.20/email/email-de.tmpl0000644000000000000000000000232612433712601016671 0ustar00usergroup00000000000000#encoding UTF-8 ## Translation by Severin Heiniger ## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd Auftrag $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd hat "$name" heruntergeladen SABnzbd konnte "$name" nicht herunterladen Fertiggestellt: $end_time Heruntergeladen: $size Ergebnis des Auftrages: Stufe $stage $result Ausgabe des Benutzerskripts "$script" (beendet mit Code $script_ret): $script_output Viel Spass! Entschuldigung! SABnzbd-0.7.20/email/email-en.tmpl0000644000000000000000000000205712433712601016704 0ustar00usergroup00000000000000## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has job $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has downloaded "$name" SABnzbd has failed to download "$name" Finished at $end_time Downloaded $size Results of the job: Stage $stage $result Output from user script "$script" (Exit code = $script_ret): $script_output Enjoy! Sorry! SABnzbd-0.7.20/email/email-es.tmpl0000644000000000000000000000224212433712601016705 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Plantilla de correo predeterminada para SABnzbd ## This a Cheetah template ## Documentación: http://sabnzbd.wikidot.com/email-templates ## ## !Los saltos de línea y espacios en blanco son significativos¡ ## ## Cabeceras de correo electrónico To: $to From: $from Date: $date Subject: SABnzbd job $name X-priority: 5 X-MS-priority: 5 ## !Después de esto viene el cuerpo del mensaje, la línea en blanco es necesaria! Hola, SABnzbd he bajado "$name" SABnzbd fallo en bajar "$name" Terminado a las $end_time $size bajado Resultado de la transferencia: Etapa $stage $result Producción desde el script de usuario "$script" (Exit code = $script_ret): $script_output Que lo disfrutes! Perdon! SABnzbd-0.7.20/email/email-fi.tmpl0000644000000000000000000000224112433712601016673 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Oletus sähköpostipohja SABnzbd:lle ## Tämä on Cheetah pohja ## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates ## ## Rivinvaihdot ja välilyönnit ovat merkitseviä! ## ## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa! To: $to From: $from Date: $date Subject: SABnzbd on työssä $name X-priority: 5 X-MS-priority: 5 ## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on pakollinen! Hei, SABnzbd on ladannut "$name" SABnzbd on epäonnistunut "$name" latauksessa Valmistui $end_time Ladattu $size Työn lopputulos: Tila $stage $result Käyttäjän skriptin tuloste "$script" (Exit code = $script_ret): $script_output Nauti! Pahoittelut! SABnzbd-0.7.20/email/email-fr.tmpl0000644000000000000000000000223112433712601016703 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Template Email pour SABnzbd ## Ceci est un template Cheetah ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Les retours à la ligne et les espaces sont importants ! ## ## Entêtes de l'email To: $to From: $from Date: $date Subject: SABnzbd SuccèsEchec du téléchargement $name X-priority: 5 X-MS-priority: 5 ## Après cela vient le contenu, la ligne vide est nécessaire! Bonjour, SABnzbd a téléchargé avec succès "$name" SABnzbd a téléchargé sans succès "$name" Terminé à $end_time Téléchargé $size Résultat du téléchargement : Etape $stage $result Sortie du script utilisateur "$script" (Code Retour = $script_ret): $script_output A bientôt ! Désolé ! SABnzbd-0.7.20/email/email-nb.tmpl0000644000000000000000000000213412433712601016675 0ustar00usergroup00000000000000#encoding UTF-8 ## Translation by ProtX ## ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd har jobb $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hei, SABnzbd har lastet ned "$name" SABnzbd mislyktes med å laste ned "$name" Ferdig $end_time Nedlastet $size Resultat av jobben: Steg $stage $result Utskrift fra brukerskript "$script" (Exit code = $script_ret): $script_output Gratulerer! Synd! SABnzbd-0.7.20/email/email-nl.tmpl0000644000000000000000000000216712433712601016715 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Standaard Email sjabloon voor SABnzbd ## Dit is een Cheetah sjabloon ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ## Lege regels en witruimte zijn belangrijk! ## ## Dit zijn de email koppen To: $to From: $from Date: $date Subject: SABnzbd: opdracht $name is X-priority: 5 X-MS-priority: 5 ## Hier onder volgt de hoofdtekst, de lege regel is noodzakelijk! Hallo, SABnzbd heeft "$name" gedownload SABnzbd is niet geslaagd in het downloaden van "$name" Klaar om $end_time Hoeveelheid gedownload $size Resultaat van de opdracht: Fase $stage $result Bericht van het script "$script" (Exit code = $script_ret): $script_output Veel plezier! Sorry! SABnzbd-0.7.20/email/email-pl.tmpl0000644000000000000000000000206112433712601016710 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Domyslny szablon maila w SABnzbd ## To jest szablon Cheetah ## Dokumentacja: http://sabnzbd.wikidot.com/email-templates ## ## Znak nowego wiersza i spacji ma znaczenie! ## ## To sa naglowki maila To: $to From: $from Date: $date Subject: SABnzbd zadanie $name X-priority: 5 X-MS-priority: 5 ## Nastepnie tresc maila, wymagana jest pusta linia! Czesc, SABnzbd pobral "$name" SABnzbd nie pobral "$name" Zakonczono o $end_time Pobrano $size Rezultat zadania: Etap $stage $result Odpowiedz od skryptu "$script" (kod wyjscia = $script_ret): $script_output Baw sie dobrze! Przykro mi! SABnzbd-0.7.20/email/email-pt_BR.tmpl0000644000000000000000000000216312433712601017306 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Template padrão de e-mail para SABnzbd ## Este é um template Cheetah ## Documentação: http://sabnzbd.wikidot.com/email-templates ## ## Novas linhas e espaços em branco são significativos! ## ## Estes são os cabeçalhos de e-mail To: $to From: $from Date: $date Subject: SABnzbd a tarefa $name X-priority: 5 X-MS-priority: 5 ## Depois daqui vem o corpo. A linha vazia é necessária! Olá, SABnzbd baixou "$name" SABnzbd falhou no download de "$name" Completado em $end_time Baixados $size Resultados da tarefa: Etapa $stage $result Retorno do script de usuário "$script" (Código de retorno = $script_ret): $script_output Aproveite! Lamento! SABnzbd-0.7.20/email/email-ro.tmpl0000644000000000000000000000217612433712601016724 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Sablon Email Original pentru SABnzbd ## Acesta este un Sablon Cheetah ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ##Rândurile noi si caracterele spatiu sunt importante! ## ## Acestea sunt antetele email To: $to From: $from Date: $date Subject: SABnzbd sarcina $name X-priority: 5 X-MS-priority: 5 ## Dupã acesta urmeazã continutul, este necesar o linie goalã! Salut, SABnzbd a descãrcat "$name" SABnzbd nu a reusit sã descarce "$name" Terminat la $end_time Mãrime $size Rezultatele sarcinii: Stagiu $stage $result Rezultatul script-ului utilizatorului "$script" (Exit code = $script_ret): $script_output Bucurati-vã! Ne pare rau! SABnzbd-0.7.20/email/email-sv.tmpl0000644000000000000000000000220212433712601016722 0ustar00usergroup00000000000000#encoding UTF-8 ## Translation by Andreas Lindberg andypandyswe@gmail.com ## Default Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers Till: $to Från: $from Datum: $date Ämne: SABnzbd has job $name X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hej, SABnzbd har laddat ned "$name" SABnzbd misslyckades med att ladda ned "$name" Färdig $end_time Nedladdat $size Resultat: Stage $stage $result Utmatning från användarskript "$script" (Exit code = $script_ret): $script_output Lycka till! Beklagar! SABnzbd-0.7.20/email/rss-da.tmpl0000644000000000000000000000103712433712601016403 0ustar00usergroup00000000000000#encoding UTF-8 ## ## RSS Email skabelon til SABnzbd ## Dette er Cheetah skabelon ## Dokumentation: http://sabnzbd.wikidot.com/email-templates ## ## Linjeskift og blanktegn er betydelig! ## ## Dette er email headers To: $to From: $from Date: $date Subject: SABnzbd har tilføjet $antal jobs til køen X-priority: 5 X-MS-priority: 5 ## Efter dette kommer body, den tomme linje kræves! Hej, SABnzbd har tilføjet $antal job(s) til køen. De er fra RSS feed "$feed". $job Farvel SABnzbd-0.7.20/email/rss-de.tmpl0000644000000000000000000000111212433712601016401 0ustar00usergroup00000000000000#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hallo, SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt. Sie stammen vom RSS-Feed "$feed". $job SABnzbd-0.7.20/email/rss-en.tmpl0000644000000000000000000000103212433712601016414 0ustar00usergroup00000000000000## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd has added $amount jobs to the queue X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hi, SABnzbd has added $amount job(s) to the queue. They are from RSS feed "$feed". $job Bye SABnzbd-0.7.20/email/rss-es.tmpl0000644000000000000000000000117412433712601016430 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Plantilla de correo RSS para SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## !Los saltos de línea y espacios en blanco son significativos¡ ## ## Cabeceras de correo electrónico To: $to From: $from Date: $date Subject: SABnzbd he añadido $amount transferencia(s) a la cola X-priority: 5 X-MS-priority: 5 ## !Después de esto viene el cuerpo del mensaje, la línea en blanco es necesaria! Hola, SABnzbd he añadido $amount transferencia(s) a la cola. Originaron desde el RSS "$feed". $job Adios SABnzbd-0.7.20/email/rss-fi.tmpl0000644000000000000000000000117212433712601016415 0ustar00usergroup00000000000000#encoding UTF-8 ## ## RSS sähköpostipohja SABnzbd:lle ## Tämä on Cheetah pohja ## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates ## ## Rivinvaihdot ja välilyönnit ovat merkitseviä! ## ## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa! To: $to From: $from Date: $date Subject: SABnzbd on lisännyt $amount työtä jonoon X-priority: 5 X-MS-priority: 5 ## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on pakollinen! Hei, SABnzbd on lisännyt $amount työtä jonoon. Ne ovat RSS syötteestä "$feed". $job Heippa SABnzbd-0.7.20/email/rss-fr.tmpl0000644000000000000000000000114612433712601016427 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Template Email pour SABnzbd ## Ceci est un template Cheetah ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Les retours à la ligne et les espaces sont importants ! ## ## Entêtes de l'email To: $to From: $from Date: $date Subject: SABnzbd a ajouté $amount fichier(s) à la file d'attente X-priority: 5 X-MS-priority: 5 ## Après cela vient le contenu, la ligne vide est nécessaire! Bonjour, SABnzbd a ajouté $amount fichier(s) à la file d'attente. Ils proviennent du Flux RSS "$feed". $job Au Revoir SABnzbd-0.7.20/email/rss-nb.tmpl0000644000000000000000000000106012433712601016412 0ustar00usergroup00000000000000#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers To: $to From: $from Date: $date Subject: SABnzbd har lagt $amount jobber til køen X-priority: 5 X-MS-priority: 5 ## Etter dette kommer meldingen, den tomme linjen er nødvendig! Hei, SABnzbd har lagt $amount jobb(er) til køen. Disse er fra RSS feeden "$feed". $job Hade SABnzbd-0.7.20/email/rss-nl.tmpl0000644000000000000000000000110312433712601016422 0ustar00usergroup00000000000000#encoding UTF-8 ## ## RSS Email sjabloon voor SABnzbd ## Dit is een Cheetah sjabloon ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ## Lege regels en spaties zijn belangrijk! ## ## Dit zijn de email koppen To: $to From: $from Date: $date Subject: SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd X-priority: 5 X-MS-priority: 5 ## Hierna komt de inhoud, de lege regel is benodigd! Hallo, SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd. Ze komen van de RSS bron "$feed". $job SABnzbd-0.7.20/email/rss-pl.tmpl0000644000000000000000000000105612433712601016433 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Szablon wiadomosci RSS dla SABnzbd ## To jest szablon Cheetah ## Dokumentacja: http://sabnzbd.wikidot.com/email-templates ## ## Znak nowego wiersza i spacji ma znaczenie! ## ## To sa naglowki maila To: $to From: $from Date: $date Subject: SABnzbd dodal $amount zadan/zadania do kolejki X-priority: 5 X-MS-priority: 5 ## Nastepnie tresc maila, wymagana jest pusta linia! Czesc, SABnzbd dodal $amount zadanie/zadan do kolejki. Pochodza one z wiadomosci RSS "$feed". $job Nara SABnzbd-0.7.20/email/rss-pt_BR.tmpl0000644000000000000000000000125312433712601017025 0ustar00usergroup00000000000000#encoding UTF-8 ## ## Template de e-mail RSS para SABnzbd ## Este é um template Cheetah ## Documentação: http://sabnzbd.wikidot.com/email-templates ## ## Novas linhas e espaços em branco são significativos! ## ## Estes são os cabeçalhos de e-mail To: $to From: $from Date: $date Subject: SABnzbd adicionou $amount à fila X-priority: 5 X-MS-priority: 5 ## Depois daqui vem o corpo. A linha vazia é necessária! Olá, SABnzbd adicionou $amount à fila. Elas são do feed RSS "$feed". $job Tchau! SABnzbd-0.7.20/email/rss-ro.tmpl0000644000000000000000000000113012433712601016431 0ustar00usergroup00000000000000#encoding UTF-8 ## Sablon Email RSS pentru SABnzbd ## Acesta este un sablon Cheetah ## Documentatie: http://sabnzbd.wikidot.com/email-templates ## ## Rândurile noi si caracterele spatiu sunt importante! ## ## Acestea sunt antetele email To: $to From: $from Date: $date Subject: SABnzbd a adãugat $amount sarcini în coadã X-priority: 5 X-MS-priority: 5 ## Dupã acesta urmeazã continutul, este necesar o linie goalã! Salut, SABnzbd a adãugat $amount sarcinã(e) în coadã. Ele sunt din fluxuri RSS "$feed". $job La revedere ! SABnzbd-0.7.20/email/rss-sv.tmpl0000644000000000000000000000105512433712601016447 0ustar00usergroup00000000000000#encoding UTF-8 ## ## RSS Email template for SABnzbd ## This a Cheetah template ## Documentation: http://sabnzbd.wikidot.com/email-templates ## ## Newlines and whitespace are significant! ## ## These are the email headers Till: $to Från: $from Datum: $date Ämne: SABnzbd har lagt till $amount jobb i kön X-priority: 5 X-MS-priority: 5 ## After this comes the body, the empty line is required! Hej, SABnzbd har lagt till $amount jobb i kön. De kommer från RSS feed "$feed". $job Hej då SABnzbd-0.7.20/gntp/notifier.py0000644000000000000000000001715512433712602016377 0ustar00usergroup00000000000000""" The gntp.notifier module is provided as a simple way to send notifications using GNTP .. note:: This class is intended to mostly mirror the older Python bindings such that you should be able to replace instances of the old bindings with this class. `Original Python bindings `_ """ import gntp import socket import logging import platform __all__ = [ 'mini', 'GrowlNotifier', ] logger = logging.getLogger(__name__) def mini(description, applicationName='PythonMini', noteType="Message", title="Mini Message", applicationIcon=None, hostname='localhost', password=None, port=23053, sticky=False, priority=None, callback=None, notificationIcon=None, identifier=None): """Single notification function Simple notification function in one line. Has only one required parameter and attempts to use reasonable defaults for everything else :param string description: Notification message .. warning:: For now, only URL callbacks are supported. In the future, the callback argument will also support a function """ growl = GrowlNotifier( applicationName=applicationName, notifications=[noteType], defaultNotifications=[noteType], applicationIcon=applicationIcon, hostname=hostname, password=password, port=port, ) result = growl.register() if result is not True: return result return growl.notify( noteType=noteType, title=title, description=description, icon=notificationIcon, sticky=sticky, priority=priority, callback=callback, identifier=identifier, ) class GrowlNotifier(object): """Helper class to simplfy sending Growl messages :param string applicationName: Sending application name :param list notification: List of valid notifications :param list defaultNotifications: List of notifications that should be enabled by default :param string applicationIcon: Icon URL :param string hostname: Remote host :param integer port: Remote port """ passwordHash = 'MD5' socketTimeout = 3 def __init__(self, applicationName='Python GNTP', notifications=[], defaultNotifications=None, applicationIcon=None, hostname='localhost', password=None, port=23053): self.applicationName = applicationName self.notifications = list(notifications) if defaultNotifications: self.defaultNotifications = list(defaultNotifications) else: self.defaultNotifications = self.notifications self.applicationIcon = applicationIcon self.password = password self.hostname = hostname self.port = int(port) def _checkIcon(self, data): ''' Check the icon to see if it's valid If it's a simple URL icon, then we return True. If it's a data icon then we return False ''' logger.debug('Checking icon') return data.startswith('http') def register(self): """Send GNTP Registration .. warning:: Before sending notifications to Growl, you need to have sent a registration message at least once """ logger.debug('Sending registration to %s:%s', self.hostname, self.port) register = gntp.GNTPRegister() register.add_header('Application-Name', self.applicationName) for notification in self.notifications: enabled = notification in self.defaultNotifications register.add_notification(notification, enabled) if self.applicationIcon: if self._checkIcon(self.applicationIcon): register.add_header('Application-Icon', self.applicationIcon) else: id = register.add_resource(self.applicationIcon) register.add_header('Application-Icon', id) if self.password: register.set_password(self.password, self.passwordHash) self.add_origin_info(register) self.register_hook(register) return self._send('register', register) def notify(self, noteType, title, description, icon=None, sticky=False, priority=None, callback=None, identifier=None): """Send a GNTP notifications .. warning:: Must have registered with growl beforehand or messages will be ignored :param string noteType: One of the notification names registered earlier :param string title: Notification title (usually displayed on the notification) :param string description: The main content of the notification :param string icon: Icon URL path :param boolean sticky: Sticky notification :param integer priority: Message priority level from -2 to 2 :param string callback: URL callback .. warning:: For now, only URL callbacks are supported. In the future, the callback argument will also support a function """ logger.debug('Sending notification [%s] to %s:%s', noteType, self.hostname, self.port) assert noteType in self.notifications notice = gntp.GNTPNotice() notice.add_header('Application-Name', self.applicationName) notice.add_header('Notification-Name', noteType) notice.add_header('Notification-Title', title) if self.password: notice.set_password(self.password, self.passwordHash) if sticky: notice.add_header('Notification-Sticky', sticky) if priority: notice.add_header('Notification-Priority', priority) if icon: if self._checkIcon(icon): notice.add_header('Notification-Icon', icon) else: id = notice.add_resource(icon) notice.add_header('Notification-Icon', id) if description: notice.add_header('Notification-Text', description) if callback: notice.add_header('Notification-Callback-Target', callback) if identifier: notice.add_header('Notification-Coalescing-ID', identifier) self.add_origin_info(notice) self.notify_hook(notice) return self._send('notify', notice) def subscribe(self, id, name, port): """Send a Subscribe request to a remote machine""" sub = gntp.GNTPSubscribe() sub.add_header('Subscriber-ID', id) sub.add_header('Subscriber-Name', name) sub.add_header('Subscriber-Port', port) if self.password: sub.set_password(self.password, self.passwordHash) self.add_origin_info(sub) self.subscribe_hook(sub) return self._send('subscribe', sub) def add_origin_info(self, packet): """Add optional Origin headers to message""" packet.add_header('Origin-Machine-Name', platform.node()) packet.add_header('Origin-Software-Name', 'gntp.py') packet.add_header('Origin-Software-Version', gntp.__version__) packet.add_header('Origin-Platform-Name', platform.system()) packet.add_header('Origin-Platform-Version', platform.platform()) def register_hook(self, packet): pass def notify_hook(self, packet): pass def subscribe_hook(self, packet): pass def _send(self, messagetype, packet): """Send the GNTP Packet""" packet.validate() data = packet.encode() #logger.debug('To : %s:%s <%s>\n%s', self.hostname, self.port, packet.__class__, data) #Less verbose logger.debug('To : %s:%s <%s>', self.hostname, self.port, packet.__class__) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(self.socketTimeout) s.connect((self.hostname, self.port)) s.send(data) recv_data = s.recv(1024) while not recv_data.endswith("\r\n\r\n"): recv_data += s.recv(1024) response = gntp.parse_gntp(recv_data) s.close() #logger.debug('From : %s:%s <%s>\n%s', self.hostname, self.port, response.__class__, response) #Less verbose logger.debug('From : %s:%s <%s>', self.hostname, self.port, response.__class__) if type(response) == gntp.GNTPOK: return True if response.error()[0] == '404' and 'disabled' in response.error()[1]: # Ignore message saying that user has disabled this class return True logger.error('Invalid response: %s', response.error()) return response.error() if __name__ == '__main__': # If we're running this module directly we're likely running it as a test # so extra debugging is useful logging.basicConfig(level=logging.DEBUG) mini('Testing mini notification') SABnzbd-0.7.20/gntp/__init__.py0000644000000000000000000003300012433712602016302 0ustar00usergroup00000000000000import re import hashlib import time import StringIO __version__ = '0.8' #GNTP/ [:][ :.] GNTP_INFO_LINE = re.compile( 'GNTP/(?P\d+\.\d+) (?PREGISTER|NOTIFY|SUBSCRIBE|\-OK|\-ERROR)' + ' (?P[A-Z0-9]+(:(?P[A-F0-9]+))?) ?' + '((?P[A-Z0-9]+):(?P[A-F0-9]+).(?P[A-F0-9]+))?\r\n', re.IGNORECASE ) GNTP_INFO_LINE_SHORT = re.compile( 'GNTP/(?P\d+\.\d+) (?PREGISTER|NOTIFY|SUBSCRIBE|\-OK|\-ERROR)', re.IGNORECASE ) GNTP_HEADER = re.compile('([\w-]+):(.+)') GNTP_EOL = '\r\n' class BaseError(Exception): def gntp_error(self): error = GNTPError(self.errorcode, self.errordesc) return error.encode() class ParseError(BaseError): errorcode = 500 errordesc = 'Error parsing the message' class AuthError(BaseError): errorcode = 400 errordesc = 'Error with authorization' class UnsupportedError(BaseError): errorcode = 500 errordesc = 'Currently unsupported by gntp.py' class _GNTPBuffer(StringIO.StringIO): """GNTP Buffer class""" def writefmt(self, message="", *args): """Shortcut function for writing GNTP Headers""" self.write((message % args).encode('utf8', 'replace')) self.write(GNTP_EOL) class _GNTPBase(object): """Base initilization :param string messagetype: GNTP Message type :param string version: GNTP Protocol version :param string encription: Encryption protocol """ def __init__(self, messagetype=None, version='1.0', encryption=None): self.info = { 'version': version, 'messagetype': messagetype, 'encryptionAlgorithmID': encryption } self.headers = {} self.resources = {} def __str__(self): return self.encode() def _parse_info(self, data): """Parse the first line of a GNTP message to get security and other info values :param string data: GNTP Message :return dict: Parsed GNTP Info line """ match = GNTP_INFO_LINE.match(data) if not match: raise ParseError('ERROR_PARSING_INFO_LINE') info = match.groupdict() if info['encryptionAlgorithmID'] == 'NONE': info['encryptionAlgorithmID'] = None return info def set_password(self, password, encryptAlgo='MD5'): """Set a password for a GNTP Message :param string password: Null to clear password :param string encryptAlgo: Supports MD5, SHA1, SHA256, SHA512 """ hash = { 'MD5': hashlib.md5, 'SHA1': hashlib.sha1, 'SHA256': hashlib.sha256, 'SHA512': hashlib.sha512, } self.password = password self.encryptAlgo = encryptAlgo.upper() if not password: self.info['encryptionAlgorithmID'] = None self.info['keyHashAlgorithm'] = None return if not self.encryptAlgo in hash.keys(): raise UnsupportedError('INVALID HASH "%s"' % self.encryptAlgo) hashfunction = hash.get(self.encryptAlgo) password = password.encode('utf8') seed = time.ctime() salt = hashfunction(seed).hexdigest() saltHash = hashfunction(seed).digest() keyBasis = password + saltHash key = hashfunction(keyBasis).digest() keyHash = hashfunction(key).hexdigest() self.info['keyHashAlgorithmID'] = self.encryptAlgo self.info['keyHash'] = keyHash.upper() self.info['salt'] = salt.upper() def _decode_hex(self, value): """Helper function to decode hex string to `proper` hex string :param string value: Human readable hex string :return string: Hex string """ result = '' for i in range(0, len(value), 2): tmp = int(value[i:i + 2], 16) result += chr(tmp) return result def _decode_binary(self, rawIdentifier, identifier): rawIdentifier += '\r\n\r\n' dataLength = int(identifier['Length']) pointerStart = self.raw.find(rawIdentifier) + len(rawIdentifier) pointerEnd = pointerStart + dataLength data = self.raw[pointerStart:pointerEnd] if not len(data) == dataLength: raise ParseError('INVALID_DATA_LENGTH Expected: %s Recieved %s' % (dataLength, len(data))) return data def _validate_password(self, password): """Validate GNTP Message against stored password""" self.password = password if password == None: raise AuthError('Missing password') keyHash = self.info.get('keyHash', None) if keyHash is None and self.password is None: return True if keyHash is None: raise AuthError('Invalid keyHash') if self.password is None: raise AuthError('Missing password') password = self.password.encode('utf8') saltHash = self._decode_hex(self.info['salt']) keyBasis = password + saltHash key = hashlib.md5(keyBasis).digest() keyHash = hashlib.md5(key).hexdigest() if not keyHash.upper() == self.info['keyHash'].upper(): raise AuthError('Invalid Hash') return True def validate(self): """Verify required headers""" for header in self._requiredHeaders: if not self.headers.get(header, False): raise ParseError('Missing Notification Header: ' + header) def _format_info(self): """Generate info line for GNTP Message :return string: """ info = u'GNTP/%s %s' % ( self.info.get('version'), self.info.get('messagetype'), ) if self.info.get('encryptionAlgorithmID', None): info += ' %s:%s' % ( self.info.get('encryptionAlgorithmID'), self.info.get('ivValue'), ) else: info += ' NONE' if self.info.get('keyHashAlgorithmID', None): info += ' %s:%s.%s' % ( self.info.get('keyHashAlgorithmID'), self.info.get('keyHash'), self.info.get('salt') ) return info def _parse_dict(self, data): """Helper function to parse blocks of GNTP headers into a dictionary :param string data: :return dict: """ dict = {} for line in data.split('\r\n'): match = GNTP_HEADER.match(line) if not match: continue key = unicode(match.group(1).strip(), 'utf8', 'replace') val = unicode(match.group(2).strip(), 'utf8', 'replace') dict[key] = val return dict def add_header(self, key, value): if isinstance(value, unicode): self.headers[key] = value else: self.headers[key] = unicode('%s' % value, 'utf8', 'replace') def add_resource(self, data): """Add binary resource :param string data: Binary Data """ identifier = hashlib.md5(data).hexdigest() self.resources[identifier] = data return 'x-growl-resource://%s' % identifier def decode(self, data, password=None): """Decode GNTP Message :param string data: """ self.password = password self.raw = data parts = self.raw.split('\r\n\r\n') self.info = self._parse_info(data) self.headers = self._parse_dict(parts[0]) def encode(self): """Encode a generic GNTP Message :return string: GNTP Message ready to be sent """ buffer = _GNTPBuffer() buffer.writefmt(self._format_info()) #Headers for k, v in self.headers.iteritems(): buffer.writefmt('%s: %s', k, v) buffer.writefmt() #Resources for resource, data in self.resources.iteritems(): buffer.writefmt('Identifier: %s', resource) buffer.writefmt('Length: %d', len(data)) buffer.writefmt() buffer.write(data) buffer.writefmt() buffer.writefmt() return buffer.getvalue() class GNTPRegister(_GNTPBase): """Represents a GNTP Registration Command :param string data: (Optional) See decode() :param string password: (Optional) Password to use while encoding/decoding messages """ _requiredHeaders = [ 'Application-Name', 'Notifications-Count' ] _requiredNotificationHeaders = ['Notification-Name'] def __init__(self, data=None, password=None): _GNTPBase.__init__(self, 'REGISTER') self.notifications = [] if data: self.decode(data, password) else: self.set_password(password) self.add_header('Application-Name', 'pygntp') self.add_header('Notifications-Count', 0) def validate(self): '''Validate required headers and validate notification headers''' for header in self._requiredHeaders: if not self.headers.get(header, False): raise ParseError('Missing Registration Header: ' + header) for notice in self.notifications: for header in self._requiredNotificationHeaders: if not notice.get(header, False): raise ParseError('Missing Notification Header: ' + header) def decode(self, data, password): """Decode existing GNTP Registration message :param string data: Message to decode """ self.raw = data parts = self.raw.split('\r\n\r\n') self.info = self._parse_info(data) self._validate_password(password) self.headers = self._parse_dict(parts[0]) for i, part in enumerate(parts): if i == 0: continue # Skip Header if part.strip() == '': continue notice = self._parse_dict(part) if notice.get('Notification-Name', False): self.notifications.append(notice) elif notice.get('Identifier', False): notice['Data'] = self._decode_binary(part, notice) #open('register.png','wblol').write(notice['Data']) self.resources[notice.get('Identifier')] = notice def add_notification(self, name, enabled=True): """Add new Notification to Registration message :param string name: Notification Name :param boolean enabled: Enable this notification by default """ notice = {} notice['Notification-Name'] = u'%s' % name notice['Notification-Enabled'] = u'%s' % enabled self.notifications.append(notice) self.add_header('Notifications-Count', len(self.notifications)) def encode(self): """Encode a GNTP Registration Message :return string: Encoded GNTP Registration message """ buffer = _GNTPBuffer() buffer.writefmt(self._format_info()) #Headers for k, v in self.headers.iteritems(): buffer.writefmt('%s: %s', k, v) buffer.writefmt() #Notifications if len(self.notifications) > 0: for notice in self.notifications: for k, v in notice.iteritems(): buffer.writefmt('%s: %s', k, v) buffer.writefmt() #Resources for resource, data in self.resources.iteritems(): buffer.writefmt('Identifier: %s', resource) buffer.writefmt('Length: %d', len(data)) buffer.writefmt() buffer.write(data) buffer.writefmt() buffer.writefmt() return buffer.getvalue() class GNTPNotice(_GNTPBase): """Represents a GNTP Notification Command :param string data: (Optional) See decode() :param string app: (Optional) Set Application-Name :param string name: (Optional) Set Notification-Name :param string title: (Optional) Set Notification Title :param string password: (Optional) Password to use while encoding/decoding messages """ _requiredHeaders = [ 'Application-Name', 'Notification-Name', 'Notification-Title' ] def __init__(self, data=None, app=None, name=None, title=None, password=None): _GNTPBase.__init__(self, 'NOTIFY') if data: self.decode(data, password) else: self.set_password(password) if app: self.add_header('Application-Name', app) if name: self.add_header('Notification-Name', name) if title: self.add_header('Notification-Title', title) def decode(self, data, password): """Decode existing GNTP Notification message :param string data: Message to decode. """ self.raw = data parts = self.raw.split('\r\n\r\n') self.info = self._parse_info(data) self._validate_password(password) self.headers = self._parse_dict(parts[0]) for i, part in enumerate(parts): if i == 0: continue # Skip Header if part.strip() == '': continue notice = self._parse_dict(part) if notice.get('Identifier', False): notice['Data'] = self._decode_binary(part, notice) #open('notice.png','wblol').write(notice['Data']) self.resources[notice.get('Identifier')] = notice class GNTPSubscribe(_GNTPBase): """Represents a GNTP Subscribe Command :param string data: (Optional) See decode() :param string password: (Optional) Password to use while encoding/decoding messages """ _requiredHeaders = [ 'Subscriber-ID', 'Subscriber-Name', ] def __init__(self, data=None, password=None): _GNTPBase.__init__(self, 'SUBSCRIBE') if data: self.decode(data, password) else: self.set_password(password) class GNTPOK(_GNTPBase): """Represents a GNTP OK Response :param string data: (Optional) See _GNTPResponse.decode() :param string action: (Optional) Set type of action the OK Response is for """ _requiredHeaders = ['Response-Action'] def __init__(self, data=None, action=None): _GNTPBase.__init__(self, '-OK') if data: self.decode(data) if action: self.add_header('Response-Action', action) class GNTPError(_GNTPBase): """Represents a GNTP Error response :param string data: (Optional) See _GNTPResponse.decode() :param string errorcode: (Optional) Error code :param string errordesc: (Optional) Error Description """ _requiredHeaders = ['Error-Code', 'Error-Description'] def __init__(self, data=None, errorcode=None, errordesc=None): _GNTPBase.__init__(self, '-ERROR') if data: self.decode(data) if errorcode: self.add_header('Error-Code', errorcode) self.add_header('Error-Description', errordesc) def error(self): return (self.headers.get('Error-Code', None), self.headers.get('Error-Description', None)) def parse_gntp(data, password=None): """Attempt to parse a message as a GNTP message :param string data: Message to be parsed :param string password: Optional password to be used to verify the message """ match = GNTP_INFO_LINE_SHORT.match(data) if not match: raise ParseError('INVALID_GNTP_INFO') info = match.groupdict() if info['messagetype'] == 'REGISTER': return GNTPRegister(data, password=password) elif info['messagetype'] == 'NOTIFY': return GNTPNotice(data, password=password) elif info['messagetype'] == 'SUBSCRIBE': return GNTPSubscribe(data, password=password) elif info['messagetype'] == '-OK': return GNTPOK(data) elif info['messagetype'] == '-ERROR': return GNTPError(data) raise ParseError('INVALID_GNTP_MESSAGE') SABnzbd-0.7.20/icons/nzb.ico0000644000000000000000000006664012433712535015646 0ustar00usergroup00000000000000 V 00 %2  X h8iPNG  IHDR\rfJIDATx{%W]׼M.$y'(()x[| (AAD-)*_hXX j eB6d7l^dwv^~9{fv?}Nn#@iikvPb J @(1%@Pb J @(1%@SZtPw6ҥy_;iw\14"V+"be,ŹI:/_fP( |F}1}#tkЇ hf=ų3Q>I_f[3 RSxQܸ5.p; 7;'|Q|òT]>)6n7Jlv. \Dc(O~]J P0z(n>/Tc[j\Tx=}=(.C"( 9;+ϡCQl J ;z9vfNs\n1>̝DqQz,o(  ( ׳l߳c\lkh7Lry2rA>q"6 )J>.k?kgWvƏ87AEc.zG;ҁG{n\{V.W]w qK7q: 6~+LS(9{NMxo?NEb\ Biy /D{ wrزcy|[G/$jvQ@8[xF.D"N \@n xoYVA@Cx'~2WKx: .4p)ػwz@($]ܲ'Чy$4 &pi}\.2zD翃 (&*c"_04p) p/U `1wZxZCa~ZI0h@/]s1&N|cl] Mq`\gRv;R?'0Is<9]@@੟f'Vz]9o `ˀ:x9ɛTˀAA%r$AۃbntD=|\OCA`E 5R,4VIZGˀm"sq+9b"P1p`^֩28  \@nZ_L.K8,ˀ@rỴ@}i63p|e}.&@9և:R. ]Sr9Bw҆( ,JS'8.4'wT/WX/((@Chy KC>_Iᨃ s0л?/NqyAOvnW9g5 4@ABi&"z 6ajogyd6tKN5Vc\?1 &@Iq0dy(`\樏AbbkzU]ɠqV"yu"`$@kIq0. U7H@QMVgrݙ9cϤ {l;7 F*@@/d"А{"6KpTD1Q"t2w8J䲟Ěm9*sd h8$@sZ`rPg8v qZ*]|v*2X7G=nkvjk.ԛ|BA4/]AWJtTo6&`C\Ҡ,钆iބ^"0Q  P'  p xǮ/ 0Բc-pLĝ(.^ngtz^ 6q0  @U@3re*vDEtQ9W6xC:%W3S|sT}%ˀX#@r pئk qT@Y)6CSEc{`!ۺ WHTz}(@A hqx /R2`y 6#S~|Soo]^&u%j $@6 h]F#; t6 (jx$G4xSs$ny٭a"X2m'NV<  `p HZ,q.@߮Ԁ1E6#fxVҬlo{lO Nd*BECNZ𧑫 ]ޝR-^I;| iܡ~2N9=ounAYwFqa_r#S$ >ygm"}6&X1hp׈Ӑs !knVExyPs.e16?IߖTTO$#i7Kj403'!)@+ ,tni _ƧHCuQtq6 *mUHN !47 LJ_nlgk8m]Y',Z'T_-Bo2(n~gR¦iX>E*fWF*Sss}l0/WlgBTY_CV{ۮoWtUc;q1TzӁ @KplEk56.*&5`˂S< f7a[öu-y'YeY {P70ߊ ( % 5(mHӒC"i!7T7O͟} XwjV!Xa ].z;_Ge@ZN!2EIn{#-+@VEz(ӻ\mcאda{PތlKuo5՟[jkzO^5x0*So_*X}wPPNNmgYygz?T gOQ^+gǭਏY'aM6olW' Zgm`Yoõ678VW;(gr[}nNVN'~]{dB=l@ń" 8tk;}LuF[o/91zL=] rNT'|^|YV+Oޙ 36t`b^xZߊG.ja^(NT*r6uK]]@?yNz>v&xDb @Uy ;5wۣ8x9.Nz9{Ws컠z}R@ֆnnr[o1nA6Tج"X4vk\s3L%}Q*Mr&/s]L,o/Q8S|Jr֥  E7MQ'.w󠡵"TI]7t xXmISm 3._"4d޼7Pv4[<,]E'yЈyXXF~(Nг:hOU{! @ 8|u;7KEm$Sf"xġX~o;!< "M>y AR EfigyOI1K}Y]9  OJ|OF=@W82*|8Tv:qW壧K{m;(gS"5˽ajlĻC4]*&)6=آO);SoJoKu*g=2BWUFqu<űwЊy3vȸdL!6̗*j}gul~S/t)|ns W-܌;{;˪%j'!@~@ N9(\I=+PClqs G^ 醶St-̮quU{7ܗG5'H):$Qޘj9\9@FRֹcћB І޷NyAR\Tef?@o&= ztl _F5i UVglw8v>=;L[9-@+.P -g3B~58vqa]lY?]˩qolciȶ˃5`w9hfYAA*X~& `ҷ_GrwIԛyj4x^ U% ܰ4rv p { I@Á)7l' ܰ_Q?P=pP_<8 @}@}@}@}@}@}@}@}@}@}@}WDz*|lyJ _E'h^j}!/WWZ_ UDz*|lyJ _E'h^j}!/WWZ_ UDz*|lyJ _E'h^j}!/WWZ_ UDzUoVP@^3@7E+w /ly՛;L6мMjy p&h^h<8 4zSrZW)ZC-OyAdͫܡ' gUoVP@^3@7E+w /ly՛;L6мMjy p&h^h<8 4zSrZW^R? g敗h /ly((Z p&h^y)J9VW^R? g敗h /ly((Z p&h^y)J9VW^R? g敗h /ly((Z p&h^y)J9Vɖ E'[B_ɖ E'[B_ɖ E'[Bh %@Pb.@Pb J @(1%@Pb J @(1%yIENDB`PNG  IHDR>aIDATxy}ǿ3;Ձ$$@ $t6l1`c|" G;88DP?eW8N\ )M!"iZi%v=Gy\ݿٙ~>w'@|-B J%s \|.>PRHY6p)օhF%׈4ΎÈcebRJ+QUٌݑZ|+B]!ߒ;9 B%T4a[Uz{S!+^ wpcl ](+UQ58;N`?@E6ԬB0+pSk<.\ A^$.ZfЫb(ħ쏒NfGS>" /Tg+#uy+H$lWb)!^n#F80DGxeMI>FY p'd*Wr嗷-`}L&e)*['!P?6iy ~36>MUP^5kpf/#˰wnxx7-c y?|RIn,-P@8v>DQ>ڌ\9j_ւM +WSP{u'pRj/Kz)pu^;ϓ8MV`n;q;Yd>ʕsjn{g3/>7=wh La,E)1p.kÑX(Q[n/<گ[6b>a>{=SPFN⩙a<@{8 ԯZ>3L.3]͸u1FE377%$ 0m0}dA'C67 1ǥ@Q4}_6] @<=3).&\uj+)8b6=8m n@`ud>E#ϼ{:0O/ia2aj[ CWPЗb\;{p^ CP@`ӷq^x[ϣo}J k\6n.fnxK8z`^FN\:҂Xb&(Y>pJܯ%O4ANt>H.@F ;wery,ԕx:(ۃɠwvXU8Ubk I` <.#kn>,=ʧ,lH` շr ~ @]^,9_~r qeA t9n+K2V c8eD x,ڿ Ĵ']``KlĞ{~tōs,`.?r`hP"r?0 p }.`Y~|% WV {8QFLz YZI Z:o:%@ % 8$r,'X` zSxq_1۪?W,[HY3g@u@p> 1@H ٲGMuL6SM~bH=^`+eͩDɞW FbϛJ .{A$y-lYkPplMFWby5]S5TF1;/{\`şq n3MǸgOXg{ =A 2 0pklK YY@9(if![H1mۀ3$SQc b.9T+o5Y|lZW6*7lmCHJOn+0v>!slw7{  4-Rf=ul%9lk6;Pdl=tX|.R:Kd,]_L"H:o<''z(ЕmXťIe-j0qś.LBҪ˙6l[ogZ AZX1g51 DK6CL7(̎>3UZJb<iWU4H%d 疈=XZg)6- M4wpK;}.+D*LX8<'0BbM|%:yWGZvǑzܔ%_yn(W W4:ty6t&O sk!h pf 6lYn >${.@TS7k.ӤgzsAf 96+ bQ9ѷ4.l}>Q>Xm@_s+/O^`!+Yg5^>63.3y^W(+1Y>8%ɼeS=}PJ+_2 /+ylsPon,ejmk;  CA&@\蘽j]Uk樳qQ%!r{0_"q;v|+-d#x3`)63ﲯ7@l9 kHt@-<$;da2"(< BA*`-h/GVul*7I[x* 16JiM 1}Gt=lk&`qו[yˏGNB,r.e1n[j/IE eAۏBmAR (JPݢwU: P-Nû\.pyg/[8?:=A[3Dy[mir$MR(Y]D5w0.~R7(h!sX@]d_h.!v5<O`/)G;e?*olGo'+!Wtgֹ574PuQJfߵ0֑ur%'O/=2?e+~+צR&:uqr e5V)؜ Ѿ8E5ҍi:E99Re+pm6<Vcwl*:Ay5SG&Ren] FVHB`L ǿ=E=}J*񞦝Ii5Vi"+hŷmө"U6 IQ!"SLoJ |\8`]ۚJ;ұ{ADlM03˪2,R-RY? l y}7hiNC6X3;:^6;i|Dv4z)r%_ ~,*9f-V ؔmKkGtrXn'd?&~Ei ^7lLbY#sqsv`#W%\<B*4NPr\>/Wrl6NSksd"Z,\H1 _. }"k|_+ . }"k/P豆"k\\#_@"kXrq|]? ʦ,rJHr%K\%R\)W@d+x>%sY0x\|.>K%sJeq2IENDB`(0` $- <84 H@@ ```000YYY@???######vvv@???111mmmyyy{{{ooo@??????@?????? ***///@??????@??????@?????? www@??????vvv@***vvv@######vvv@yuw{~x}x}x}x}x}x}x}y}y}y}y}y}y}y}z}ysw{{{{yz{~|~|~`__4   BFA|-CDCCBAAA??><<;988555/z~ . y-W!NG8 GM J2IIGGGGFFEDDBBA@>=<:9:4z}1 1n)]$V"S! 8 ^M N4HECCCCCBBA@@?==;;:97660xsv/ {.h'd&X"S!S"!E$MM\#:JFEFEBBAA@@??==<;:986560 8}/g'd%`%W"T!T" <Gk(2///}-2A@???>=<=<;99855541I:5 4 3 ,  Aa&W"V!S!T!PT"1 'HKD;;;=0N?@====<:;:98765432266432x-W#N KKFGGIN [ 2,i+c+b*^-j8W"=A@AAA@=:7786553311/~/{-v+u*g'K:#%b,`+b+c.i </T!>FDDDDDDB<644433220/|.w,s*r+d&O (0P?HEEEEEEFGC:212110.|-y+t*p*o*a%M)/M?IFFFFFFFGHG@6/~.//}-y,t*p*l)l)_%J'.J>JHHHHHHHGHHII@3u+s*v+u*r*m)i(i']$G&-G=MIIIIIIIIIIIILJ@1m)c&d&g'g'f&Z"F%-D=NKKKKKKKKKKKJJMNKA4o)Y#R!X"V!E$,B=OLLLLLLLLLLLLLLLMOPH=3p*V!B#)>=QMMMMMMMMMMMMMMMMMMPRQNn)4")<=SNNNNNNNNNNNNNNNNNNNNPTu+1")8<SOOOOOOOOOOOOOOOOOOOOQRr*0! (7=XPPPPPPPPPPPPPPPPPPPPQSs+/ '4A#lQRRRRRRRRRRRRRRRRRRQUXt*, &2FN Y\\\\\\\\\\\\\\\\\\ Y hiv&+ %/Gu6x9y9y9y9y9y9y9y9y9y9y9y9y9y9y9y9y9y9y4uT8}x"( $-GgiiiiiiiiiiiiiiiiiifEz' $* Lg%  &w'[I}R) ,+0[ m/h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+h+i,m,M,.5 c*"! """""""""""""""""""" %/T r!                     l??( @   ">n)CJGFEDBA?=<:86l(Y"8b -Ft+CFEDDCBA@=<;875p*d&Y"=r)K/EFDCBBA@?=<;9754m)h'`$T!C n C_$4546@@?>=<<:975431/|-t*c&_%Z#X"S!R %+XA><@M<>>>=;98754310}.x,m)HCDCAD ;    $R >CCCBA;654310.y,t*j(Ix    L@GEEEEE@6110.y,t*o)f&G bH@IGGGGGHF=2y-v+t*o)j(b%D gF@KIIIIIIJKH;/l)d&b%]$A gBAMKKKKKKKKLMK@2j'Y"@ g?AOMMMMMMMMMMNOOL28 g <BROOOOOOOOOOOOOS95g 8B YQQQQQQQQQQQQQe94g 6B[TVVVVVVVVVVVTl:2g 4C"h,o,o,o,o,o,o,o,o,o,o,o"h;0g 0E=.`  ,8edddddddddddn1,; 6PQ P P P P P P P P P P P R N6  g!"""""""""""""! h?????(   G3=@@><:6h'd&MLGF;B?:538<L:>HFD<1v+p*d&?@LIJKE8v,]$9APMMMOOL3 4B \PQQPQs> 0GA -=aQQQQQb87CAAAABE3SABnzbd-0.7.20/icons/sabnzbd.ico0000644000000000000000000011367012433712535016474 0ustar00usergroup00000000000000 FV dF00 %]   hPPNG  IHDR\rfEIDATx}i$us}],O xhJ,LIl J e̐lR a & @$@$@`űG9vjz9}/3pppزHlt6088la8pppఅa #- G[088la8pppఅa #- G[[RI$RkG;mSؖJa֝H=@|>F!Ey=m2ŵ ,g1Oe=ϽS-Adl:4w5ԡ]"AS~ n$ՔF!2^i2e2&&y\fq5̈́8t& 2r6ƶ&moƃ &hCR]Fx&4_KK6}#I }ZFlHS=tFaR4KiI$Ryz+&2&ju4Xõ[dD>1Y"$b>5Iꧨokk Dܿ?>;" c!ZXƋ K"^&5pȁcٍ.BM~v4d*~Tho!Up2şM9r.9aT"k 㿱:ܙ]zVL546 65pZd'Nn?Iߟ}?n%. p ?g tFDQʝq *p =s 8s xpaT%AL 3r Kxf_,*܀ njxHI||U_7;~"^nq~cMC$ Vz5ڤ`LVF^|K^'28?Zt&*HZ,$fii94?i7]75'ӎ;weĿI P  |62,stԍ};ko]|g 0< L ɋnAxe4>giEfP5MMhnk6|@M\K.)  |(ǽpCjߥ_x*piHgEπx)2>r>xqbOG|ZNї5cBoog%ש-nфJ`^2@ C# vy9ʓXxKq2(ۑO/=wmI`Ydu<&MirsA5 ܀XJ,/^(3;vwPߥR]^[&67{6E!^M)Yr6FbOg8KQCMMo#Yɶ&<ڄKY'fm]>O~wF[<#ѷ`7^,^ x5a.EA ;|s|/-,DoɋLe@8ZqJ*!D? Wġ~:-/kW $+dr')oIx"X nN0߉O6a"{ @OrO(VO؁]7\qXspVy;  iBM&Lgh~BA0Mtx6"a8JC^?oue;$,q_ d!6LԪ6z!'WS$}+_&v`@MAS YxR @xypL6"" p[la&V=jv=Ldṿ&? `>O@6aIiX+ _ṯϿi'% T# `?ֈ F$ N~8l(=D 7x"d  k#"*'`@f<ݏA$1hڃ{s `ß]peRI@ϣpL|x xcR81Hi0 x}( ]p"#쳂x -y wL ?O8n(@+N-h>|ˆ1@pS MB!я?eL$0wDE $n@G1Fh@b,ӶW.$CGI1G5&? lPp/l`&@j.o!H]&`Wͤ%^yVt9BpVpVt$P[H3> \Z?쒘&F0@IA7ܺOݭ  &^$@l!|OMϫs # S]w,Ӗ}? `Vu,F30<g@U zfqtc![x.MjԌN#t;s?(f}NEbq `~ٮ >9v11S:S۸Y,ABSn,ƀgQQ"0)/O5 L Y!Mb8~tv9-ΊDd n:Z Tdq*/'{ҕOy9\̖ , { D w(\&݊C84첟4Zkya[]wyWg(cJ R hd9dߖq.1GŠ"Vc,@^K`pa"vC`v -YMN9gJk'g S2s=ipIͺT<P$>y3k]2xVh  ^{ DGxOIp:;{㳢%Uilx90՟|y#%`PPsru &$s:1thI,/ . \UjF{ŗQi9}iL TqKy$ϛVB|-y>$-@\L ޛĪ@t,pZem@"Cz[W9O9Yu@ S T,@ LWL'-{wɠtF X'clg@(o"3PBͮ3/pĬs(ca)Z|4S@0%`t#B>NIAp*#!*@YsLЕ Ou4|s }:"p Vƽ,3r[Ypr~=ݜ"Sr%5I@]~=x  '']9%lL9@X Ij@+>w Wҗ{~o>~A5݁VAy=( `C6 Lcb &}L@5`h 7xJf"n"2Vz2L &1:wLF%}y_گ|`Q4o9 #ءx@jPEUWSPS3rBo e$ 7uP_n 0Q `" 3SbU &lm: n? U/|3r[ʠl_دAKJpNzJr|(/ ipo2N<"13ߐ+Joj7SiW˹|{(5}rMs>f aV   20ʣYLL #xb~ux(h㣘TlӶؖE˦v-^}Oas JZuP| WbjB798 "%xBN^`3|[leVWiL \]k~-&g@8ؕ>iGPL@/-e8,KDYIj4 2!1GDh)U&<|Q6PL/yRk/eK/Q[6) Q0+Q5s(#y9 O`@H@>*yz>r|cܥ3,I8vY֪$]3d>}fKZvj@JDb(VGs ;d#I~"͒&$Zͷ_G_.-LiZ̡u.\ &:e oB D XA,%v~CF乳B@|b]}G.יz96"GmB42u6zϭ~:[_Mʺ"LtB3֠TU}V"+b7")9'58sI4p0@xH$>(I(@ޘL7 bMP-l Х᫙vuM b_g%yD@D Ws,$y" c`vSDܓLʵo'x)vA Rl)sTU=uZJg@Pj4@eЏ RaJ5vN0{k2|z`B@Y!EJ `f.c oI8G;ڒ 'HN 2@ݸH;Zpg{3N%/&%EF<:з PO+beDvV܋5g_Vp lDX< P r.(TXS%:ej `EwYWUH>ʿ犬xw󨱁 0([L ,QH{TGi ` Gzbp~~ !Cd3u}mܒirg<3i,3)+2N?&jiO@C=vR*Rm;V[PZq(>.*WJ>B @c'D*p$EUdP ^N}z BWiyZfRPQ܂市XG%`2s\S#JC8K:.!Hce"!:n>)Ly#DX"".`HiaitJllEP_]r wា&mk-D mdtm%Ks} g$wu͊/|2To#'hoH~!W2ƗzHX3-U%eW KbЮ7jPP*]zb^ uD.5xr ߻b"T gw%ׇ>աl׭(olAώnCۿ$Cs#\Kpq""&9m[еtRHE%eU؅3={J.aA%_KZ^0VJbP(%JlT{PFiXj/q$>?4MHf&e{gw>JDpmKxB v"P !(kN) cЅ{ ځ1| S XSRK+!;C@ɗ[v6+P#2O;?1;?:kCt%P-oǡ~&TERk ISd1汶_ ]u6.t/W8"'pFWu&ﷷTg3:桷KvƉ*SXɇՁ}Ƶu?SW qcPFT6 %A"(hnȑ]@yY9'U B{s+:el WfhjC\ß\ƳkB|Od| >4<]"Z+(|.S|x% m"$x Db9ϸ% @WHE T$uUڜq+.f\ȗN}VV=`bz;.}pXvFȥ& B&oh6<`oR)#C5W20J 䈤$+Y$qm h) Cq zE7O(D+UQ&Z{0[ܯf@ZIz\ WsKWZ뚭ޒ Hd#& ]Xk0[0`k+_[7IEuzb7`eV3531:#3rn{u/`||/yx.&VdQֵvQA{1Ï "J ~-WQ@I1G kuĘ=!*ssr 0yKcj(a^9 )҂pi o_;&x ؎| ~cA?!世k- UU;2Q 8Kk_)[l$c΢J ׉MU $H=UeYƜvߣG" cV?Wrem 7(}^}Mṹ%F]z;[Nm؀:l31܁VN^u$D c_]u`k>WeȦ  *cS&!H`L%Pn!,dSa^9E\^vB]kw]APP =3ԬjX°E\ ^ˤ^%y H-~Zy6ޮfhmuI48ʦԍ 88iP7ҖdItey y|Wݐ*oum.`%)J$Е@1D.$ 3XH@W9$`@ihL}mRPQ ^$4X^σF' o ЉOԼMS8R3X\b޺8$MҟmW\T`$vԮ>|78NJ,}~2aMZM*egWI "0 "\!u]Ŵ[0gDZ.]3 {TΜMoKܱqr[ I>CZޕQ-:dϣVDTD\f7` "F 6b\Jm$@<$6ԲF{V>P#PjP E.|g% %(~:h ށjϯCFP5OcvKx8ޙ[۴qՍ[H%#5iũF&\WpyA]޾u\Fjӣ q?ACηcVa!%&\  zv_Zs7C/!M(Ҵdj*8qODYai|C㳸B{Ccx+'$?GG oBu-M褖n2O;p2QQA]{8D*  vF`>7 L D%"VRƠYb Q+pE|`OJ|}zAq/N-`|fyyo/,Ro6$(Rhơxx wކ:t7L/΋ tuz ݧZݰ;(;L)W|etgmQe^i/JbH@^ C j)@ΦҼ/~:#U GiΏLI|ot oG!pwrU?c.wM h%H=X_;d2a_S+p>!k j"+ z! L2ؕ@XƠ\(]a*bbx-5 _{`ܚ16!ިZJ="e}ˈX vz۱{[;{zy@'m'# c*%:E㣶9>Jo\H ؂%]dFtW@0 ʈ)T3Rk=,U@I?:קb|YGa=BL7oE1ޅݍA'qH28.gb/)\۾/\ P6V -@D *@"|~u*$RPxNF2z&j0ěړ O 14t;t=NaWfJXPu:[1ӆcpG=d%@:8W)Mxt'pjhd,߶RDy|z3[gT8.Z (sAu|T%4U~m}tb>*6yϾ07羽WH]啈H),,,c(޺H ޘ[S{9 >9o zNCCCڷuF K@;# Ce$Z@o1S4KСJībX00L}ns3ITiK'`N(@aX2\&ej/^ERoO]"wEWkb Rkтӏ5aOk#vsAYϚʋyyR[ 4F=cVvyjc mJ@]2#;Ե#@5_8=jbT˟)>lzs,13#x(.-y8_u7_%\ducooN ]=)Kz0t.A/PB;"|ATRAF%}%($TG9eQW1ZoP/sHI_ù87>f.tU:d櫄? F݇mÓ 8XD-.|C5jnBuVlY)EWbw{X= $J`Aik5 xm1 ^=E ?-[ ~Cvva߿8xGc_U7_%\H".G޿hjD_shB,n%K.x RfK[lFZ|:պ:QH D % ٔg ʌBa$0ω+.>\hJZ~p7_71g>=ӿ&|+KD򿋌=xG;[p"fS~coS>`?5hram"_yQFQ;DQì1h@ P_>SA}aOS)cN@n+_Ȉ>&J_ZI,O,`ȹQvyghb?wpUwU†,H)Lً{-x {EHeM D\]!G$R َ,E e -韮JvлW+ϊV l3LR|?;s0~_BĵV\5$-`/|x[nu$P>P @!N>u8C8a(h¨ y͐kDu "*B$BfpP~@x9+p/_FsbIZ~R "Y\x8xb/5櫄 ]֞Zf]}xonфD@4D~~W`PLAA?0D *l;JJq˰%`1y K)Q ǕO __UrOP֕q?K`W[-*:Wߧw:֧ UᖅGn'ÉRQg 2L[a@I T"Y5s{~*&(/ &1R1l\&R|q]kc38 1}}3B~7!-͍э[vKN.A;N ӏ7FOP: ĕ~ Q*2S˿H>wq _;Cxmfӯ"]}AejGSS:q\w0: 8HS݄?8@d Fat~(ƌlЌ  غBff#]$#=<+CӸB#S8wh>q:H\>ܻo?@J`C*`4JՈx} u0ؑ`PkJ>~ 0SM, ZT@r>( !x/_F?J`%JPƾL( B%ÆMOϣΓah gƧnzOQ}׵L|Itn]8@.MhnLuͰKӍq@,WNA.o5I 0V郎7%P *àaW㬶[+F/e13ƅQ;Y4ثF-6m(N~y4!VܷjiDC $n?Hϫh{.o#Sj(` UTRqu((@@9*(5ª:*  \˟c2 ?:'g^VcH?hb3*'O51}8}`;nőOcjbMX.Gq@\+N\  kʼn+6aq8qE\&,#8 'ڄrĵq}^\‸V"k@׊Wymr9Zq⊸>MX.Gq@\+N\  kʼn+6aq8qE\&,W< rrZr9C ^++z@b\\ֳ\ʵr W.W,#0rrg!/ȕ˕k= 1xA\\Y.Ga rrZr9C ^++z@b\\ֳ\ʵ-8q{^@*tupϫ:89\yUG1= p:UBW#UWups ]bW{^@*tupϫ:89\yUG1={ppp8pppఅa #êlƆ&#- G[088la8pppఅa #- G[0?m9)g9IENDB`PNG  IHDR>acIDATxytՕ?Ydy  &= da H@,cH9& pf6Y,6X&zWSu%Z]ժ~}-[qx|^ 7}0q(͡@5m9ӂ'Ϡ^vz9; ՟ ˠٖ0t ,»(O;}[*jͳ-8^R0r0_0oOI͏`z {/1<C BFt:4d)7QmAG!HHd!khgfbPv:;`H ;RkQG!aMx(nM셄0v(Z7㊁ (ȤVdeCQN?c_CH7kJM5PT-Ozږ8YH=g/F 6N i -n=j4뙊|*6zڀ@PC5; c='ں0V5kމjr*AlA4o*5t3=hN07,okB0i;| 5L?9Α& @15'Ed! 3hUpp]m:X6Gew7=8X>L,zx W8rB@ )4L%a|+ 4\10rzj JpDF6JkLmL1.RΠ0pYTu 6`(y@6.RR WRC Nl}%?2PHԤ8sc]Q_(|V$ w @Us`s[4?p'G$={()y -<߼UIv \[.Yީ[*R\+̽gIߒJm1J^w*@p+w,s6A/@ҷP848`3)%j EL~R5%o@/j [ IR9[+0(0wC0Rrw%/ lp^"uCd@L cH'_?Y(@0/e/@f&t @p@ꆀtrxV> 2e@} ^P{RLI)e @gp/0J =S8=z6<\C^riC3@A7px 0[AybH'\Md9ACMAZhƩVʎ'~OQhp&}KQqW<9Nt59v%2smֽ ᏿;ꛭ$0Zk c?&rYD\|T&;"]aB0, )SNZ* 0R>"KNv㘞=P\i>_Tiy(hN![ X^WL@ 0: -Sd'6l; i[Aq~Fx$` dŐ) >s 43مۖ%41x!\ h @,L,u*ZP7l&m#YȶsZCP d1Gy%Z* B6^i*K} `0dpv{jMbtXMgxn׆ӥ@f0o '*k)sNhH!NK! P8v[Ɵϙ;{A?|\p GtpHawpNJ(Z|RF`$[ȑGNw@ʙ1"찐5z@D x{8\X8Cj TvI@10pK<ӭaKGGah!fg* O(K!N 90cXra1yf;fSw13a@aCRcu-2MG%ִ Z+pPNYg9NԄ<Ö@&T֧8W 2UO(3<-*(+G"1C` ;X ZZz8X'އo#9euq:N`C .@M%R 0@VSMj|Jn 5ψFzCXs/ls2G!MΣA+k^Cv7ظ HyfbB{-ҿ :HʤuuBH]M9G2B܇X2*>Rd&_]448DT] x7^!R6qg'#K#2d)]i='x'Է)kK:(Ά] 0c@:0s|*pӏ@9vbz?:+iK_q{dN}Ca?\) VbLswayםnu9c(;`PB= ElMf,p GOٗOx6F2}`&Ec -a L c/BV"@6;V2 aBz¨xKg1xZ'Qg4 )L `s@-ai, I]`:NXT tӾcvM :#'\Rꍣ"w<MF Wolzdp1E̵A${7dO:sC. ,:At1] 8qmlvJ;pW1Kآ]awg+Hw/D`l,rkw?s,pRgƒОj@tlvWՁ:Y6c ("[2/~:*~pwο{V)|V ŗ[ h+t+WBɺs eXI >.W>n/M c<ϴ B6*kn0t s1 xc`,r@`I2BŰZUhuGQ`M|UA4%(. ,xΗ* 7oUu8l Iff14)#qc!*뾰 (GEa@{\zhJ _뉡r dpE`P'T8Ofr {`;~Ji6޹1ߗ;B:{hs4Df4b7g4뷑>V:\ PG#% 5c=e4_h :_l;{Mz9= ֕t-k,f^`M@1_{W-\VcQ%/p@VE{%ܧKO*A|k w-zbs2DFq]7> ϼ !f8rF '7I" o5|AG@y?D*9\jgp&M/yulo<_~ cH>f;dﺂdqhɟa{O '~e-1Tgu^AB ]G^OH)n5'qxBByZOvh]LD90n;lFusCɡG~ 5'p\ɣdڑ&me_桴P0&'$پ[_Q}oo¿PwwӣI5;AL5N/2[g r*B7ps.hq?Z?O*&`Bu!g8Qt SKݜ?؅_OQ;v鼮Q˝7~mJO1 &¨bJlGșD*"z/"AB|A^ pwGexo~UkQ]Kfc}fy_x*`%>>>.TjRzx i‹ا]smx{oY 2#뉋2L\b.~Bu&#y˝?(zr&%?~O&Z9nVFe̋}ubK]hi] ]$-;,袥]9xZS|<.x|<ޮ˚xc K2X>X9-Œi<@,dN|b$sZ<%y,|h@:'YIv$s]> dm@:'YەӒsp,|<~,/=.x|<.+@n>.Cp~[[qx|ZT|}yuqniaB`7P$4t'8c'9c'9c'9c&8b)?8RPw|xvqnif^@\&86PNs}xurnkfc\>Z&75MMq|yvrokhdaY=X%54KJlvqnkgd`]W;T$32IGijhca]ZT|9S#20GFf h^[XQw7Q!1/ECb"!!!!!!!!!!!!!!!!"#cQv6N!/-CB` 7666666666666666666679,k5L -,A?\JHHIHHIHHIHHIHHIHHIHIHEp3J,+?=Y_^^_^^_^^_^^_^^_^^_^_^Yq1G+*>;Wxvvvvvvvvvvvvvvvvvvvvvpr0F))<9S$s/D((:7P+t.A&'85N3v-@&&64J9w+?$%41F>u*=",*=lxLn(:+%6-AFfMrMrNrMqMqNrMqMqNrMqMqNrMqMqNrMqMqNrMqNrMq@\);$3 ]%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5%5#3 = @NNNNNNNNNNNNNNNNNNNNM; ?( @  ,?^DE 6N_'*;R  "7QfSy2Hb -@\m]Rx8Pr)Edz~xqmfaYNqX=X>Z;    $Ln|xqmcC`x    Fe}xrmg_@]bC`romhc\>Z g?[ ze][W~X<:6h'd&MLGF;B?:538<LW:>HFD<1v+p*d&' ?@LIJKE8v,]$9APMMMOOL3 4B \PQQPQs> 0GA -=aQQQQQb8&6\7CAAAABE3eAAAAAAAAAAAAAAAASABnzbd-0.7.20/icons/sabnzbd16paused.ico0000644000000000000000000000217612433712535020043 0ustar00usergroup00000000000000 h(  4 o\FCCCddd___HHH GGGBBBAAA333888GGGW666įrrrlll___ :::dzrrrXXX444ȶ000ȹ+++'''Ǯ &&&\333>>>============>>>AAA...eAAAAAAAAAAAAAAAASABnzbd-0.7.20/interfaces/Classic/README.TXT0000644000000000000000000000163512433712601020273 0ustar00usergroup00000000000000# # Copyright 2008-2014 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # This is the "Classic" web interface for SABnzbd # Simple, but compatible with all popular browsers. # We recommend use of the more advanced versions. #SABnzbd-0.7.20/interfaces/Classic/templates/config.tmpl0000644000000000000000000000320712433712601023073 0ustar00usergroup00000000000000

$T('configuration')

$T('confgFile'): $configfn

$T('explain-Restart')



$T('explain-orphans')

">
$T('name')
$folder


$T('explain-Repair')
SABnzbd-0.7.20/interfaces/Classic/templates/config_cat.tmpl0000644000000000000000000000721712433712601023727 0ustar00usergroup00000000000000

$T('configCat')

$T('explain-configCat')
$T('explain-catTags')
$T('explain-catTags2')
$T('explain-relFolder') $defdir

">
$T('category')  $T('mode')   $T('priority')  $T('script') $T('catFolderPath') $T('catTags')
$T('default')
SABnzbd-0.7.20/interfaces/Classic/templates/config_folders.tmpl0000644000000000000000000000622212433712601024611 0ustar00usergroup00000000000000

$T('folderConfig')

$T('explain-folderConfig')

$T('userFolders') $T('in') "$my_home"

$T('opt-download_dir'):
$T('explain-download_dir')


$T('opt-download_free'):
$T('explain-download_free')


$T('opt-complete_dir'):
$T('explain-complete_dir')


$T('opt-permissions'):
$T('explain-permissions')


$T('opt-dirscan_dir'):
$T('explain-dirscan_dir')


$T('opt-dirscan_speed'):
$T('explain-dirscan_speed')


$T('opt-script_dir'):
$T('explain-script_dir')


$T('opt-email_dir'):
$T('explain-email_dir')


$T('opt-password_file'):
$T('explain-password_file')
$T('systemFolders') $T('in') "$my_lcldata"

$T('opt-admin_dir'):
$T('explain-admin_dir1')
$T('explain-admin_dir2')


$T('opt-log_dir'):
$T('explain-log_dir')


$T('opt-nzb_backup_dir'):
$T('explain-nzb_backup_dir')

SABnzbd-0.7.20/interfaces/Classic/templates/config_general.tmpl0000644000000000000000000001163112433712601024570 0ustar00usergroup00000000000000

$T('generalConfig')

SABnzbd-0.7.20/interfaces/Classic/templates/config_indexers.tmpl0000644000000000000000000000224312433712601024773 0ustar00usergroup00000000000000

NzbMatrix

$T('explain-nzbmatrix')

$T('accountInfo') $T('opt-username_matrix'):
$T('explain-username_matrix')


$T('opt-apikey_matrix'):
$T('explain-apikey_matrix')


0 then "checked=1" else ""#--> /> $T('opt-newzbin_unbookmark'):
$T('explain-newzbin_unbookmark')

SABnzbd-0.7.20/interfaces/Classic/templates/config_notify.tmpl0000644000000000000000000000751112433712601024465 0ustar00usergroup00000000000000

$T('configEmail')

$T('emailOptions') $T('opt-email_endjob')
/> $T('email-never') /> $T('email-always') /> $T('email-errorOnly')


$T('explain-email_full')


$T('explain-email_rss')
$T('opt-email_dir'):
$T('explain-email_dir')
$T('emailAccount') $T('opt-email_server'):
$T('explain-email_server').


$T('opt-email_to'):
$T('explain-email_to')


$T('opt-email_from'):
$T('explain-email_from')


$T('opt-email_account'):
$T('explain-email_account')


$T('opt-email_pwd'):
$T('explain-email_pwd')
$T('growlSettings')
$T('explain-ntfosd_enable')


$T('explain-growl_enable')

$T('opt-growl_server'):
$T('explain-growl_server')


$T('opt-growl_password'):
$T('explain-growl_password')

  

$T('emailResult') = $lastmail SABnzbd-0.7.20/interfaces/Classic/templates/config_rss.tmpl0000644000000000000000000003414012433712601023762 0ustar00usergroup00000000000000

$T('configRSS')

>/> $T('feed') $feed




            $T('rss-order') $T('rss-type') $T('rss-filter') $T('category') Mode $T('script') $T('priority')
/>   $T('Incorrect filter')


$error

$T('rss-matched')

">
   $T('rss-skip')   $T('rss-filter')  $T('sort-title')
$job[2] $job[3] $job[1]

$T('rss-notMatched')

">
   $T('rss-skip')   $T('rss-filter')  $T('sort-title')
$job[2] $job[3] $job[1]

$T('rss-done')


">
$T('sort-title')
$job
$T('newFeedURI')  

$T('explain-RSS')

$T('opt-rss_rate')
$T('explain-rss_rate')
RSS
 
">
$T('enabled') $T('feed') URL
/>
$feed $rss[$feed]['uri']
SABnzbd-0.7.20/interfaces/Classic/templates/config_scheduling.tmpl0000644000000000000000000000445112433712601025302 0ustar00usergroup00000000000000

$T('configSchedule')

$T('addSchedule') <%import time t = time.localtime() hour = t[3] if hour != 23: hour += 1 else: hour = 0 %> $T('hour'):
:
$T('sch-frequency'):
$T('monday')
$T('tuesday')
$T('wednesday')
$T('thursday')
$T('friday')
$T('saturday')
$T('sunday')

$T('sch-action'):

$T('sch-arguments'):

$T('currentSchedules'):

$T('sch-task') $taskinfo[$schednum][0]: $taskinfo[$schednum][1]:$taskinfo[$schednum][2] - $taskinfo[$schednum][3] - $taskinfo[$schednum][4]

SABnzbd-0.7.20/interfaces/Classic/templates/config_server.tmpl0000644000000000000000000001035612433712601024464 0ustar00usergroup00000000000000

$T('configServer')

$T('addServer') $T('srv-host'):

$T('srv-port'):

$T('srv-username'):

$T('srv-password'):

$T('srv-timeout'):

$T('srv-connections'):

$T('srv-retention') ($T('days')):

$T('srv-ssl') $T('opt-notInstalled') > $T('srv-ssl')
 $T('srv-fillserver')
 $T('srv-optional')
 $T('srv-enable')

$server $T('srv-host'):

$T('srv-port'):

$T('srv-username'):

$T('srv-password'):

$T('srv-timeout'):

$T('srv-connections'):

$T('srv-retention'):

$T('srv-ssl') $T('opt-notInstalled') /> $T('srv-ssl')
/> $T('srv-fillserver')
/> $T('srv-optional')
/> $T('srv-enable')

$T('total')$servers[$server]['amounts'][0] $T('thisMonth')$servers[$server]['amounts'][1]
$T('today')$servers[$server]['amounts'][3] $T('thisWeek')$servers[$server]['amounts'][2]
SABnzbd-0.7.20/interfaces/Classic/templates/config_sorting.tmpl0000644000000000000000000004261612433712601024647 0ustar00usergroup00000000000000

$T('configSort')

$T('seriesSorting') 0 then "checked=1" else ""#--> /> $T('opt-tvsort')

$T('affectedCat'):


$T('sort-legenda')
$T('sort-meaning') $T('sort-pattern') $T('sort-result')
$T('show-name') %sn $T('show-sp-name')
%s.n $T('show-dot-name')
%s_n $T('show-us-name')
$T('show-seasonNum') %s 1
%0s 01
$T('show-epNum') %e 5
%0e 05
$T('ep-name') %en $T('ep-sp-name')
%e.n $T('ep-dot-name')
%e_n $T('ep-us-name')
$T('fileExt') %ext avi
$T('orgFilename') %fn $T("sort-File")
$T('orgDirname') %dn $T("sort-Folder")
$T('lowercase') {$T('TEXT')} $T('text')

$T('sortString'):

$T('presetSort'):


$T('example'):


$T('genericSort') 0 then "checked=1" else ""#--> /> $T('opt-movieSort')

0 then "checked=1" else ""#--> /> $T('opt-movieExtra')

$T('affectedCat'):


$T('sort-legenda')
$T('sort-meaning') $T('sort-pattern') $T('sort-result')
$T('sort-title') %title $T('movie-sp-name')
%.title $T('movie-dot-name')
%_title $T('movie-us-name')
$T('year') %y 2000
$T('extension') %ext avi
$T('partNumber') %1 1
$T('decade') %decade 00
$T('decade') %0decade 2000
$T('orgFilename') %fn $T('sort-File')
$T('lowercase') {$T('TEXT')} $T('text')


$T('sortString'):

$T('multiPartLabel'):

$T('presetSort'):


$T('example'):


$T('dateSorting') 0 then "checked=1" else ""#--> /> $T('opt-dateSort')

$T('affectedCat'):


$T('sort-legenda')
$T('sort-meaning') $T('sort-pattern') $T('sort-result')
$T('show-name') %t $T('show-sp-name')
%.t $T('show-dot-name')
%_t $T('show-us-name')
$T('year') %y 2009
$T('month') %m 1
%0m 01
$T('day-of-month') %d 2
%0d 02
$T('decade') %decade 00
$T('decade') %0decade 2000
$T('orgFilename') %fn $T('sort-File')
$T('lowercase') {$T('TEXT')} $T('text')

$T('sortString'):

$T('presetSort'):


$T('example'):

SABnzbd-0.7.20/interfaces/Classic/templates/config_switches.tmpl0000644000000000000000000002415712433712601025013 0ustar00usergroup00000000000000

$T('switchesConfig')

$T('processingSwitches')
$T('explain-quick_check')


$T('explain-pre_check')


$T('explain-enable_unrar')


$T('explain-enable_unzip')


$T('explain-enable_filejoin')


$T('explain-ts_join')


$T('explain-enable_par_cleanup')


$T('explain-fail_on_crc')


$T('explain-top_only')


$T('explain-safe_postproc')


$T('explain-pause_on_pwrar')


$T('explain-unpack_check')

$T('opt-no_dupes'):
$T('explain-no_dupes')
/> $T('nodupes-off') /> $T('nodupes-ignore') /> $T('nodupes-pause')


$T('explain-sfv_check')


$T('explain-folder_rename')


$T('opt-pre_script'):
$T('explain-pre_script')



$T('explain-par2_multicore')

$T('opt-par_option'):
$T('explain-par_option')


$T('opt-nice'):
$T('explain-nice')


$T('opt-ionice'):
$T('explain-ionice')


$T('otherSwitches')
$T('explain-max_art_tries')



$T('explain-max_art_opt')


$T('explain-auto_disconnect')


$T('explain-send_group')


$T('explain-auto_sort')


$T('explain-check_new_rel')


$T('explain-replace_spaces')


$T('explain-replace_dots')


$T('explain-replace_illegal')


$T('explain-auto_browser')


$T('explain-pause_on_post_processing')


$T('explain-ampm')

$T('opt-ignore_samples'):
$T('explain-ignore_samples')
/> $T('igsam-off') /> $T('igsam-del') /> $T('igsam-not')

$T('opt-ssl_type'):
$T('explain-ssl_type')

$T('opt-quota_size'):
$T('explain-quota_size')


$T('opt-quota_period'):
$T('explain-quota_period')


$T('opt-quota_day'):
$T('explain-quota_day')


$T('swtag-quota')
$T('explain-quota_resume')

SABnzbd-0.7.20/interfaces/Classic/templates/history.tmpl0000644000000000000000000001446112433712601023333 0ustar00usergroup00000000000000 $T('purgeHist') | $T('purgeHistFailed') | $T('purgeFailed-Files') | $T('hideDetails') | $T('showDetails') | $T('showAllHis') $T('showFailedHis')

$T('sizeHist'): $total_size  |  $T('today'): $day_size  |   $T('thisWeek'): $week_size  |  $T('thisMonth'): $month_size

<% import datetime %> <% from sabnzbd.misc import time_format %> <% compl = datetime.datetime.fromtimestamp(float(line['completed'])).strftime(time_format('%Y-%m-%d %H:%M:%S')) %> "> ">">
$T('completed') $T('name') $T('size') $T('status') Rating
$compl $line.name - $line.action_line - $line.fail_message $line.size $Tx('post-'+$line.status)
$T('video') $line.rating_avg_video $T('audio') $line.rating_avg_audio

$T('video') 
$T('audio') 
 $T('spam')  $T('encrypted')  $T('expired')
$Tx('stage-'+$stage.name.title.lower())
$action

$T('category')
$line.category

$T('msg-path')
$line.storage

SABnzbd-0.7.20/interfaces/Classic/templates/inc_bottom.tmpl0000644000000000000000000000270112433712601023761 0ustar00usergroup00000000000000

$T('ft-warning')

$warning SABnzbd-0.7.20/interfaces/Classic/templates/inc_cmenu.tmpl0000644000000000000000000000355512433712601023574 0ustar00usergroup00000000000000 $T('cmenu-general') | $T('cmenu-general') | $T('cmenu-folders') | $T('cmenu-folders') | $T('cmenu-switches') | $T('cmenu-switches') | $T('cmenu-servers') | $T('cmenu-servers') | $T('cmenu-scheduling') | $T('cmenu-scheduling') | $T('cmenu-rss') | $T('cmenu-rss') | $T('cmenu-notif') | $T('cmenu-notif') | $T('cmenu-newzbin') | $T('cmenu-newzbin') | $T('cmenu-cat') | $T('cmenu-cat') | $T('cmenu-sorting') $T('cmenu-sorting') SABnzbd-0.7.20/interfaces/Classic/templates/inc_top.tmpl0000644000000000000000000000464312433712601023266 0ustar00usergroup00000000000000 $mbleft MB $T('queued') - SABnzbd $version

SABnzbd+ $version$T('signOn')

$T('menu-home') | $T('menu-home') | $T('menu-queue') | $T('menu-queue') | $T('menu-history') | $T('menu-history') | $T('menu-config') | $T('menu-config') | $T('menu-cons') | $T('menu-cons') | SABnzbd-0.7.20/interfaces/Classic/templates/main.tmpl0000644000000000000000000000752112433712601022555 0ustar00usergroup00000000000000 $T('link-resume') $T('link-pause') | $T('link-shutdown')

$T("addNewJobs")

$T('add') URL
$T('addFile')
SABnzbd-0.7.20/interfaces/Classic/templates/nzo.tmpl0000644000000000000000000001172112433712601022434 0ustar00usergroup00000000000000  

$T('nzoDetails')



















$T('nzo-selection'):$T('nzo-all') $T('nzo-none') $T('nzo-invert') active">
$T('nzo-filename')/$T('nzo-subject')$T('size')$T('nzo-age')
> $file.filename $file.size $file.age
SABnzbd-0.7.20/interfaces/Classic/templates/queue.tmpl0000644000000000000000000002070712433712601022756 0ustar00usergroup00000000000000 $T('link-resume') $T('link-pause') | $T('link-sortByName') | $T('link-sortByAge') | $T('link-sortBySize') | $T('link-hideFiles') $T('link-showFiles')| $T('onQueueFinish'): | $T('speedLimit'):  $T('KBs') | $T('pauseFor'):  $T('minute') | $T('purgeQueue')

$slot.priority $slot.status"> finished"> active"> waiting">
$T('order') $T('category') $T('mode')$T('priority') $T('script') $T('name')$T('remainTotal')$T('eta')$T('age')
$slot.filename $slot.sizeleft/$slot.size $slot.eta $slot.avg_age
Finished$line.filename$line.mbleft/$line.mb MB$line.age
RemoveActive$line.filename$line.mbleft/$line.mb MB$line.age
Waiting$line.filename (set: $line.set)$line.mbleft/$line.mb MB$line.age
SABnzbd-0.7.20/interfaces/Classic/templates/status.tmpl0000644000000000000000000000331512433712601023151 0ustar00usergroup00000000000000 $T('link-resetQuota') | $T('link-forceDisc') | $T('link-showLog') $T('logging'):

$T('connections')

  • $server[0]: $server[2] ($T('server-blocked'))   $server[6]
    • $T('thread') #$thrd[0] -> $thrd[1] -> $thrd[2] -> $thrd[3]

$T('lastWarnings') ($T('clearWarnings'))

$warn
SABnzbd-0.7.20/interfaces/Classic/templates/static/placeholder.txt0000644000000000000000000000000012433712601025226 0ustar00usergroup00000000000000SABnzbd-0.7.20/interfaces/Classic/templates/static/images/favicon.ico0000644000000000000000000000217612433712536025620 0ustar00usergroup00000000000000 h(  4 o \FB_a]Gg FfA]@\2J7OFeW5Loi]"' 9T& oV#3Ke278PU0Cfkkgp+='8lqqqv &6\2H>X a, td > a { color:white; } a.remove { color:black; } .feedEnabled{color:green;} .feedDisabled{color:red;} .rating_overall { margin:0px 5px 3px 0px; } .rating_item { float:left; margin:5px 15px 5px 5px; } SABnzbd-0.7.20/interfaces/Classic/templates/static/stylesheets/colorschemes/black.css0000644000000000000000000000231412433712601031045 0ustar00usergroup00000000000000body { background-color: #3a3a3a; color: #888; } a { color: #000; } input, select { background-color:#232323; border-color:#3a3a3a; color:white; } legend { color: #ccc; } fieldset.EntryFieldSet { color: #ccc; border-color:#3a3a3a; } .MainMenu a { color: #4e4e4e; } .SubMenu a { color: #ccc; } a:hover { background-color: #f5f5f5; color:black; } a{color:white;} a.current:hover { background-color: #ccc; } .blockWithBorder { border-color: #b5b5b5; background-color: #eeeeee; } .MainMenu { background-color: #232323; } .SubMenu { background-color: #000; } table { color: white; } th { background: #000; color: white; } h1 { border-bottom: 1px solid #4e4e4e; } #catchfrase { color: white; } .footer { background-color: #232323; border-top: 1px solid #000; color:#4e4e4e; } .SubMenu, .blockWithBorder , a.current, th { background-color: #000; color:white; } a.current { color: #777; background-color: #000; } tr.even, tr.odd { background-color: #111; color:white; } tr.evenLine, tr.oddLine { background-color: #232323; color:#666; } #first, #second, #third { color: #000; } a.current:hover, a:hover { background-color: black; color:white } a.remove{color:#888} SABnzbd-0.7.20/interfaces/Classic/templates/static/stylesheets/colorschemes/classic.css0000644000000000000000000000157212433712601031417 0ustar00usergroup00000000000000.SubMenu, .blockWithBorder , a.current, tr.even, tr.odd{ background-color: #b5b5b5; color:black; } .SubMenu{ border: 1px solid #b5b5b5; } .MainMenu { display: block; border-width: 1px; border-style: solid; border-color: #b5b5b5; background-color: #eeeeee; padding: 5px; } .SubMenu a { font-weight: bold; color: #000000; text-decoration: none; } body{ color: #808080; } th { background: #b5b5b5; color: white; font-weight: bold; } tr.even{ background-color: #cdf; } tr.evenLine { background-color: #eee; } tr.odd { background-color: #99bbff; } tr.oddLine { background-color: #f8f8f8; } #third { color: #808080; } #first, legend{ color:#c32ee4; } #second{ color:#99bbff; } a.current:hover, a:hover { background-color: black; color:white } .SubMenu a.current{ color:white; } a{ color:black; } td > a, td > a { color:white; } a.remove { color:black; } SABnzbd-0.7.20/interfaces/Classic/templates/static/stylesheets/colorschemes/darkblue.css0000644000000000000000000000054412433712601031565 0ustar00usergroup00000000000000.SubMenu, .blockWithBorder , a.current, tr.even, tr.odd{ background-color: #44577c; color:white; } th { background-color: #333; color:white; } #first, #third { color: #44577c; } .SubMenu a.current { color:#ccc; } a.current:hover, a:hover { background-color: black; color:white } td > a, td > a { color:white; } a.remove { color:black; } SABnzbd-0.7.20/interfaces/Classic/templates/static/stylesheets/colorschemes/green.css0000644000000000000000000000054212433712601031072 0ustar00usergroup00000000000000.SubMenu, .blockWithBorder , a.current, tr.even, tr.odd{ background-color: #3f7c78; color:white; } #first, #third { color: #3f7c78; } th{ background-color: #333; color:white; } .SubMenu a.current { color:#444; } a.current:hover, a:hover { background-color: black; color:white } td > a, td > a { color:white; } a.remove { color:black; } SABnzbd-0.7.20/interfaces/Classic/templates/static/stylesheets/colorschemes/lightblue.css0000644000000000000000000000054412433712601031753 0ustar00usergroup00000000000000.SubMenu, .blockWithBorder , a.current, tr.even, tr.odd{ background-color: #5ca5ff; color:white; } #first, #third { color: #5ca5ff; } th { background-color: #000; color:white; } .SubMenu a.current { color:black; } a.current:hover, a:hover { background-color: black; color:white } td > a, td > a { color:white; } a.remove { color:black; } SABnzbd-0.7.20/interfaces/Classic/templates/static/stylesheets/colorschemes/red.css0000644000000000000000000000054412433712601030546 0ustar00usergroup00000000000000.SubMenu, .blockWithBorder , a.current, tr.even, tr.odd{ background-color: #CC0033; color:white; } th { background-color: #333; color:white; } #first, #third { color: #CC0033; } .SubMenu a.current { color:black; } a.current:hover, a:hover { background-color: black; color:white } td > a, td > a { color:white; } a.remove { color:black; } SABnzbd-0.7.20/interfaces/Classic/templates/static/stylesheets/colorschemes/white-black.css0000644000000000000000000000054412433712601032166 0ustar00usergroup00000000000000 .SubMenu, .blockWithBorder , a.current, tr.even, tr.odd{ background-color: #4e4e4e; color:white; } th { background-color: #333; color:white; } #first, #third { color: #4e4e4e; } .SubMenu a.current { color:#ccc; } a.current:hover, a:hover { background-color: black; color:white } td > a, td > a { color:white; } a.remove { color:black; } SABnzbd-0.7.20/interfaces/Config/README.txt0000644000000000000000000000311212433712602020250 0ustar00usergroup00000000000000 uniConfig for SABnzbd 0.7.x zoggy@sabnzbd.org ======================================================== LIBRARIES USED jQuery * Project repository: https://github.com/jquery/jquery * Dual licensed under the MIT and GPL licenses: * http://www.gnu.org/licenses/gpl.html * http://www.opensource.org/licenses/mit-license.php jQuery UI * Project repository: https://github.com/jquery/jquery-ui * Dual licensed under the MIT and GPL licenses: * http://www.gnu.org/licenses/gpl.html * http://www.opensource.org/licenses/mit-license.php jQuery Form Plugin * Project repository: https://github.com/malsup/form * Dual licensed under the MIT and GPL licenses: * http://www.gnu.org/licenses/gpl.html * http://www.opensource.org/licenses/mit-license.php jQuery Tools (tabs) * Project repository: https://github.com/jquerytools/jquerytools Formalize * Project repository: https://github.com/nathansmith/formalize * Dual licensed under the MIT and GPL licenses: * http://www.gnu.org/licenses/gpl.html * http://www.opensource.org/licenses/mit-license.php normalize.css * Project repository: https://github.com/necolas/normalize.css * Licensed under public domain qTip2 * Project repository: https://github.com/craga89/qtip2 * Dual licensed under the MIT and GPL licenses: * http://www.gnu.org/licenses/gpl.html * http://www.opensource.org/licenses/mit-license.php ======================================================== IMAGES USED /images/loading-*.gif - source: http://www.AjaxLoad.info /images/flags/* - source: http://www.famfamfam.com/lab/icons/flags/ SABnzbd-0.7.20/interfaces/Config/templates/config.tmpl0000644000000000000000000000517712433712602022730 0ustar00usergroup00000000000000
$T('version'): $version
$T('uptime'): $uptime
$T('confgFile'): $configfn
$T('cache').capitalize(): $msg
$T('parameters'): $cmdline
$T('pythonVersion'): $sys.version[:120]
$T('homePage') http://sabnzbd.org/
$T('menu-wiki') http://wiki.sabnzbd.org/faq
$T('menu-forums') http://forums.sabnzbd.org/
$T('source') https://github.com/sabnzbd/sabnzbd
$T('menu-irc') #sabnzbd on irc.synirc.net $T('or') (webchat)
$T('oznzb')https://www.oznzb.com/register
SABnzbd-0.7.20/interfaces/Config/templates/config_cat.tmpl0000644000000000000000000001151112433712602023544 0ustar00usergroup00000000000000

$T('explain-catTags') $T('explain-catTags2')

$T('explain-relFolder'): $defdir
" style="background-color: #FFFFE0;">
$T('category') $T('priority') $T('mode') $T('script') $T('catFolderPath') $T('catTags')  
SABnzbd-0.7.20/interfaces/Config/templates/config_folders.tmpl0000644000000000000000000001505512433712602024442 0ustar00usergroup00000000000000

$T('userFolders')

$T('explain-folderConfig')

$T('base-folder'): $my_home
$T('explain-download_dir')
$T('explain-download_free')
$T('explain-complete_dir')
"> /> $T('explain-permissions')
$T('explain-dirscan_dir')
$T('explain-dirscan_speed')
$T('explain-script_dir')
$T('explain-email_dir')
$T('explain-password_file')

$T('systemFolders')

$T('explain-folderConfig')

$T('base-folder'): $my_lcldata
$T('explain-admin_dir1') $T('explain-admin_dir2')
$T('explain-log_dir')
$T('explain-nzb_backup_dir')
SABnzbd-0.7.20/interfaces/Config/templates/config_general.tmpl0000644000000000000000000002727312433712602024426 0ustar00usergroup00000000000000

$T('webServer')

$T('restartRequired')

$T('explain-host')
$T('explain-port')
$T('explain-web_username')
$T('explain-web_password')
$T('explain-web_dir')
$T('explain-web_dir2')
$T('explain-language')
0 then 'checked="checked"' else ""#--> /> $T('explain-disableApikey')
$T('explain-apikey')
$T('explain-nzbkey')

$T('httpsSupport')

$T('restartRequired')

$T('base-folder'): $my_lcldata
"> 0 then 'checked="checked"' else ""#--> /> $T('explain-enable_https')
$T('explain-https_port')
$T('explain-https_cert')
$T('explain-https_key')
$T('explain-https_chain')

$T('tuning')

$T('explain-bandwidth_limit')
$T('explain-cache_limitstr')
$T('explain-cleanup_list')
SABnzbd-0.7.20/interfaces/Config/templates/config_indexers.tmpl0000644000000000000000000000667712433712602024637 0ustar00usergroup00000000000000

NzbMatrix $T('accountInfo')

$T('explain-nzbmatrix')

$T('explain-username_matrix')
$T('explain-apikey_matrix')
0 then 'checked="checked"' else ""#--> /> $T('explain-newzbin_unbookmark')
SABnzbd-0.7.20/interfaces/Config/templates/config_notify.tmpl0000644000000000000000000002515012433712602024311 0ustar00usergroup00000000000000

$T('emailOptions')

0 then 'checked="checked"' else ""#--> /> $T('explain-email_full')
0 then 'checked="checked"' else ""#--> /> $T('explain-email_rss')
$T('explain-email_dir')

$T('emailAccount')

$T('explain-email_server')
$T('explain-email_to')
$T('explain-email_from')
$T('explain-email_account')
$T('explain-email_pwd')
 

$T('growlSettings')

$T('explain-notify_classes')
"> 0 then 'checked="checked"' else ""#--> /> $T('explain-ncenter_enable')
"> 0 then 'checked="checked"' else ""#--> /> $T('explain-ntfosd_enable')
0 then 'checked="checked"' else ""#--> /> $T('explain-growl_enable')
$T('explain-growl_server')
$T('explain-growl_password')
 
SABnzbd-0.7.20/interfaces/Config/templates/config_rss.tmpl0000644000000000000000000006165412433712602023621 0ustar00usergroup00000000000000

$T('explain-RSS')

  $T('name') $T('feed') URL  

" > ">
rel="$feed_item" />
$rss[$feed_item]['uri']

  $T('Next scan at:') $rss_next $T('explain-rss_rate')

$T('cmenu-rss') » $active_feed

$error

  $T('rss-order') $T('rss-type') $T('rss-filter') $T('category') $T('priority') $T('mode') $T('script')  
">
/>   $T('Incorrect filter')

">
$T('link-download') $T('rss-skip') $T('rss-filter') $T('sort-title')
$job[2] $job[3] $job[1]
$T('none')
">
$T('link-download') $T('rss-skip') $T('rss-filter') $T('sort-title')
$job[2] $job[3] $job[1]
$T('none')
">
$T('sort-title')
$job
$T('none')
SABnzbd-0.7.20/interfaces/Config/templates/config_scheduling.tmpl0000644000000000000000000001153512433712602025130 0ustar00usergroup00000000000000 <% import time t = time.localtime() hour = t[3] if hour != 23: hour += 1 else: hour = 0 %>

$T('addSchedule')

 : 

$T('currentSchedules')

">
$taskinfo[$schednum][1]:$taskinfo[$schednum][2]$taskinfo[$schednum][3] $taskinfo[$schednum][4]
SABnzbd-0.7.20/interfaces/Config/templates/config_server.tmpl0000644000000000000000000002612512433712602024312 0ustar00usergroup00000000000000

$servers[$server]['name']

rel="$server" />  $T('enabled')

$T('srv-bandwidth'):
$T('total'): $(servers[$server]['amounts'][0])B
$T('today'): $(servers[$server]['amounts'][3])B
$T('thisWeek'): $(servers[$server]['amounts'][2])B
$T('thisMonth'): $(servers[$server]['amounts'][1])B
SABnzbd-0.7.20/interfaces/Config/templates/config_sorting.tmpl0000644000000000000000000006436412433712602024500 0ustar00usergroup00000000000000

$T('seriesSorting')

$T('affectedCat')

$T('ft-download'): $complete_dir
0 then 'checked="checked"' else ""#--> />

 
$T('sort-meaning') $T('sort-pattern') $T('sort-result')
$T('show-name'): %sn $T('show-sp-name')
  %s.n $T('show-dot-name')
  %s_n $T('show-us-name')
$T('show-name'): %sN $T('show-sp-name') ($T('case-adjusted'))
  %s.N $T('show-dot-name') ($T('case-adjusted'))
  %s_N $T('show-us-name') ($T('case-adjusted'))
$T('show-seasonNum'): %s 1
  %0s 01
$T('show-epNum'): %e 5
  %0e 05
$T('ep-name'): %en $T('ep-sp-name')
  %e.n $T('ep-dot-name')
  %e_n $T('ep-us-name')
$T('fileExt'): %ext avi
$T('orgFilename'): %fn $T("sort-File")
$T('orgDirname'): %dn $T("sort-Folder")
$T('lowercase'): {$T('TEXT')} $T('text')

$T('genericSort')

$T('affectedCat')

$T('ft-download'): $complete_dir
0 then 'checked="checked"' else ""#--> />
0 then 'checked="checked"' else ""#--> />
 
$T('sort-meaning') $T('sort-pattern') $T('sort-result')
$T('sort-title'): %title $T('movie-sp-name')
  %.title $T('movie-dot-name')
  %_title $T('movie-us-name')
$T('year'): %y 2009
$T('extension'): %ext avi
$T('decade'): %decade 00
  %0decade 2000
$T('orgFilename'): %fn $T('sort-File')
$T('orgDirname'): %dn $T("sort-Folder")
$T('lowercase'): {$T('TEXT')} $T('text')
$T('multiPartLabel') $T('sort-pattern') $T('sort-result')
$T('partNumber'): %1 1

$T('dateSorting')

$T('affectedCat')

$T('ft-download'): $complete_dir
0 then 'checked="checked"' else ""#--> />
 
$T('sort-meaning') $T('sort-pattern') $T('sort-result')
$T('show-name'): %t $T('show-sp-name')
  %.t $T('show-dot-name')
  %_t $T('show-us-name')
$T('year'): %y 2009
$T('month'): %m 1
  %0m 01
$T('day-of-month'): %d 2
  %0d 02
$T('decade'): %decade 00
  %0decade 2000
$T('orgFilename'): %fn $T('sort-File')
$T('lowercase'): {$T('TEXT')} $T('text')
SABnzbd-0.7.20/interfaces/Config/templates/config_special.tmpl0000644000000000000000000000515212433712602024421 0ustar00usergroup00000000000000

$T('explain-special')

$T('sptag-boolean')

"> 0 then 'checked="checked"' else ""#--> />  

$T('sptag-entries')

">
SABnzbd-0.7.20/interfaces/Config/templates/config_switches.tmpl0000644000000000000000000010240012433712602024624 0ustar00usergroup00000000000000

$T('swtag-general')

$T('explain-check_new_rel')
0 then 'checked="checked"' else ""#--> /> $T('explain-auto_browser')
"> 0 then 'checked="checked"' else ""#--> /> $T('explain-ampm')

$T('swtag-server')

$T('explain-max_art_tries')
0 then 'checked="checked"' else ""#--> /> $T('explain-max_art_opt')
0 then 'checked="checked"' else ""#--> /> $T('explain-auto_disconnect')
0 then 'checked="checked"' else ""#--> /> $T('explain-send_group')
$T('explain-ssl_type')

$T('swtag-queue')

0 then 'checked="checked"' else ""#--> /> $T('explain-fail_hopeless')
0 then 'checked="checked"' else ""#--> /> $T('explain-pre_check')
$T('explain-no_dupes')
0 then 'checked="checked"' else ""#--> /> $T('explain-pause_on_post_processing')
$T('explain-pause_on_pwrar')
$T('explain-action_on_unwanted_extensions')
$T('explain-unwanted_extensions')
0 then 'checked="checked"' else ""#--> /> $T('explain-top_only')
0 then 'checked="checked"' else ""#--> /> $T('explain-auto_sort')
$T('explain-pre_script')

$T('swtag-pp')

$T('explain-ignore_samples')
0 then 'checked="checked"' else ""#--> /> $T('explain-quick_check')
0 then 'checked="checked"' else ""#--> /> $T('explain-enable_unrar')
0 then 'checked="checked"' else ""#--> /> $T('explain-enable_unzip')
0 then 'checked="checked"' else ""#--> /> $T('explain-enable_filejoin')
0 then 'checked="checked"' else ""#--> /> $T('explain-ts_join')
0 then 'checked="checked"' else ""#--> /> $T('explain-enable_par_cleanup')
0 then 'checked="checked"' else ""#--> /> $T('explain-fail_on_crc')
0 then 'checked="checked"' else ""#--> /> $T('explain-safe_postproc')
0 then 'checked="checked"' else ""#--> /> $T('explain-sfv_check')
0 then 'checked="checked"' else ""#--> /> $T('explain-unpack_check')
"> 0 then 'checked="checked"' else ""#--> /> $T('explain-par2_multicore')
$T('explain-par_option')
"> /> $T('explain-nice')
"> /> $T('explain-ionice')

$T('swtag-naming')

0 then 'checked="checked"' else ""#--> /> $T('explain-folder_rename')
0 then 'checked="checked"' else ""#--> /> $T('explain-replace_spaces')
0 then 'checked="checked"' else ""#--> /> $T('explain-replace_dots')
0 then 'checked="checked"' else ""#--> /> $T('explain-replace_illegal')

$T('swtag-quota')

$T('explain-quota_size')
$T('explain-quota_period')
$T('explain-quota_day')
0 then 'checked="checked"' else ""#--> /> $T('explain-quota_resume')

$T('swtag-indexing')

0 then 'checked="checked"' else ""#--> /> $T('explain-rating_enable')
$T('explain-rating_api_key')
0 then 'checked="checked"' else ""#--> /> $T('explain-rating_feedback')
0 then 'checked="checked"' else ""#--> /> $T('explain-rating_filter_enable')

0 then 'checked="checked"' else ""#--> /> 0 then 'checked="checked"' else ""#--> />

0 then 'checked="checked"' else ""#--> /> 0 then 'checked="checked"' else ""#--> />

0 then 'checked="checked"' else ""#--> />

$T('explain-rating_filter_keywords')

0 then 'checked="checked"' else ""#--> /> 0 then 'checked="checked"' else ""#--> />

0 then 'checked="checked"' else ""#--> /> 0 then 'checked="checked"' else ""#--> />

0 then 'checked="checked"' else ""#--> />

$T('explain-rating_filter_keywords')

SABnzbd-0.7.20/interfaces/Config/templates/main.tmpl0000644000000000000000000000022112433712602022370 0ustar00usergroup00000000000000/* This file was intentionally left blank and is only needed for 'skin' detection routine */ /* https://github.com/thezoggy/sabnzbd-uni_Config */SABnzbd-0.7.20/interfaces/Config/templates/_inc_footer_uc.tmpl0000644000000000000000000000051612433712602024430 0ustar00usergroup00000000000000 SABnzbd-0.7.20/interfaces/Config/templates/_inc_header_uc.tmpl0000644000000000000000000001746112433712602024371 0ustar00usergroup00000000000000 SABnzbd $version - $T('queued'): $mbleft $T('MB') #if $pane == "Config"# #set global $root = '../'# #else# #set global $root = '../../'# #end if#
SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/style.css0000644000000000000000000013671312433712602025177 0ustar00usergroup00000000000000/*! * BEGIN normalize.css *//*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */article,aside,details,figcaption,figure,footer,header,hgroup,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:hover,a:active{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.75em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}mark{background:#ff0;color:#000}p,pre{margin:1em 0}pre,code,kbd,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:75%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}/*! * BEGIN formalize.css */.input_tiny{width:50px}.input_small{width:100px}.input_medium{width:150px}.input_large{width:200px}.input_xlarge{width:250px}.input_xxlarge{width:300px}.input_full{width:100%}.input_full_wrap{display:block;padding-right:8px}input[type="search"]::-webkit-search-decoration{display:none}input:invalid,button:invalid,select:invalid,textarea:invalid{-webkit-box-shadow:none;-moz-box-shadow:none;-o-box-shadow:none;box-shadow:none}input:focus,button:focus,select:focus,textarea:focus{-webkit-box-shadow:#06f 0 0 5px 0;-moz-box-shadow:#06f 0 0 5px 0;-o-box-shadow:#06f 0 0 5px 0;box-shadow:#06f 0 0 5px 0;z-index:1}input[type="file"]:focus,input[type="file"]:active,input[type="radio"]:focus,input[type="radio"]:active,input[type="checkbox"]:focus,input[type="checkbox"]:active{-webkit-box-shadow:none;-moz-box-shadow:none;-o-box-shadow:none;box-shadow:none}button,input[type="reset"],input[type="submit"],input[type="button"]{-webkit-appearance:none;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;-o-border-radius:4px;border-radius:4px;-webkit-background-clip:padding;-moz-background-clip:padding;-ms-background-clip:padding-box;-o-background-clip:padding-box;background-clip:padding-box;background:#ddd url('../images/button.png?1298351022') repeat-x;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(0%,#fff),color-stop(100%,#ddd));background-image:-webkit-linear-gradient(#fff,#ddd);background-image:-moz-linear-gradient(#fff,#ddd);background-image:-o-linear-gradient(#fff,#ddd);background-image:-ms-linear-gradient(#fff,#ddd);background-image:linear-gradient(#fff,#ddd);border:1px solid;border-color:#ddd #bbb #999;cursor:pointer;color:#333;font:bold 12px/1.3 "Helvetica Neue",Arial,"Liberation Sans",FreeSans,sans-serif;outline:0;overflow:visible;margin:0;padding:3px 10px;text-shadow:white 0 1px 1px;vertical-align:top;width:auto;*padding-top:2px;*padding-bottom:0}button:hover,input[type="reset"]:hover,input[type="submit"]:hover,input[type="button"]:hover{background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(0%,#fff),color-stop(1px,#eee),color-stop(100%,#ccc));background-image:-webkit-linear-gradient(#fff,#eee 1px,#ccc);background-image:-moz-linear-gradient(#fff,#eee 1px,#ccc);background-image:-o-linear-gradient(#fff,#eee 1px,#ccc);background-image:-ms-linear-gradient(#fff,#eee 1px,#ccc);background-image:linear-gradient(#fff,#eee 1px,#ccc)}button:active,input[type="reset"]:active,input[type="submit"]:active,input[type="button"]:active{background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(0%,#fff),color-stop(1px,#ddd),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#fff,#ddd 1px,#eee);background-image:-moz-linear-gradient(#fff,#ddd 1px,#eee);background-image:-o-linear-gradient(#fff,#ddd 1px,#eee);background-image:-ms-linear-gradient(#fff,#ddd 1px,#eee);background-image:linear-gradient(#fff,#ddd 1px,#eee);-webkit-box-shadow:inset rgba(0,0,0,0.25) 0 1px 2px 0;-moz-box-shadow:inset rgba(0,0,0,0.25) 0 1px 2px 0;-o-box-shadow:inset rgba(0,0,0,0.25) 0 1px 2px 0;box-shadow:inset rgba(0,0,0,0.25) 0 1px 2px 0;border-color:#999 #bbb #ddd}button::-moz-focus-inner,input[type="reset"]::-moz-focus-inner,input[type="submit"]::-moz-focus-inner,input[type="button"]::-moz-focus-inner{border:0;padding:0}button{*padding-top:1px;*padding-bottom:1px}textarea,select,input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="email"],input[type="month"],input[type="number"],input[type="password"],input[type="search"],input[type="tel"],input[type="text"],input[type="time"],input[type="url"],input[type="week"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-background-clip:padding;-moz-background-clip:padding;-ms-background-clip:padding-box;-o-background-clip:padding-box;background-clip:padding-box;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;-o-border-radius:0;border-radius:0;-webkit-appearance:none;background-color:white;border:1px solid;border-color:#848484 #c1c1c1 #e1e1e1;color:black;outline:0;margin:0;padding:2px 3px;text-align:left;font-size:13px;font-family:Arial,"Liberation Sans",FreeSans,sans-serif;height:1.8em;vertical-align:top;*padding-top:2px;*padding-bottom:1px;*height:auto}textarea[disabled],select[disabled],input[type="date"][disabled],input[type="datetime"][disabled],input[type="datetime-local"][disabled],input[type="email"][disabled],input[type="month"][disabled],input[type="number"][disabled],input[type="password"][disabled],input[type="search"][disabled],input[type="tel"][disabled],input[type="text"][disabled],input[type="time"][disabled],input[type="url"][disabled],input[type="week"][disabled]{background-color:#eee}button[disabled],input[disabled],select[disabled],select[disabled] option,select[disabled] optgroup,textarea[disabled]{-webkit-box-shadow:none;-moz-box-shadow:none;-o-box-shadow:none;box-shadow:none;-moz-user-select:-moz-none;-webkit-user-select:none;-khtml-user-select:none;user-select:none;color:#888;cursor:default}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#888}input:-moz-placeholder,textarea:-moz-placeholder{color:#888}input.placeholder_text,textarea.placeholder_text{color:#888}textarea,select[size],select[multiple]{height:auto}select[size="0"],select[size="1"]{height:1.8em;*height:auto}@media(-webkit-min-device-pixel-ratio:0){select[size],select[multiple],select[multiple][size]{background-image:none;padding-right:3px}select,select[size="0"],select[size="1"]{background-image:url('../images/select_arrow.gif?1298351050');background-repeat:no-repeat;background-position:right center;padding-right:20px}::-webkit-validation-bubble-message{-webkit-box-shadow:none;box-shadow:none;background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#666),color-stop(1,black));border:1px solid;border-color:#747474 #5e5e5e #4f4f4f;color:white;font:13px/17px "Lucida Grande",Arial,"Liberation Sans",FreeSans,sans-serif;overflow:hidden;padding:15px 15px 17px;text-shadow:black 0 0 1px;height:16px}::-webkit-validation-bubble-arrow,::-webkit-validation-bubble-top-outer-arrow,::-webkit-validation-bubble-top-inner-arrow{-webkit-box-shadow:none;box-shadow:none;background:#666;border:0}}textarea{min-height:40px;overflow:auto;resize:vertical;width:100%}optgroup{color:black;font-style:normal;font-weight:normal;font-family:Arial,"Liberation Sans",FreeSans,sans-serif}optgroup::-moz-focus-inner{border:0;padding:0}.ie6_button,* html button{background:#ddd url('../images/button.png?1298351022') repeat-x;border:1px solid;border-color:#ddd #bbb #999;cursor:pointer;color:#333;font:bold 12px/1.2 Arial,sans-serif;padding:2px 10px 0;overflow:visible;width:auto}* html button{padding-top:1px;padding-bottom:1px}.ie6_input,* html textarea,* html select{background:white;border:1px solid;border-color:#848484 #c1c1c1 #e1e1e1;color:black;padding:2px 3px 1px;font-size:13px;font-family:Arial,sans-serif;vertical-align:top}* html select{margin-top:1px}.placeholder_text,.ie6_input_disabled,.ie6_button_disabled{color:#888}.ie6_input_disabled{background:#eee}/*! * BEGIN jquery-ui-1.8.18.custom.css */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{zoom:1}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#dcdcdc url(images/ui-bg_highlight-soft_75_dcdcdc_1x100.png) 50% top repeat-x;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_0_ffffff_40x100.png) 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #aaa;background:#efefef url(images/ui-bg_highlight-soft_75_efefef_1x100.png) 50% 50% repeat-x;font-weight:bold;color:#222}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#222;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#ddd url(images/ui-bg_highlight-soft_75_dddddd_1x100.png) 50% 50% repeat-x;font-weight:bold;color:#222}.ui-state-hover a,.ui-state-hover a:hover{color:#222;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#dfdfdf url(images/ui-bg_inset-soft_75_dfdfdf_1x100.png) 50% 50% repeat-x;font-weight:bold;color:#140f06}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#140f06;text-decoration:none}.ui-widget :active{outline:0}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #aaa;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #aaa;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#8c291d}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#8c291d}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#8c291d}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_8c291d_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_8c291d_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-off{background-position:-96px -144px}.ui-icon-radio-on{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px}.ui-widget-overlay{background:#eee url(images/ui-bg_flat_0_eeeeee_40x100.png) 50% 50% repeat-x;opacity:.80;filter:Alpha(Opacity=80)}.ui-widget-shadow{margin:-4px 0 0 -4px;padding:4px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.60;filter:Alpha(Opacity=60);-moz-border-radius:4px;-khtml-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-autocomplete{position:absolute;cursor:default}* html .ui-autocomplete{width:1px}.ui-menu{list-style:none;padding:2px;margin:0;display:block;float:left}.ui-menu .ui-menu{margin-top:-3px}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;float:left;clear:left;width:100%}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:.2em .4em;line-height:1.5;zoom:1}.ui-menu .ui-menu-item a.ui-state-hover,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:hidden;*overflow:visible}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:1.4}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-dialog{position:absolute;padding:.2em;width:300px;overflow:hidden}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:0;overflow:auto;zoom:1}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px}.ui-draggable .ui-dialog-titlebar{cursor:move}/*! * BEGIN jquery.qtip.css */.ui-tooltip,.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px}.ui-tooltip-fluid{display:block;visibility:hidden;position:static!important;float:left!important}.ui-tooltip-content{position:relative;padding:5px 9px;overflow:hidden;border:1px solid #000001;text-align:left;word-wrap:break-word;overflow:hidden}.ui-tooltip-titlebar{position:relative;min-height:14px;padding:5px 35px 5px 10px;overflow:hidden;border:1px solid #000001;border-width:1px 1px 0;font-weight:bold}.ui-tooltip-titlebar+.ui-tooltip-content{border-top-width:0!important}/*! Default close button class */.ui-tooltip-titlebar .ui-state-default{position:absolute;right:4px;top:50%;margin-top:-9px;cursor:pointer;outline:medium none;border-width:1px;border-style:solid}* html .ui-tooltip-titlebar .ui-state-default{top:16px}.ui-tooltip-titlebar .ui-icon,.ui-tooltip-icon .ui-icon{display:block;text-indent:-1000em}.ui-tooltip-icon,.ui-tooltip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.ui-tooltip-icon .ui-icon{width:18px;height:14px;text-align:center;text-indent:0;font:normal bold 10px/13px Tahoma,sans-serif;color:inherit;background:transparent none no-repeat -100em -100em}/*! Default tooltip style */.ui-tooltip-default .ui-tooltip-titlebar,.ui-tooltip-default .ui-tooltip-content{border-color:#f1d031;background-color:#ffffa3;color:#555}.ui-tooltip-default .ui-tooltip-titlebar{background-color:#ffef93}.ui-tooltip-default .ui-tooltip-icon{border-color:#CCC;background:#f1f1f1;color:#777}.ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{border-color:#AAA;color:#111}#qtip-overlay{position:fixed;left:-10000em;top:-10000em}#qtip-overlay.blurs{cursor:pointer}#qtip-overlay div{position:absolute;left:0;top:0;width:100%;height:100%;background-color:black;opacity:.7;filter:alpha(opacity=70);-ms-filter:"alpha(opacity=70)"}.ui-tooltip .ui-tooltip-tip{margin:0 auto;overflow:hidden;z-index:10}.ui-tooltip .ui-tooltip-tip,.ui-tooltip .ui-tooltip-tip *{position:absolute;line-height:.1px!important;font-size:.1px!important;color:#123456;background:transparent;border:0 dashed transparent}.ui-tooltip .ui-tooltip-tip canvas{top:0;left:0}/*! Light tooltip style */.ui-tooltip-light .ui-tooltip-titlebar,.ui-tooltip-light .ui-tooltip-content{border-color:#e2e2e2;color:#454545}.ui-tooltip-light .ui-tooltip-content{background-color:white}.ui-tooltip-light .ui-tooltip-titlebar{background-color:#f1f1f1}/*! Dark tooltip style */.ui-tooltip-dark .ui-tooltip-titlebar,.ui-tooltip-dark .ui-tooltip-content{border-color:#303030;color:#f3f3f3}.ui-tooltip-dark .ui-tooltip-content{background-color:#505050}.ui-tooltip-dark .ui-tooltip-titlebar{background-color:#404040}.ui-tooltip-dark .ui-tooltip-icon{border-color:#444}.ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}/*! Cream tooltip style */.ui-tooltip-cream .ui-tooltip-titlebar,.ui-tooltip-cream .ui-tooltip-content{border-color:#f9e98e;color:#a27d35}.ui-tooltip-cream .ui-tooltip-content{background-color:#fbf7aa}.ui-tooltip-cream .ui-tooltip-titlebar{background-color:#f0de7d}.ui-tooltip-cream .ui-state-default .ui-tooltip-icon{background-position:-82px 0}/*! Red tooltip style */.ui-tooltip-red .ui-tooltip-titlebar,.ui-tooltip-red .ui-tooltip-content{border-color:#d95252;color:#912323}.ui-tooltip-red .ui-tooltip-content{background-color:#f78b83}.ui-tooltip-red .ui-tooltip-titlebar{background-color:#f06d65}.ui-tooltip-red .ui-state-default .ui-tooltip-icon{background-position:-102px 0}.ui-tooltip-red .ui-tooltip-icon{border-color:#d95252}.ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{border-color:#d95252}/*! Green tooltip style */.ui-tooltip-green .ui-tooltip-titlebar,.ui-tooltip-green .ui-tooltip-content{border-color:#90d93f;color:#3f6219}.ui-tooltip-green .ui-tooltip-content{background-color:#caed9e}.ui-tooltip-green .ui-tooltip-titlebar{background-color:#b0de78}.ui-tooltip-green .ui-state-default .ui-tooltip-icon{background-position:-42px 0}/*! Blue tooltip style */.ui-tooltip-blue .ui-tooltip-titlebar,.ui-tooltip-blue .ui-tooltip-content{border-color:#add9ed;color:#5e99bd}.ui-tooltip-blue .ui-tooltip-content{background-color:#e5f6fe}.ui-tooltip-blue .ui-tooltip-titlebar{background-color:#d0e9f5}.ui-tooltip-blue .ui-state-default .ui-tooltip-icon{background-position:-2px 0}/*! Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE6+, Safari 2+ */.ui-tooltip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15)}.ui-tooltip-shadow .ui-tooltip-titlebar,.ui-tooltip-shadow .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.Shadow(Color='gray',Direction=135,Strength=3);-ms-filter:"progid:DXImageTransform.Microsoft.Shadow(Color='gray', Direction=135, Strength=3)";_margin-bottom:-3px;.margin-bottom:-3px}/*! Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */.ui-tooltip-rounded,.ui-tooltip-rounded .ui-tooltip-content,.ui-tooltip-tipsy,.ui-tooltip-tipsy .ui-tooltip-content,.ui-tooltip-youtube,.ui-tooltip-youtube .ui-tooltip-content{-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.ui-tooltip-rounded .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-titlebar{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.ui-tooltip-rounded .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-tipsy .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-youtube .ui-tooltip-titlebar+.ui-tooltip-content{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px}/*! Youtube tooltip style */.ui-tooltip-youtube{-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333}.ui-tooltip-youtube .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,0.85);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border-color:#ccc}.ui-tooltip-youtube .ui-tooltip-icon{border-color:#222}.ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}.ui-tooltip-jtools{background:#232323;background:rgba(0,0,0,0.7);background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333}.ui-tooltip-jtools .ui-tooltip-titlebar{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"}.ui-tooltip-jtools .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"}.ui-tooltip-jtools .ui-tooltip-titlebar,.ui-tooltip-jtools .ui-tooltip-content{background:transparent;color:white;border:0 dashed transparent}.ui-tooltip-jtools .ui-tooltip-icon{border-color:#555}.ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{border-color:#333}.ui-tooltip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,0.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,0.4);box-shadow:4px 4px 5px rgba(0,0,0,0.4)}.ui-tooltip-cluetip .ui-tooltip-titlebar{background-color:#87876a;color:white;border:0 dashed transparent}.ui-tooltip-cluetip .ui-tooltip-content{background-color:#d9d9c2;color:#111;border:0 dashed transparent}.ui-tooltip-cluetip .ui-tooltip-icon{border-color:#808064}.ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{border-color:#696952;color:#696952}.ui-tooltip-tipsy{border:0}.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,.87);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border:0 transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:bold;line-height:16px;text-shadow:0 1px black}.ui-tooltip-tipsy .ui-tooltip-titlebar{padding:6px 35px 0 10}.ui-tooltip-tipsy .ui-tooltip-content{padding:6px 10}.ui-tooltip-tipsy .ui-tooltip-icon{border-color:#222;text-shadow:none}.ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{border-color:#303030}.ui-tooltip-tipped .ui-tooltip-titlebar,.ui-tooltip-tipped .ui-tooltip-content{border:3px solid #959fa9;filter:none;-ms-filter:none}.ui-tooltip-tipped .ui-tooltip-titlebar{background:#3a79b8;background-image:-moz-linear-gradient(top,#3a79b8,#2e629d);background-image:-webkit-gradient(linear,left top,left bottom,from(#3a79b8),to(#2e629d));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";color:white;font-weight:normal;font-family:serif;border-bottom-width:0;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0}.ui-tooltip-tipped .ui-tooltip-content{background-color:#f9f9f9;color:#454545;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.ui-tooltip-tipped .ui-tooltip-icon{border:2px solid #285589;background:#285589}.ui-tooltip-tipped .ui-tooltip-icon .ui-icon{background-color:#fbfbfb;color:#555}.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{filter:none;-ms-filter:none}/*! * BEGIN config.css */html{overflow-y:auto;-webkit-overflow-scrolling:touch}a{color:#00f;text-decoration:none}a:visited{color:#00b}a:hover{color:#f00}a:focus{outline:0}#sidebar{background-color:#ededed;background-image:linear-gradient(top,#ededed 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ededed,#f5f5f5);background-image:-moz-linear-gradient(center top,#ededed 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left 500,color-stop(0,#ededed),color-stop(1,#f5f5f5));background-image:-webkit-linear-gradient(top,#ededed 0,#f5f5f5 100%);background-image:-ms-linear-gradient(top,#ededed 0,#f5f5f5 100%);border-right:1px solid #c2c2c2;bottom:0;left:0;position:absolute;top:0;width:150px;-moz-box-shadow:inset -12px 0 30px -30px #000;-webkit-box-shadow:inset -12px 0 30px -30px #000;box-shadow:inset -12px 0 30px -30px #000;text-shadow:#f5f5f5 0 1px 0;z-index:2}#sidebar-pane{border-right:1px solid #c2c2c2;position:absolute;padding:0;margin:0;font-size:1px;overflow:hidden;top:0;width:5px;left:151px;cursor:default;height:100%;background-color:#dfdfdf;text-align:left;z-index:2}#sidebar-trigger{position:absolute;padding:0;margin:0;overflow:hidden;text-align:center;font-size:1px;cursor:pointer;z-index:1;visibility:visible;height:35px;width:5px;top:50%;left:0}.trigger-left{background:url('../images/mini-left.gif') no-repeat scroll right top transparent}.trigger-right{background:url('../images/mini-right.gif') no-repeat scroll right top transparent}#logo{display:block;margin:auto;margin-top:5px}#tab-container{bottom:0;left:0;overflow-x:hidden;overflow-y:auto;position:absolute;right:0;text-align:right;top:50px}#tab-container a{text-decoration:none}#tab-container div{border-bottom:1px solid transparent;border-top:1px solid transparent;color:#808080;cursor:pointer;font-size:13px;height:28px;line-height:28px;padding-right:25px}#tab-container div.active,#tab-container div:hover{background-color:#d4d4d4;border-color:#bfbfbf;color:#000;-moz-box-shadow:inset -12px 0 30px -30px #000;-webkit-box-shadow:inset -12px 0 30px -30px #000;box-shadow:inset -12px 0 30px -30px #000;text-shadow:0 1px 0 #dbdbdb}#content{bottom:0;left:156px;color:#000;overflow-y:scroll;position:absolute;right:0;top:0;padding:15px 20px 20px;min-width:400px;font-size:13px}.colmask{z-index:20;position:relative;clear:both;float:left;overflow:visible;border:1px solid #dfdede;background:#f4f4f4;width:100%}.section,.Servers form,#addFeed,#addFeedContent{border-bottom:1px solid #dfdede;overflow:auto}.section:last-child,.Servers form:last-child{border:0}.col2{z-index:10;float:left;overflow:auto;font-family:"Trebuchet MS",Verdana,Helvetica,sans-serif;padding:12px;width:250px}.col1{z-index:11;width:100%;float:none;padding:12px 0}.col2 h3{background:none repeat scroll 0 0 #666;color:#fff;padding:6px 8px;vertical-align:middle;margin:0}.example{background-color:#fefeee}.presets input{margin:2px 0}label.config{overflow:auto;float:left;width:24%;font-weight:700;display:block;text-align:left;margin-right:10px;margin-left:20px}label.narrow{width:200px!important}label.wide{width:auto!important}.desc{display:block;margin:0 0 0 24%;padding:3px 0 0 31px;font-size:12px;font-style:italic}.desc.narrow{margin:0 0 0 200px!important}.desc-check{font-size:12px;font-style:italic;padding:0 1px}.col2 p{font-size:12px;color:#666;margin:1em 0}div.field-pair{padding:6px;clear:both;float:none;overflow:hidden;min-width:555px}#content fieldset{border:0;outline:0;min-width:350px;margin:0;padding:0 12px 12px 6px}textarea,select,input[type="date"],input[type="datetime"],input[type="datetime-local"],input[type="email"],input[type="month"],input[type="number"],input[type="password"],input[type="search"],input[type="tel"],input[type="text"],input[type="time"],input[type="url"],input[type="week"]{padding-left:5px;border:1px solid #d4d0c8}select .selected{font-weight:700}select option{padding-left:5px}input[type='checkbox']{display:block;white-space:nowrap;padding:0;margin-left:5px}textarea:hover,select:hover,input[type="date"]:hover,input[type="datetime"]:hover,input[type="datetime-local"]:hover,input[type="email"]:hover,input[type="month"]:hover,input[type="number"]:hover,input[type="password"]:hover,input[type="search"]:hover,input[type="tel"]:hover,input[type="text"]:hover,input[type="time"]:hover,input[type="url"]:hover,input[type="week"]:hover,textarea:focus,select:focus,input[type="date"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="email"]:focus,input[type="month"]:focus,input[type="number"]:focus,input[type="password"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="text"]:focus,input[type="time"]:focus,input[type="url"]:focus,input[type="week"]:focus{background-color:#fffff0;border:1px solid #aaa}.col1 input[type='checkbox']{position:absolute;top:auto!important;height:16px;width:16px;margin-left:0}.alt{background-color:#eee}.even{background-color:#dfdede}.readonly{background-color:#eff}.multiple_cats{padding:5px 10px!important;margin-top:2px}.padding{padding:6px}.disabled{color:#aaa}.padTable p{margin-top:0}.nomargin{margin:0}.copyright{margin:0;padding:6px}.path{font-family:Verdana,Helvetica,Sans-serif,sans;color:#000;font-weight:400}.darkred{color:#900}.scheduleEntry{padding:3px 0}.time{padding:0 10px;color:#000;font-weight:700}.frequency{padding-right:5px;letter-spacing:.5px}.padTable{padding:15px;overflow:auto;clear:both}.padTable h3{margin-top:0}.catTable th,.catTable td{padding:5px}.catTable th{text-align:center}.default{background-color:#ffffe0;border-bottom:1px solid #aaa;border-top:1px solid #ddd}.hidden{visibility:hidden}.float-left{float:left}.float-right{float:right}.align-left{text-align:left}.align-right{text-align:right}.align-center{text-align:center}.nowrap{white-space:nowrap}.Key{display:none;border:1px solid #ccc;width:425px}.Key th{background:none repeat scroll 0 0 #666;color:#fff;margin:0;padding:3px 9px}.Key td{padding:2px}.Key tr{border-bottom:1px solid #ccc}#infoTable{font-family:Verdana,Helvetica,Sans-serif,sans;font-size:12px;width:100%}#infoTable tr{line-height:17px}.infoTableHeader,.infoTableCell{padding:6px}.infoTableHeader{font-weight:700;width:160px}.infoTableSeperator{border-top:1px solid #ddd}.icon{padding-left:20px}.loading{background:url('../images/loading16.gif') no-repeat left bottom}.success{background:url('../images/yes16.png') no-repeat left bottom}.failure{background:url('../images/no16.png') no-repeat left bottom}#fileBrowserDialog{max-height:480px;overflow-y:auto}#fileBrowserDialog h1{border-bottom:1px solid #4e4e4e;font-size:1em;font-weight:700;margin-bottom:12px;padding-bottom:4px;text-align:left}#fileBrowserDialog ul{margin:0;padding:0}#fileBrowserDialog ul li{margin:2px;padding:4px 0;cursor:pointer;list-style-type:none}#fileBrowserDialog ul li a{color:#000;display:block}#fileBrowserDialog ul li a:hover{color:#00f;background:0}#fileBrowserDialog ul li a span.ui-icon{margin:0 4px;float:left}.browserDialog .ui-dialog-buttonpane{background-color:transparent!important}.browserDialog.busy .ui-dialog-buttonpane{background:url('../images/loading-bar.gif') 10px 50% no-repeat!important}.fileBrowser{margin-left:5px!important}.ui-autocomplete-loading{background:#fff url('../images/loading16.gif') right center no-repeat}.ui-autocomplete{max-height:140px;overflow-y:scroll;overflow-x:hidden}* html .ui-autocomplete{height:140px}.ui-menu .ui-menu-item{background-color:#eee}.ui-menu .ui-menu-item-alternate{background-color:#fff}.ui-menu a.ui-state-hover{background:0;background-color:#0a246a;color:#fff}h2.activeRSS{margin-bottom:10px}.activeRSS a,.activeRSS a:visited{text-decoration:none;color:#000}.activeRSS a:hover{color:#4b4742}.favicon{background-position:center center!important;opacity:1;top:-1px;height:16px;width:16px;float:left;margin-right:2px}.feed{text-decoration:none}.feed_enabled{color:#000}.feed_disabled{color:#900}#subscriptions td{border:0 none;padding-top:.4em}#subscriptions .chk{padding-right:5px;width:14px}#subscriptions .title{font-weight:bold;padding-right:.3em;width:auto}.ie6 .subscription-title{width:20em}.subscription-title{max-width:35em;min-width:20em;overflow:hidden;white-space:nowrap}.data-row td{border-top:1px solid #ddd}.controls{text-align:right;padding-right:5px;white-space:nowrap}.feed-row td{color:#777;max-width:40em;padding:0 0 .5em}.feed-row div{padding-right:10px}.tab-content{background-color:#f8f4e7}span.count{-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;background:none repeat scroll 0 0 #aca79c;color:#fff;margin:-3px 0 0 5px;padding:1px 10px}a.current .count{background-color:#777!important}a.current:hover .count{background-color:#333!important}ul.tabs{margin:0!important;padding:0;height:30px}ul.tabs li{float:left;padding:0;margin:0;list-style-type:none}ul.tabs a{float:left;font-size:13px;display:block;padding:5px 30px;text-decoration:none;border:1px solid #dfdede;height:18px;background-color:#f1ede0;color:#777;margin-right:2px;position:relative;top:1px;outline:0;-webkit-border-top-left-radius:4px;-webkit-border-top-right-radius:4px;-moz-border-radius-topleft:4px;-moz-border-radius-topright:4px;border-top-left-radius:4px;border-top-right-radius:4px}ul.tabs a:hover{background-color:#fcf8eb;color:#333}ul.tabs a.current{background-color:#f8f4e7;border-bottom:1px solid #f8f4e7;color:#000;cursor:default}.ui-tooltip-qrcode{max-width:320px}.ui-tooltip-qrcode img{margin:0 auto} .checkbox-days{float: left} .checkbox-days p{margin: 0 0 5px 0} .checkbox-days input {vertical-align:middle; margin-top: -1px;} .checkbox-days label{padding-left: 20px} .rating-filter {float: left} .rating-filter p {margin: 0 0 5px 0} .rating-filter select {vertical-align:middle} .rating-filter input {vertical-align:middle; margin-top:-1px} .rating-filter label {display:inline-block; padding-left:0px; width:100px} .rating-filter input[type="checkbox"] {display:inline} .rating-filter input[type="checkbox"] + label {padding-left:20px; width:auto} .rating-filter p > span:first-child {float:left; width:130px} .rating-filter .desc {display:block; margin:0px; padding-left:103px} SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_flat_0_aaaaaa_40x100.png0000644000000000000000000000026412433712541031702 0ustar00usergroup00000000000000PNG  IHDR(ddrz{IDATh1 17Y$t3;_TUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTüŝc)IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_flat_0_eeeeee_40x100.png0000644000000000000000000000026412433712541031732 0ustar00usergroup00000000000000PNG  IHDR(ddrz{IDATh1 1ַP$t3;_TUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPTUAUPT݊IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_flat_0_ffffff_40x100.png0000644000000000000000000000026212433712541031736 0ustar00usergroup00000000000000PNG  IHDR(ddrzyIDATh1 R 7(ȚV`%X V`%X V`%X V`%X V`%X V`%X V`%X V`%X V`%X V`%X V`%X V`%X Vj)2NIENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_glass_55_fbf9ee_1x400.png0000644000000000000000000000017012433712541032046 0ustar00usergroup00000000000000PNG  IHDRoX ?IDAT81 0Bѯl`6Cs<]:[&BA e7lQJŜQY*IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_glass_95_fef1ec_1x400.png0000644000000000000000000000016712433712541032051 0ustar00usergroup00000000000000PNG  IHDRoX >IDAT81 0Cџ $CB}1@)e_ƅ`I8-%cM0 )" LIENDB`././@LongLink0000000000000000000000000000015100000000000013226 Lustar00usergroup00000000000000SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_highlight-soft_75_dcdcdc_1x100.pngSABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_highlight-soft_75_dcdcdc_1x1000000644000000000000000000000021512433712541033135 0ustar00usergroup00000000000000PNG  IHDRd0+jTIDATQ 0o 46nIXD4 =KrIUU]ݔ_!Zړ_n8VW wIENDB`././@LongLink0000000000000000000000000000015100000000000013226 Lustar00usergroup00000000000000SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_highlight-soft_75_dddddd_1x100.pngSABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_highlight-soft_75_dddddd_1x1000000644000000000000000000000014012433712541033135 0ustar00usergroup00000000000000PNG  IHDRdG,Z`'IDATcx&!DJ h$4jJ  1]KFIENDB`././@LongLink0000000000000000000000000000015100000000000013226 Lustar00usergroup00000000000000SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_highlight-soft_75_efefef_1x100.pngSABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_highlight-soft_75_efefef_1x1000000644000000000000000000000020012433712541033143 0ustar00usergroup00000000000000PNG  IHDRd0+jGIDATA 0ts)(ł2踘rV@)T۩#dA+Yl H.&IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-bg_inset-soft_75_dfdfdf_1x100.png0000644000000000000000000000021112433712541033100 0ustar00usergroup00000000000000PNG  IHDRd0+jPIDAT 0 ӳ%iTTGjq!IS*-fֱln@l[Nafϑ?h}sP<IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-icons_222222_256x240.png0000644000000000000000000001042112433712541030640 0ustar00usergroup00000000000000PNG  IHDRIJPLTE$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$$"$ÈNtRNS2P."Tp@f` <BHJZ&0R,4j8D|($ blߝF>n~hhHIDATx]b۶H儒-{iZK:glkn-tIqq? E$dK>$>;PZsVh!Sy0E0}H)-t koܪKp\RϠ .E7 ) *V;~Pe Bx*,=$zDؾ JҸٻ9{ ǸHpqW@"2'B[$ @TiH/b٥96!XHq`DE*R HV!%;" i] dddddddd4y5  Rb@(8CdŪݡ,@T@ibrq0alX!pe, =4bW { 5Ƭhu~(Q^@3="b5XC@JCT76q_5 @,r šɩD)T|O@ ON-ՙ [n@RXIm݋(F @?=0puL;g$@6η K`>п @h գKVn"a" %l@.v$/U^ G:#`` uTtK~ŋZ5T%kxk]\*Q ,҇B44 OXK|yg+_M(lоEO V$T1BXb-|?@ fBXr%'@ҹA\IJ,}BBc\V rh(]tI^}oצo S3 ";ʙb}"߰ ){b$Gwwݾab")T@pF_er6JvШ"mޭM-d76x˰6ӥ;/`>KrP\_^u1%OTM.}Q3.Nس})>-w`a+sy$t)NbFFFFBejnNVn4,A*X*5>PGa 3 {oB &<L[ Nc.öi=`Q@d ͆I.Il`\t[< Cit484-r +f쑱BCB MH iy }>rxp|z;BǏ;burcK4tz1G~`ؚK| ̔>ۡO$~ Ao)0pzz }i`;ADm8n:cfA@s7L Z/..h8or? N93B~o_'`opO- :TG L;7]`B%˛>*wTpM0H}&t ^1'Oqr'2P͡+z,tIW''|en=dzgRm[NStK{҉mؓVt6ҲR`ζN&}B U(rۗ&1%Q''?l׸+&r{jN಻4) `N狌. ߭ ǣ)q 2?n3Hb`} .`pqY1e_bu7e+N_F(DT,L}LLrmP5|x芥1cx DAb`M(7NED~Mz +4BXd.Mzv͈Pd8p<6?8N*x.6ڍ6GFZ)O !lSshssNp8`'0/<s}.@Ǩs7ξO۟VDa5av]m1+3y6۠>@u50Ps51==p *KVҫ܂ݻc$N4(Xr2###c- 賟Lδ>]5.sYs1f0;'̨Yg銛{@9 `aC(=%bo2=n1 jBoS$n#m=i0ci9}oI qT]W%.(؅]z\x f"]o'u䫵tk{v;AC3ֆwwR_#X (xҋ/q%W hpk_IX'b/fXKi"#####QCLi2t 5L0 QiH2;yTOok;ע ٶ`RNg{zy!Kxm?A(vU~mL(`o/!nmX-{v[ dw=n「sdwzn(}Oy~ m ?XU;,V'+ V&JRZ]᧭:zC'-߆@y 4u `Vۓwъ#zP@Q N>2/{\o)W~a3xLw :_Q;=pּdt\'8~3SRP6y+XQ*޺r ̗ѭ*޺r gl/\U^u$|mbVnw \V|D͊NVNy7k<;/E}?E*dzgO ~g/96f cD}% g$QG7o)U Jo,O@0߾Q(;bw:5 NwRN5Iy'K?}:9mֽ*@f@jU9mҫÍ{$ؗ}dFp|%!DdF>}G{@FFFFFFƦQܞH 3 u Mo~vy}mwz<7nP9rWku=|_nz쿳}@IXn?sn~hhHIDATx]b۶H儒-{iZK:glkn-tIqq? E$dK>$>;PZsVh!Sy0E0}H)-t koܪKp\RϠ .E7 ) *V;~Pe Bx*,=$zDؾ JҸٻ9{ ǸHpqW@"2'B[$ @TiH/b٥96!XHq`DE*R HV!%;" i] dddddddd4y5  Rb@(8CdŪݡ,@T@ibrq0alX!pe, =4bW { 5Ƭhu~(Q^@3="b5XC@JCT76q_5 @,r šɩD)T|O@ ON-ՙ [n@RXIm݋(F @?=0puL;g$@6η K`>п @h գKVn"a" %l@.v$/U^ G:#`` uTtK~ŋZ5T%kxk]\*Q ,҇B44 OXK|yg+_M(lоEO V$T1BXb-|?@ fBXr%'@ҹA\IJ,}BBc\V rh(]tI^}oצo S3 ";ʙb}"߰ ){b$Gwwݾab")T@pF_er6JvШ"mޭM-d76x˰6ӥ;/`>KrP\_^u1%OTM.}Q3.Nس})>-w`a+sy$t)NbFFFFBejnNVn4,A*X*5>PGa 3 {oB &<L[ Nc.öi=`Q@d ͆I.Il`\t[< Cit484-r +f쑱BCB MH iy }>rxp|z;BǏ;burcK4tz1G~`ؚK| ̔>ۡO$~ Ao)0pzz }i`;ADm8n:cfA@s7L Z/..h8or? N93B~o_'`opO- :TG L;7]`B%˛>*wTpM0H}&t ^1'Oqr'2P͡+z,tIW''|en=dzgRm[NStK{҉mؓVt6ҲR`ζN&}B U(rۗ&1%Q''?l׸+&r{jN಻4) `N狌. ߭ ǣ)q 2?n3Hb`} .`pqY1e_bu7e+N_F(DT,L}LLrmP5|x芥1cx DAb`M(7NED~Mz +4BXd.Mzv͈Pd8p<6?8N*x.6ڍ6GFZ)O !lSshssNp8`'0/<s}.@Ǩs7ξO۟VDa5av]m1+3y6۠>@u50Ps51==p *KVҫ܂ݻc$N4(Xr2###c- 賟Lδ>]5.sYs1f0;'̨Yg銛{@9 `aC(=%bo2=n1 jBoS$n#m=i0ci9}oI qT]W%.(؅]z\x f"]o'u䫵tk{v;AC3ֆwwR_#X (xҋ/q%W hpk_IX'b/fXKi"#####QCLi2t 5L0 QiH2;yTOok;ע ٶ`RNg{zy!Kxm?A(vU~mL(`o/!nmX-{v[ dw=n「sdwzn(}Oy~ m ?XU;,V'+ V&JRZ]᧭:zC'-߆@y 4u `Vۓwъ#zP@Q N>2/{\o)W~a3xLw :_Q;=pּdt\'8~3SRP6y+XQ*޺r ̗ѭ*޺r gl/\U^u$|mbVnw \V|D͊NVNy7k<;/E}?E*dzgO ~g/96f cD}% g$QG7o)U Jo,O@0߾Q(;bw:5 NwRN5Iy'K?}:9mֽ*@f@jU9mҫÍ{$ؗ}dFp|%!DdF>}G{@FFFFFFƦQܞH 3 u Mo~vy}mwz<7nP9rWku=|_nz쿳}@IXn?sn~hhH_IDATx] c۶JZgv,ٲ&{?:-[3Ү3qJOptB }6x9s SmCXȸR<QήF ?SHf+&ytSE-G8>Am٪d ~Z#sկ6'аfN( 0%#r(DXXKQL^J*KʱzTA~yd-TLieSS(Kň< bۜE%NS~._c$QUb=+C5>W-Z8BHؗ+$~ǫ+e9*9J*VDoq@.i ovR~SH6w_v cU˂5y@~Rת#J9"!ꎾJ:d$. 3@nVew%w>#vSv ᤵ #,e]T q/|cթbfppߋbH1FS s L(?"#YP)C6C\$V-A$b ߏ3R4m`G\~ c:C.UasuC]7<e7,4 ʯUW-Cv7uT{%*9"VzOFU8ь)Y~+%X4STaWDSWeju^ѓIMg/_Moe"&~m ' sOW7-;3xf7yr#C+9ckM].8qYd#R`kaU^k#/P?*u$~HY52֟^|b{|a,?kE/vkL?o=;dxlE{A:?aM2$GqB+hC>te_O8d0wPlE` AAɂ[.zdaVĀ#O4&k?V `]ْP#NJ7Ybe7,H[F24eYSۉ|B&]KR˥Ŷ ATS6?h{9 "\vr9U{qvk/0W+?q"GW˨`wͤWAF-`ae]n"bMB]p+5޿ 3G]SÎ.1Yax)Ã[<+> smT؆*sɴ,K۶\ij`erY9yaЩ L|Ϟ)L[ T7GRPP$/0*vStWFCE/2:htL?8;>l fYd6ɩ}{ZiukDJӟS\^z L,uFtKyh}jdrf$3:Cd.Uٽ{AojRN 簐џQ S/]VTq _G9sE$Zwa͏FUH# e G1ZwV7>naO[+ʀ4HF^ ׆ONfTpza ƀV@O//S]SύwxTnځZG#N"a]s՜X7 `G{v´?VW_FYͩi+U'4 V 7%yT`뇪rXfOo@Ao>W n2K*fǦMh:75M+ЏyN<ÊP Lon> h:ǙvI~9畺K 5f dķc=8983K4jvyi|@v0cNv+̩1WrJ<=Qm[=(A3LJLX H˦6:խziJc'f&Ltv}15 |%۶%2oCm _x\c)VaF3p[oǽ$\FFO"v p30Fz8L&2pG>0V~XQO~!E  0t${  F0{F「{bZ),\(<`0o%JVA=#J֟߆ L 4lO /ܫbĪ (X&ܮ`XZw222>*Dg) 0ݱ*ouJ(=M^ 8IV },f>+!>? @ejBD8pOagd|PTqg$Ǐ8i)s0,C~\ :UV6U \`77`V1c@fN/ɪǿfPʃV]*h w.藢{7iHu}Jn3@ vebd?wPyW˂ErٵyI*RV2~ET~=N8e! *{,F- :.Yg (^!.j4^6Ե5o B}|~[ ];CU [R)aT>7/{Ky&Ϥ{QOy)#ârύ~a!&Wz Z졽TץRҥ_s]4"oEDAwUT8Hvo%sn\Hy$ȴhz4qR;yu5:??@V'.vlcl77^W QgZ-&5_D?1EBT NN ٞqJ/ {^b!#{ ~M{x/-Jn)Qljk=%46}t yX3KȊ7D:m{μ0-2TULPĆX@ ׎|M#D/vzXp< %#_%=/9(@C@ YMkf#-r@Cʭd8aG@ƌ<@޻@Fƃǃ~?lldž/wlTLdžRnFWbA%Igש½'39R^MRV֡UuC +0i=YS}!uۖ,V/B5, .C|r Z^;0p&h"?ȏo7~olap,lr_UaFH\zh+G_mB[޶CշjSz322`t裇:{GC@{E :\^ ?*;ۢ9/BAo_ @[@ ] Ql uf;sIENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/css/images/ui-icons_cd0a0a_256x240.png0000644000000000000000000001042112433712541031135 0ustar00usergroup00000000000000PNG  IHDRIJPLTE FcNtRNS2P."Tp@f` <BHJZ&0R,4j8D|($ blߝF>n~hhHIDATx]b۶H儒-{iZK:glkn-tIqq? E$dK>$>;PZsVh!Sy0E0}H)-t koܪKp\RϠ .E7 ) *V;~Pe Bx*,=$zDؾ JҸٻ9{ ǸHpqW@"2'B[$ @TiH/b٥96!XHq`DE*R HV!%;" i] dddddddd4y5  Rb@(8CdŪݡ,@T@ibrq0alX!pe, =4bW { 5Ƭhu~(Q^@3="b5XC@JCT76q_5 @,r šɩD)T|O@ ON-ՙ [n@RXIm݋(F @?=0puL;g$@6η K`>п @h գKVn"a" %l@.v$/U^ G:#`` uTtK~ŋZ5T%kxk]\*Q ,҇B44 OXK|yg+_M(lоEO V$T1BXb-|?@ fBXr%'@ҹA\IJ,}BBc\V rh(]tI^}oצo S3 ";ʙb}"߰ ){b$Gwwݾab")T@pF_er6JvШ"mޭM-d76x˰6ӥ;/`>KrP\_^u1%OTM.}Q3.Nس})>-w`a+sy$t)NbFFFFBejnNVn4,A*X*5>PGa 3 {oB &<L[ Nc.öi=`Q@d ͆I.Il`\t[< Cit484-r +f쑱BCB MH iy }>rxp|z;BǏ;burcK4tz1G~`ؚK| ̔>ۡO$~ Ao)0pzz }i`;ADm8n:cfA@s7L Z/..h8or? N93B~o_'`opO- :TG L;7]`B%˛>*wTpM0H}&t ^1'Oqr'2P͡+z,tIW''|en=dzgRm[NStK{҉mؓVt6ҲR`ζN&}B U(rۗ&1%Q''?l׸+&r{jN಻4) `N狌. ߭ ǣ)q 2?n3Hb`} .`pqY1e_bu7e+N_F(DT,L}LLrmP5|x芥1cx DAb`M(7NED~Mz +4BXd.Mzv͈Pd8p<6?8N*x.6ڍ6GFZ)O !lSshssNp8`'0/<s}.@Ǩs7ξO۟VDa5av]m1+3y6۠>@u50Ps51==p *KVҫ܂ݻc$N4(Xr2###c- 賟Lδ>]5.sYs1f0;'̨Yg銛{@9 `aC(=%bo2=n1 jBoS$n#m=i0ci9}oI qT]W%.(؅]z\x f"]o'u䫵tk{v;AC3ֆwwR_#X (xҋ/q%W hpk_IX'b/fXKi"#####QCLi2t 5L0 QiH2;yTOok;ע ٶ`RNg{zy!Kxm?A(vU~mL(`o/!nmX-{v[ dw=n「sdwzn(}Oy~ m ?XU;,V'+ V&JRZ]᧭:zC'-߆@y 4u `Vۓwъ#zP@Q N>2/{\o)W~a3xLw :_Q;=pּdt\'8~3SRP6y+XQ*޺r ̗ѭ*޺r gl/\U^u$|mbVnw \V|D͊NVNy7k<;/E}?E*dzgO ~g/96f cD}% g$QG7o)U Jo,O@0߾Q(;bw:5 NwRN5Iy'K?}:9mֽ*@f@jU9mҫÍ{$ؗ}dFp|%!DdF>}G{@FFFFFFƦQܞH 3 u Mo~vy}mwz<7nP9rWku=|_nz쿳}@IXn?s|#/̅ŹS'><[K 璄Dʯ􅷾v_ـ`]nIYTWX&Z"9X?9شCbya8= Y;)Ƨ;S+"xi#fvzgs{nW~1D?p}Gn#=%,.dY,9ᒨ\s1;Nun֥yѐm;[:nAL"0xȟ%p(Qv삝3~dff=w$z+"nU?AX7t{]x!JLJV/cY|sYNpћq"4^DP)&4B;ig8a"u߷]>7ߕ^?tՎ[7$g~ s/~(a3HőGoJ9V]Qb9N58nTόF^艝L\c"&"CʟGE"j:#c6փ{ox'K Uj9'N}gy7y76Hi1rыz0s EJ4Llʎ+Gg(?z躨∸=_&mG)ݖu4\[I!A;oc$!WGHԟw?vuQ4 85诿|}W$%{ۍw~!))W,]%]Wl`fPh q0jle^vۧ2 rrsKqG_;\ر4GRN7#*g<-+񉳏,0]?| >;n}oa:Qe/JE+"9\v$.C$EtHq2""p) 굻_6O'C48府|U= .бAO˘?=]1EDN~|}$%}ӓ3/[XG<ٓ{ M(9Gnfvͬ7L-?$1Ľz|!: 5 |^F!߬B0 06MZh\46MFmH#5j:1֝lR# CxdI;T>G70a࠵C:PHwŵneCǴtFwxm?矂}jS3/?[[bFTEz$J{EmEg!'= ,ĕ:S 3W(qk.}USǓlcVz%z,ɅgPBŮc I^ Vʞ$۳s-Bu)ܣ}7ܳhL k]},ǻWù0C ȿwsDhUFx MGah/Ģe3ocrݸV/~ ƽZu!}M$Q^F颎ߛH>?uSU|vQ b@Bb.;)!EEhv"p!J\_TBxz#qUqr3]ṕG:59nH籈-M A9SLfq&JOԑ<!yocIwp?6X=Ry|~@ O!5H2݄>!.Yѷ~t"[6 0 dܣ %ǻW'ТQD8 A~Y!FO)\X$W'lYu0\~'J ™":й@3tױIJw5#dgGtEtvSїyAJEppN,go?Vۍ!4ÖŰayNB$U}.!-ݴ#.Q͞tbA5^"Ua.Unuk@Zx&S/Hd H5O&X\H9ՑTwt QYU}V\vg6q&45=mWƧ>S#b1n;$i6G DeL0@'HcK΋݋RM*`-4x `h=Fm6bF&F2F{=a,Yyw%^gɹ4F*ϯ a,I\/sj Ԙ̣Z߰~+[dM鏪%faѺ"|ز~DA sWđge+9nKsmtqw$D IrX>qvLVc*ڷLuӉ&e=Hg& 1dB((j}Jb|MSn|˸87Vt^K'Ӯ^O+zs&c.tUvxMմUң={'M`%bԪRHˀc+K̿]D*[p%ҏ  f""Gų#pzj-hc77LN:ڠ*-mդ<х1Hsc ?t'6>/sU0ޛΨhQYQ֭ ɸ,*=>gU0:։Y2Jxƍs+ ͓ѧ{tf^ʣ0񜷥vڵēVaqx\1"8XZ55) Sՙ:ᖮ9'Ƣ!( Rt\$'y250&#JcE_AWG4GB:6_$=[G阛0~s/pL.xЦLLBDRLvBY:B&j!KC67ďMd=O# "ܣK{3K4!n{)1gv6}n9u^\}gƦơI$ Z8%'u6dqF̋,ÈH.D iM$H"'F<>+}Al(O5с?+G.=XȎ981 pRn饰+^R ݡ}\+BȞА8chuQ{o%I %NaB2w7>TOzROz!.K42pCZ'Fn*AwbIpJD+IʪR84(8"21`)Y#ؑhG#0r!On ą'a҉⨋0O{$bI:YJȍk|[Ds()HO7&5X59ҤDEfsB>SAj >?{ gEUr~T0poHWRگPkB"Gtl !)%cőגn шނ\9|D/+9Ump%O&@6v%6K|@% 'R6W!'ѿ6ğИ5Ya+^*mEbb ]̋L۲e=9AWGfYѣaԶXeGv#V*; Ly+ %SG\aŵ.?I=֨CGhEN$$qH|]ApiИ|>NYFٍBT'=m6-<\"5HN'ņŁNf ],q?X%wh۲pVLAb"!~D |zҤLPqT 9UN '5Ts9ۑ1pzm"'}.bXcF-B%,5QB9%SS x#W]8 3PGh Dl~\"Iѝ E05wQsyDJbFAH66?PJQh%])Ldq}Bt8Ι*rv^))bUd‡ص/%]zEUBUqaVed\"\YNJP-#P`#kf1!lȢp垺i?[ K ϴF.⇍,ZP4A|.PI'bIߠ: 9jru#-'Sɵ!7hiq _;Ս3!z̑#[%qӅnT?lm.Tr%Éx/SG u#g-۔VPIГ$܊Y9POb&$<tZF2E^;GAUL/K?9 [53R##=sM9ו9:}B4Ќ Z~Q+ bbAt\\Sbc.΁s x+UaB B;GxSu/\\ 0<58z=+U5/Tc5;\6AH Aq /֔ld;#`?>GTFWdFXrt(fbn%7k:~?S%JD@LE5O-ÓOSC8yn$R'f"}wAK  N=<^ʎS\W"Uԑmv:>Eb*éw*sqAo?NjDѭ"4ͳ,BO}tK~rN#8}!҆!eA$JK/0 |4&IYP̙Z`v"%Cfm5D(!q_NSTFY\P ϩd¥> @RYJQk=["x. `!a(Qe24Cm+~XWJpPQ*qҀQ_֫=j_U+pf~+ NЫfθs%5(+]9LCz'B߯BĄgNM\OO\pi#*=7l92IMlQ1}Qo_-sςRK 3K X]_x- <CUE71pI30=9 cX@ \*QC-<+yS17֬xL7|8|" z 07<[>pyF7V^D=ܨP;qLj0rzx37g< {v cIpkkD7lJD`S }yġKVӇ O O&]3Mm zS8(a&1D3ɌX SOzPF,l42Dj">;ȝC|P M?dRiW 筐Ǝ+)>o@ۦֹy*Qh&0)f>Od='s#AUW㍀?XȊ}2|Bd_D#%@rcjI XOIE( Θ]tRI=3Al/66\KRG6n=>#EjACGhq7LaA 6`c=` bfYI &ˏvl M!lBN_ֆ!y'EOC=py#]oJ]Z`8Ok0ZK' ୪g =%Rq:? F'z %/D^tI5qZrs"[K)!A鸁k`Yu )bҰvՌ$Cws+l{'SF(.jYo<icT'T'U8s|u%Rs¿p#- $V'3h/T,NBX'N~%.v@QL`(?b:ꩿ?D( Io4Q5" .>|d5lCKTi3}K%XEEI5FL"`o3%=\ #S#zHNšF70I:ѰebB́.Gxϑ(\ڱS)*CNm]n^課 qOܙ `K:7Xi188,~%H,K6TxGUzx׭kӅ4zoj!mIB@b"thH,1jpi5DLKnFvbى}!`+B1#F$oZتLEZx\+C-dx'k q@lTѫ *7lF_Ĺ7ޟ}7H7\X܄e2v}ۍwVvq to_O.pswGkI<1،hB(r-) ʘ5r5HQP&@J`I㠤BL#]Zqfc >qN"q$;mrE+튺pF!S~=WpW՛72&3PZzD%^,6EzAJl c6MmA!ktfo`TC6*OV g?]u)r6/ΒbN2vnLn1q|tܫ^+Y2Dr#l0%~=k&Ĭ4#hh䗔cfXzo צ;H -A(zX\@ܞ<s1v"IŕbF5!s+~DᐟU Fåa: O=ƟZrO%8s o Yll i ADLo([A6ND4]SF)[~'qRR+L,%"g&Y`[ T.XNߋ{{arh1n5mP(ō^.(ӝ' nX7aI8;ܲHoIO? -rx  R (𺝀#]FW%#l$w|x ~/|=^w_z×ņ]\a[}Su|9>7ܼ[ƒ-_o nET{#8.ܒTR#vLA}3O} yILwHD [2Xsb#塸F44u6I؊*ޔ(ek~_ywkjJIe6>:sE#Gȓ 7d*itG")Xw3I0\5e2+1R']:=n񛀎FɫBXt9Ly|Á{IX}0۬}5<8?/ҍQ8+Ͷ[ E/*RD(L@яu`zmt,ә+/GOٳY,qS~8A}DD - ,(ˠPi"8`Gd 8m uν㰾Ґ)i`BXhZjsZr6uEh͚ s:wS?X{|3#;h}i7[n0qȆp[ﺽ~I.jx.rQx|n/MCI'J>֋Լs.יgZe>ۑ91zIp=7&$F*0YQI5p7O? Npv_Ne}?L{sGh,\9p[ÙR?cA|d6a+ET?'Ma;y^R=b,5‰ixd(*ꍴF6IkYԥ5d,|Ft*y$G1'YOsx ztn7H잂7 wwlB:'ɺ $BZ) %Q!ؑUb6#qjY 6h+HRW b1i$u1>ӳT/~p칻>U57QjP@o'1iL`%$CFwV93'FwG'`> v<8 DT勵ש{װl? Dt%~L {$:3BpPOmi"V^!B$]%;X̜3"| `r xP`h9Gtux[d>һΨ.`F1b}D{yS687D,hc۟: 1~SGϸw?9~oF3~fKp뭷3u/~|$tM~&''ac)ݳg|߆~ϡm<> ka2ǟy߃N~Cկ9.'N,@ۍ.; T\v3UL!Ε9(Z1 "׷d?ӏ5zdE޽3]i{/>O!Q=Qa4P#Sd*80xtjiz ūDsU|"qƣi]j=t F i fj;>IN ŕGYN5zZ6MWO!/pqgffmNijl3)%!գN&RZ+1K=/--#*.c:?SҗT\O}ÙM0^ѣG\6y,..g>=x]oy[/Uc*\J"[%z iy{֭̔K<>'>ڱQɓw뢠bK]OZ4u]Ҭ_IEڡIkK8K' LȍrMZ:2uf!".@ j۱c"]vmxIxNs).j~%t?x=HtJo;:Rbjg>So,9&&9nAeimۮ;Kv׊C.px9.+9's:rXR>,'ΑTo] QC?T _ϓpeqΝ;w nb^9 N6Πhfg1kQ˹C <:Ƒ(3\Ez;7|3Kj]h`{K@% "ڼPVFj#*-U/,>r֧Dd@rQ+Wmq%x_o~rw_Fxm_=}jȭ18B0׵{֣Aj6meBr$8g}ΝW8w\!pl7?F9yt:@λlKqXH,֙$,%Dz )\eL%cEQ\^ŵz6̳q)ArQ[&H2I1ŇAozӛ%Zg @㥹\ s:ә,eFI{hGIWY~D<[vs5땊wg `D@rsssݫ9{*>7OG4T HLH2{dq^tys<_J1#ίteqIWQ&ɼjNp:_kvІfTu]GFDNL,iCx snF4GД֙}&{;.BP`H.\1cw5ĮW|,vlcn:%6p,/̽o}] 0,y76 ? 5a.1hF'>Vi  4d3Σ Hp^4HsӵBaUQ- b$.")t.?w~-l p95&G&G=S'?qz}jۯ6 a;p\1~չ@IXT[?I=?t8I= `ؙVWY# qs:B6fvt*4j-ZF-:#\W Rq^gBnJb{]YF0=y UG]y踼憲ݥEE3 Eql#NJA=ٴw-ɽ6ޟ|ɮ/u<}#~ E5NVg֛*͍H]?F9!KF¨841_bV:N$.T_\o;37kn{=J 0VA;~'IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/ico/apple-touch-icon-144x144-precomposed.png0000644000000000000000000004763312433712541032435 0ustar00usergroup00000000000000PNG  IHDRFtEXtSoftwareAdobe ImageReadyqe<O=IDATx %Wuϩnu#/  bH`Y&+a,Bp[_Gw7vg Mxû^k_ٱ}s󣁏E/]`7%2݃L\)̂֙fx1O/<{pS`|'#Gy?|ϯO'666Mۯnxh~ DLnZ"87$'# *w4%~a]hMXòe#C/7}woWWϾW-1nJdW|qc=zËnݝ9-H%KqU_BMI1J% I0,8%JI0ON[ݟ/OG@WUo{|U _kYJei+GI;{5J=SҜ0hDViQiXp,~Os`eep e 3 W\ Ĺ!U6 ك!ZaSY'z!_lT􀊥D ֓TYBW}{˿莿w?yU~P*)-1"֮gLx*=@i/X>4]\ēH7-JG~ǿvP~koy) 34~qS%+N!IAy{RPO icĸ*V[Ҵ!#? AD}Ώ~C/o>?o{a}}8Ϲy?@'OrSZ ]]ލ_/D;b;b h^_p =i`:Ot&GHBJ$WTNR>!rCZ ضҭ ۟KӏvnT*MB8-}Mz*vC{}0-܀J='5CL'!R 8LiYMF`RXi!̗G[?s^y}ѶgM W,Tkݹiϵs=iwf8z@9Von/w00pFX0N¬p SW%qN@~)&@t9-/-n5x_m[d> e!ɸ .^HC'+AmqDzwV^`*K..LR>YmU!1a Q^4ja/}+}:#B>o?R= Ш(ȴJ4aﹷ'>b}˫n|^ 49Xh=R\C3+݉4mD.(UTߑςM%UTJ3&1*  ^$F0Kz*^/X5_`4-&K-Y`Myc+ HvLc#^q߮{ny"#7./,Edf<ϒ/FT=ը&ynY4wjDž (\Q ]ɲjy"-I3,$ya=Iw@QbZGpr$BJciX _ .9h4G=9 o7T'_6_e;(/ O'0nӾ/Zr< bxx"/•#@W?.GguR *^nB9yRu>v<_RՀ㳟 VSn`H5յaüH}y=Kp!hW|\}- KW򂻄D[r&'yzqޖ\w1-i\h=,Q,? eIՇ.1.0btnXB \S[\aUr|/~Bi4{'8X^9(Ah-K=#h,AB/`*1D{! 4B >r)`g^VɰjX}> Akd"3&9 ӭ1Yc.(ȿe.A{ gfS%TCzGy`-n*8sd[Jt*{8NFWxvF $Uw|w3^h'A,|`/o;&EPxdz:wmTj(ii#d)JhA@Q$3K?IبG? '%cQ4S(/0Y݄ضw;RI$ ;u(SȚZ_)>'d#<){Cτ}U-9Td`S}&^VԒ2obH+.G]|bʙrpM .1&lu֞ 7>;{Vtn[u%lk|u&>AECF*-fsPA&V EW!=1AC UУƄJf!OξZ!rM,5Y" eӿϪލץtE@K[힫$p =wh.rmѢ 7kk% L"׃s 5d,ƜpCDn  h.Ż8*BNKyL}d4tS@7UUmyR%|mڂ HqNsܘ݉tW~_Q~|ǓA8$_֛%76܁38MTgX6SU:+ 1G)jS:@UN&ZXQydbON%GE=!I3J594ZԈj#|78י+Iltik'N&ɚ$CQ%Z<ĽQpٜS|:mW hcTUtz#M/6)@d$ 431BŽP\R=Cuy!޵&1 |& 9ol:9x{`tmxCBr%)-#JCIg{($&j AmK1؜8hAP8C)]\-k,7~-f̚kINRK,qxr"Dh}9SIJzҏ0^jC1cl1N rmr H䮽PkUʋy9(Do4I5C3֕1C, 9;d 뱒 E^JbUTaU(h Et@K J&!jaQ&}&~ [z6P5Q,hr`k:x[k.C=0$Kr*)$gùAB@ j32@B3Ȥ7rEdtBJ(H]I`a A+4-)<辯4G*D̡α0L}{]  &WH@Tƹ:*ME@cq\āUÒ˘f hU`Er!-QXZHs@J/:H~t&L">t𜣀!¨ƨ* 5 D? đH_pDvΆ\1p_Qsr;\&UN9?.e#'a}?&9CQS& 0褏x$+}p̌ R<ٯA\3Q&ɣFp Cˁp;βZ k*]y 4oֶ +d8p ɲE+PH\kQNh#!2K u}ov&iJ楘/ZǍm #Ke]Zsȇ٧˖H:4~= <(eWQPXbh+*,q>xBOHc ;Hu(2=hmCXoNr>uC'u|\C͔P&\8gV\T4\ ckā}:rk سL0dg4NFІ &80@sʼO.\sM(ٵgA25IRqߢ}Ha(+0\H,S`s!8; ^Lv YL<=K(nFPuz6+cZc;B O$э\FC~֫KN=Vx,0N$UDh(۴Sy$o؅^*̹&Yl3 !c(YLKRFw.${ *} b:|J $ԏ 7M8Sri3gO):uM7z!hmC<pxSc@n9J#b[ HLDو1F&!_pLV\Iq1hq/}ӝMm':]ܥi$icI*)O?DUݗZX@ӝ#x͡nO WZ̍8#5E5NX])8>*uLzUZ,[6g@s*]}oszU A898ZDΔT8걨Kթ5PDJvS4UwH7iNbe[>;<%̭VwŹ88$IZIʆbM:zV E=EڥuL33@&ڰK_RTgD(e,|Y%FNJA}Lie6R+ْB3kj;}px_ |NlB#5YoўIHԑȅ)S,3hWkO1WC*t6CKJR3o8_ɗ@}jD1 L?KZAHd)h';BbR`o=Y0o2Q.Y 9|e֌\Fk 3Zr۶+Fіو{[v X"ZR k&'ˉ/Һ!G/_W SP[277 H'8h8Gxd7tZkƨ4s{>- .ƿ.?KVKB0}i $;Net 1I?Ωe5D8g&H;ۙxAjC'it>X80{wPM$`ZLu2KKb ݩb.gq&FdEiRabe>d˟5"=oWqmac¶-m`K2 T'ԢJb#u.m5ψ.K> Y<+Ec\HW;RG:,ڥ9(|T=A-lC nWҦg`UMxqolďl҄"kϐ9'K`|>6 ;M&c8|NNNYOFX]_Uض .]ԑ-R@ł1gx=DԦ%>H$u$$@;jCi0(uE? 1͐K=֥dΖḧ́`HUq PiS. 5lҵk'z09Uk8xL^ ,wXX];8;nT<0!k:aVX[`b%TUL0:FI۔:H cHSvrC &ois=O+hw#iM#H*Y8rӡ B`B'´Ot- EWrdԄ' 's8ZM MpYYeu'AӴ7tϱ_jk{./ uW`VI'r0W>I%>:<Y5EudMz$9cN"qsNB 1?g qMƛeDZok%zS9d&* 7tr>Ƀz7M6<WE1ia4+k6"hHӖ4DD5Od< a_֎^t%C8AOXn()AUq@z@KuRXc%.RL4$pR!JgcT+N>@ GN˄-Ndm @qhH^ێ;kkvKo&tf-8 [L=O$lv:j¨ [`i}x}%imY\q:Wba"*gs.VJ"㝊Zs8 K*ǧt5r|m,|8+m(&b&*x|u$𽐬ۉ4'E;Jf`X,9YދݶJJywjbT3S u1,(l"H$[ fgy[Ps|'<:aЛfɝxj}'E a:pV'Uc],*[p@bA ]`:f砝흝G7,PSr} Pk *6ǰ;lxs{Pn̟{M\CْϚbN21A& 4Ve(HlNo<VOF)M:x݁\w5_Z߿?%dZd9Z#$9w衼z0wRgu%]^k}o6 H}{Kҿ Yisrzm}\e8a܄LMۑݦYMMǚj]{2'N|s.IYU=vIv~./T|/:r8gwQ$`$@Mv%'e5r Lx&-ܨ+Z`u*"RSchkLsԪ隗ın:UK;I}ݸŻٰKB6!&:8f iqh 隮Oz:ݺ9|4yOI>9R kQ'ZUTQM 52tLAіWԿ2$83|miR`=Pךij:Ě1R=3'OCfRؘx7ϺaOrYmQULkwglr (ujS=d}u'|4=Kѝ>6fi.(f _ A%A#or(I4#5&zХf9L<"m<_͡3X:N(&!â?}`o?0^}-ҎEw&-9G4ԫ{.4PDjYYII'%;21'0thFƮ%㯉 mʜ.,SI(l$M3 K^¶UNtDVz#\c#@ȚOuT^ ڜgib W+IքEzx a9Vec^Ve1L*xJ[ XXkoQ)?ib[{MpR3vn1WVۚlb.)ȟjEJ&S3U"sj_w21[)$!45]UJBkg"qhhflerG[G1d)(wb“:s%Ya~a> ?υٿ0KȱF<#BozcB˒R4v38%aZ~ZïL.TS5L _ܶ)"t>MPh[2ZZV'LXkGS]mDFy}&K))w|'~T Ɨaz͠IbbUnp-U4N`x8W* Q 0 21wIy0eAm+WY4-E\͐Ac2R Rr:+岟JĭpJ//ǔ\3-.vR"b1ɋzo])rFݙ#}nؑF_98}.~rVv9oՙ]oohYNV)c?H~zن4^{chx,m5`uwm]kQP_c IըfYdxv?&'Џmt\(wKW_ ]w1,P2S42t(?-^ܳykWMV1Ӱڊ38 2^uZvݸil߳cO'HqD(V:ݮ٤S&|FF l*EhJ;  88Gn]0YpOU:_.J(qQT>OUĒ1h +x.a}}YD!/j$_*ȸ"NtTJ!\#3};;n.Y[#h6۴NFjŞMKHJĜ1$4ri2rn1:\D,'iC'H߹wB8E}0r4< xcwM `z`Dtˎ4M[fefT*̝!t=*9Α c/ǖq/np;ܸ :l)տь So2v&ͥp9SȖ.xR冥biQR8_ G.muȰXznݹ u+<[ࢇYhxwwy'~ J,&%}0Ⱓ:+Ibw z\0< s×O_ =o/\z=8osx$L& DUY;;P*|'SmV07R: ʌ?P RkD/=Vn &sKۻwufj%|\^A4粚zm pY1;QGJ%Qwq/Wžj#̣Jd吇0?7D2bŅyjsI'2*KjNؾ\|wlYe|<黪g9{_۽JbTjiL#,.Y]޼|O֙qLLd}d&ThR6 z~G}/|[ 1S?䬈{D.4qS?h<C4DRR HγHk$o,FNd^p=]Vyq/j`vv6oy Lb=mOuk2 Iޫة6yW;8[pp]pYWwv-\yӳRDZVt;TG9P?w ⥛ົ;NdA~xAq@a#'R&pN5BK5}Cې ZB5>kp-%8X9id9G^-*76[vI-JBry3͋vF~X$EbYv+FW'C￳TNߥt4=U?[)_>rU}EYV슉F%ƴ+dž0lNhej\la>ǚD?fpBv.[/?& ORASINR`Rxe6(t3VRA:!s\+9 3n5 I=X l߾~ϊmW\qկ>)p㕯|9;8rH\Ҁi|ziSU/!Q/Gb^/hN0mgVsa{1p4s&~χ8_dWZjb 81.547wy~(t9mȜOmf+8b I>s.K]+ 8:-mԡew2~i5K cX$]$Qg̓>|n8~YhJ?讻Bp饗ypT oUaJIB&c|WHQXF0Ci <藪]@/,ۿwqBwy'~tL2WO|_,-oՙGQi*Na3>F(CrdT}NĹ%mϑ$ʍTJ9ГIχFbŤTF>N,p׬g$SS I6pɑ6˲VJr5W IH .Ӄd-pCpYq˴@d}{lu]Gklfnn.c%cǎ=b i\xh$+ >yv2bΖL'+̉LS$Cڽؤ3y؏X|x[ wq||*;Wy6.JGga)}fg#T,f(8F0dGґ˴bsSa )?N%ϧz|JJ o^Jki>w`B< 'ڝr2+~Ps\W4ZpEϱ61#g&}֠G_ 鬊ZѢqJ^3/AC9o:w-gH}ܳ$+@'I=1«h\h,v16Fvەҧ*'h>~rYO$QA cVyV}MozS1ibT%%BQ}z~C|#pǿyx^ގD'J~ O]Γn['c5߇/NI5j@\zK3O")oabK_ɜ>vNw2e2oQCA8R .Q˯73V' }hDkdIֲfr);q.wxf=8Z=C:̍ RO hH$%2b1I6ǐF昱(<ް7YsDu3} 2gB}Za^F(/NZrz-#9O>[76]Oe-(Ɯ| t}P A_ ?PO j{PFk@F{5ͩϥr;u DatܒM7|( WN`na_rT:fM))5Sr}o jXzimYbٚW?c3`@M ٚ6}D0QOo{ű͋(f-$Ĝ*FŬ꒠cZ>5oڥ}dgEbҏsoO^d#b~jƳÒ:y I6 }l@J.~wy>MЉ{VKۈ7+ |U'9Gw6<(ڇȘH]TiҐsf)|W7F1& bbd ݸy:": rcnJ2= `\pŸuo?.O<^c.8tޥn$oڠՎ !VqVrT ^ĎV2HSV<ߪX}ȍ@mcE&'OGqTz9hiSrHgD21ՕKT1.*A"ر&]@%MC|6}{@k6mi3.ggRSfv3 iQzgm=s _ǓW =cI,C1dQ]JA5՜~tJ=W5/)*0轱d:qyav*r 7:1fu oACv<5A3栻1Ψ4L8O"qDű us~iA+>sTLCBG1MǹZUGTPh'4h WcP2Yp!ޓ#M?8.^qď`vܭ "SR=8XE8Nl8=:(zKcXM} {t2NljD۠e:DjE&'^CRE9T:~\xqEMm6%!#7e&LK-~7d^†p"8N~'Y]!{mK;4!eBDHNX!E'k :j 16e\O&D2 E;wbu'ŗft[bMRWzliy7O׶fhjZ   @Tj7&ocjW Ztm-ËOrV[VQK:I"3oC6UMiSA0A?cgDwq7圓uwmF[ OrS'/ ?LD2{L>gr8X؈Ԡz_l4^#,|E&0L]i,tiVU҅jq(nP"-LHL>sD:Lmgy'aJR3!!6JD i09e"%]ڊզQ^K^Ky)8@:g~bZtWA>]*PKMQe*/yO 7NT d#?t,D=zh^2z]>UυetrKAԳ,湳:k[GMΤ ge@nK1[Ga긕VoPȲ̑@hB  YG)Im){[<`Bd*MԋMXE$$[GDzlyE o>@f\rkqԫNT쑣iVsaވRrN:QD`N [1=@$[ yC#s5HGi&&Nc?d=' Irj f5,JTUg5 M|D8xu77eg <&NϝϚGٽӚ3[Ms.oA\]>_VFC~AWCji( =S^Q{K_z8xpd7/ӂȕ rƌٜs+%V M]4z^dByE!XH w'!!!9KH)E=A z]a_NT.TyAԓL;„0J6>PzB4!U!` z1H/'̉NL G 8<=|<ﱇ~!yw6TY +Ib;'&JѨ#LDe4Iɠm9>21*:MoqDj bѢp+*tRK% Z?!/iK^KjT@w~ xx4}ùF 띌+➓GSF>_u-Q<̅y/֩cAgoM"o/-;HB8%c0u<c'3E7vwΑ!I\_%1%?r:$!wé|[lu틅.gЕ))wEP `!ƵNoAЮazz==.Ҹf. ڔ`'4O|],<6@E#j=)ͫMf*sT\` ,LV %0`b4`8cgOU~μyELtSffhaxYy$?Q1oTɚ)gI>`;J$ C,@}0J9 {q3qI( I|[;di|gi ++++3(k~l G)I<;OGi)g:xYPvEQoTy:qEՁsNnõ{.} .mQ uvVWQf N!zwT.,s63PFB\!mf+,1?Ќ{W7V>c~ScD S< IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/ico/apple-touch-icon-57x57-precomposed.png0000644000000000000000000001276612433712541032302 0ustar00usergroup00000000000000PNG  IHDR99tEXtSoftwareAdobe ImageReadyqe<IDATxڬ[ fU}sofvvf߻, ݅EhAJD6i5 b66)6+ !#M,i}Ě6i1 kk H*]e3~|8y{;}]G8Fo1i;'cð\J@k@?s|I)E6]w:;H.L$:<Ǘ翸^YXZ_'%%"Xi.ƫޝĶ;&v Ϝ&+ F%#a>=Ff¢s]ʃq\=ޖ*g?q0s쳌gZ6 {LwM~js~MRНxG'.бJcGiO+K~kk|lrIUrKwwV hoD:Kwݽ6n^]M K01G0%&Q}{Jsʝc;9k}.}J}Q]]o<<( %K)7/($2FQ!0X`XC*(e%iB"v&Mәg/Yvos,TH̿ytNT'hootF8PV̰ s~;52gZ )i.[Sgb$/ĕawo2J IeU*'IRI#fNh{N9 ճD&YȝgQ8͠?V6[kd%F]whcj;6il&!ib&@P昁HEoڜ]+x$"r(WIk NѤQ[dWe,U\/`]'6_ͤ& CA%xDA/a*svRA*gtA" `SrUԬĽa5DuzDҌ"ҙj]P M2X>NZ- 27O߮VR5$N Tr@-y#9-I$ GcMe`DEG0w| vT!%j^!DK#; HDt/Ƀw $2Ѭ=1`Y۪{G!VDfiamf"Y܀]7{Ճ/Vf5 dTe` <ey}UhUol@Jc7 btnz=trFF5 5w|>jCN=@xΜZY1hVIڔV"l&QDt(̾B{$ QwMsz5q zED}>s3(:@`l8kA&4 1рzIDXO,Q8@3h Ki IDPeQ w3wP,,BQ!瞂ޯv7Q95I;WX6 _C12Mx}Qw֕ӰεKdSt>V 'y9 bIb ף\8I0 m Pv Q2fVCYo&tA}Zdc>62Ɋ)aMWl&.f$,6_!T4 sI@&uv rWLd{h4Єi?*dؽ^`J*t7_5 f)[|eLZJ频E\3֢0`|V0ɀ$ AL_'UOZ㉜|^.=kzJ(*eL awf"u~qI.D2d^ %1%H\衺4WΞ`vgcH6JbAՠ5&EP,4ʐՀS6`'ऍ L S4.;GL/M&}@]=9j,(/q>V(z%*%" jPy`T@9d{$Kc1s|q$G&6ߥ0 ;F 5'~̌B+&l5ci5u1J)l݉Z:<5 w0R30#!X.&' a#}C02,+dpYO^90{^#t&'<3EBʤb/"t14$\ rqlF/#F0^Y*T_Ү[d0s8G"L#oiG:$l-{ ҝv@Vmcsacie\a@>R%@hF 2őa܈ؘ#ʇۇ7x, KyL52Xs,a!x@^B8LU"3 ?tش#QvkUp*\*48Ȣ ;RLj<- rX( bd2y|06v?X[VҤjĖڂډ\\=@}pem ۙ$^"6I>aM`l.Q ZDkʓrMfiȑ#xG/{ycp7tfggL8p࢓޸z  [:wnOΪw=wchQ?s mv+ϰd9TF L‰IN4 "Ө9e%]oo| n{Evx `Jmy>bxxk&z29 Uw} 9/x*hkBZ}? QF-Wϣ^잾n'TTL@iJm+WS\JgY(^/ߚL>^jYqÇy籴[6˞y})uر#n )b- woVhaSK8%قLtc0~aʸi.Tgpm[/ {k*Ŧ,\S*m‘Mך }ij85AiL^Y> _'hPBd{Me۹S M``4e,g ^j*kaI7RC-q~'|ϰyUh4yuڽBj#w|mȊ&AQ)0pA dഛt'`267&Y@R컪DWViJT+*Xh/?|mxZ]yf2pR< O&}uFB6 Lb)Ha/iYE Ue[,6 j&Tt1w&$(Kb?WJ&FFT="S.Rh?7'3T L˚!RWBtͧWeUk;%ǎnXڒ%}\T-Z}I[Jy/y#ƣgziӚڬky.8+,S?Qڵ P}uQx@@My7Du N(3oѰݲ ^>sW%ņ7I?-.t83}gO{OT l KPW+eTl5 lqv0U@> 6ًT)`N͟^ͨ?dVdյ(}d|Zr{Z= ݐD'$qkYɰ,Ro]&tuCkݓCYOZfsUҸ13`$ \,ȱIENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/ico/apple-touch-icon-72x72-precomposed.png0000644000000000000000000001734612433712541032273 0ustar00usergroup00000000000000PNG  IHDRHHUGtEXtSoftwareAdobe ImageReadyqe<IDATxڼ\ %Uy龏cvB+b&AM hBIBUIU2h(hU1A|Y"E4.ywwϣϽ3}OŦ7( P" ¹ÖWA+mBPҠ߹i9o9r/E M_nigi$i?>w_&]LNZcS05s,˾20{Tə1? q<1쐆fv֮Z6_uFW E5Tv6c~k{`yP1͚FPrgp7&irǟ;N8[wD}5j]uɵY9NVj! EExzT{RcyΉ6u+/}ݝ'&/߾wX雏) _xy˭Yns(nPasVlwpվǺvv݂}DxL4`k{Jm)s ZI 4Cnx&N{ؾC(^yWoJo>C?Z=)l =8I 6GkEp'awk[ Bu<~VL#he7\ުʁUy2@DWja%woӳ^nR?<K| M[Pu|iCy*xVTPw["j3ߑ`XzMpD_3 [my|m."cpt;#IBYZ,]G0l&=m{ ,l锍Q22-Ci2[^.wWe[׬[4mYkdBPR {+ y ~ZsH}ԩ̓fxoP!sJ2Td.叡0߰,qҊ5=5/87m~QݒQҫrR0U%1el$ɀ8(7&ȈPN df D*UR-GX'oZkZIAZ}CvԛUR8Gphf祥(:NH1q_T3dȬFt &dIBqϗ Ph+IM)"~Ne}a(xN~Yj}`7 61ɟ'ne%aCA i:3نV QV y6 zGPaA#-(XUlJr@PN eJyXu3FL-J'm 5ɂ>&iE"@s)Y 26 5xL, {G]>cH3KA idVHYf&dAvjjeqWco\U&sТv) 8DbxHΧfuO XF1u2RVPS,<>41"wN+d>既1hEA_kPBA#"W̓ yYAE 8HEh*iK 3,־MY6 ptN a'%1+9ՠES5H)A-<ݲ,F&g>;|$I[i5rٓobkL*4.2~#r˚x=5FJ"SjPEh1MϏT#r XVS9(K04k1B<.alTT6*,Hbmd3S fYYăA* ݲ85;S6F;EN*`M1EEA IUEg zp:s"0;C)#|.p,uPSbF3(p>OaXтFQ<:6ot;fq~A])CA >蠣o@w7W_EES,( U ie)P,@|l\btNMfO rU釾A%@T@+@d(&ۡpًuLLX@`2PP CqԆZNb)kQ)FnHjhnFyn7jupjTa |JZpn(/)5YAA0`'P} 2mDVmy>0{irPͼqa]@}ތMZ*J.V).3Ha8 *uh4*W1.qx.N?F8q#uIC<'4v@ %6n,D)fX@_o+ƏRejbJEf V YiFm@jr@MnQ>q@vwEoT \D}es}f4ǁ&dIJ($ZxAm& ±+lF0*Vp_D+:0•d$Ө+8F1vZ 'u ]8믆#JeWX,4ʒmDIhP@qcj 6ȼ6㓰NaNyG,% 1KeQne- ڔrN e D(4Yr??@^r K4%}CNfS^Xx8_"Nu@OYZ,K{7a cnaZ˸dm<<p|x9fJhZgQDžBy\"m֍\v goi ֮"ʌE1 .{aMߌCH ue'j P`MHXvI`Îm#afl/R<q,SQk? w6 #wH}R_ btR@PK\ e IRّҐ@\)  V ֖IGׯp$jId*`A)Z8a90?]52Tp6|)W0ka S-95x`DAtH u{w) Zn;LxþL #8S֞7w C᜸z?T}y4v?TQ6OA ٪.!C0svw /6i) ,f)L-pX!5[ɭ+I}G(ʫl*=KAoFq+QB9yxp;+"8dN&|퓰5s" bl օ-7I(r p_%[aa;`a|cx|o^`k笠dȦ1G·- ؂U|[,V{ƚ8%`u {$:*xv`y[vËbBw"_*GTѻ+(C7s9>Hy=<-43 (bȮȬs,o%]@ΓpNiN u<o{64-p X`Bl CkL7\&נ"^;PFp #b Ãn7?C$w#ۀ5z8ԇ&u D ͢y$.EEsӉ &a99 ̡ l90 i 6Su82Ed-Sƴ?A}'`׮og_v> ͏X[n@_'O}9#ฑDaO!2Yds~%U'M& FqF!bȊ;OZ3 vH9!e'zCbu ?hϧ?ix'2ؿ?e>ww#_Ghv=o˖-߰a2 Z#wDŽj٭ r ύr!og;ʅlݻ>o.[ ͛ ,GaNqZW >a#g@*L+vҒy[g=馛ꫯ>c r. %Y)X288MfIN(Κ-}&&&^Y2A\@%KSV>HV"tƒvM.6} kKǗm|u]wݵ,0rm83v^d3Fs|l@Oy3'6*)xzSÇ9fw,-Grm$ѧۄ N"f׸9(G"#EG\~镰1Xs 7܀R 3nk6vܹ4{2IE!%ݓajPHCmâ*%I'''?Kx}F֩O|q=^~l :Ki~UHū|U+2Q:Z1C,ɼr?ׯ7y'GFFΨ v3^҄j2+ V[]g ao|_nI.8p"]ޢ}yI gg{a֭-%N]L>C؈898򱋎{Q^?HlҐaKlro } p<ІZJ'W*ظq-1֪) +5f}}l!(ǎz,x)~* \vjCAq"*jHF V\]SA}6Wù݁E% %G#Uu`86}ֽC%\G(03ed\I<ҖYҘO m ݥ|2nOvh_f"l6U6A`2h$2A5 GiW4Ǒ Fv7/7+\_JC7E@'S,TB%;+ ])ʗ-HUo-$m_H/bi5ۓQz >_BA'j`Et),m̧?n Sԡ:ߌ n[[-d[fW%;jg6Szd|Ogs-~>h6Tz*W [yu>O&-{H'!p˕C&B\hj]ױwDuNV~n:@Jw8$r #G|5UU}}=pS`A-M$vrEFyEb5G+wv"WWY/brAe4"&'k\m Φ e܍h KGۣlvMK|A}aVqra®Z.#4OQf0cY+u[iI❆d)`Ue칃_ѣSCRlΪ˫3oFU1/"5Km×tken=|'ܢrH=Ff¢s]ʃq\=ޖ*g?q0s쳌gZ6 {LwM~js~MRНxG'.бJcGiO+K~kk|lrIUrKwwV hoD:Kwݽ6n^]M K01G0%&Q}{Jsʝc;9k}.}J}Q]]o<<( %K)7/($2FQ!0X`XC*(e%iB"v&Mәg/Yvos,TH̿ytNT'hootF8PV̰ s~;52gZ )i.[Sgb$/ĕawo2J IeU*'IRI#fNh{N9 ճD&YȝgQ8͠?V6[kd%F]whcj;6il&!ib&@P昁HEoڜ]+x$"r(WIk NѤQ[dWe,U\/`]'6_ͤ& CA%xDA/a*svRA*gtA" `SrUԬĽa5DuzDҌ"ҙj]P M2X>NZ- 27O߮VR5$N Tr@-y#9-I$ GcMe`DEG0w| vT!%j^!DK#; HDt/Ƀw $2Ѭ=1`Y۪{G!VDfiamf"Y܀]7{Ճ/Vf5 dTe` <ey}UhUol@Jc7 btnz=trFF5 5w|>jCN=@xΜZY1hVIڔV"l&QDt(̾B{$ QwMsz5q zED}>s3(:@`l8kA&4 1рzIDXO,Q8@3h Ki IDPeQ w3wP,,BQ!瞂ޯv7Q95I;WX6 _C12Mx}Qw֕ӰεKdSt>V 'y9 bIb ף\8I0 m Pv Q2fVCYo&tA}Zdc>62Ɋ)aMWl&.f$,6_!T4 sI@&uv rWLd{h4Єi?*dؽ^`J*t7_5 f)[|eLZJ频E\3֢0`|V0ɀ$ AL_'UOZ㉜|^.=kzJ(*eL awf"u~qI.D2d^ %1%H\衺4WΞ`vgcH6JbAՠ5&EP,4ʐՀS6`'ऍ L S4.;GL/M&}@]=9j,(/q>V(z%*%" jPy`T@9d{$Kc1s|q$G&6ߥ0 ;F 5'~̌B+&l5ci5u1J)l݉Z:<5 w0R30#!X.&' a#}C02,+dpYO^90{^#t&'<3EBʤb/"t14$\ rqlF/#F0^Y*T_Ү[d0s8G"L#oiG:$l-{ ҝv@Vmcsacie\a@>R%@hF 2őa܈ؘ#ʇۇ7x, KyL52Xs,a!x@^B8LU"3 ?tش#QvkUp*\*48Ȣ ;RLj<- rX( bd2y|06v?X[VҤjĖڂډ\\=@}pem ۙ$^"6I>aM`l.Q ZDkʓrMfiȑ#xG/{ycp7tfggL8p࢓޸z  [:wnOΪw=wchQ?s mv+ϰd9TF L‰IN4 "Ө9e%]oo| n{Evx `Jmy>bxxk&z29 Uw} 9/x*hkBZ}? QF-Wϣ^잾n'TTL@iJm+WS\JgY(^/ߚL>^jYqÇy籴[6˞y})uر#n )b- woVhaSK8%قLtc0~aʸi.Tgpm[/ {k*Ŧ,\S*m‘Mך }ij85AiL^Y> _'hPBd{Me۹S M``4e,g ^j*kaI7RC-q~'|ϰyUh4yuڽBj#w|mȊ&AQ)0pA dഛt'`267&Y@R컪DWViJT+*Xh/?|mxZ]yf2pR< O&}uFB6 Lb)Ha/iYE Ue[,6 j&Tt1w&$(Kb?WJ&FFT="S.Rh?7'3T L˚!RWBtͧWeUk;%ǎnXڒ%}\T-Z}I[Jy/y#ƣgziӚڬky.8+,S?Qڵ P}uQx@@My7Du N(3oѰݲ ^>sW%ņ7I?-.t83}gO{OT l KPW+eTl5 lqv0U@> 6ًT)`N͟^ͨ?dVdյ(}d|Zr{Z= ݐD'$qkYɰ,Ro]&tuCkݓCYOZfsUҸ13`$ \,ȱIENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/ico/favicon.ico0000644000000000000000000000217612433712541025425 0ustar00usergroup00000000000000 h(  4 o \FB_a]Gg FfA]@\2J7OFeW5Loi]"' 9T& oV#3Ke278PU0Cfkkgp+='8lqqqv &6\2H>X%@#hIENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/images/loading-bar.gif0000644000000000000000000002510312433712542026641 0ustar00usergroup00000000000000GIF89aƙͯԳ֬Ϻ׋! NETSCAPE2.0!Created with ajaxload.info! , dihlp,tmx|pHrl:ШtJZجv:(zݸHxhh|{~zxkwuyst`f^+]d dpn p½õǾźʱӰ,  ׏ ;x/!A{ОÂNF}\H\:YEr0V8wС<:ϥG*T͠U>źӪѨZrjW+XA-ZpSYK‚vpgɭ;n^św/_ E\8`q&Y]ʴӅYb̀-EB-,,Jk;u]Ǿ,ݻe |7y\䰏Ås_Wݛt Ө-mא`͟~~z݋/v_]xxpƊf1 voNZbHI!YX?8Yh Ao5USta)cs;h\8xTB*GciձƣLʋ& P ^ԗaW&~`JIbnզXo^Wh `4 F}>'Ngjg h+.٠H:أ*M*ꨤj*]ꪬ꫰*무j'! , dihlp,tmx|pHrl:ШtJZجv:( 6ap݃z݆|Jy㙗w=}Ko\?g<,! |_v0XV X[d]b^'ͅjZɵA!v !lsb+ZW/ 6Z^7\"rx v`X$5$#ʸ#*v!{.*a(8ar GfdNa}%B"&hܛ|b]p_m-tݢ2vz)y()fr G+)bBfvvP*{9Zxvu,Q!z^"+kik9gJ`k.Da>#|H卦99>2I8gH@ `.YLf4|҈Fs ,O% l' map2@,Y(fIi+*{r c2httM?4Ԁn7zEF1I،4g/ `,Gpjh-{5TbӭxyZۋHl砇.SEꬷ.~B! , dihlp,tmx|pHrl:ШtJZجv:ix6hpA!M_ x<@lx}ipo}{jon|nwli{km`^+]k  gt Аg hhet}ڈiV4 7P8(``A A.(p@ɓ| )AI `T$P@M2c\fN<\d1քpΞE=)է֠d ThX!A0+䄻wxfz 2ΛC7Fvy%868rLǔV3eH5m軪'oԬYxӮ!gw< 0OAss,HOu K>aA]k0|Λξ{зWw}<]uwY|] 2ũp\P`l]gAymLxȄ5l2 N@c'RL4g`"8/ʸc=V,B5NV$,fN7b)h8&X{)htezʼ' ȷfY烲!z墆ieIgR-_yv*hpy $Ph@ ݂݊;F1Y t2 d<#Zuׄvkoia&1?b+n&BChkna-[E{Er *+Y@$n).2 )&ty$x-yL2^Rd K%4Va_3VI8Fo5nL(7{0mX2l05$h`[y->sЧ} XKG9'*y[3P_ZXYʩ&-LQKvGhOX*wɫnfx2-E7K1 yxޥIo7ݎ8V8|/o<]7G/Wo'! , dihlp,tmx|pHrl:ШtJZجv:g0tqpچ1O yy}u~m{|~jxqov}jwn~poxzzpeg,]wo  h ih~ؒ juuNХG\A?T@0S0$yA L e'QBX`M2g>в2i\ %\,З&ss$Ԙ(d3̣<.Aȕ1hEH0n , `]x%o߿uƣY38V,ٚ*+1g~C fӊUho!]A !ூ $XFxǑU| 'P'jt{~SaL2#^r VWT̊^@>cCx׉Hbw<"w)VK!wvc is)ʓfyщ̜l0|2 ܉Y pb(gz'ꢡ%t)] 4i$ TO,hmg_' 0]lפ77ÜKXYCeq%(6maPD" kagw]Y }ܮ劽v-k%$o{?/q [;?o^ӻ-T=rtB $Pi &z-&_H=l@]gV|ebfe֘ovih3D8tp x኏xMy#:g"vmAbnuPf=f ^0 ~ Ȣ[xXNhԉt#Q%i22֗43&@]&֠eZt(%ߊȚQV7h1 &ommۗXג)(ڱb `v}A!^sܧSZ*Uu~ͅyyIz'AYٙio6'l^N) Տz4f [AuF6Z]8ڋ}뛆2[z oGȚ@lІG05&H, ɯ&g1P`pŌL|-KV؀Mis=h9s Y&\:ۇhrJ-jW]sud3l^HAʉv&ph-/&ܼ8K8\*,yx-<CXn=*|7 6[TtQo'7П! , dihlp,tmx|pHrl:ШtJZجv:);Oano#~x< 7 yye||g~vx o{fzhwy qrwpnGea^+yɂ  ѵۀlvɊmnA$߷ps` X0eB 0$Ǝ$ir#J `\˘%c:g#M-} JRP/ UN<dP ʧ7 Й,bXʝpNP[qu k  Ob72$38[rFYh3GN|z&sB fWAbtZ0܂v^q;[9l .tv<7V^^!j nYuvYd@ Te]Afuq=[f&Z&R&"{n.quAb̂ HY8̊!8׆!1ɣ`P` ^0Ф\ahYRh؍ȧ%`]F @'\rk2@'3>&z9܌o䵝fxʼn͡Ee'LVݕ@sJ&7N0~'ZN\ـ'c^#lڪ"쉭+z|ĩj]Ǟg' v]c/ڐ^&fE!H^ ݆6k9ʫ0Jp &c*kp@x[辙1]Eez&Zsv%~gRۀ\'8k@|z+i[W6^0cvcs3Is}zb3GUp/GW_\?Kp|wu~Wv'p*tzr_= 1cbD.n;]/o'! , dihlp,tmx|pHrl:ШtJZجv:ph4i7f9=x$ِ6=vx|jwzciu p~xfc~y{~yv{o ea^+ `Ô ºy”mٕm“nгCLۛz 0a@Qƒ2j\@/\ԸAE %H'+l1%Ŕ3IL gN |<3ˡ!BSҠ|Zfŕ-K@ 1EچҪpǚj`Ѯjε sӂT@Ykk \ u%e` WÁ&P0as뎶a1굪1T vI~kmC  $(.wʙWH+!za޲oWλq/x`엝b 'ͻ9rl)m* B)ßeA˜Fle}r e!ah!gtۃɇH3*px8`բXcjI` S%kY@o j j][ed%Y0fl)bg g'E&ϭYfqfpxB  G9|g,u\٘l-yU] Qzn)Z-* 暤[*쫦'†JZuW5͹(\}W'4)!ofnj#zغY5cKVl[,YNpYek\ 0]K"ž H ,UZWia:ہͥɌfJ䍎N2jL,'JlB]eZShj^YArcdrWffC+RʲP킧]دR dP̘Ʊs)'pjp lpo#yˍH`;⒫exٕf=7ޞ;]!o'7'! , dihlp,tmx|pHrl:ШtJZجv:P h)l#1O;~x{}~cvw ~|zx| gkk|kyqzd^+ oypo zB90a GE @qA\@#Ǎ rCɓ?-^=Hl/SE'7G/WB! , dihlp,tmx|pHrl:ШtJZجv:(8!6̮{~6x y}~ul lcp tkizzoye^+ {`фzͿ ьyq[ =k$0  (p@ŋ4\̶#ǏDxAI @b%ʕ f,i2ȟ [s$͡' ZNJFw3FScδ8hhh(@`@@Aʝ R5ΝA$jZl6̭`{뮭p_ niH yH +,ʋ1EzeEw{Y,0ٻ ,{8Z 7 '>aAlktqǵ޶q7UY:k=6m* @c%s}eV3GۂX!3!_ b kZff%B`{}^2&[bȕ|}HXF` "h1qS֠Vf{ӥiYMz7AYc&$tԵpnةxxꉀ2v)Emx.e5)W< i T@$|05"HΑZjt~ިx kE+t}'k[[IJV(+!+Apbی'&XmVq2'>;m"^8kay6tIb2&|- 0r$'d"E]\_Λr Xe-Y G]BޟHh.iYIGF4L\%6dɅVo `c +m;\ Hjt#wYH~0q*vk| .ANdBP\+!/`#ꬷNEEn/ !;SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/images/loading16.gif0000644000000000000000000000222112433712542026242 0ustar00usergroup00000000000000GIF89awwwfffUUUDDD333! NETSCAPE2.0!,FIҔA'uۘyb&OH\;_aTCP&@P() @H*+Af .TRM-! , 1i]!]2XX .GJ@U~0! ,CAH2SatE!yVR`c++ I QeP`ӳȜOHK! ,CE Q Sp"$(uG%Y-8"љG֛ BGKp.>T9@@b!+"! ,F cH ɐTfy(Z1}I.48^@ aH~`$Lrt,t2+6%! ,CF  4"NA PT aY-%8:x@,l1d"_NM(^%! ,J iX@ uZ9ǑMQSP_ C~Ql) T:LSX-8Adw! ,J iXp䔐Z) @IMp1f}6PU ^ HpQS)g涗8Ρ! ,K  %i!X4fmB,l $b0tX `(d$MQxjnr! ,CI 8DHI U`i[JP Ν`jB" @n;(C.3~$! ,J V4 If[z!O'%*Fvr bRbi hUİTY!,I V4 If[YzmݭB ؄Cd($A0! l+~-;SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/images/logo.png0000644000000000000000000000540312433712542025442 0ustar00usergroup00000000000000PNG  IHDRx-e'tEXtSoftwareAdobe ImageReadyqe< IDATx\[UW̕;N[ hHMkҴ@;U`چLGIhW"N* t@( B:swg93=+{uֿ>y;EQU"J/".!wRU.\Fv T"YRa ZzIj5 A%ɰU`Ց4 Â&Iddd$@uo,YZ Z q͌:wmF&4I"ꪗz tMu֠Op@rDˬܽpyǓ[u(Et Wd<+boS*<ܠcC==h"L;r \p-}&θ&M|EY!v2 wU*1}%t,!`c/N?qq30d%jt,c/Ryp4RY[VrHaIr/o' x2ڻIq"PL (P:_oB~R |h̬EzdJXg;v}7$$k7cϢmN`ED,wLd_eV`aEش- zlNf[N߰lh3YM"xJ I%18bI;x{=HwG[f0!#ۃ _YdHzץۊx6{~'Y''REe/* 51}s#Dwq&Ar~sΥ.r3'kGR ~8Egvm'UnĚK/yGo0N 9֗Xxe&C3h:G̶.]Lw B}Y{z/n\pXvJPī?eaڮ^ m 1cjY1%-YqQ=;2& }NsFm'v;<kGd52gY}{ϕ{ rً4Be/U3 4TMOon-_kƞv-d7H,DnjHagqB{Kh8F-G=AS3|3Ŗr-iR='5yc'^TOhߨRDqr?yOEܲ#o$Vh'30~m+tjH&G;Qux `bO } W Ɠ:q"ɬtFr?aY½krⶳ%S wUm6ɚ8xi=ʛ|iG7V[>/eS٪(.KXr\̹!$iW88:] \N?#SXsőRU ^9˩50QMCY9nʺ註dѮZn#e  |P-KP/AU584IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/images/mini-left.gif0000644000000000000000000000154712433712542026354 0ustar00usergroup00000000000000GIF89a#CCE@@!,#D `0@!Æ:É)^cE r9Rˌ0=nLP Cq ;SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/images/mini-right.gif0000644000000000000000000000155012433712542026531 0ustar00usergroup00000000000000GIF89a#CCE@@!,#E@L*d8QbD/Vh1G4(ɑ@n\ǎ09dP`…  ;SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/images/no16.png0000644000000000000000000000201012433712542025254 0ustar00usergroup00000000000000PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDATxb?% X@RFF_ jo\7Q>˻H1,,٩S7]trb`!PVc/NHBD ӄwGwxx5 6`O)u=<[9/JPG Ry')oܹۿ_!6_\?H/@1񶭻^~6e>ov?1HdAý __?3ddbP= W֮; @`e`Y$)uX4;" o(p, /@̝۟Ыʧd@zf7?`9e xx~|g_ r334cok{ݻ O@zH(0 .EB c U: drty ۪@`㙗CXdߎ] ?ņ1z+ofv3\e`s!g!)-@D@zlU+݅~f@ۥf2(\dЯ ^jJ^$p'$/ 03(N_߈ᷜE XX~p 6A?"  O'̋GNYb 8,u%e_jyFL:TUBF -tˉw7DO)]Y @.)O=WAC i-VDdyfmJ2tAX)eeE$ uS j*E.kgW4,--PpgF21L㋉vd?`SRU=f;tpxz :)2&'cݧ:\0/bv}bLqшmSi 5 " BX ƕ%·7 r מd˳@A{z٨bY}eSuy|76f1F=–V|>ތZw*/1bD&E҆h76Эm|W&j){N2b |quO?r vqaj^*Zӫrvpt"߮R>읨f߯Ϻۻº !X?71ɱ0`E o/:U G4z$tlTk 0\2IENDB`SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/script.js0000644000000000000000000100464612433712602025013 0ustar00usergroup00000000000000/*! jQuery v1.7.2 jquery.com | jquery.org/license */ (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="
"+""+"
",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
t
",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f .clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); /*! * jQuery UI 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI */(function(a,b){function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;if(!b.href||!g||f.nodeName.toLowerCase()!=="map")return!1;h=a("img[usemap=#"+g+"]")[0];return!!h&&d(h)}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}a.ui=a.ui||{};a.ui.version||(a.extend(a.ui,{version:"1.8.18",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)});return c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){if(c===b)return g["inner"+d].call(this);return this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){if(typeof b!="number")return g["outer"+d].call(this,b);return this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);/* * jQuery UI Position 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Position */(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1];return this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]!==e){var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0}},top:function(b,c){if(c.at[1]!==e){var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];if(!c||!c.ownerDocument)return null;if(b)return this.each(function(){a.offset.setOffset(this,b)});return h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);/* * jQuery UI Draggable 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Draggables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!!this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy();return this}},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle"))return!1;this.handle=this._getHandle(b);if(!this.handle)return!1;c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('
').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")});return!0},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment();if(this._trigger("start",b)===!1){this._clear();return!1}this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.helper.addClass("ui-draggable-dragging"),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b);return!0},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1){this._mouseUp({});return!1}this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,b);return!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",b)!==!1&&d._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b);return a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)});return c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute");return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.lefth[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.toph[3]?j-this.offset.click.toph[2]?k-this.offset.click.left=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f=k&&g<=l||h>=k&&h<=l||gl)&&(e>=i&&e<=j||f>=i&&f<=j||ej);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();droppablesLoop:for(var g=0;g
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e');/sw|se|ne|nw/.test(f)&&h.css({zIndex:++c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){c.disabled||(a(this).removeClass("ui-resizable-autohide"),b._handles.show())},function(){c.disabled||b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement);return this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b);return!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui());return!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),ea.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null);return a},_proportionallyResize:function(){var b=this.options;if(!!this._proportionallyResizeElements.length){var c=this.helper||this.element;for(var d=0;d');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.18"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,d){a(b).each(function(){var b=a(this),e=a(this).data("resizable-alsoresize"),f={},g=d&&d.length?d:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(e[b]||0)+(h[b]||0);c&&c>=0&&(f[b]=c||null)}),b.css(f)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!!i){e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/e.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*e.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);/* * jQuery UI Selectable 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Selectables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("
")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy();return this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(!this.options.disabled){var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element});return!1}})}},_mouseDrag:function(b){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!!i&&i.element!=c.element[0]){var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.righth||i.bottome&&i.rightf&&i.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f){e=a(this);return!1}});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}this.currentItem=e,this._removeCurrentsFromItems();return!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(b,c){if(!!b){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"=");return d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")});return d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+jf&&b+ka[this.floating?"width":"height"]?l:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a),this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];e||(b.style.visibility="hidden");return b},update:function(a,b){if(!e||!!d.forcePlaceholderSize)b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!!c)if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.topthis.containment[3]?h-this.offset.click.topthis.containment[2]?i-this.offset.click.left=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",context:{autocompleteRequest:++c},success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length").data("item.autocomplete",c).append(a("").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})})(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend(""),d.secondary&&b.append(""),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})})(jQuery);/* * jQuery UI Dialog 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Dialog * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * jquery.ui.button.js * jquery.ui.draggable.js * jquery.ui.mouse.js * jquery.ui.position.js * jquery.ui.resizable.js */(function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||" ",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("
")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("
")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){b.close(a);return!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1!==c._trigger("beforeClose",b)){c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d);return c}},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;if(e.modal&&!b||!e.stack&&!e.modal)return d._trigger("focus",c);e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c);return d},open:function(){if(!this._isOpen){var b=this,c=b.options,d=b.uiDialog;b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey){d.focus(1);return!1}if(b.target===d[0]&&b.shiftKey){e.focus(1);return!1}}}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open");return b}},_createButtons:function(b){var c=this,d=!1,e=a("
").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("
").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){a!=="click"&&(a in f?e[a](b):e.attr(a,b))}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||" "))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.18",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");b||(this.uuid+=1,b=this.uuid);return"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&c.bgiframe(),this.instances.push(c);return c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;if(a.browser.msie&&a.browser.version<7){b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return bk)return f.click(0,d)}if(!i.length){if(j>=0)return f;c=e.initialIndex,i=h.eq(c)}if(c===j)return f;d=d||a.Event(),d.type="onBeforeClick",g.trigger(d,[c]);if(!d.isDefaultPrevented()){b[e.effect].call(f,c,function(){j=c,d.type="onClick",g.trigger(d,[c])}),h.removeClass(e.current),i.addClass(e.current);return f}},getConf:function(){return e},getTabs:function(){return h},getPanes:function(){return i},getCurrentPane:function(){return i.eq(j)},getCurrentTab:function(){return h.eq(j)},getIndex:function(){return j},next:function(){return f.click(j+1)},prev:function(){return f.click(j-1)},destroy:function(){h.unbind(e.event).removeClass(e.current),i.find("a[href^=#]").unbind("click.T");return f}}),a.each("onBeforeClick,onClick".split(","),function(b,c){a.isFunction(e[c])&&a(f).bind(c,e[c]),f[c]=function(b){b&&a(f).bind(c,b);return f}}),e.history&&a.fn.history&&(a.tools.history.init(h),e.event="history"),h.each(function(b){a(this).bind(e.event,function(a){f.click(b,a);return a.preventDefault()})}),i.find("a[href^=#]").bind("click.T",function(b){f.click(a(this).attr("href"),b)}),location.hash&&e.tabs=="a"&&c.find("[href="+location.hash+"]").length?f.click(location.hash):(e.initialIndex===0||e.initialIndex>0)&&f.click(e.initialIndex)}a.fn.tabs=function(b,c){var d=this.data("tabs");d&&(d.destroy(),this.removeData("tabs")),a.isFunction(c)&&(c={onBeforeClick:c}),c=a.extend({},a.tools.tabs.conf,c),this.each(function(){d=new e(a(this),b,c),a(this).data("tabs",d)});return c.api?d:this}})(jQuery); /* * qTip2 - Pretty powerful tooltips * http://craigsworks.com/projects/qtip2/ * * Version: nightly * Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com * * Dual licensed under MIT or GPLv2 licenses * http://en.wikipedia.org/wiki/MIT_License * http://en.wikipedia.org/wiki/GNU_General_Public_License * * Date: Sat Mar 3 09:04:15.0000000000 2012 *//*jslint browser: true, onevar: true, undef: true, nomen: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: true *//*global window: false, jQuery: false, console: false, define: false */(function(a){typeof define==="function"&&define.amd?define(["jquery"],a):a(jQuery)})(function(a){function C(d){var e=this,f=d.options.show.modal,h=d.elements,i=h.tooltip,j="#qtip-overlay",k=".qtipmodal",l=k+d.id,n="is-modal-qtip",p=a(document.body),q;d.checks.modal={"^show.modal.(on|blur)$":function(){e.init(),h.overlay.toggle(i.is(":visible"))}},a.extend(e,{init:function(){if(!f.on)return e;q=e.create(),i.attr(n,b).css("z-index",g.modal.zindex+a(m+"["+n+"]").length).unbind(k).unbind(l).bind("tooltipshow"+k+" tooltiphide"+k,function(b,c,d){var f=b.originalEvent;if(b.target===i[0])if(f&&b.type==="tooltiphide"&&/mouse(leave|enter)/.test(f.type)&&a(f.relatedTarget).closest(q[0]).length)try{b.preventDefault()}catch(g){}else(!f||f&&!f.solo)&&e[b.type.replace("tooltip","")](b,d)}).bind("tooltipfocus"+k,function(b){if(!b.isDefaultPrevented()&&b.target===i[0]){var c=a(m).filter("["+n+"]"),d=g.modal.zindex+c.length,e=parseInt(i[0].style.zIndex,10);q[0].style.zIndex=d-1,c.each(function(){this.style.zIndex>e&&(this.style.zIndex-=1)}),c.end().filter("."+o).qtip("blur",b.originalEvent),i.addClass(o)[0].style.zIndex=d;try{b.preventDefault()}catch(f){}}}).bind("tooltiphide"+k,function(b){b.target===i[0]&&a("["+n+"]").filter(":visible").not(i).last().qtip("focus",b)}),f.escape&&a(window).unbind(l).bind("keydown"+l,function(a){a.keyCode===27&&i.hasClass(o)&&d.hide(a)}),f.blur&&h.overlay.unbind(l).bind("click"+l,function(a){i.hasClass(o)&&d.hide(a)});return e},create:function(){function d(){q.css({height:a(window).height(),width:a(window).width()})}var b=a(j);if(b.length)return h.overlay=b.insertAfter(a(m).last());q=h.overlay=a("
",{id:j.substr(1),html:"
",mousedown:function(){return c}}).insertAfter(a(m).last()),a(window).unbind(k).bind("resize"+k,d),d();return q},toggle:function(d,g,h){if(d&&d.isDefaultPrevented())return e;var j=f.effect,k=g?"show":"hide",o=q.is(":visible"),r=a("["+n+"]").filter(":visible").not(i),s;q||(q=e.create());if(q.is(":animated")&&o===g||!g&&r.length)return e;g?(q.css({left:0,top:0}),q.toggleClass("blurs",f.blur),p.bind("focusin"+l,function(b){var d=a(b.target),e=d.closest(".qtip"),f=e.length<1?c:parseInt(e[0].style.zIndex,10)>parseInt(i[0].style.zIndex,10);!f&&a(b.target).closest(m)[0]!==i[0]&&i.find("input:visible").filter(":first").focus()})):p.undelegate("*","focusin"+l),q.stop(b,c),a.isFunction(j)?j.call(q,g):j===c?q[k]():q.fadeTo(parseInt(h,10)||90,g?1:0,function(){g||a(this).hide()}),g||q.queue(function(a){q.css({left:"",top:""}),a()});return e},show:function(a,c){return e.toggle(a,b,c)},hide:function(a,b){return e.toggle(a,c,b)},destroy:function(){var b=q;b&&(b=a("["+n+"]").not(i).length<1,b?(h.overlay.remove(),a(window).unbind(k)):h.overlay.unbind(k+d.id),p.undelegate("*","focusin"+l));return i.removeAttr(n).unbind(k)}}),e.init()}function B(f,h){function w(a){var b=a.precedance==="y",c=n[b?"width":"height"],d=n[b?"height":"width"],e=a.string().indexOf("center")>-1,f=c*(e?.5:1),g=Math.pow,h=Math.round,i,j,k,l=Math.sqrt(g(f,2)+g(d,2)),m=[p/f*l,p/d*l];m[2]=Math.sqrt(g(m[0],2)-g(p,2)),m[3]=Math.sqrt(g(m[1],2)-g(p,2)),i=l+m[2]+m[3]+(e?0:m[0]),j=i/l,k=[h(j*d),h(j*c)];return{height:k[b?0:1],width:k[b?1:0]}}function v(b){var c=k.titlebar&&b.y==="top",d=c?k.titlebar:k.content,e=a.browser.mozilla,f=e?"-moz-":a.browser.webkit?"-webkit-":"",g=b.y+(e?"":"-")+b.x,h=f+(e?"border-radius-"+g:"border-"+g+"-radius");return parseInt(d.css(h),10)||parseInt(l.css(h),10)||0}function u(a,b,c){b=b?b:a[a.precedance];var d=l.hasClass(q),e=k.titlebar&&a.y==="top",f=e?k.titlebar:k.content,g="border-"+b+"-width",h;l.addClass(q),h=parseInt(f.css(g),10),h=(c?h||parseInt(l.css(g),10):h)||0,l.toggleClass(q,d);return h}function t(a,d,g,h){if(k.tip){var l=i.corner.clone(),n=g.adjusted,o=f.options.position.adjust.method.split(" "),p=o[0],q=o[1]||o[0],r={left:c,top:c,x:0,y:0},s,t={},u;i.corner.fixed!==b&&(p==="shift"&&l.precedance==="x"&&n.left&&l.y!=="center"?l.precedance=l.precedance==="x"?"y":"x":p==="flip"&&n.left&&(l.x=l.x==="center"?n.left>0?"left":"right":l.x==="left"?"right":"left"),q==="shift"&&l.precedance==="y"&&n.top&&l.x!=="center"?l.precedance=l.precedance==="y"?"x":"y":q==="flip"&&n.top&&(l.y=l.y==="center"?n.top>0?"top":"bottom":l.y==="top"?"bottom":"top"),l.string()!==m.corner.string()&&(m.top!==n.top||m.left!==n.left)&&i.update(l,c)),s=i.position(l,n),s.right!==e&&(s.left=-s.right),s.bottom!==e&&(s.top=-s.bottom),s.user=Math.max(0,j.offset);if(r.left=p==="shift"&&!!n.left)l.x==="center"?t["margin-left"]=r.x=s["margin-left"]-n.left:(u=s.right!==e?[n.left,-s.left]:[-n.left,s.left],(r.x=Math.max(u[0],u[1]))>u[0]&&(g.left-=n.left,r.left=c),t[s.right!==e?"right":"left"]=r.x);if(r.top=q==="shift"&&!!n.top)l.y==="center"?t["margin-top"]=r.y=s["margin-top"]-n.top:(u=s.bottom!==e?[n.top,-s.top]:[-n.top,s.top],(r.y=Math.max(u[0],u[1]))>u[0]&&(g.top-=n.top,r.top=c),t[s.bottom!==e?"bottom":"top"]=r.y);k.tip.css(t).toggle(!(r.x&&r.y||l.x==="center"&&r.y||l.y==="center"&&r.x)),g.left-=s.left.charAt?s.user:p!=="shift"||r.top||!r.left&&!r.top?s.left:0,g.top-=s.top.charAt?s.user:q!=="shift"||r.left||!r.left&&!r.top?s.top:0,m.left=n.left,m.top=n.top,m.corner=l.clone()}}var i=this,j=f.options.style.tip,k=f.elements,l=k.tooltip,m={top:0,left:0},n={width:j.width,height:j.height},o={},p=j.border||0,r=".qtip-tip",s=!!(a("")[0]||{}).getContext;i.mimic=i.corner=d,i.border=p,i.offset=j.offset,i.size=n,f.checks.tip={"^position.my|style.tip.(corner|mimic|border)$":function(){i.init()||i.destroy(),f.reposition()},"^style.tip.(height|width)$":function(){n={width:j.width,height:j.height},i.create(),i.update(),f.reposition()},"^content.title.text|style.(classes|widget)$":function(){k.tip&&i.update()}},a.extend(i,{init:function(){var b=i.detectCorner()&&(s||a.browser.msie);b&&(i.create(),i.update(),l.unbind(r).bind("tooltipmove"+r,t));return b},detectCorner:function(){var a=j.corner,d=f.options.position,e=d.at,h=d.my.string?d.my.string():d.my;if(a===c||h===c&&e===c)return c;a===b?i.corner=new g.Corner(h):a.string||(i.corner=new g.Corner(a),i.corner.fixed=b),m.corner=new g.Corner(i.corner.string());return i.corner.string()!=="centercenter"},detectColours:function(b){var c,d,e,g=k.tip.css("cssText",""),h=b||i.corner,m=h[h.precedance],p="border-"+m+"-color",r="border"+m.charAt(0)+m.substr(1)+"Color",s=/rgba?\(0, 0, 0(, 0)?\)|transparent|#123456/i,t="background-color",u="transparent",v=" !important",w=a(document.body).css("color"),x=f.elements.content.css("color"),y=k.titlebar&&(h.y==="top"||h.y==="center"&&g.position().top+n.height/2+j.offset",{"class":"ui-tooltip-tip"}).css({width:b,height:c}).prependTo(l),s?a("").appendTo(k.tip)[0].getContext("2d").save():(d='',k.tip.html(d+d),a("*",k.tip).bind("click mousedown",function(a){a.stopPropagation()}))},update:function(e,f){var h=k.tip,l=h.children(),q=n.width,r=n.height,t="px solid ",v="px dashed transparent",x=j.mimic,y=Math.round,z,B,C,D,E;e||(e=m.corner||i.corner),x===c?x=e:(x=new g.Corner(x),x.precedance=e.precedance,x.x==="inherit"?x.x=e.x:x.y==="inherit"?x.y=e.y:x.x===x.y&&(x[e.precedance]=e[e.precedance])),z=x.precedance,i.detectColours(e),o.border!=="transparent"&&o.border!=="#123456"?(p=u(e,d,b),j.border===0&&p>0&&(o.fill=o.border),i.border=p=j.border!==b?j.border:p):i.border=p=0,C=A(x,q,r),i.size=E=w(e),h.css(E),e.precedance==="y"?D=[y(x.x==="left"?p:x.x==="right"?E.width-q-p:(E.width-q)/2),y(x.y==="top"?E.height-r:0)]:D=[y(x.x==="left"?E.width-q:0),y(x.y==="top"?p:x.y==="bottom"?E.height-r-p:(E.height-r)/2)],s?(l.attr(E),B=l[0].getContext("2d"),B.restore(),B.save(),B.clearRect(0,0,3e3,3e3),B.translate(D[0],D[1]),B.beginPath(),B.moveTo(C[0][0],C[0][1]),B.lineTo(C[1][0],C[1][1]),B.lineTo(C[2][0],C[2][1]),B.closePath(),B.fillStyle=o.fill,B.strokeStyle=o.border,B.lineWidth=p*2,B.lineJoin="miter",B.miterLimit=100,p&&B.stroke(),B.fill()):(C="m"+C[0][0]+","+C[0][1]+" l"+C[1][0]+","+C[1][1]+" "+C[2][0]+","+C[2][1]+" xe",D[2]=p&&/^(r|b)/i.test(e.string())?parseFloat(a.browser.version,10)===8?2:1:0,l.css({antialias:""+(x.string().indexOf("center")>-1),left:D[0]-D[2]*Number(z==="x"),top:D[1]-D[2]*Number(z==="y"),width:q+p,height:r+p}).each(function(b){var c=a(this);c[c.prop?"prop":"attr"]({coordsize:q+p+" "+(r+p),path:C,fillcolor:o.fill,filled:!!b,stroked:!b}).css({display:p||b?"block":"none"}),!b&&c.html()===""&&c.html('')})),f!==c&&i.position(e)},position:function(d){var e=k.tip,f={},g=Math.max(0,j.offset),h,l,m;if(j.corner===c||!e)return c;d=d||i.corner,h=d.precedance,l=w(d),m=[d.x,d.y],h==="x"&&m.reverse(),a.each(m,function(a,c){var e,i;c==="center"?(e=h==="y"?"left":"top",f[e]="50%",f["margin-"+e]=-Math.round(l[h==="y"?"width":"height"]/2)+g):(e=u(d,c,b),i=v(d),f[c]=a?p?u(d,c):0:g+(i>e?i:0))}),f[d[h]]-=l[h==="x"?"width":"height"],e.css({top:"",bottom:"",left:"",right:"",margin:""}).css(f);return f},destroy:function(){k.tip&&k.tip.remove(),l.unbind(r)}}),i.init()}function A(a,b,c){var d=Math.ceil(b/2),e=Math.ceil(c/2),f={bottomright:[[0,0],[b,c],[b,0]],bottomleft:[[0,0],[b,0],[0,c]],topright:[[0,c],[b,0],[b,c]],topleft:[[0,0],[0,c],[b,c]],topcenter:[[0,c],[d,0],[b,c]],bottomcenter:[[0,0],[b,0],[d,c]],rightcenter:[[0,0],[b,e],[0,c]],leftcenter:[[b,0],[b,c],[0,e]]};f.lefttop=f.bottomright,f.righttop=f.bottomleft,f.leftbottom=f.topright,f.rightbottom=f.topleft;return f[a.string()]}function z(d){var e=this,f=d.elements.tooltip,g=d.options.content.ajax,h=".qtip-ajax",i=/)<[^<]*)*<\/script>/gi,j=b,k=c,l;d.checks.ajax={"^content.ajax":function(a,b,c){b==="ajax"&&(g=c),b==="once"?e.init():g&&g.url?e.load():f.unbind(h)}},a.extend(e,{init:function(){g&&g.url&&f.unbind(h)[g.once?"one":"bind"]("tooltipshow"+h,e.load);return e},load:function(b,f){function r(a,b,c){!k&&a.status!==0&&d.set("content.text",b+": "+c)}function q(b){k||(m&&(b=a("
").append(b.replace(i,"")).find(m)),d.set("content.text",b))}function p(){k||(n&&(d.show(b.originalEvent),f=c),a.isFunction(g.complete)&&g.complete.apply(this,arguments))}var h=g.url.indexOf(" "),j=g.url,m,n=g.once&&!g.loading&&f;if(n)try{b.preventDefault()}catch(o){}else if(b&&b.isDefaultPrevented())return e;l&&l.abort&&l.abort(),h>-1&&(m=j.substr(h),j=j.substr(0,h)),l=a.ajax(a.extend({success:q,error:r,context:d},g,{url:j,complete:p}))},destroy:function(){l&&l.abort&&l.abort(),k=b}}),e.init()}function y(e,h){var i,j,k,l,m,n=a(this),o=a(document.body),p=this===document?o:n,q=n.metadata?n.metadata(h.metadata):d,r=h.metadata.type==="html5"&&q?q[h.metadata.name]:d,s=n.data(h.metadata.name||"qtipopts");try{s=typeof s==="string"?(new Function("return "+s))():s}catch(u){v("Unable to parse HTML5 attribute data: "+s)}l=a.extend(b,{},f.defaults,h,typeof s==="object"?w(s):d,w(r||q)),j=l.position,l.id=e;if("boolean"===typeof l.content.text){k=n.attr(l.content.attr);if(l.content.attr!==c&&k)l.content.text=k;else{v("Unable to locate content for tooltip! Aborting render of tooltip on element: ",n);return c}}j.container.length||(j.container=o),j.target===c&&(j.target=p),l.show.target===c&&(l.show.target=p),l.show.solo===b&&(l.show.solo=j.container.closest("body")),l.hide.target===c&&(l.hide.target=p),l.position.viewport===b&&(l.position.viewport=j.container),j.at=new g.Corner(j.at),j.my=new g.Corner(j.my);if(a.data(this,"qtip"))if(l.overwrite)n.qtip("destroy");else if(l.overwrite===c)return c;l.suppress&&(m=a.attr(this,"title"))&&a(this).removeAttr("title").attr(t,m),i=new x(n,l,e,!!k),a.data(this,"qtip",i),n.bind("remove.qtip-"+e+" removeqtip.qtip-"+e,function(){i.destroy()});return i}function x(r,s,v,x){function Q(){var b=[s.show.target[0],s.hide.target[0],y.rendered&&F.tooltip[0],s.position.container[0],s.position.viewport[0],window,document];y.rendered?a([]).pushStack(a.grep(b,function(a){return typeof a==="object"})).unbind(E):s.show.target.unbind(E+"-create")}function P(){function o(a){D.is(":visible")&&y.reposition(a)}function n(a){if(D.hasClass(l))return c;clearTimeout(y.timers.inactive),y.timers.inactive=setTimeout(function(){y.hide(a)},s.hide.inactive)}function k(b){if(D.hasClass(l)||B||C)return c;var f=a(b.relatedTarget||b.target),g=f.closest(m)[0]===D[0],h=f[0]===e.show[0];clearTimeout(y.timers.show),clearTimeout(y.timers.hide);if(d.target==="mouse"&&g||s.hide.fixed&&(/mouse(out|leave|move)/.test(b.type)&&(g||h)))try{b.preventDefault(),b.stopImmediatePropagation()}catch(i){}else s.hide.delay>0?y.timers.hide=setTimeout(function(){y.hide(b)},s.hide.delay):y.hide(b)}function j(a){if(D.hasClass(l))return c;clearTimeout(y.timers.show),clearTimeout(y.timers.hide);var d=function(){y.toggle(b,a)};s.show.delay>0?y.timers.show=setTimeout(d,s.show.delay):d()}var d=s.position,e={show:s.show.target,hide:s.hide.target,viewport:a(d.viewport),document:a(document),body:a(document.body),window:a(window)},g={show:a.trim(""+s.show.event).split(" "),hide:a.trim(""+s.hide.event).split(" ")},i=a.browser.msie&&parseInt(a.browser.version,10)===6;D.bind("mouseenter"+E+" mouseleave"+E,function(a){var b=a.type==="mouseenter";b&&y.focus(a),D.toggleClass(p,b)}),s.hide.fixed&&(e.hide=e.hide.add(D),D.bind("mouseover"+E,function(){D.hasClass(l)||clearTimeout(y.timers.hide)})),/mouse(out|leave)/i.test(s.hide.event)?s.hide.leave==="window"&&e.window.bind("mouseout"+E+" blur"+E,function(a){/select|option/.test(a.target)&&!a.relatedTarget&&y.hide(a)}):/mouse(over|enter)/i.test(s.show.event)&&e.hide.bind("mouseleave"+E,function(a){clearTimeout(y.timers.show)}),(""+s.hide.event).indexOf("unfocus")>-1&&d.container.closest("html").bind("mousedown"+E,function(b){var c=a(b.target),d=!D.hasClass(l)&&D.is(":visible"),e=c.parents(m).filter(D[0]).length>0;c[0]!==r[0]&&c[0]!==D[0]&&!e&&!r.has(c[0]).length&&!c.attr("disabled")&&y.hide(b)}),"number"===typeof s.hide.inactive&&(e.show.bind("qtip-"+v+"-inactive",n),a.each(f.inactiveEvents,function(a,b){e.hide.add(F.tooltip).bind(b+E+"-inactive",n)})),a.each(g.hide,function(b,c){var d=a.inArray(c,g.show),f=a(e.hide);d>-1&&f.add(e.show).length===f.length||c==="unfocus"?(e.show.bind(c+E,function(a){D.is(":visible")?k(a):j(a)}),delete g.show[d]):e.hide.bind(c+E,k)}),a.each(g.show,function(a,b){e.show.bind(b+E,j)}),"number"===typeof s.hide.distance&&e.show.add(D).bind("mousemove"+E,function(a){var b=G.origin||{},c=s.hide.distance,d=Math.abs;(d(a.pageX-b.pageX)>=c||d(a.pageY-b.pageY)>=c)&&y.hide(a)}),d.target==="mouse"&&(e.show.bind("mousemove"+E,function(a){h={pageX:a.pageX,pageY:a.pageY,type:"mousemove"}}),d.adjust.mouse&&(s.hide.event&&(D.bind("mouseleave"+E,function(a){(a.relatedTarget||a.target)!==e.show[0]&&y.hide(a)}),F.target.bind("mouseenter"+E+" mouseleave"+E,function(a){G.onTarget=a.type==="mouseenter"})),e.document.bind("mousemove"+E,function(a){G.onTarget&&!D.hasClass(l)&&D.is(":visible")&&y.reposition(a||h)}))),(d.adjust.resize||e.viewport.length)&&(a.event.special.resize?e.viewport:e.window).bind("resize"+E,o),(e.viewport.length||i&&D.css("position")==="fixed")&&e.viewport.bind("scroll"+E,o)}function O(b,d){function g(b){function i(e){e&&(delete h[e.src],clearTimeout(y.timers.img[e.src]),a(e).unbind(E)),a.isEmptyObject(h)&&(y.redraw(),d!==c&&y.reposition(G.event),b())}var g,h={};if((g=f.find("img[src]:not([height]):not([width])")).length===0)return i();g.each(function(b,c){if(h[c.src]===e){var d=0,f=3;(function g(){if(c.height||c.width||d>f)return i(c);d+=1,y.timers.img[c.src]=setTimeout(g,700)})(),a(c).bind("error"+E+" load"+E,function(){i(this)}),h[c.src]=c}})}var f=F.content;if(!y.rendered||!b)return c;a.isFunction(b)&&(b=b.call(r,G.event,y)||""),b.jquery&&b.length>0?f.empty().append(b.css({display:"block"})):f.html(b),y.rendered<0?D.queue("fx",g):(C=0,g(a.noop));return y}function N(b,d){var e=F.title;if(!y.rendered||!b)return c;a.isFunction(b)&&(b=b.call(r,G.event,y));if(b===c||!b&&b!=="")return J(c);b.jquery&&b.length>0?e.empty().append(b.css({display:"block"})):e.html(b),y.redraw(),d!==c&&y.rendered&&D.is(":visible")&&y.reposition(G.event)}function M(a){var b=F.button,d=F.title;if(!y.rendered)return c;a?(d||L(),K()):b.remove()}function L(){var c=A+"-title";F.titlebar&&J(),F.titlebar=a("
",{"class":j+"-titlebar "+(s.style.widget?"ui-widget-header":"")}).append(F.title=a("
",{id:c,"class":j+"-title","aria-atomic":b})).insertBefore(F.content).delegate(".ui-tooltip-close","mousedown keydown mouseup keyup mouseout",function(b){a(this).toggleClass("ui-state-active ui-state-focus",b.type.substr(-4)==="down")}).delegate(".ui-tooltip-close","mouseover mouseout",function(b){a(this).toggleClass("ui-state-hover",b.type==="mouseover")}),s.content.title.button?K():y.rendered&&y.redraw()}function K(){var b=s.content.title.button,d=typeof b==="string",e=d?b:"Close tooltip";F.button&&F.button.remove(),b.jquery?F.button=b:F.button=a("",{"class":"ui-state-default ui-tooltip-close "+(s.style.widget?"":j+"-icon"),title:e,"aria-label":e}).prepend(a("",{"class":"ui-icon ui-icon-close",html:"×"})),F.button.appendTo(F.titlebar).attr("role","button").click(function(a){D.hasClass(l)||y.hide(a);return c}),y.redraw()}function J(a){F.title&&(F.titlebar.remove(),F.titlebar=F.title=F.button=d,a!==c&&y.reposition())}function I(){var a=s.style.widget;D.toggleClass(k,a).toggleClass(n,s.style.def&&!a),F.content.toggleClass(k+"-content",a),F.titlebar&&F.titlebar.toggleClass(k+"-header",a),F.button&&F.button.toggleClass(j+"-icon",!a)}function H(a){var b=0,c,d=s,e=a.split(".");while(d=d[e[b++]])b0&&!a("#"+i).length&&(D[0].id=i,F.content[0].id=i+"-content",F.title[0].id=i+"-title")},"^content.text$":function(a,b,c){O(c)},"^content.title.text$":function(a,b,c){if(!c)return J();!F.title&&c&&L(),N(c)},"^content.title.button$":function(a,b,c){M(c)},"^position.(my|at)$":function(a,b,c){"string"===typeof c&&(a[b]=new g.Corner(c))},"^position.container$":function(a,b,c){y.rendered&&D.appendTo(c)},"^show.ready$":function(){y.rendered?y.toggle(b):y.render(1)},"^style.classes$":function(a,b,c){D.attr("class",j+" qtip ui-helper-reset "+c)},"^style.widget|content.title":I,"^events.(render|show|move|hide|focus|blur)$":function(b,c,d){D[(a.isFunction(d)?"":"un")+"bind"]("tooltip"+c,d)},"^(show|hide|position).(event|target|fixed|inactive|leave|distance|viewport|adjust)":function(){var a=s.position;D.attr("tracking",a.target==="mouse"&&a.adjust.mouse),Q(),P()}},a.extend(y,{render:function(d){if(y.rendered)return y;var e=s.content.text,f=s.content.title.text,h=s.position,i=a.Event("tooltiprender");a.attr(r[0],"aria-describedby",A),D=F.tooltip=a("
",{id:A,"class":j+" qtip ui-helper-reset "+n+" "+s.style.classes+" "+j+"-pos-"+s.position.my.abbrev(),width:s.style.width||"",height:s.style.height||"",tracking:h.target==="mouse"&&h.adjust.mouse,role:"alert","aria-live":"polite","aria-atomic":c,"aria-describedby":A+"-content","aria-hidden":b}).toggleClass(l,G.disabled).data("qtip",y).appendTo(s.position.container).append(F.content=a("
",{"class":j+"-content",id:A+"-content","aria-atomic":b})),y.rendered=-1,B=C=1,f&&(L(),a.isFunction(f)||N(f,c)),a.isFunction(e)||O(e,c),y.rendered=b,I(),a.each(s.events,function(b,c){a.isFunction(c)&&D.bind(b==="toggle"?"tooltipshow tooltiphide":"tooltip"+b,c)}),a.each(g,function(){this.initialize==="render"&&this(y)}),P(),D.queue("fx",function(a){i.originalEvent=G.event,D.trigger(i,[y]),B=C=0,y.redraw(),(s.show.ready||d)&&y.toggle(b,G.event,c),a()});return y},get:function(a){var b,c;switch(a.toLowerCase()){case"dimensions":b={height:D.outerHeight(),width:D.outerWidth()};break;case"offset":b=g.offset(D,s.position.container);break;default:c=H(a.toLowerCase()),b=c[0][c[1]],b=b.precedance?b.string():b}return b},set:function(e,f){function m(a,b){var c,d,e;for(c in k)for(d in k[c])if(e=(new RegExp(d,"i")).exec(a))b.push(e),k[c][d].apply(y,b)}var g=/^position\.(my|at|adjust|target|container)|style|content|show\.ready/i,h=/^content\.(title|attr)|style/i,i=c,j=c,k=y.checks,l;"string"===typeof e?(l=e,e={},e[l]=f):e=a.extend(b,{},e),a.each(e,function(b,c){var d=H(b.toLowerCase()),f;f=d[0][d[1]],d[0][d[1]]="object"===typeof c&&c.nodeType?a(c):c,e[b]=[d[0],d[1],c,f],i=g.test(b)||i,j=h.test(b)||j}),w(s),B=C=1,a.each(e,m),B=C=0,D.is(":visible")&&y.rendered&&(i&&y.reposition(s.position.target==="mouse"?d:G.event),j&&y.redraw());return y},toggle:function(e,f){function q(){e?(a.browser.msie&&D[0].style.removeAttribute("filter"),D.css("overflow",""),"string"===typeof i.autofocus&&a(i.autofocus,D).focus(),p=a.Event("tooltipvisible"),p.originalEvent=f?G.event:d,D.trigger(p,[y]),i.target.trigger("qtip-"+v+"-inactive")):D.css({display:"",visibility:"",opacity:"",left:"",top:""})}if(!y.rendered)return e?y.render(1):y;var g=e?"show":"hide",i=s[g],j=D.is(":visible"),k=!f||s[g].target.length<2||G.target[0]===f.target,l=s.position,n=s.content,o,p;(typeof e).search("boolean|number")&&(e=!j);if(!D.is(":animated")&&j===e&&k)return y;if(f){if(/over|enter/.test(f.type)&&/out|leave/.test(G.event.type)&&f.target===s.show.target[0]&&D.has(f.relatedTarget).length)return y;G.event=a.extend({},f)}p=a.Event("tooltip"+g),p.originalEvent=f?G.event:d,D.trigger(p,[y,90]);if(p.isDefaultPrevented())return y;a.attr(D[0],"aria-hidden",!e),e?(G.origin=a.extend({},h),y.focus(f),a.isFunction(n.text)&&O(n.text,c),a.isFunction(n.title.text)&&N(n.title.text,c),!u&&l.target==="mouse"&&l.adjust.mouse&&(a(document).bind("mousemove.qtip",function(a){h={pageX:a.pageX,pageY:a.pageY,type:"mousemove"}}),u=b),y.reposition(f,arguments[2]),(p.solo=!!i.solo)&&a(m,i.solo).not(D).qtip("hide",p)):(clearTimeout(y.timers.show),delete G.origin,u&&!a(m+'[tracking="true"]:visible',i.solo).not(D).length&&(a(document).unbind("mousemove.qtip"),u=c),y.blur(f)),k&&D.stop(0,1),i.effect===c?(D[g](),q.call(D)):a.isFunction(i.effect)?(i.effect.call(D,y),D.queue("fx",function(a){q(),a()})):D.fadeTo(90,e?1:0,q),e&&i.target.trigger("qtip-"+v+"-inactive");return y},show:function(a){return y.toggle(b,a)},hide:function(a){return y.toggle(c,a)},focus:function(b){if(!y.rendered)return y;var c=a(m),d=parseInt(D[0].style.zIndex,10),e=f.zindex+c.length,g=a.extend({},b),h,i;D.hasClass(o)||(i=a.Event("tooltipfocus"),i.originalEvent=g,D.trigger(i,[y,e]),i.isDefaultPrevented()||(d!==e&&(c.each(function(){this.style.zIndex>d&&(this.style.zIndex=this.style.zIndex-1)}),c.filter("."+o).qtip("blur",g)),D.addClass(o)[0].style.zIndex=e));return y},blur:function(b){var c=a.extend({},b),d;D.removeClass(o),d=a.Event("tooltipblur"),d.originalEvent=c,D.trigger(d,[y]);return y},reposition:function(b,d){if(!y.rendered||B)return y;B=1;var e=s.position.target,f=s.position,i=f.my,k=f.at,l=f.adjust,m=l.method.split(" "),n=D.outerWidth(),o=D.outerHeight(),p=0,q=0,r=a.Event("tooltipmove"),t=D.css("position")==="fixed",u=f.viewport,v={left:0,top:0},w=f.container,x=c,A=y.plugins.tip,C={horizontal:m[0],vertical:m[1]=m[1]||m[0],enabled:u.jquery&&e[0]!==window&&e[0]!==z&&l.method!=="none",left:function(a){var b=C.horizontal==="shift",c=-w.offset.left+u.offset.left+u.scrollLeft,d=i.x==="left"?n:i.x==="right"?-n:-n/2,e=k.x==="left"?p:k.x==="right"?-p:-p/2,f=A&&A.size?A.size.width||0:0,g=A&&A.corner&&A.corner.precedance==="x"&&!b?f:0,h=c-a+g,j=a+n-u.width-c+g,m=d-(i.precedance==="x"||i.x===i.y?e:0)-(k.x==="center"?p/2:0),o=i.x==="center";b?(g=A&&A.corner&&A.corner.precedance==="y"?f:0,m=(i.x==="left"?1:-1)*d-g,v.left+=h>0?h:j>0?-j:0,v.left=Math.max(-w.offset.left+u.offset.left+(g&&A.corner.x==="center"?A.offset:0),a-m,Math.min(Math.max(-w.offset.left+u.offset.left+u.width,a+m),v.left))):(h>0&&(i.x!=="left"||j>0)?v.left-=m:j>0&&(i.x!=="right"||h>0)&&(v.left-=o?-m:m),v.left!==a&&o&&(v.left-=l.x),v.leftj&&(v.left=a));return v.left-a},top:function(a){var b=C.vertical==="shift",c=-w.offset.top+u.offset.top+u.scrollTop,d=i.y==="top"?o:i.y==="bottom"?-o:-o/2,e=k.y==="top"?q:k.y==="bottom"?-q:-q/2,f=A&&A.size?A.size.height||0:0,g=A&&A.corner&&A.corner.precedance==="y"&&!b?f:0,h=c-a+g,j=a+o-u.height-c+g,m=d-(i.precedance==="y"||i.x===i.y?e:0)-(k.y==="center"?q/2:0),n=i.y==="center";b?(g=A&&A.corner&&A.corner.precedance==="x"?f:0,m=(i.y==="top"?1:-1)*d-g,v.top+=h>0?h:j>0?-j:0,v.top=Math.max(-w.offset.top+u.offset.top+(g&&A.corner.x==="center"?A.offset:0),a-m,Math.min(Math.max(-w.offset.top+u.offset.top+u.height,a+m),v.top))):(h>0&&(i.y!=="top"||j>0)?v.top-=m:j>0&&(i.y!=="bottom"||h>0)&&(v.top-=n?-m:m),v.top!==a&&n&&(v.top-=l.y),v.top<0&&-v.top>j&&(v.top=a));return v.top-a}},E;if(a.isArray(e)&&e.length===2)k={x:"left",y:"top"},v={left:e[0],top:e[1]};else if(e==="mouse"&&(b&&b.pageX||G.event.pageX))k={x:"left",y:"top"},b=(b&&(b.type==="resize"||b.type==="scroll")?G.event:b&&b.pageX&&b.type==="mousemove"?b:h&&h.pageX&&(l.mouse||!b||!b.pageX)?{pageX:h.pageX,pageY:h.pageY}:!l.mouse&&G.origin&&G.origin.pageX&&s.show.distance?G.origin:b)||b||G.event||h||{},v={top:b.pageY,left:b.pageX};else{e==="event"?b&&b.target&&b.type!=="scroll"&&b.type!=="resize"?e=G.target=a(b.target):e=G.target:e=G.target=a(e.jquery?e:F.target),e=a(e).eq(0);if(e.length===0)return y;e[0]===document||e[0]===window?(p=g.iOS?window.innerWidth:e.width(),q=g.iOS?window.innerHeight:e.height(),e[0]===window&&(v={top:(u||e).scrollTop(),left:(u||e).scrollLeft()})):e.is("area")&&g.imagemap?v=g.imagemap(e,k,C.enabled?m:c):e[0].namespaceURI==="http://www.w3.org/2000/svg"&&g.svg?v=g.svg(e,k):(p=e.outerWidth(),q=e.outerHeight(),v=g.offset(e,w)),v.offset&&(p=v.width,q=v.height,x=v.flipoffset,v=v.offset);if(g.iOS<4.1&&g.iOS>3.1||g.iOS==4.3||!g.iOS&&t)E=a(window),v.left-=E.scrollLeft(),v.top-=E.scrollTop();v.left+=k.x==="right"?p:k.x==="center"?p/2:0,v.top+=k.y==="bottom"?q:k.y==="center"?q/2:0}v.left+=l.x+(i.x==="right"?-n:i.x==="center"?-n/2:0),v.top+=l.y+(i.y==="bottom"?-o:i.y==="center"?-o/2:0),C.enabled?(u={elem:u,height:u[(u[0]===window?"h":"outerH")+"eight"](),width:u[(u[0]===window?"w":"outerW")+"idth"](),scrollLeft:t?0:u.scrollLeft(),scrollTop:t?0:u.scrollTop(),offset:u.offset()||{left:0,top:0}},w={elem:w,scrollLeft:w.scrollLeft(),scrollTop:w.scrollTop(),offset:w.offset()||{left:0,top:0}},v.adjusted={left:C.horizontal!=="none"?C.left(v.left):0,top:C.vertical!=="none"?C.top(v.top):0},v.adjusted.left+v.adjusted.top&&D.attr("class",D[0].className.replace(/ui-tooltip-pos-\w+/i,j+"-pos-"+i.abbrev())),x&&v.adjusted.left&&(v.left+=x.left),x&&v.adjusted.top&&(v.top+=x.top)):v.adjusted={left:0,top:0},r.originalEvent=a.extend({},b),D.trigger(r,[y,v,u.elem||u]);if(r.isDefaultPrevented())return y;delete v.adjusted,d===c||isNaN(v.left)||isNaN(v.top)||e==="mouse"||!a.isFunction(f.effect)?D.css(v):a.isFunction(f.effect)&&(f.effect.call(D,y,a.extend({},v)),D.queue(function(b){a(this).css({opacity:"",height:""}),a.browser.msie&&this.style.removeAttribute("filter"),b()})),B=0;return y},redraw:function(){if(y.rendered<1||C)return y;var a=s.position.container,b,c,d,e;C=1,s.style.height&&D.css("height",s.style.height),s.style.width?D.css("width",s.style.width):(D.css("width","").addClass(q),c=D.width()+1,d=D.css("max-width")||"",e=D.css("min-width")||"",b=(d+e).indexOf("%")>-1?a.width()/100:0,d=(d.indexOf("%")>-1?b:1)*parseInt(d,10)||c,e=(e.indexOf("%")>-1?b:1)*parseInt(e,10)||0,c=d+e?Math.min(Math.max(c,e),d):c,D.css("width",Math.round(c)).removeClass(q)),C=0;return y},disable:function(b){"boolean"!==typeof b&&(b=!D.hasClass(l)&&!G.disabled),y.rendered?(D.toggleClass(l,b),a.attr(D[0],"aria-disabled",b)):G.disabled=!!b;return y},enable:function(){return y.disable(c)},destroy:function(){var b=r[0],c=a.attr(b,t),d=r.data("qtip");y.rendered&&(D.stop(1,0).remove(),a.each(y.plugins,function(){this.destroy&&this.destroy()})),clearTimeout(y.timers.show),clearTimeout(y.timers.hide),Q();if(!d||y===d)a.removeData(b,"qtip"),s.suppress&&c&&(a.attr(b,"title",c),r.removeAttr(t)),r.removeAttr("aria-describedby");r.unbind(".qtip-"+v),delete i[y.id];return r}})}function w(b){var e;if(!b||"object"!==typeof b)return c;if(b.metadata===d||"object"!==typeof b.metadata)b.metadata={type:b.metadata};if("content"in b){if(b.content===d||"object"!==typeof b.content||b.content.jquery)b.content={text:b.content};e=b.content.text||c,!a.isFunction(e)&&(!e&&!e.attr||e.length<1||"object"===typeof e&&!e.jquery)&&(b.content.text=c);if("title"in b.content){if(b.content.title===d||"object"!==typeof b.content.title)b.content.title={text:b.content.title};e=b.content.title.text||c,!a.isFunction(e)&&(!e&&!e.attr||e.length<1||"object"===typeof e&&!e.jquery)&&(b.content.title.text=c)}}if("position"in b)if(b.position===d||"object"!==typeof b.position)b.position={my:b.position,at:b.position};if("show"in b)if(b.show===d||"object"!==typeof b.show)b.show.jquery?b.show={target:b.show}:b.show={event:b.show};if("hide"in b)if(b.hide===d||"object"!==typeof b.hide)b.hide.jquery?b.hide={target:b.hide}:b.hide={event:b.hide};if("style"in b)if(b.style===d||"object"!==typeof b.style)b.style={classes:b.style};a.each(g,function(){this.sanitize&&this.sanitize(b)});return b}function v(){v.history=v.history||[],v.history.push(arguments);if("object"===typeof console){var a=console[console.warn?"warn":"log"],b=Array.prototype.slice.call(arguments),c;typeof arguments[0]==="string"&&(b[0]="qTip2: "+b[0]),c=a.apply?a.apply(console,b):a(b)}}"use strict";var b=!0,c=!1,d=null,e,f,g,h,i={},j="ui-tooltip",k="ui-widget",l="ui-state-disabled",m="div.qtip."+j,n=j+"-default",o=j+"-focus",p=j+"-hover",q=j+"-fluid",r="-31000px",s="_replacedByqTip",t="oldtitle",u;f=a.fn.qtip=function(g,h,i){var j=(""+g).toLowerCase(),k=d,l=a.makeArray(arguments).slice(1),m=l[l.length-1],n=this[0]?a.data(this[0],"qtip"):d;if(!arguments.length&&n||j==="api")return n;if("string"===typeof g){this.each(function(){var d=a.data(this,"qtip");if(!d)return b;m&&m.timeStamp&&(d.cache.event=m);if(j!=="option"&&j!=="options"||!h)d[j]&&d[j].apply(d[j],l);else if(a.isPlainObject(h)||i!==e)d.set(h,i);else{k=d.get(h);return c}});return k!==d?k:this}if("object"===typeof g||!arguments.length){n=w(a.extend(b,{},g));return f.bind.call(this,n,m)}},f.bind=function(d,j){return this.each(function(k){function r(b){function d(){p.render(typeof b==="object"||l.show.ready),m.show.add(m.hide).unbind(o)}if(p.cache.disabled)return c;p.cache.event=a.extend({},b),p.cache.target=b?a(b.target):[e],l.show.delay>0?(clearTimeout(p.timers.show),p.timers.show=setTimeout(d,l.show.delay),n.show!==n.hide&&m.hide.bind(n.hide,function(){clearTimeout(p.timers.show)})):d()}var l,m,n,o,p,q;q=a.isArray(d.id)?d.id[k]:d.id,q=!q||q===c||q.length<1||i[q]?f.nextid++:i[q]=q,o=".qtip-"+q+"-create",p=y.call(this,q,d);if(p===c)return b;l=p.options,a.each(g,function(){this.initialize==="initialize"&&this(p)}),m={show:l.show.target,hide:l.hide.target},n={show:a.trim(""+l.show.event).replace(/ /g,o+" ")+o,hide:a.trim(""+l.hide.event).replace(/ /g,o+" ")+o},/mouse(over|enter)/i.test(n.show)&&!/mouse(out|leave)/i.test(n.hide)&&(n.hide+=" mouseleave"+o),m.show.bind("mousemove"+o,function(a){h={pageX:a.pageX,pageY:a.pageY,type:"mousemove"},p.cache.onTarget=b}),m.show.bind(n.show,r),(l.show.ready||l.prerender)&&r(j)})},g=f.plugins={Corner:function(a){a=(""+a).replace(/([A-Z])/," $1").replace(/middle/gi,"center").toLowerCase(),this.x=(a.match(/left|right/i)||a.match(/center/)||["inherit"])[0].toLowerCase(),this.y=(a.match(/top|bottom|center/i)||["inherit"])[0].toLowerCase();var b=a.charAt(0);this.precedance=b==="t"||b==="b"?"y":"x",this.string=function(){return this.precedance==="y"?this.y+this.x:this.x+this.y},this.abbrev=function(){var a=this.x.substr(0,1),b=this.y.substr(0,1);return a===b?a:a==="c"||a!=="c"&&b!=="c"?b+a:a+b},this.clone=function(){return{x:this.x,y:this.y,precedance:this.precedance,string:this.string,abbrev:this.abbrev,clone:this.clone}}},offset:function(b,c){function j(a,b){d.left+=b*a.scrollLeft(),d.top+=b*a.scrollTop()}var d=b.offset(),e=b.closest("body")[0],f=c,g,h,i;if(f){do f.css("position")!=="static"&&(h=f.position(),d.left-=h.left+(parseInt(f.css("borderLeftWidth"),10)||0)+(parseInt(f.css("marginLeft"),10)||0),d.top-=h.top+(parseInt(f.css("borderTopWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0),!g&&(i=f.css("overflow"))!=="hidden"&&i!=="visible"&&(g=f));while((f=a(f[0].offsetParent)).length);g&&g[0]!==e&&j(g,1)}return d},iOS:parseFloat((""+(/CPU.*OS ([0-9_]{1,3})|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent)||[0,""])[1]).replace("undefined","3_2").replace("_","."))||c,fn:{attr:function(b,c){if(this.length){var d=this[0],e="title",f=a.data(d,"qtip");if(b===e&&f&&"object"===typeof f&&f.options.suppress){if(arguments.length<2)return a.attr(d,t);f&&f.options.content.attr===e&&f.cache.attr&&f.set("content.text",c);return this.attr(t,c)}}return a.fn["attr"+s].apply(this,arguments)},clone:function(b){var c=a([]),d="title",e=a.fn["clone"+s].apply(this,arguments);b||e.filter("["+t+"]").attr("title",function(){return a.attr(this,t)}).removeAttr(t);return e}}},a.each(g.fn,function(c,d){if(!d||a.fn[c+s])return b;var e=a.fn[c+s]=a.fn[c];a.fn[c]=function(){return d.apply(this,arguments)||e.apply(this,arguments)}}),a.ui||(a["cleanData"+s]=a.cleanData,a.cleanData=function(b){for(var c=0,d;(d=b[c])!==e;c++)try{a(d).triggerHandler("removeqtip")}catch(f){}a["cleanData"+s](b)}),f.version="nightly",f.nextid=0,f.inactiveEvents="click dblclick mousedown mouseup mousemove mouseleave mouseenter".split(" "),f.zindex=15e3,f.defaults={prerender:c,id:c,overwrite:b,suppress:b,content:{text:b,attr:"title",title:{text:c,button:c}},position:{my:"top left",at:"bottom right",target:c,container:c,viewport:c,adjust:{x:0,y:0,mouse:b,resize:b,method:"flip flip"},effect:function(b,d,e){a(this).animate(d,{duration:200,queue:c})}},show:{target:c,event:"mouseenter",effect:b,delay:90,solo:c,ready:c,autofocus:c},hide:{target:c,event:"mouseleave",effect:b,delay:0,fixed:c,inactive:c,leave:"window",distance:c},style:{classes:"",widget:c,width:c,height:c,def:b},events:{render:d,move:d,show:d,hide:d,toggle:d,visible:d,focus:d,blur:d}},g.ajax=function(a){var b=a.plugins.ajax;return"object"===typeof b?b:a.plugins.ajax=new z(a)},g.ajax.initialize="render",g.ajax.sanitize=function(a){var b=a.content,c;b&&"ajax"in b&&(c=b.ajax,typeof c!=="object"&&(c=a.content.ajax={url:c}),"boolean"!==typeof c.once&&c.once&&(c.once=!!c.once))},a.extend(b,f.defaults,{content:{ajax:{loading:b,once:b}}}),g.tip=function(a){var b=a.plugins.tip;return"object"===typeof b?b:a.plugins.tip=new B(a)},g.tip.initialize="render",g.tip.sanitize=function(a){var c=a.style,d;c&&"tip"in c&&(d=a.style.tip,typeof d!=="object"&&(a.style.tip={corner:d}),/string|boolean/i.test(typeof d.corner)||(d.corner=b),typeof d.width!=="number"&&delete d.width,typeof d.height!=="number"&&delete d.height,typeof d.border!=="number"&&d.border!==b&&delete d.border,typeof d.offset!=="number"&&delete d.offset)},a.extend(b,f.defaults,{style:{tip:{corner:b,mimic:c,width:6,height:6,border:b,offset:0}}}),g.modal=function(a){var b=a.plugins.modal;return"object"===typeof b?b:a.plugins.modal=new C(a)},g.modal.initialize="render",g.modal.sanitize=function(a){a.show&&(typeof a.show.modal!=="object"?a.show.modal={on:!!a.show.modal}:typeof a.show.modal.on==="undefined"&&(a.show.modal.on=b))},g.modal.zindex=f.zindex+1e3,a.extend(b,f.defaults,{show:{modal:{on:c,effect:b,blur:b,escape:b}}})}) var FORMALIZE=function(a,k,e){function f(b){var a=e.createElement("b");a.innerHTML="<\!--[if IE "+b+"]>
";return!!a.getElementsByTagName("br").length}var g="placeholder"in e.createElement("input"),h="autofocus"in e.createElement("input"),i=f(6),j=f(7);return{go:function(){var b,a=this.init;for(b in a)a.hasOwnProperty(b)&&a[b]()},init:{full_input_size:function(){j&&a("textarea, input.input_full").length&&a("textarea, input.input_full").wrap('')}, ie6_skin_inputs:function(){if(i&&a("input, select, textarea").length){var b=/button|submit|reset/,c=/date|datetime|datetime-local|email|month|number|password|range|search|tel|text|time|url|week/;a("input").each(function(){var d=a(this);this.getAttribute("type").match(b)?(d.addClass("ie6_button"),this.disabled&&d.addClass("ie6_button_disabled")):this.getAttribute("type").match(c)&&(d.addClass("ie6_input"),this.disabled&&d.addClass("ie6_input_disabled"))});a("textarea, select").each(function(){this.disabled&& a(this).addClass("ie6_input_disabled")})}},autofocus:function(){!h&&a(":input[autofocus]").length&&a(":input[autofocus]:visible:first").focus()},placeholder:function(){!g&&a(":input[placeholder]").length&&(FORMALIZE.misc.add_placeholder(),a(":input[placeholder]").each(function(){if(this.type!=="password"){var b=a(this),c=b.attr("placeholder");b.focus(function(){b.val()===c&&b.val("").removeClass("placeholder_text")}).blur(function(){FORMALIZE.misc.add_placeholder()});b.closest("form").submit(function(){b.val()=== c&&b.val("").removeClass("placeholder_text")}).bind("reset",function(){setTimeout(FORMALIZE.misc.add_placeholder,50)})}}))}},misc:{add_placeholder:function(){!g&&a(":input[placeholder]").length&&a(":input[placeholder]").each(function(){if(this.type!=="password"){var b=a(this),c=b.attr("placeholder");(!b.val()||b.val()===c)&&b.val(c).addClass("placeholder_text")}})}}}}(jQuery,this,this.document);jQuery(document).ready(function(){FORMALIZE.go()}); (function(b){function o(a){var c=a.data;a.isDefaultPrevented()||(a.preventDefault(),b(this).ajaxSubmit(c))}function s(a){var c=a.target,g=b(c);if(!g.is(":submit,input:image")){c=g.closest(":submit");if(c.length===0)return;c=c[0]}var f=this;f.clk=c;if(c.type=="image")a.offsetX!==void 0?(f.clk_x=a.offsetX,f.clk_y=a.offsetY):typeof b.fn.offset=="function"?(g=g.offset(),f.clk_x=a.pageX-g.left,f.clk_y=a.pageY-g.top):(f.clk_x=a.pageX-c.offsetLeft,f.clk_y=a.pageY-c.offsetTop);setTimeout(function(){f.clk= f.clk_x=f.clk_y=null},100)}function p(){if(b.fn.ajaxSubmit.debug){var a="[jquery.form] "+Array.prototype.join.call(arguments,"");window.console&&window.console.log?window.console.log(a):window.opera&&window.opera.postError&&window.opera.postError(a)}}var t,u;t=b("").get(0).files!==void 0;u=window.FormData!==void 0;b.fn.ajaxSubmit=function(a){function c(c){for(var f=new FormData,e=0;e').attr("value",d.extraData[l]).appendTo(j)[0]);d.iframeTarget||(r.appendTo("body"),m.attachEvent?m.attachEvent("onload",g):m.addEventListener("load",g,!1));setTimeout(a,15);j.submit()}finally{j.setAttribute("action",i),c?j.setAttribute("target",c):k.removeAttr("target"),b(h).remove()}}function g(a){if(!i.aborted&& !z){try{q=m.contentWindow?m.contentWindow.document:m.contentDocument?m.contentDocument:m.document}catch(c){p("cannot access response document: ",c),a=x}if(a===t&&i)i.abort("timeout");else if(a==x&&i)i.abort("server abort");else if(q&&q.location.href!=d.iframeSrc||s){m.detachEvent?m.detachEvent("onload",g):m.removeEventListener("load",g,!1);var a="success",e;try{if(s)throw"timeout";var f=d.dataType=="xml"||q.XMLDocument||b.isXMLDoc(q);p("isXml="+f);if(!f&&window.opera&&(q.body===null||!q.body.innerHTML)&& --B){p("requeing onLoad callback, DOM not available");setTimeout(g,250);return}var h=q.body?q.body:q.documentElement;i.responseText=h?h.innerHTML:null;i.responseXML=q.XMLDocument?q.XMLDocument:q;if(f)d.dataType="xml";i.getResponseHeader=function(a){return{"content-type":d.dataType}[a]};if(h)i.status=Number(h.getAttribute("status"))||i.status,i.statusText=h.getAttribute("statusText")||i.statusText;var j=(d.dataType||"").toLowerCase(),l=/(json|script|text)/.test(j);if(l||d.textarea){var k=q.getElementsByTagName("textarea")[0]; if(k)i.responseText=k.value,i.status=Number(k.getAttribute("status"))||i.status,i.statusText=k.getAttribute("statusText")||i.statusText;else if(l){var o=q.getElementsByTagName("pre")[0],w=q.getElementsByTagName("body")[0];if(o)i.responseText=o.textContent?o.textContent:o.innerText;else if(w)i.responseText=w.textContent?w.textContent:w.innerText}}else if(j=="xml"&&!i.responseXML&&i.responseText)i.responseXML=C(i.responseText);try{u=D(i,j,d)}catch(A){a="parsererror",i.error=e=A||a}}catch(y){p("error caught: ", y),a="error",i.error=e=y||a}i.aborted&&(p("upload aborted"),a=null);i.status&&(a=i.status>=200&&i.status<300||i.status===304?"success":"error");if(a==="success")d.success&&d.success.call(d.context,u,"success",i),n&&b.event.trigger("ajaxSuccess",[i,d]);else if(a){if(e===void 0)e=i.statusText;d.error&&d.error.call(d.context,i,a,e);n&&b.event.trigger("ajaxError",[i,d,e])}n&&b.event.trigger("ajaxComplete",[i,d]);n&&!--b.active&&b.event.trigger("ajaxStop");d.complete&&d.complete.call(d.context,i,a);z= !0;d.timeout&&clearTimeout(v);setTimeout(function(){d.iframeTarget||r.remove();i.responseXML=null},100)}}}var j=k[0],h,l,d,n,o,r,m,i,s,v;h=!!b.fn.prop;if(c)if(h)for(l=0;l'),r.css({position:"absolute",top:"-1000px",left:"-1000px"})),m=r[0],i={aborted:0,responseText:null,responseXML:null,status:0,statusText:"n/a",getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(a){var c=a==="timeout"?"timeout":"aborted";p("aborting upload... "+c);this.aborted=1;r.attr("src",d.iframeSrc);i.error= c;d.error&&d.error.call(d.context,i,c,a);n&&b.event.trigger("ajaxError",[i,d,c]);d.complete&&d.complete.call(d.context,i,c)}},(n=d.global)&&0===b.active++&&b.event.trigger("ajaxStart"),n&&b.event.trigger("ajaxSend",[i,d]),d.beforeSend&&d.beforeSend.call(d.context,i,d)===!1)d.global&&b.active--;else if(!i.aborted){if(c=j.clk)if((h=c.name)&&!c.disabled)if(d.extraData=d.extraData||{},d.extraData[h]=c.value,c.type=="image")d.extraData[h+".x"]=j.clk_x,d.extraData[h+".y"]=j.clk_y;var t=1,x=2,c=b("meta[name=csrf-token]").attr("content"); if((h=b("meta[name=csrf-param]").attr("content"))&&c)d.extraData=d.extraData||{},d.extraData[h]=c;d.forceSync?e():setTimeout(e,10);var u,q,B=50,z,C=b.parseXML||function(a,b){window.ActiveXObject?(b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a)):b=(new DOMParser).parseFromString(a,"text/xml");return b&&b.documentElement&&b.documentElement.nodeName!="parsererror"?b:null},E=b.parseJSON||function(a){return window.eval("("+a+")")},D=function(a,c,d){var e=a.getResponseHeader("content-type")|| "",f=c==="xml"||!c&&e.indexOf("xml")>=0,a=f?a.responseXML:a.responseText;f&&a.documentElement.nodeName==="parsererror"&&b.error&&b.error("parsererror");d&&d.dataFilter&&(a=d.dataFilter(a,c));typeof a==="string"&&(c==="json"||!c&&e.indexOf("json")>=0?a=E(a):(c==="script"||!c&&e.indexOf("javascript")>=0)&&b.globalEval(a));return a}}}if(!this.length)return p("ajaxSubmit: skipping submit process - no element selected"),this;var f,e,k=this;typeof a=="function"&&(a={success:a});f=this.attr("method");e= this.attr("action");(e=(e=typeof e==="string"?b.trim(e):"")||window.location.href||"")&&(e=(e.match(/^([^#]+)/)||[])[1]);a=b.extend(!0,{url:e,success:b.ajaxSettings.success,type:f||"GET",iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank"},a);e={};this.trigger("form-pre-serialize",[this,a,e]);if(e.veto)return p("ajaxSubmit: submit vetoed via form-pre-serialize trigger"),this;if(a.beforeSerialize&&a.beforeSerialize(this,a)===!1)return p("ajaxSubmit: submit aborted via beforeSerialize callback"), this;var l=a.traditional;if(l===void 0)l=b.ajaxSettings.traditional;var h,j=this.formToArray(a.semantic);if(a.data)a.extraData=a.data,h=b.param(a.data,l);if(a.beforeSubmit&&a.beforeSubmit(j,this,a)===!1)return p("ajaxSubmit: submit aborted via beforeSubmit callback"),this;this.trigger("form-submit-validate",[j,this,a,e]);if(e.veto)return p("ajaxSubmit: submit vetoed via form-submit-validate trigger"),this;e=b.param(j,l);h&&(e=e?e+"&"+h:h);a.type.toUpperCase()=="GET"?(a.url+=(a.url.indexOf("?")>=0? "&":"?")+e,a.data=null):a.data=e;var n=[];a.resetForm&&n.push(function(){k.resetForm()});a.clearForm&&n.push(function(){k.clearForm(a.includeHidden)});if(!a.dataType&&a.target){var o=a.success||function(){};n.push(function(c){var e=a.replaceTarget?"replaceWith":"html";b(a.target)[e](c).each(o,arguments)})}else a.success&&n.push(a.success);a.success=function(b,c,e){for(var f=a.context||a,g=0,h=n.length;g0;e=k.attr("enctype")== "multipart/form-data"||k.attr("encoding")=="multipart/form-data";l=t&&u;p("fileAPI :"+l);a.iframe!==!1&&(a.iframe||(h||e)&&!l)?a.closeKeepAlive?b.get(a.closeKeepAlive,function(){g(j)}):g(j):(h||e)&&l?c(j):b.ajax(a);this.trigger("form-submit-notify",[this,a]);return this};b.fn.ajaxForm=function(a){a=a||{};a.delegation=a.delegation&&b.isFunction(b.fn.on);if(!a.delegation&&this.length===0){var c=this.selector,g=this.context;if(!b.isReady&&c)return p("DOM not ready, queuing ajaxForm"),b(function(){b(c, g).ajaxForm(a)}),this;p("terminating; zero elements found by selector"+(b.isReady?"":" (DOM not ready)"));return this}return a.delegation?(b(document).off("submit.form-plugin",this.selector,o).off("click.form-plugin",this.selector,s).on("submit.form-plugin",this.selector,a,o).on("click.form-plugin",this.selector,a,s),this):this.ajaxFormUnbind().bind("submit.form-plugin",a,o).bind("click.form-plugin",a,s)};b.fn.ajaxFormUnbind=function(){return this.unbind("submit.form-plugin click.form-plugin")};b.fn.formToArray= function(a){var c=[];if(this.length===0)return c;var g=this[0],f=a?g.getElementsByTagName("*"):g.elements;if(!f)return c;var e,k,l,h,j,n;for(e=0,n=f.length;e").text(i.current_path).appendTo(c);e=a("
    ").appendTo(c);a.each(b,function(b,c){f=a("").click(function(){l(c.path,d)}).text(c.name);a('').prependTo(f);f.hover(function(){a("span", this).addClass("ui-icon-folder-open")},function(){a("span",this).removeClass("ui-icon-folder-open")});f.appendTo(e)});a("a",e).wrap('
  • ');c.dialog("option","dialogClass","browserDialog")}))}var c,j,k=null;a.fn.nFileBrowser=function(b,d){d=a.extend({},a.Browser.defaults,d);c||(c=a('
    ').appendTo("body").dialog({dialogClass:"browserDialog",title:d.title,position:["center",40],minWidth:Math.min(a(document).width()- 80,650),minHeight:320,height:a(document).height()-80,modal:!0,autoOpen:!1}));c.dialog("option","buttons",{Ok:function(){b(j,d);c.dialog("close")},Cancel:function(){c.dialog("close")}});var h=d.field.val()||d.initialDir||"";l(h,d.url);c.dialog("option","title",d.title);c.dialog("open");return!1};a.fn.fileBrowser=function(b){b=a.extend({},a.Browser.defaults,b);b.field=a(this);if(b.field.autocomplete&&b.autocompleteURL){var c="";b.field.autocomplete({appendTo:"#content",source:function(g,e){c=a.ui.autocomplete.escapeRegex(g.term); a.ajax({url:b.autocompleteURL,data:g,dataType:"json",success:function(b){var g=RegExp("^"+c,"i"),b=a.grep(b,function(a){return g.test(a)});e(b)}})},open:function(){a(".ui-autocomplete li.ui-menu-item a").removeClass("ui-corner-all");a(".ui-autocomplete li.ui-menu-item:odd a").addClass("ui-menu-item-alternate")}}).data("autocomplete")._renderItem=function(b,e){var f=e.label,f=f.replace(RegExp("(?![^&;]+;)(?!<[^<>]*)("+c+")(?![^<>]*>)(?![^&;]+;)","gi"),function(a){return""+a+""});return a("
  • ").data("item.autocomplete", e).append("
    "+f+"").appendTo(b)}}var h,i=null,i=function(a,b){b.field.val(a)};h=b.field.val()||"";b=a.extend(b,{initialDir:h});return b.field.addClass("fileBrowserField").after(a('').click(function(){a(this).nFileBrowser(i,b);return!1}))}})(jQuery); SABnzbd-0.7.20/interfaces/Mobile/README.txt0000644000000000000000000000114012433712601020250 0ustar00usergroup00000000000000 Mobile 0.1 for SABnzbd 0.6 | Sept 01 2009 assembled by pairofdimes - see LICENSE-CC.txt ============== LIBRARIES USED jQuery http://jquery.com Copyright (c) 2010 John Resig See LICENSE-MIT & LICENSE-GPL Sizzle CSS Selector Engine http://sizzlejs.com/ Copyright (c) 2010 The Dojo Foundation See LICENSE-MIT, LICENSE-BSD, & LICENSE-GPL jQuery jQTouch Plugin http://www.jqtouch.com/ Copyright (c) 2009 jQTouch project members See LICENSE-MIT The image templates/static/images/sab.png was provided by inpheaux. All other images and stylesheets provided by jQuery jQTouch Plugin package (see notes above). SABnzbd-0.7.20/interfaces/Mobile/licenses/LICENSE-BSD.txt0000644000000000000000000000336412433712601022622 0ustar00usergroup00000000000000 = Regents of the University of California = University of California, Berkeley = 1998 In the original BSD license, both occurrences of the phrase "COPYRIGHT HOLDERS AND CONTRIBUTORS" in the disclaimer read "REGENTS AND CONTRIBUTORS". Here is the license template: Copyright (c) , All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.SABnzbd-0.7.20/interfaces/Mobile/licenses/LICENSE-CC.txt0000644000000000000000000004126412433712602022501 0ustar00usergroup00000000000000http://creativecommons.org/licenses/by/3.0/ http://creativecommons.org/licenses/by/3.0/legalcode License THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 1. Definitions 1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. 2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. 3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. 4. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. 5. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. 6. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. 7. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. 8. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. 9. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: 1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; 2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; 3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and, 4. to Distribute and Publicly Perform Adaptations. 5. For the avoidance of doubt: 1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; 2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, 3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: 1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested. 2. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. 3. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. 5. Representations, Warranties and Disclaimer UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. Termination 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 8. Miscellaneous 1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. 6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. SABnzbd-0.7.20/interfaces/Mobile/licenses/LICENSE-GPL.txt0000644000000000000000000004310312433712602022630 0ustar00usergroup00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. SABnzbd-0.7.20/interfaces/Mobile/licenses/LICENSE-MIT.txt0000644000000000000000000000207112433712602022636 0ustar00usergroup00000000000000The MIT License Copyright (c) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.SABnzbd-0.7.20/interfaces/Mobile/templates/main.tmpl0000644000000000000000000003021412433712602022377 0ustar00usergroup00000000000000 SAB+ Mobile

    $T('Mobile-button-options')

    $T('Mobile-button-close')

    $T('onQueueFinish'):

    $T('menu-queue') NZB

    $T('button-back') $T('Mobile-rename')
    • $T('remainTotal') ⁄  $T('MB') %
    • $T('eta')
    • $T('Mobile-left')
    • $T('nzo-age')
    • $T('link-pause') NZB
    • $T('order')
    • $T('category')
    • $T('priority')
    • $T('pp')
    • $T('script')
    • $T('nzo-delete') NZB

    $T('menu-history') NZB

    $T('button-back')
    • $T('status')
    • $T('size')
    • $T('completed')
    • $T('category')
    • $T('connections')
      • $T('catFolderPath')

      $T('Mobile-warnings')

      $T('button-back') $T('button-clear')
      SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/sab.png0000644000000000000000000000527112433712545024577 0ustar00usergroup00000000000000PNG  IHDR@@iqtIME &3Z pHYsnu>gAMA a HIDATxZYl\W{lJ"(M))A Re*, HD$$$@AʢRh ҅,uhܖ5ڎc;= ;73gbxν۽flm#7vG@ǰD!F ß)l'Cxd|Լ`p p˞j.a+ /-ot 0x{wvje L_[WY@R~Mgf#w }?{'502 tN`a_F9$;.2!Y2ow`'u3ܹT?xqkIN-qˉ-YR8 ! C?hq Md^ TIVJl&FHp}xt܏%j|, `3Oq%@x奊 yMLTL:p̆ TS/Tf0TGIM2\c_m+K @U=Xhp,i( M K}}$&7(v -G@v^lNƢ\3_!L$/^ GnөVƼp]sasN $5Љ؀E\[ܾ;A:iOof ixu8R1;4SX") ?9so1xME}27Y5rM+ύ=AVezN"F%2mX7( k>+tm -JԂM{udC'myKM< ^;}!g/24YH 49)KkQ;9E/!9 %L;[z ϩR]!du@MK^vͽFGJ4U5q^dB_hєvRi SnLn%F8ۼf6/VBKW LF0U5qQ" Lݧ-+ 9pDuV-G1nQ5fZ4!t 6=']niC꾃"*s!84C;EٌdA~ʃiV֬Ų[zy-y%^לy&**u8tzM/"+V8~82Q-d+Da*d0a4H"R 1S8kx8Ǯe ,>?6Qdo?~W.sJ݂F9wtDΥ^xe9Ϩf^g Ǝ9OSFS`nFV.pw xn&ÿ3[[^RO3y&nhq"ګ>?يZT=|m ̷c}<.dХEe6z, MUuKj%kp6 jLxzHC{>I!E'^wO 'r⺾Ϡrq֖^jV DT,q0]S_p&' 4}q0.64V&|WU[U>a~ZU~VUB~Jh=֨iJ[o5ߟTS*[mx $>IO=FmSVF7`6lx 6zmk@,-"n7MO'[>oEhm.bIENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/back_button.png0000644000000000000000000000725412433712544027250 0ustar00usergroup00000000000000PNG  IHDR!w RiCCPICC ProfilexwPTϽwr 0 C9 Ir Ea` 3`("IdUW kD uA"꺸ޝJxwNUo _ ! |ܙ1L|?lNNVRp3Ixdw7Tuo:_ԜPvy$YNPF(牲$ii1 (l+J!IY {Pޖ+桌\| etqw(3x0_㤠l2E恲JN\"J4O<2V )">ǀiaoby"IrYl*Yr IjDlkaokkbimAۯס b2`͠9Kc }.}`{yIL< )g*[혞$8]Ĕ)2s俇\ւcX뇍&cral6v1pz8;/.[ێۏkŝ q3x<^ owx_??Ou%K6 M!$a(C!:\*b)E NH$=3)JH .^dM=9'o W)rC%"ܣRTWj,UDAm^>IJIqKUKK I&JHI^-].}Rz@ QFWC-NŽ̰,MB6X6CvlU٧rx9]9/9\!r4Eqhi K :GK?r+ȏ2.Ï(e`a|PPUpS))( )*.RtU)+*VTRJSڥԡPl|@EE8Xt_V1T SYrHOeFUMG5KR 5ZjS4|=ԟ1ntf9!֨טӌܤ٪PJڣխ5ݬ}_I٧ӫ3UCjfT}lz[8A~aaldk7o4h57PLLrMMLL;L_iŚ25lncn`>b!goɢKCKe-+zNWF<wmh6A6[mm> m[ljYtVk;=~i";8969>us958;k:G3',>xEÅRU˕zu-Kwsw{Z󞈧ggWW#oMdfi5>}|T8~~vk{(K  A,,~d }fֻ4~iҷ#Hȸ(Ϩhcc1ñ3˼]6gWwg˯P^Lt<;d6!*)#;]ϞIKIxpqs]{SrZt3gIg ~9/.$_}VOhOKW.{_{Wƺqz{M_/6 tް54xveMϛoݺ~{;w }z/ޫF6<>(~(ʣ_ ~m=39xqDIƧOOOyOxs/ ˟~wo:zz՗?Vz}Go3Szw=}sy+>|/_ -49IDATH W}HSQoMk2+gZY"H$aIQ J3֊$)?"j +X%O?" #*ʲ8Mv:xwϹwl\zH_41ȑb5; ޶lg4a.?[lL!Ӧ6.nsu(R%];HjjjTX\_bLGt:8Nzp9#EqKvrչLJQ^~Rp5u8N\ 0ӬUsfZS>zt8/m^/] Wʸ>ʹ_HPv>/ʋ)S=3Pߘ9J=#`zĬ0e>kL :WxE#Q Vܮw8-m9N9R}8FYlg {dpw__/ ¢]9 Ґe@tif6c\꣡tTTT?p ?O46QqE862!)lwk.$ΚGc?(F3Cܹ48KHH-:>\>>A*;pGH!q֒ǤW>i8=^WVf>aDhGkɤ .=#ST,Fh0o(sK?1wrvYcq:9u8-_~>mO}Pre)p+jUq/FB:7W[YŚ0Qc^^^C/Y>@n"Xܸ~m?wha'DӡXz"ᜓvYYYoΞ>uvs(ܩ{,ūXY+;VJ삍5ԶrJvC "99V+\fxQ/\ؤ BM&luq"7&{wEՄrmZZnl2˧iϏv8SzjM00 m+T}te8?-i6>,\$ Oǀiaoby"IrYl*Yr IjDlkaokkbimAۯס b2`͠9Kc }.}`{yIL< )g*[혞$8]Ĕ)2s俇\ւcX뇍&cral6v1pz8;/.[ێۏkŝ q3x<^ owx_??Ou%K6 M!$a(C!:\*b)E NH$=3)JH .^dM=9'o W)rC%"ܣRTWj,UDAm^>IJIqKUKK I&JHI^-].}Rz@ QFWC-NŽ̰,MB6X6CvlU٧rx9]9/9\!r4Eqhi K :GK?r+ȏ2.Ï(e`a|PPUpS))( )*.RtU)+*VTRJSڥԡPl|@EE8Xt_V1T SYrHOeFUMG5KR 5ZjS4|=ԟ1ntf9!֨טӌܤ٪PJڣխ5ݬ}_I٧ӫ3UCjfT}lz[8A~aaldk7o4h57PLLrMMLL;L_iŚ25lncn`>b!goɢKCKe-+zNWF<wmh6A6[mm> m[ljYtVk;=~i";8969>us958;k:G3',>xEÅRU˕zu-Kwsw{Z󞈧ggWW#oMdfi5>}|T8~~vk{(K  A,,~d }fֻ4~iҷ#Hȸ(Ϩhcc1ñ3˼]6gWwg˯P^Lt<;d6!*)#;]ϞIKIxpqs]{SrZt3gIg ~9/.$_}VOhOKW.{_{Wƺqz{M_/6 tް54xveMϛoݺ~{;w }z/ޫF6<>(~(ʣ_ ~m=39xqDIƧOOOyOxs/ ˟~wo:zz՗?Vz}Go3Szw=}sy+>|/_ -49IDATH VoHSQo6to AC"AYk`-E_(´}CiPP`Qe(%0SŰf6m9펷6[k;s9{ι]Ux<:29#+J^UV^W݋J4`mFHZQ*Q#A ].277G>ﯠ[cYh408pHwANeHz@>/v8HII ,Kܼ<p$Y\XWnz5 ,sA u \G`WVVR"p:]ZVF1(b0*#9Lzǵ'2*1/aMCyIB_WDkkki9hbE"jz*S{Av|7fgq>Mt)V6!r$ڐrO"|0?jjr[QwnA ,AeAl޾Ypy)(̀\OGSKKGt}>555X2rXz(cyyӵP~ $ ǀiaoby"IrYl*Yr IjDlkaokkbimAۯס b2`͠9Kc }.}`{yIL< )g*[혞$8]Ĕ)2s俇\ւcX뇍&cral6v1pz8;/.[ێۏkŝ q3x<^ owx_??Ou%K6 M!$a(C!:\*b)E NH$=3)JH .^dM=9'o W)rC%"ܣRTWj,UDAm^>IJIqKUKK I&JHI^-].}Rz@ QFWC-NŽ̰,MB6X6CvlU٧rx9]9/9\!r4Eqhi K :GK?r+ȏ2.Ï(e`a|PPUpS))( )*.RtU)+*VTRJSڥԡPl|@EE8Xt_V1T SYrHOeFUMG5KR 5ZjS4|=ԟ1ntf9!֨טӌܤ٪PJڣխ5ݬ}_I٧ӫ3UCjfT}lz[8A~aaldk7o4h57PLLrMMLL;L_iŚ25lncn`>b!goɢKCKe-+zNWF<wmh6A6[mm> m[ljYtVk;=~i";8969>us958;k:G3',>xEÅRU˕zu-Kwsw{Z󞈧ggWW#oMdfi5>}|T8~~vk{(K  A,,~d }fֻ4~iҷ#Hȸ(Ϩhcc1ñ3˼]6gWwg˯P^Lt<;d6!*)#;]ϞIKIxpqs]{SrZt3gIg ~9/.$_}VOhOKW.{_{Wƺqz{M_/6 tް54xveMϛoݺ~{;w }z/ޫF6<>(~(ʣ_ ~m=39xqDIƧOOOyOxs/ ˟~wo:zz՗?Vz}Go3Szw=}sy+>|/_ -49\IDATH VNA>Cj%Z ro# /Lh {/P0 1ЋW@"jάeeZrigvgw~dXennUOaЉ7Rd϶?;=*'sdȲ,ޗ !u]}Cϟ<^(+;w2MI0 I`^Oklv)By$R9 bF^dX_[ΖS:vQgG =XhdYێS=_8`]*B8x9[ `A^U}/!6~>X2tu6p\2ܗpsdWs e|Wsߩh+*z7Y_ǚn2 /at`|9C(G+߬w4GAvz:cءxG06pi qbR^paN]媿ik]ڪofa}6'IatûsxZ|8CAIQ`n3&{ ~ >IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/button_clicked.png0000644000000000000000000000632312433712544027742 0ustar00usergroup00000000000000PNG  IHDR%h RiCCPICC ProfilexwPTϽwr 0 C9 Ir Ea` 3`("IdUW kD uA"꺸ޝJxwNUo _ ! |ܙ1L|?lNNVRp3Ixdw7Tuo:_ԜPvy$YNPF(牲$ii1 (l+J!IY {Pޖ+桌\| etqw(3x0_㤠l2E恲JN\"J4O<2V )">ǀiaoby"IrYl*Yr IjDlkaokkbimAۯס b2`͠9Kc }.}`{yIL< )g*[혞$8]Ĕ)2s俇\ւcX뇍&cral6v1pz8;/.[ێۏkŝ q3x<^ owx_??Ou%K6 M!$a(C!:\*b)E NH$=3)JH .^dM=9'o W)rC%"ܣRTWj,UDAm^>IJIqKUKK I&JHI^-].}Rz@ QFWC-NŽ̰,MB6X6CvlU٧rx9]9/9\!r4Eqhi K :GK?r+ȏ2.Ï(e`a|PPUpS))( )*.RtU)+*VTRJSڥԡPl|@EE8Xt_V1T SYrHOeFUMG5KR 5ZjS4|=ԟ1ntf9!֨טӌܤ٪PJڣխ5ݬ}_I٧ӫ3UCjfT}lz[8A~aaldk7o4h57PLLrMMLL;L_iŚ25lncn`>b!goɢKCKe-+zNWF<wmh6A6[mm> m[ljYtVk;=~i";8969>us958;k:G3',>xEÅRU˕zu-Kwsw{Z󞈧ggWW#oMdfi5>}|T8~~vk{(K  A,,~d }fֻ4~iҷ#Hȸ(Ϩhcc1ñ3˼]6gWwg˯P^Lt<;d6!*)#;]ϞIKIxpqs]{SrZt3gIg ~9/.$_}VOhOKW.{_{Wƺqz{M_/6 tް54xveMϛoݺ~{;w }z/ޫF6<>(~(ʣ_ ~m=39xqDIƧOOOyOxs/ ˟~wo:zz՗?Vz}Go3Szw=}sy+>|/_ -49XH|g 3% 2>f~fWزֺ8`0@(9.U 4kr9# dX݄ܵλ܅?Д-gpd6,۱?=oqs@A~b#bZFp8KjwNdޠ.9F}NK 1ZZRWoyW;e|֧!3&ZVooWQy(h,.-z~v5`[[bgl'KAxIIENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/chevron.png0000644000000000000000000000600212433712544026407 0ustar00usergroup00000000000000PNG  IHDR/j =iCCPiccxڝSgTS=BKKoR RBTi@숨"q"Ay((6T}7o9g}>F`DdJ<6.'w T @- m@n8P $ B2r22 t%[j;eOv$(S*@@&X`(ʑs`̔`)d` SGE3(xW\!Sd咔Tn!\]x87CP؄ ee3FvD9;:;8:|?E񋖴e /B_TBfgk+ m_ _׃  2r<[&q?.wL'bPGKĹi ˒$ IHk`~B[P. %w߂1w0hْ 4P6h>؀#;x̆P8XBHLC.,UP%BZF8-p<^0 o`A2DX6b"ֈ#Ef!~H0!H "ERd5R#U^9E.!==F~C>@٨jڡ\ Bh G h%ZBѳڋ>G03l0.Bx,c˱b6b#{";!0 $,",'̈́ Ba$nD>1B%+uc[!\H8Ri D:C!d6ٚA% ry;4:yBP)xR@\ RƩjTS5*.Qkmԫ8MfNEhhFyC+:nDw%JaEz=Ca1J~=+&ib3 z9c; _EBZY U| գWUGԨjfj<5rjjwY/i544D4i01VjYYlۜgK߱٣34545Ojr0qpns>Lћ=Ejkh4km8ndn4ר1͘klŸx$dI}S)4ti[3sf-fCZ||L OE57-I\t˝׬P+'Tj֨zu44ii50lmrlll9-/L6u}wϰ0ۡ7G+GcWLor ]3:B:;}rvq;7:$pesø܋DW'\߻9)܎n~}hLڙFY4xx>2yy z[zy~c#9[;vi{o?$L 10(pS_ȯvlvG#(2*IU<- 999-(yr`GryPGTԊ OR%y;mzh􉌘LJfbq4]ڑ#z-ںhT$Fg* Ki\˙S.7:hz4k]BX"\Ҿp骥}˼],OZ޾xEኁ+J_S}Ay1 W XPR$/}uuu맯߾sr}IERaofbC2]Ioot\<s--.zbFmmmMo*VOuw)y}׮zKv#swo}}9Fv~N~:],k@ Ç]FƽMpXy>t(h?8:V܌4/nmImmk9>x{{۱mDI͓eh OM?=vFvflŞ}> uzwq%K/s/\qu'u;w7_uzZ[̞S={M+=; wz˸~+?R{TXqϖ?7:zA?q)iŠ`Љak=x.{>>R/;^XW_FcG^_NVJ3^=~fm;wsw~08姶ANdNL%c3 cHRMz%u0`:o_F pHYs   vpAgLޔ0PLTETotRNS (08HPXhpx2bKGDdIDATc``2`ya̺w/aLwLw.Ä޽2߽3޻g,w.A@޽8޽eƽ{eƼ{ 3!dY E"ō%tEXtcreate-date2009-09-03T17:03:23+00:00W%tEXtmodify-date2009-09-03T17:03:23+00:00IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/chevron_circle.png0000644000000000000000000000233312433712544027733 0ustar00usergroup00000000000000PNG  IHDR# r pHYsHHFk> vpAg#$0JPLTE qqquuuiiihhhɸ絵Q W\\`b%bdfhikl"l#lmn#p(p$q%r;t=t/v@w?QRST]]ceehhkrs|bKGDx IDATxmWAG$2 !fEzA@t EB ͮĆJQ# j=lpϛydI4'rst%cs`Zadf k̀bՇpU ΃ ;p+ikwn+o6:4~1ZrxnIp8 vpAg.`bKGD̿>IDATHǝo\E3wwn;$vBD4A%ET<* Q!P#Q H`%qbu^޽wfNVf4{o3g~{Quc7Gi3|Syn>'|!3`.pEUxEBU.w_H skׯ,fZN2\P-ge\<ۯ,H G,U5ϰ-H+|F3~k}ut{xFH>Նc#/=)]cBBq[?1Ro$B5f5$'#z 0J8&Fa!а`j9ӎ% ŐSv7TjDGM)EuZ7D(P=ţ^ I;N#bԀ=XTXI&<ޫiF T:qM S*QUHQ#Y zbWE@ SU $XD(~9t!=X$('hje&FDuP:DnQg]_* R3 GI? ˴v$ýj3!! , $$(eZY$#Q#Ì΃УW !;PH^χC  x4H3k^apiDpP@yw`J#  ? y og f'8{'Cp`jn"2{`xjy4C,4o#n$ß!! , $$deZy$#qcQ Ңā ҉p88D/(C G„Z0v#0 DŶAN(+ܴ@x (@gUx* kK) ?K  $" *K Wx?G#WкnhK,+*!! , $$eZ9 #1 qFҢO' b )dQ؍d"B! Vh0p4(0M@ e*3@ iI)'?I  @,# 5,"Ez?@E@)*!! , $$ eB"0;('"@ CS%dq)e[TE5PŨd6{6($%`3 gIw3   *h")q4) #g# S$"$>%`rJ{ 1$ʈ!! , $$$e.aD @2"= ߈@\"$0-d- V@2|?(Jqp)e4xyc? 3 #wyJ l% o ^[b_0V T[0m  $4>'VZ c3$X%!! , $$De$:2((, 'Z(Bs L("HMj#ȉA \O)`u =Y EVL=I > suI WJm|\"_b0 BcV"d ]*K1 " H|@B? I4# S$-||!! , $$,e$A:B H /K$W-  `3F=pF@!tѢ  {f~*yS*mg) enuE^Z^g@ kw (b&-w#" x W "t##%U$`to!! , $$,e$A:* ¸ 1v/KDzk# F Y" % E Cb AI4$(z:2mILl##F##>F!! , $$,e$A:* ¸ 1v/KDVtKG1" 7r<$! QJQ`0 y l |~6zw2j# F"%VC ]6a$Q :2\  EF I&x"͓F4$]#x!!, $$,eZId㌂0.<B?QTHje E,C\3^3[ S|?!;SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/on_off.png0000644000000000000000000000470012433712544026214 0ustar00usergroup00000000000000PNG  IHDRu pHYsHHFk> vpAgOcbKGDԂIDATx}l[WƟq$6-mE , jiHDHݠĐOH H P4Hmc+i%*Sfm7ؚ/Ҥi'NrxĎb{?ձs{?=9`sB*  ؊:ۑ ݎbjj CCCu8p MMMRk6- %+/Cd 0&5E(Cرc`ٰZ̠w0fgg i w"ˍn(u@P9AIs!IHJEyy9zxZȲhV, `.#AVgggHRuF@ iNT*]!!ɴg[566f]IV&pͅ(p:)R[\\jUZC_f5 *\HӅU9fa ʌyR\QdvNL $n*$@ ` JUUle&A šoC9U,N701`-]!]p>fU]Xոn")T(, l"&Oo l~ \n;#{dL͌?ʄ M»+pm-~󘣾.L JL0♉2oq>r%ߟn-EffrJXJd.<[)6Au񹵵8l# QP!~_ğ;,H|xuit9| Tݍ7o A-p qp°}v\rKo>vٙ-cYdd%Is'6GW@X rY[Y(CcjĵS1=:{-AS⹁S1b9UիW!`ؘ,;O4ΕbռS)ʊqTњ_LGqk2HNF|46sOw\ƻ8n|s8|ZE;ׯ__Ū[ss3YXPȾ0Qۍ0Ge {|"+%+m9eG$E*3G8L~{ϫ֙sR.Q  l]~=2220>>ΥDT.$uqy Th ٌh4fF<Hoݖp;H lh%88sO@6HJ Q!.,Z.PT ;LT'OD$G 92>̮]mr*MAl%h쀮G`e6'6r-MyQZK߫8T's/,:|ص\!4Nm*4]6CLro׉mْ8OSck;H?Գ z&=2yxaOBUְJ%yc\p73#E Lw'r*9U<{ AE1;LkKH9A:F[INnu d[Nw KrOQQ:okkٴiS؄,3i |D8U|?-"O7kV_GuYO+;P8q1I,v);qLKK g쳞_t s =/Trcxg{VDWӉF|}?xqRN9>CYIuuud"{_̏J@:uE͢}g;@-8E{@xD::thU__fL.Cs*77t mMd;tK(ŧ:ZHs={qwg5\,feea5טyŋ犟F!;17J)|A1r*Tϩئ5PT9GR$,% Ug =E.^cUMpkVӌ#hHvm)AAb t]J;?eazipdk{YToP{08Zj$%Dk$X-+uttkjtД٣>99ݨM1l+8> \(" 깝XM19n H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F*IDATc<"Ā@,Q, X10¤{"ډ2IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/toggleOn.png0000644000000000000000000000024312433712544026522 0ustar00usergroup00000000000000PNG  IHDR$[tEXtSoftwareAdobe ImageReadyqe<EIDAT @@r-v7u`?|8x}%Hi$H$B*fQ*PވIENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/toolbar.png0000644000000000000000000000144512433712544026413 0ustar00usergroup00000000000000PNG  IHDR >RJtEXtSoftwareAdobe ImageReadyqe<)PLTE    ! " # # !" !$!"%"#&#$%#$'#%'$$$$&)%&)%&*%'*&&&''''(('(+((((),(*-))))*-*+.++++,/+,0+-0,-.,-1,.1----.2./2.03/04/14000014015025123126666678:;<<<)R&uur{1VqZFWr8ð[sARMhD9D~|^u ]8n+ T찶y[[u/ \weŕLV` N5JZ,j4M_ .o͘Zbi4b~ l?~prE QDh6^5dySU*/3l6^dx>CI1W*a=ۦ+Ẑ9M+50ipH~ lA`IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/dark/whiteButton.png0000644000000000000000000000172212433712544027263 0ustar00usergroup00000000000000PNG  IHDR.~tڇ pHYsHHFk> vpAg.`bKGD̿aIDATHǝMh\U;L͇IVXW]QJAsJBQq]ŅD!` H&cIff2yo޻fM79wЭ7^:[kA#vY3SQL5[1CT5 )b;k2aQx=pR$m*(N=v2IZԣ`:qSor_E*^R`OmXx<ԹzՈ\\-"bUݮh&8Ԇ&@/oz髛\Eg{^^6NE Ds[߯_M cQBpgF ^hMv ?qd ^X17%7Fab]p5\/=T[V>\&iNVWz/R񵜖uHif9V fg+5d]Ƣj)[)!h~̮G%%unf#W4f6 hCIHE4Gj^&3>^>g{*>`<6VWΈ@&S.gwvVڊ?T[4\IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/backButton.png0000644000000000000000000000141712433712545027233 0ustar00usergroup00000000000000PNG  IHDR+:ptEXtSoftwareAdobe ImageReadyqe<IDATxkOayF*  `p!Ġ"1D4hވQpK(ݶ;3  sF{2 K&3Ͽ~@Q]SupD Xz8o Khs}у`WJDpDmߙRp= of&%*1AMM=Y\PH"dp8}%ËoUX4w 7oxLO_UI$-r˟tꚑQB9\CW/; ;0M{Hpj.8]@+|\zgZ]ReIH Zlan~5vAb@CzҒ/.HG~\"H,7" "dų@Cp8  < 8 =;0F(I!]Mԣ 'AA$Krg %|f2zX\oi=Z2Qw‘@oLlC(1`oK< v =Y8S9Ƅ<~=DG2 Җ쭐mm2aL 7- 1g1}lSv.4d̄^lXǽD܎&G:>,_Y݈&۝W"%UwJVJKSU!K$aZۑګ'ܝ΍IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/blueButton.png0000644000000000000000000000100512433712545027253 0ustar00usergroup00000000000000PNG  IHDR'n#tEXtSoftwareAdobe ImageReadyqe<PLTE*`3u85p?@A@FFHIKNGOPQKLTTUVW!C!D"D"E"_#G#H$b'J'd(J(R*S.N.i/Z0j3m9pAwCxFzHiIoMTUXY[`dgnoqrsssuvvzɕƧIDATӍ@!+Z轆]]̬gx :g{#ooTg Pb%Yg1% d" >$8R6Bb@$qD Z#(&c#OGy(@GQ56+hqy6QyDNn|KF;ݎp]| >DNZIENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/cancel.png0000644000000000000000000000055212433712545026363 0ustar00usergroup00000000000000PNG  IHDR'ՆtEXtSoftwareAdobe ImageReadyqe< IDAT(υAJ@@R6B 7(qۍ`0KBAAĂPhb:$(&{K۽:&#O9 )[%,}>g&>^k܌k՟MݓE ۾5Ű 3.Y+A]6IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/chevron.png0000644000000000000000000000040312433712545026575 0ustar00usergroup00000000000000PNG  IHDRxwtEXtSoftwareAdobe ImageReadyqe<IDATxb?DuP N-ADbCb,%5@܊oE͢ ZJ4)W9@,DMKOR,YfjM,@)WdKqpZ^܁@M @q";&_sIENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/grayButton.png0000644000000000000000000000165712433712545027303 0ustar00usergroup00000000000000PNG  IHDR.~tڇ pHYsHHFk> vpAg.`bKGD̿>IDATHǝo\E3wwn;$vBD4A%ET<* Q!P#Q H`%qbu^޽wfNVf4{o3g~{Quc7Gi3|Syn>'|!3`.pEUxEBU.w_H skׯ,fZN2\P-ge\<ۯ,H G,U5ϰ-H+|F3~k}ut{xFH>Նc#/=)]cBBq[?1Ro$B5f5$'#z 0J8&Fa!а`j9ӎ% ŐSv7TjDGM)EuZ7D(P=ţ^ I;N#bԀ=XTXI&<ޫiF T:qM S*QUHQ#Y zbWE@ SU $XD(~9t!=X$('hje&FDuP:DVf <#%7}b3\"׏z Ȣ;Q-Jv"5aE[5 /;p~7?7Y"&~P0Շ }o@2Rr,( H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FZIDATx] 0 8؄bMURt9jmۏ1FM8GK=N N\gN]dz%@nս5p IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/loading.gif0000644000000000000000000000263312433712545026536 0ustar00usergroup00000000000000GIF89arcH~;t! NETSCAPE2.0! ,q1uFsPΨ5c$+IN1a|LC`p@cA84OQ8BZ^ -q$g8A 9P4O T p% # c% U! ,\Б"l¢I3J (7#dd<Ƅ!\VP! |~dQi^ R>`,U 1LQD6! ,ZTXYsD6O琙S=KL #!KI6 4JP R.FN| Veu1D@L4ޏƚ+^]G! ,\)g4 & LN#%\ 9"%( A r (KcP5ㄑ}B&-! ,EX =(!^!0@X^OaJ¤P)},sH;GԩQPE! ,k%H9$O2Ys4g#b!D5#pL Ã48GAa4U`($،b0AA6O 00:@!fJPh#il~! ,ZZX2ܵxJJ3>łYX!!spIb1p"8M y ap' @pFD! ,Y$crpm vxJM,e$ӬB>%ш(jaT6mqD@8 b0P`3 …i(bxMR29]4 $P`A~ ֲ%A(! ,XIxVE@R1$MZ!҉Ҡg7@ǢU$qp>bS$D&^  ,O vpAgOcbKGDԂ NIDATx[[l朙DZc.I,;YJʲ j -KUZ> ,ݶ>T/]j>7ڭ*!vR@,hBa+n!!dsI'M$qĉx3s>s/6hybn,BnH$n4559 m6a'Nh*wfAQ @&4f eTcJ ֭CYYLl!hnnFOO8eaxxhkkURezAo>4݄ )*!As5WQW/`޼ylAFl΋$$~?#AΝ;oRz/izj2i9,bPP7`V? ϰWZZ )%|>_^Ey+++ZOU` iaiBsܩ @"WlzA䋰b߅t* L KwQT6SᏘb9bRD"Ju :n@7LHBws >4Xp/,+-no5!A$H FFrIDtfD;Ȫ9'*˕WNrDIܒ:GS?Ÿ@'xi|,~.@G@/46!YX²j =@肔n4𕭄Q?'@H[ ,Ⱥ#s ٌD````<ˎ~ xaՊ~m)]zڒg7?C0ĥRI(*NÇ1L xlٲѦr౜N &XXT0iꖉ NIa8 ^(x<XB{8y=]kL|*\ny] EQL\䘩\ǨUS2ɩ8MT.C´dNE4.`>xGP bقzR9,$BoZCj+vc\jgN*pߤwС)l_zN%Gr^\ő?F*Oė/-A|0_}^nd q'>ak>KOf^J4ʹFztP^^ઇ!˖-S(M5Y?T:]I%c̴4϶Z{(xwʱ?pr5Kh̓9iEW]"ifHSMK,R^x5)G@`^3g΀|}¹&"թtRqkaSÁWNq<I.QQ9O a:!Dj>Vԧݦݻwѣ\>C9D~ ̩TDUi)jC~s.u+񑅓>L>d u @ѝ.7nL TUU](<3e,YPU偔ƌG\.݃zf #DZw^N_ǏcϞ=Ywg5\M2&8=f^wԩRa[eQp%JHy*7"h@/H>'r=Qϟ{! I,:`Q.:PU)<W)sZרE2u-J@b5H8xA!ݺua{i',,RTSс AUwjXa_z^2}6ZZZ8F͛5ꃃ\=9jyȇ~= RVz}yf=Sy_(aj Z%d%tEXtcreate-date2009-09-03T16:44:48+00:00h%tEXtmodify-date2009-09-03T16:44:48+00:00tEXtSoftwareAdobe ImageReadyqe<IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/pinstripes.png0000644000000000000000000000016512433712545027336 0ustar00usergroup00000000000000PNG  IHDRi#tEXtSoftwareAdobe ImageReadyqe<IDATxb H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F=IDATxu 0@cP7e-">11wdfu%S'>8YL gk4IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/toggle.png0000644000000000000000000000537712433712545026431 0ustar00usergroup00000000000000PNG  IHDRR~ pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F*IDATc<"Ā@,Q, X10¤{"ډ2IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/toggleOn.png0000644000000000000000000000024312433712545026711 0ustar00usergroup00000000000000PNG  IHDR$[tEXtSoftwareAdobe ImageReadyqe<EIDAT @@r-v7u`?|8x}%Hi$H$B*fQ*PވIENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/toolbar.png0000644000000000000000000000025012433712545026573 0ustar00usergroup00000000000000PNG  IHDR+6@utEXtSoftwareAdobe ImageReadyqe<JIDATxM!@אhwe )vDG Ya3տ{/sÁvExVp"IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/toolButton.png0000644000000000000000000000101112433712545027276 0ustar00usergroup00000000000000PNG  IHDR FtEXtSoftwareAdobe ImageReadyqe<IDATxڕJ@ISZP/.^PtnQܹPP ؍*Z443qi 'Iml2no.GLq=84Z*G{ӓrZ{.!/ݭͩ*\_]_/aj%yF7<ٕ\a01*H[e;B~qs<LAP SH:f`@dQ,)"R>@tERQ 8ytOE``( k,aW/ 0yiC>I9 BRZ.k8TxsV,6=1`*CoOwQ苿^Z-c Bqv.TmZ7֫R߶je¯#~ 1CIENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/images/light/whiteButton.png0000644000000000000000000000172212433712545027452 0ustar00usergroup00000000000000PNG  IHDR.~tڇ pHYsHHFk> vpAg.`bKGD̿aIDATHǝMh\U;L͇IVXW]QJAsJBQq]ŅD!` H&cIff2yo޻fM79wЭ7^:[kA#vY3SQL5[1CT5 )b;k2aQx=pR$m*(N=v2IZԣ`:qSor_E*^R`OmXx<ԹzՈ\\-"bUݮh&8Ԇ&@/oz髛\Eg{^^6NE Ds[߯_M cQBpgF ^hMv ?qd ^X17%7Fab]p5\/=T[V>\&iNVWz/R񵜖uHif9V fg+5d]Ƣj)[)!h~̮G%%unf#W4f6 hCIHE4Gj^&3>^>g{*>`<6VWΈ@&S.gwvVڊ?T[4\IENDB`SABnzbd-0.7.20/interfaces/Mobile/templates/static/javascripts/mobile.js0000644000000000000000000031324412433712602026211 0ustar00usergroup00000000000000/*! * jQuery JavaScript Library v1.4 * http://jquery.com/ * * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://docs.jquery.com/License * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2010, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Wed Jan 13 15:23:05 2010 -0500 */ (function(A,w){function oa(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(oa,1);return}c.ready()}}function La(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function $(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var o in b)$(a,o,b[o],f,e,d);return a}if(d!==w){f=!i&&f&&c.isFunction(d);for(o=0;o-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete t[p]}i=c(a.target).closest(f,a.currentTarget); n=0;for(l=i.length;n)[^>]*$|^#([\w-]+)$/,Pa=/^.[^:#\[\.,]*$/,Qa=/\S/, Ra=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Sa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],M,ca=Object.prototype.toString,da=Object.prototype.hasOwnProperty,ea=Array.prototype.push,R=Array.prototype.slice,V=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Oa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Sa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])]; c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ua([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return U.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a)}else return!b||b.jquery?(b||U).find(a):c(b).find(a);else if(c.isFunction(a))return U.ready(a);if(a.selector!==w){this.selector=a.selector; this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,this)},selector:"",jquery:"1.4",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length= 0;ea.apply(this,a);return this},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject|| c(null)},push:ea,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
    a";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length, htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b, a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function o(){c.support.noCloneEvent=false;d.detachEvent("onclick",o)});d.cloneNode(true).fireEvent("onclick")}c(function(){var o=s.createElement("div");o.style.width=o.style.paddingLeft="1px";s.body.appendChild(o);c.boxModel=c.support.boxModel=o.offsetWidth===2;s.body.removeChild(o).style.display="none"});a=function(o){var p=s.createElement("div");o="on"+o;var n=o in p;if(!n){p.setAttribute(o,"return;");n=typeof p[o]==="function"}return n};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var H="jQuery"+K(),Ta=0,ya={},Ua={};c.extend({cache:{},expando:H,noData:{embed:true,object:true,applet:true},data:function(a, b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var f=a[H],e=c.cache;if(!b&&!f)return null;f||(f=++Ta);if(typeof b==="object"){a[H]=f;e=e[f]=c.extend(true,{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Ua:(e[f]={});if(d!==w){a[H]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?ya:a;var d=a[H],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[H]}catch(i){a.removeAttribute&& a.removeAttribute(H)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this, a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this, a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var za=/[\n\t]/g,fa=/\s+/,Va=/\r/g,Wa=/href|src|style/,Xa=/(button|input)/i,Ya=/(button|input|object|select|textarea)/i,Za=/^(a|area)$/i,Aa=/radio|checkbox/;c.fn.extend({attr:function(a, b){return $(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(p){var n=c(this);n.addClass(a.call(this,p,n.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(fa),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i=0;else if(c.nodeName(this,"select")){var z=c.makeArray(t);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),z)>=0});if(!z.length)this.selectedIndex= -1}else this.value=t}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Wa.test(b);if(b in a&&f&&!i){if(e){if(b==="type"&&Xa.test(a.nodeName)&&a.parentNode)throw"type property can't be changed";a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue; if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Ya.test(a.nodeName)||Za.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var $a=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType=== 3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;if(!d.guid)d.guid=c.guid++;if(f!==w){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):w};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var o,p=0;o=b[p++];){var n=o.split(".");o=n.shift();d.type=n.slice(0).sort().join(".");var t=e[o],z=this.special[o]||{};if(!t){t=e[o]={}; if(!z.setup||z.setup.call(a,f,n,d)===false)if(a.addEventListener)a.addEventListener(o,i,false);else a.attachEvent&&a.attachEvent("on"+o,i)}if(z.add)if((n=z.add.call(a,d,f,n,t))&&c.isFunction(n)){n.guid=n.guid||d.guid;d=n}t[d.guid]=d;this.global[o]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===w||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/); for(var o=0;i=b[o++];){var p=i.split(".");i=p.shift();var n=!p.length,t=c.map(p.slice(0).sort(),$a);t=new RegExp("(^|\\.)"+t.join("\\.(?:.*\\.)?")+"(\\.|$)");var z=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var B in f[i])if(n||t.test(f[i][B].type))delete f[i][B];z.remove&&z.remove.call(a,p,j);for(e in f[i])break;if(!e){if(!z.teardown||z.teardown.call(a,p)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+ i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(B=c.data(a,"handle"))B.elem=null;c.removeData(a,"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[H]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType=== 8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;var i=c.data(d,"handle");i&&i.apply(d,b);var j,o;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){j=d[e];o=d["on"+e]}}catch(p){}i=c.nodeName(d,"a")&&e==="click";if(!f&&j&&!a.isDefaultPrevented()&&!i){this.triggered=true;try{d[e]()}catch(n){}}else if(o&&d["on"+e].apply(d,b)===false)a.result=false;this.triggered=false;if(!a.isPropagationStopped())(d=d.parentNode||d.ownerDocument)&&c.event.trigger(a,b,d,true)}, handle:function(a){var b,d;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result}, props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[H])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement|| s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&& a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;c.event.add(this,b.live,qa,b)},remove:function(a){if(a.length){var b=0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],qa)}},special:{}},beforeunload:{setup:function(a, b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=K();this[H]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=ba;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped= ba;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=ba;this.stopPropagation()},isDefaultPrevented:aa,isPropagationStopped:aa,isImmediatePropagationStopped:aa};var Ba=function(a){for(var b=a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ca=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover", mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ca:Ba,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ca:Ba)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return pa("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+ d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return pa("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var ga=/textarea|input|select/i;function Da(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex> -1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ha(a,b){var d=a.target,f,e;if(!(!ga.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Da(d);if(e!==f){if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",e);if(d.type!=="select"&&(f!=null||e)){a.type="change";return c.event.trigger(a,b,this)}}}}c.event.special.change={filters:{focusout:ha,click:function(a){var b=a.target,d=b.type;if(d=== "radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ha.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ha.call(this,a)},beforeactivate:function(a){a=a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Da(a))}},setup:function(a,b,d){for(var f in W)c.event.add(this,f+".specialChange."+d.guid,W[f]);return ga.test(this.nodeName)}, remove:function(a,b){for(var d in W)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),W[d]);return ga.test(this.nodeName)}};var W=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d, f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){thisObject=e;e=f;f=w}var j=b==="one"?c.proxy(e,function(o){c(this).unbind(o,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e,thisObject):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a, b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d0){y=u;break}}u=u[g]}m[r]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, e=0,i=Object.prototype.toString,j=false,o=true;[0,0].sort(function(){o=false;return 0});var p=function(g,h,k,m){k=k||[];var r=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return k;for(var q=[],v,u,y,S,I=true,N=x(h),J=g;(f.exec(""),v=f.exec(J))!==null;){J=v[3];q.push(v[1]);if(v[2]){S=v[3];break}}if(q.length>1&&t.exec(g))if(q.length===2&&n.relative[q[0]])u=ia(q[0]+q[1],h);else for(u=n.relative[q[0]]?[h]:p(q.shift(),h);q.length;){g=q.shift();if(n.relative[g])g+=q.shift(); u=ia(g,u)}else{if(!m&&q.length>1&&h.nodeType===9&&!N&&n.match.ID.test(q[0])&&!n.match.ID.test(q[q.length-1])){v=p.find(q.shift(),h,N);h=v.expr?p.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:q.pop(),set:B(m)}:p.find(q.pop(),q.length===1&&(q[0]==="~"||q[0]==="+")&&h.parentNode?h.parentNode:h,N);u=v.expr?p.filter(v.expr,v.set):v.set;if(q.length>0)y=B(u);else I=false;for(;q.length;){var E=q.pop();v=E;if(n.relative[E])v=q.pop();else E="";if(v==null)v=h;n.relative[E](y,v,N)}}else y=[]}y||(y=u);if(!y)throw"Syntax error, unrecognized expression: "+ (E||g);if(i.call(y)==="[object Array]")if(I)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&F(h,y[g])))k.push(u[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&k.push(u[g]);else k.push.apply(k,y);else B(y,k);if(S){p(S,r,k,m);p.uniqueSort(k)}return k};p.uniqueSort=function(g){if(D){j=o;g.sort(D);if(j)for(var h=1;h":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,r=g.length;m=0))k||m.push(v);else if(k)h[q]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,m,r,q){h=g[1].replace(/\\/g,"");if(!q&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,m,r){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=p(g[3],null,null,h);else{g=p.filter(g[3],h,k,true^r);k||m.push.apply(m, g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!p(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, setFilters:{first:function(g,h){return h===0},last:function(g,h,k,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return hk[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,m){var r=h[1],q=n.filters[r];if(q)return q(g,k,h,m);else if(r==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(r==="not"){h= h[3];k=0;for(m=h.length;k=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=n.attrHandle[k]?n.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== "="?k===h:m==="*="?k.indexOf(h)>=0:m==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:m==="!="?k!==h:m==="^="?k.indexOf(h)===0:m==="$="?k.substr(k.length-h.length)===h:m==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,m){var r=n.setFilters[h[2]];if(r)return r(g,k,h,m)}}},t=n.match.POS;for(var z in n.match){n.match[z]=new RegExp(n.match[z].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[z]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[z].source.replace(/\\(\d+)/g,function(g, h){return"\\"+(h-0+1)}))}var B=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){B=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,m=g.length;k";var k=s.documentElement;k.insertBefore(g,k.firstChild);if(s.getElementById(h)){n.find.ID=function(m,r,q){if(typeof r.getElementById!=="undefined"&&!q)return(r=r.getElementById(m[1]))?r.id===m[1]||typeof r.getAttributeNode!=="undefined"&& r.getAttributeNode("id").nodeValue===m[1]?[r]:w:[]};n.filter.ID=function(m,r){var q=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&q&&q.nodeValue===r}}k.removeChild(g);k=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;k[m];m++)k[m].nodeType===1&&h.push(k[m]);k=h}return k};g.innerHTML=""; if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=p,h=s.createElement("div");h.innerHTML="

    ";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){p=function(m,r,q,v){r=r||s;if(!v&&r.nodeType===9&&!x(r))try{return B(r.querySelectorAll(m),q)}catch(u){}return g(m,r,q,v)};for(var k in g)p[k]=g[k];h=null}}(); (function(){var g=s.createElement("div");g.innerHTML="
    ";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,k,m){if(typeof k.getElementsByClassName!=="undefined"&&!m)return k.getElementsByClassName(h[1])};g=null}}})();var F=s.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g, h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ia=function(g,h){var k=[],m="",r;for(h=h.nodeType?[h]:h;r=n.match.PSEUDO.exec(g);){m+=r[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;r=0;for(var q=h.length;r=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var i=d;i0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i= {},j;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var p=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,t){for(;t&&t.ownerDocument&&t!==b;){if(p?p.index(t)>-1:c(t).is(a))return t;t=t.parentNode}return null})},index:function(a){if(!a||typeof a=== "string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(sa(a[0])||sa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);ab.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||cb.test(f))&&bb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||!c(a).is(d));){a.nodeType=== 1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ga=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,db=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/"},G={option:[1,""], legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]};G.optgroup=G.option;G.tbody=G.tfoot=G.colgroup=G.caption=G.thead;G.th=G.td;if(!c.support.htmlSerialize)G._default=[1,"div
    ","
    "];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this); return d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.getText(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, wrapInner:function(a){return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&& this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this, "after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ga,"").replace(Y,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ta(this,b);ta(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType=== 1?this[0].innerHTML.replace(Ga,""):null;else if(typeof a==="string"&&!/

    $T('emailOptions')

    $T('opt-email_endjob')
    /> /> />
    />
    />

    $T('emailAccount')

    $T('growlSettings')

    />
    />
    SABnzbd-0.7.20/interfaces/Plush/templates/config_rss.tmpl0000644000000000000000000004050212433712601023473 0ustar00usergroup00000000000000
    ">
    $T('enabled').capitalize() $T('feed') URL $T('Plush-rss-delete')
    />
    id="activeFeedLink">$feed_item $rss[$feed_item]['uri']

    style="display:none">
    $T('addFeed')
    $T('name')
    $T('newFeedURI')


     

    $T('explain-RSS')

    $T('opt-rss_rate'):
    $T('explain-rss_rate')
    $T('feedSettings')
    $T('enabled').capitalize()/>
    $T('feed')
    $T('category')
    $T('pp')
    $T('script')
    $T('priority')
    ">
    $T('Plush-rss-delete')   $T('rss-order') $T('rss-type') $T('rss-filter') $T('category') $T('priority') $T('mode') $T('script') $T('Plush-rss-actions')
    />   $T('Incorrect filter')

    $T('Plush-explain-rssActions')


    $error

    $T('rss-matched') ()

    ">
    $T('link-download') $T('rss-skip') $T('rss-filter') $T('sort-title')
    $job[2] $job[3] $job[1]
    $T('none')


    $T('rss-notMatched') ()

    ">
       $T('rss-skip')   $T('rss-filter')  $T('sort-title')
    $job[2] $job[3] $job[1]
    $T('none')
    ">
    $T('sort-title')
    $job
    $T('none')
    SABnzbd-0.7.20/interfaces/Plush/templates/config_scheduling.tmpl0000644000000000000000000001015412433712601025011 0ustar00usergroup00000000000000 <% import time t = time.localtime() hour = t[3] if hour != 23: hour += 1 else: hour = 0 %>

    $T('addSchedule')

    $T('currentSchedules')

    ">

    $T('none')

    SABnzbd-0.7.20/interfaces/Plush/templates/config_server.tmpl0000644000000000000000000002157512433712601024203 0ustar00usergroup00000000000000

    $servers[$server]['name']



          




    $T('srv-bandwidth'):
    $T('total'): $servers[$server]['amounts'][0]
    $T('today'): $servers[$server]['amounts'][3]
    $T('thisWeek'): $servers[$server]['amounts'][2]
    $T('thisMonth'): $servers[$server]['amounts'][1]


    />
    />
    />
    />
    SABnzbd-0.7.20/interfaces/Plush/templates/config_sorting.tmpl0000644000000000000000000005105512433712601024356 0ustar00usergroup00000000000000

    $T('seriesSorting')

    $T('affectedCat'):

    0 then "checked=1" else ""#--> />
    $T('presetSort')
     

    $T('genericSort')

    $T('affectedCat'):

    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    $T('presetSort')

    $T('dateSorting')

    $T('affectedCat'):

    0 then "checked=1" else ""#--> />
    $T('presetSort')
     
    SABnzbd-0.7.20/interfaces/Plush/templates/config_special.tmpl0000644000000000000000000000364112433712601024307 0ustar00usergroup00000000000000


      $T('explain-special')

    $T('sptag-boolean')

    0 then "checked=1" else ""#--> />

    $T('sptag-entries')

    SABnzbd-0.7.20/interfaces/Plush/templates/config_switches.tmpl0000644000000000000000000004653312433712601024527 0ustar00usergroup00000000000000

    $T('swtag-general')

    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />

    $T('swtag-server')

    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />

    $T('swtag-queue')

    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />

    $T('swtag-pp')

    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />

    $T('swtag-naming')

    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />
    0 then "checked=1" else ""#--> />

    $T('swtag-quota')

    0 then "checked=1" else ""#--> />
    SABnzbd-0.7.20/interfaces/Plush/templates/history.tmpl0000644000000000000000000001743112433712601023045 0ustar00usergroup00000000000000<% import datetime %> <% from sabnzbd.misc import time_format %>
     
    Loadedmain_sprite_container sprite_hv_errormain_sprite_container sprite_hv_star"> 
    style="width:35%"> $line.name
    <% compl = datetime.datetime.fromtimestamp(float(line['completed'])).strftime(time_format('%Y-%m-%d %H:%M:%S')) %> class="odd">class="odd">class="odd">
    $T('completed')$compl
    $T('name')$line.name - $line.action_line - $line.fail_message
    $T('size')$line.size
    $T('status')$Tx('post-'+$line.status)
    $T('category')$line.category
    $T('msg-path')$line.storage
    $Tx('stage-'+$stage.name.title.lower()) $action

    https://$newzbin_url/browse/post/$line.report'> 
     

    $T('category'): $line.category'> 
     
     


    '> 
     $T('button-retry')

    » $line.action_line 

    » $line.fail_message 

    $line.rating_avg_vote_up
    $line.rating_avg_vote_down
    <% d = datetime.datetime.fromtimestamp(float(line['completed'])) %> $d
     
    SABnzbd-0.7.20/interfaces/Plush/templates/main.tmpl0000644000000000000000000002703612433712601022272 0ustar00usergroup00000000000000
     

     
     
    SABnzbd-0.7.20/interfaces/Plush/templates/nzo.tmpl0000644000000000000000000001255412433712601022153 0ustar00usergroup00000000000000
    active">
    $T('Plush-progress')$T('nzo-filename')/$T('nzo-subject')$T('nzo-age')
    >
    px -401px">
    $file.mbleft $T('Plush-left')
    $file.mb $T('MB')
    $file.filename $file.age
    SABnzbd-0.7.20/interfaces/Plush/templates/queue.tmpl0000644000000000000000000001604712433712601022472 0ustar00usergroup00000000000000 class="alt">
     
    main_sprite_container sprite_ql_grip_pausemain_sprite_container sprite_ql_grip_resume"> 
    <% # main_sprite_container sprite_ql_grip_active %>
    style="width:35%"> $slot.filename.replace('.', '.​').replace('_', '_​')
    px -401px">
    $slot.mb_fmt $T('MB')
    $slot.mbdone_fmt $T('MB') $T('AofB')
    $slot.timeleft $T('Plush-left') $T('post-'+$slot.status)
     
    SABnzbd-0.7.20/interfaces/Plush/templates/status.tmpl0000644000000000000000000001140212433712601022657 0ustar00usergroup00000000000000

    $T('clearWarnings').capitalize() $T('link-showLog') $T('logging'):

    $msg


    ">
    $T('warn-when') $T('warn-type') $T('warning')
    $warn.replace("\n","", 2)

    $T('none')

    $T('explain-Repair')

    $T('explain-Restart')




    $T('explain-orphans')


    ">
    $T('name')
    $folder

    $T('swtag-server'): $server[0]

    $T('status'): $T('backup').capitalize()$T('optional').capitalize()$T('enabled').capitalize()

    # $T('connections'): $server[2]

    $T('server-blocked')   $server[6] ">
    $T('article-id') $T('filename') $T('file-set')
    $thrd[1]$thrd[2]$thrd[3]



    $T('none')

    $T('link-forceDisc')
    SABnzbd-0.7.20/interfaces/Plush/templates/_inc_footer.tmpl0000644000000000000000000000054512433712601023630 0ustar00usergroup00000000000000#if $pane=="Main"# #else if $pane=="Nzo" #else# #if $pane!="Status" and $pane !="RSS"##end if#
    #end if# #include $webdir + "/_inc_modals.tmpl"# SABnzbd-0.7.20/interfaces/Plush/templates/_inc_header.tmpl0000644000000000000000000002052412433712601023561 0ustar00usergroup00000000000000#if $pane=="Status" or $pane=="Config"# #set global $path = '../'# #else if $pane=="Main"# #set global $path = ''# #else# #set global $path = '../../'# #end if# SABnzbd $version - $T('queued'): $mbleft $T('MB') #if $color_scheme# #else# #end if# #if $pane=="Main"# #else if $pane=="Nzo"# #else# #end if#
    #if $pane=="Main"# #else if $pane=="Nzo"# #else if $pane=="Status" or $pane =="RSS"#
    #else# #if $pane=="Status"# #else if $pane=="RSS"# #else# #end if#
    #end if# SABnzbd-0.7.20/interfaces/Plush/templates/_inc_modals.tmpl0000644000000000000000000002342512433712601023613 0ustar00usergroup00000000000000
    $T('menu-wiki'):$helpuri$help_uri
    $T('menu-forums'):http://forums.sabnzbd.org/
    $T('menu-irc'):http://www.sabnzbd.org/live-chat/

    SABnzbd $T('version'): $version

    Copyright (C) 2008-2014, The SABnzbd Team <team@sabnzbd.org>

    $T('yourRights')

    $T('link-forceDisc')

    ","\n")#">$T('sch-restart') $T('sch-shutdown')


    $T('Plush-refreshRate'):

    $T('Plush-containerWidth'):

    $T("Plush-blockRefresh")
    #if $pane=="Main"#


    $T('Plush-uploadTip')

    $T('pp'): #if $cat_list# #end if# #if $script_list# #end if#
    $T('category'):
    $T('priority'):
    $T('pp'):
    $T('script'):

    $T('Plush-addnzb-filename'):


    $T('purgeQueue')





    $T('purgeHist')






    title


    $T('opt-extra-NZB'):




    title

     $T('spam')
     $T('encrypted')
     $T('expired')
    $T('host')  
     $T('otherProblem')
     $T('comment')

    #end if#
    SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/config.js0000644000000000000000000001723412433712601026072 0ustar00usergroup00000000000000// ***************************************************************** // Plush Config code as follows, by pairofdimes (see LICENSE-CC.txt) jQuery(document).ready(function($){ // Top Menu var noTopMenu = $.cookie('plushNoTopMenu') ? $.cookie('plushNoTopMenu') : 0; $('#topmenu_bar').show(); // Container width var containerWidth = $.cookie('plushContainerWidth') ? $.cookie('plushContainerWidth') : '100%'; $('#master-width').css('width',containerWidth); // Confirm user exits without saving changes first if (config_pane != 'NZO') { $(':input','form').change(function(){ window.onbeforeunload = function(){return confirmWithoutSavingPrompt;} }); $('form').submit(function(){ window.onbeforeunload = null; }); } // modals $("#help").colorbox({ inline:true, href:"#help_modal", title:$("#help").text(), innerWidth:"375px", innerHeight:"350px", initialWidth:"375px", initialHeight:"350px", speed:0, opacity:0.7 }); $(".show_qrcode").colorbox({ photo:true, innerHeight:"300px", innerWidth:"300px", speed:0, opacity: 0.7, scrolling:false }); // jqueryui tabs/buttons $('.juiButton').button(); $( ".tabs" ).tabs({ cookie: { expires: 1 // store cookie for a day, without, it would be a session cookie } }); $(".vertical-tabs").tabs().addClass('ui-tabs-vertical ui-helper-clearfix'); $(".vertical-tabs li").removeClass('ui-corner-top').addClass('ui-corner-left'); // kludge for jqueryui tabs, using cookie option above for some reason does not select the default 1st tab $('.tabs').each(function(index) { if (!$(this).children('ul.ui-tabs-nav').children('li.ui-tabs-selected').length) $(this).tabs('select',0); }); // kludge for jqueryui tabs, clicking for an existing tab doesnt switch to it $('#activeFeedLink').click(function(){ // tab-feed focus $( ".tabs" ).tabs("select",1) return false; }); switch(config_pane) { // not a config page, rather queued nzb file listing page case 'NZO': $('#nzo_reload').click(function(){ document.location.reload(); }); // operations $('#nzo_delete').click(function(){ $('#action_key').val('Delete'); $('#bulk_operation').submit(); }); $('#nzo_top').click(function(){ $('#action_key').val('Top'); $('#bulk_operation').submit(); }); $('#nzo_up').click(function(){ $('#action_key').val('Up'); $('#bulk_operation').submit(); }); $('#nzo_down').click(function(){ $('#action_key').val('Down'); $('#bulk_operation').submit(); }); $('#nzo_bottom').click(function(){ $('#action_key').val('Bottom'); $('#bulk_operation').submit(); }); // selections $("#nzo_select_all").click(function(){ $("INPUT[type='checkbox']").prop('checked', true).trigger('change'); }); var last1, last2; $("#nzo_select_range").click(function(){ if (last1 && last2 && last1 < last2) $("INPUT[type='checkbox']").slice(last1,last2).prop('checked', true).trigger('change'); else if (last1 && last2) $("INPUT[type='checkbox']").slice(last2,last1).prop('checked', true).trigger('change'); }); $("#nzo_select_invert").click(function(){ $("INPUT[type='checkbox']").each( function() { $(this).prop('checked', !$(this).prop('checked')).trigger('change'); }); }); $("#nzo_select_none").click(function(){ $("INPUT[type='checkbox']").prop('checked', false).trigger('change'); }); // click filenames to select $('#config_content .nzoTable .nzf_row').click(function(event) { $('#box-'+$(event.target).parent().attr('id')).prop('checked', !$('#box-'+$(event.target).parent().attr('id')).prop('checked')).trigger('change'); // range event interaction -- see further above if (last1) last2 = last1; last1 = $(event.target).parent()[0].rowIndex ? $(event.target).parent()[0].rowIndex : $(event.target).parent().parent()[0].rowIndex; }); // $('#config_content .nzoTable .nzf_row input').change(function(e){ if ($(e.target).prop('checked')) $(e.target).parent().parent().addClass("nzo_highlight"); else $(e.target).parent().parent().removeClass("nzo_highlight"); }); // set highlighted property for checked rows upon reload $('#config_content .nzoTable .nzf_row input:checked').parent().parent().addClass("nzo_highlight"); return; // skip the rest of the config methods break; case 'Status': $('#logging_level').change(function(event){ window.location = './change_loglevel?loglevel='+$(event.target).val()+'&session='+apikey; }); break; case 'General': $('#apikey').click(function(){ $('#apikey').select() }); $('#generate_new_apikey').click(function(){ if (confirm($(this).attr('rel'))) { $.ajax({ type: "POST", url: "../../tapi", data: {mode:'config', name:'set_apikey', apikey: $('#apikey').val()}, success: function(msg){ $('#apikey,#session').val(msg); window.location.reload(); } }); } }); $('#generate_new_nzbkey').click(function(){ if (confirm($(this).attr('rel'))) { $.ajax({ type: "POST", url: "../../tapi", data: {mode:'config', name:'set_nzbkey', apikey: $('#apikey').val()}, success: function(msg){ $('#nzbkey,#session').val(msg); window.location.reload(); } }); } }); $('#sabnzbd_restart').click(function(){ return confirm($(this).attr('rel')); }); break; case 'Servers': $('form .testServer').click(function(event){ // test server $(event.target).next('span').addClass('loading'); $.ajax({ type: "POST", url: "../../tapi", data: "mode=config&name=test_server&"+ $(event.target).parents('form:first').serialize() +"&apikey="+$('#apikey').val(), success: function(msg){ alert(msg); $(event.target).next('span').removeClass('loading'); } }); }); $('form .delServer').click(function(event){ // delete server if(confirm($(event.target).attr('rel'))) $(event.target).parents('form:first').attr('action','delServer').submit(); return false; }); $('form .clrServer').click(function(event){ // clear server if(confirm($(event.target).attr('rel'))) $(event.target).parents('form:first').attr('action','clrServer').submit(); return false; }); break; case 'Categories': $(':button').click(function(event){ // delete category window.location="delete/?name="+$(event.target).attr('name')+'&session='+apikey; }); break; case 'RSS': $('.toggleFeedCheckbox').click(function(){ // enable/disable feed window.onbeforeunload = null; // lose data? this.form.action='toggle_rss_feed?session=$session'; this.form.submit(); return false; }); $('.rssOrderSelect').change(function(){ // change filter order window.onbeforeunload = null; // lose data? location = this.options[this.selectedIndex].value; }); break; case 'Email': $('#test_email').click(function(){ return confirm($('#test_email').attr('rel')); }); break; case 'Index Sites': $('#getBookmarks').click(function(){ window.location='getBookmarks?session='+apikey; }); $('#hideBookmarks').click(function(){ window.location='hideBookmarks?session='+apikey; }); $('#showBookmarks').click(function(){ window.location='showBookmarks?session='+apikey; }); break; case 'Sorting': previewtv(); previewmovie(); previewdate(); // display sorting previews -- these functions are defined below break; }; // page's save button for those pages that use it $('#save').click(function(){ window.onbeforeunload = null; $('form').submit(); }); }); // end Plush code SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/lib.js0000644000000000000000000063360212433712601025376 0ustar00usergroup00000000000000/*! * jQuery JavaScript Library v1.6.2 * http://jquery.com/ * * Copyright 2011, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Thu Jun 30 14:16:56 2011 -0400 */ (function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
    a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
    ",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
    t
    ",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i. shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j )}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bL,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bM.test(this.nodeName)||bG.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bT,isLocal:bH.test(bU[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bW(bR),ajaxTransport:bW(bS),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?bZ(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b$(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bF.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bX(bS,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
    ";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cu.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cu.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cv(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); /*! * jQuery UI 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI */ (function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.15", keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d= this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this, "overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart": "mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight, outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a, "tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&& a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted= false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); ;/* * jQuery UI Position 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Position */ (function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY, left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+= k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-= m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left= d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+= a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b), g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery); ;/* * jQuery UI Draggable 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Draggables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== "original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b= this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;d(b.iframeFix===true?"iframe":b.iframeFix).each(function(){d('
    ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")});return true},_mouseStart:function(a){var b=this.options;this.helper= this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}); this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);d.ui.ddmanager&&d.ui.ddmanager.dragStart(this,a);return true}, _mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b= false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration, 10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},_mouseUp:function(a){this.options.iframeFix===true&&d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});d.ui.ddmanager&&d.ui.ddmanager.dragStop(this,a);return d.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle|| !d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&& a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent= this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"), 10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"), 10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[a.containment=="document"?0:d(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a.containment=="document"?0:d(window).scrollTop()-this.offset.relative.top-this.offset.parent.top, (a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){a=d(a.containment);var b=a[0];if(b){a.offset();var c=d(b).css("overflow")!= "hidden";this.containment=[(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"), 10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=a}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+ this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&& !(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,h=a.pageY;if(this.originalPosition){var g;if(this.containment){if(this.relative_container){g=this.relative_container.offset();g=[this.containment[0]+g.left,this.containment[1]+g.top,this.containment[2]+g.left,this.containment[3]+g.top]}else g=this.containment;if(a.pageX-this.offset.click.leftg[2])e=g[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>g[3])h=g[3]+this.offset.click.top}if(b.grid){h=b.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/b.grid[1])*b.grid[1]:this.originalPageY;h=g?!(h-this.offset.click.topg[3])?h:!(h-this.offset.click.topg[2])?e:!(e-this.offset.click.left=0;i--){var j=c.snapElements[i].left,l=j+c.snapElements[i].width,k=c.snapElements[i].top,m=k+c.snapElements[i].height;if(j-e
    ').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d
    ');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection(); this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){e(this).removeClass("ui-resizable-autohide");b._handles.show()}},function(){if(!a.disabled)if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy(); var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a= false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"}); this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff= {width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis]; if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false}, _mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f, {top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(b){var a=this.options,c,d,f;a={minWidth:k(a.minWidth)?a.minWidth:0,maxWidth:k(a.maxWidth)?a.maxWidth:Infinity,minHeight:k(a.minHeight)?a.minHeight:0,maxHeight:k(a.maxHeight)?a.maxHeight: Infinity};if(this._aspectRatio||b){b=a.minHeight*this.aspectRatio;d=a.minWidth/this.aspectRatio;c=a.maxHeight*this.aspectRatio;f=a.maxWidth/this.aspectRatio;if(b>a.minWidth)a.minWidth=b;if(d>a.minHeight)a.minHeight=d;if(cb.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&l)b.left=i-a.minWidth;if(d&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left= null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a
    ');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+ a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+ c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]); b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.15"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(), 10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top- f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var l=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:l.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(l.css("position"))){c._revertToRelativePosition=true;l.css({position:"absolute",top:"auto",left:"auto"})}l.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType? e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a= e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing, step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement= e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset; var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left: a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top- d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition, f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25, display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b= e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height= d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery); ;/* * jQuery UI Selectable 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Selectables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"), selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("
    ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting", c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d= this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("");e.secondary&&a.append("");if(!this.options.text){d.push(f?"ui-button-icons-only": "ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")=== "ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); b.Widget.prototype.destroy.call(this)}})})(jQuery); ;/* * jQuery UI Dialog 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Dialog * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * jquery.ui.button.js * jquery.ui.draggable.js * jquery.ui.mouse.js * jquery.ui.position.js * jquery.ui.resizable.js */ (function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false, position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
    ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
    ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id", e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()};c.ui.dialog.maxZ+=1; d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("
    ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("
    ").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a, function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition, originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize", f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "): [a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f); if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"): e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a= this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height- b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.15",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "), create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()
    ").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(), height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight); b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a
    ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
  • #{label}
  • "},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| (q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= -1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, "cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.15"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k"),b.open=!0}c&&(b.onComplete=c),f.each(function(){a.data(this,e,a.extend({},a.data(this,e)||d,b)),a(this).addClass(g)}),(a.isFunction(b.open)&&b.open.call(f)||b.open)&&bc(f[0]);return f},X.init=function(){z=a(c),r=Y().attr({id:e,"class":n?f+(o?"IE6":"IE"):""}),q=Y("Overlay",o?"position:absolute":"").hide(),s=Y("Wrapper"),t=Y("Content").append(A=Y("LoadedContent","width:0; height:0; overflow:hidden"),C=Y("LoadingOverlay").add(Y("LoadingGraphic")),D=Y("Title"),E=Y("Current"),G=Y("Next"),H=Y("Previous"),F=Y("Slideshow").bind(h,bb),I=Y("Close")),s.append(Y().append(Y("TopLeft"),u=Y("TopCenter"),Y("TopRight")),Y(!1,"clear:left").append(v=Y("MiddleLeft"),t,w=Y("MiddleRight")),Y(!1,"clear:left").append(Y("BottomLeft"),x=Y("BottomCenter"),Y("BottomRight"))).children().children().css({"float":"left"}),B=Y(!1,"position:absolute; width:9999px; visibility:hidden; display:none"),a("body").prepend(q,r.append(s,B)),t.children().hover(function(){a(this).addClass("hover")},function(){a(this).removeClass("hover")}).addClass("hover"),L=u.height()+x.height()+t.outerHeight(!0)-t.height(),M=v.width()+w.width()+t.outerWidth(!0)-t.width(),N=A.outerHeight(!0),O=A.outerWidth(!0),r.css({"padding-bottom":L,"padding-right":M}).hide(),G.click(function(){X.next()}),H.click(function(){X.prev()}),I.click(function(){X.close()}),J=G.add(H).add(E).add(F),t.children().removeClass("hover"),q.click(function(){K.overlayClose&&X.close()}),a(b).bind("keydown."+f,function(a){var b=a.keyCode;S&&K.escKey&&b===27&&(a.preventDefault(),X.close()),S&&K.arrowKey&&y[1]&&(b===37?(a.preventDefault(),H.click()):b===39&&(a.preventDefault(),G.click()))})},X.remove=function(){r.add(q).remove(),a("."+g).removeData(e).removeClass(g)},X.position=function(a,c){function g(a){u[0].style.width=x[0].style.width=t[0].style.width=a.style.width,C[0].style.height=C[1].style.height=t[0].style.height=v[0].style.height=w[0].style.height=a.style.height}var d=0,e=0;z.unbind("resize."+f),r.hide(),K.fixed&&!o?r.css({position:"fixed"}):(d=z.scrollTop(),e=z.scrollLeft(),r.css({position:"absolute"})),K.right!==!1?e+=Math.max(z.width()-K.w-O-M-Z(K.right,"x"),0):K.left!==!1?e+=Z(K.left,"x"):e+=Math.round(Math.max(z.width()-K.w-O-M,0)/2),K.bottom!==!1?d+=Math.max(b.documentElement.clientHeight-K.h-N-L-Z(K.bottom,"y"),0):K.top!==!1?d+=Z(K.top,"y"):d+=Math.round(Math.max(b.documentElement.clientHeight-K.h-N-L,0)/2),r.show(),a=r.width()===K.w+O&&r.height()===K.h+N?0:a||0,s[0].style.width=s[0].style.height="9999px",r.dequeue().animate({width:K.w+O,height:K.h+N,top:d,left:e},{duration:a,complete:function(){g(this),T=!1,s[0].style.width=K.w+O+M+"px",s[0].style.height=K.h+N+L+"px",c&&c(),setTimeout(function(){z.bind("resize."+f,X.position)},1)},step:function(){g(this)}})},X.resize=function(a){if(S){a=a||{},a.width&&(K.w=Z(a.width,"x")-O-M),a.innerWidth&&(K.w=Z(a.innerWidth,"x")),A.css({width:K.w}),a.height&&(K.h=Z(a.height,"y")-N-L),a.innerHeight&&(K.h=Z(a.innerHeight,"y"));if(!a.innerHeight&&!a.height){var b=A.wrapInner("
    ").children();K.h=b.height(),b.replaceWith(b.children())}A.css({height:K.h}),X.position(K.transition==="none"?0:K.speed)}},X.prep=function(b){function h(){K.h=K.h||A.height(),K.h=K.mh&&K.mh1?(typeof K.current=="string"&&E.html(K.current.replace("{current}",Q+1).replace("{total}",i)).show(),G[K.loop||Q")[0].src=h),$(c)&&(a("")[0].src=c))):J.hide(),K.iframe?(k=a("


    $T('wizard-example') news.giganews.com

    $T('wizard-port-eg')





    $T('wizard-server-con-explain') $T('wizard-server-con-eg')

    $T('wizard-server-ssl-explain')


    $T('wizard-server-text')


    $step
    SABnzbd-0.7.20/interfaces/wizard/README.TXT0000644000000000000000000000153412433712602020211 0ustar00usergroup00000000000000# # Copyright 2009 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # This is the quick setup wizard for SABnzbd # It is used when first starting up sabnzbd # SABnzbd-0.7.20/interfaces/wizard/three.html0000644000000000000000000000316512433712552020656 0ustar00usergroup00000000000000

    Indexer

    $T('explain-rating_enable')
    $T('wizard-create-account')https://www.oznzb.com/register.

    >

    $T('tip-rating_api_key')



    $step
    SABnzbd-0.7.20/interfaces/wizard/two.html0000644000000000000000000000542712433712552020363 0ustar00usergroup00000000000000

    $T('wizard-access')

    >
    >





    >

    $T('wizard-misc')

    >


    $step
    SABnzbd-0.7.20/interfaces/wizard/static/style.css0000644000000000000000000000540512433712602022015 0ustar00usergroup00000000000000body { font-size:13px; font-family: sans-serif; background:#DEDEAF; padding-left:5%; padding-right:5%; padding-bottom:10px; text-align:center; } #page { /*background-color: #ccc;*/ /*margin:30px;*/ border: 1px solid #000; text-align:left; padding:8px; background-color: #fff; } #inner { background-color: #fff; padding:4px 32px 20px 32px; /*margin:5px;*/ border: 1px dotted #999966; } #content { min-height:520px; } #logo { float:center; /*margin-top:30px;*/ z-index:40; margin-bottom:-40px; } hr { color:#fff; background-color:#fff; border: 1px dotted #ccc; border-style:none none dotted; } .container { width:700px; margin: 0px auto; } .language { width:175px; text-align: center; float: left; } .float { float:left; } .clear { clear: left; } .inline{display:inline;} .quoteBlock { padding:5px; border: 1px dotted #000; background-color:#f5f5f5; } .success { color:green; } .failed { color:red; } #serverBlock { width:300px; float:right; } #rightGreyText { color:#ccc; width:100%; text-align:right; padding-top:3px; font-style:italic; } .indented { padding-left:10px; } .label { text-align: left; width: 100px; padding-right: 20px; padding-left:10px; } #serverDetails .label{ display: block; width: 100px; float: left; margin-bottom: 15px; } #serverDetails input { /*width: 150px;*/ } .sup { vertical-align: sup !important; } h2 { /*display:inline;*/ } h1,h2 { display:inline; } .align-right { text-align:right; } .align-center { text-align:center; } .float-center { float:center; } .unselected { padding:1px 5px 1px 5px; border: 1px solid red; margin-left:8px; margin-right:8px; color:red; } .selected { padding:1px 5px 1px 5px; color: white; background-color:red; border: 1px solid red; margin-left:8px; margin-right:8px; } .bigger { font-size:14px; } .padded { padding:12px; } .bigger input { font-size:16px; } .required-star { color:red; } .full-width { width:100%; } .bigbutton { font-size:18px !important; } .bold { font-weight:bold; } .correct { border: 2px solid #00cc22; } .incorrect { border: 2px solid red; } .hidden { display:none !important; } .text-input{ width:130px; } .text-input-wide{ width:230px; } .text-input-thin{ width:50px; } /*Fix for inputs messing up when adding a class in chrome */ .clearinput { margin-bottom:6px; } .disabled-text { text-decoration: line-through; color:#ccc; } #serverQuote{ width:100%; height:16px; display:inline; } .skin-select { height:190px; } .skin-select img{ cursor: pointer; } .skin-select-plush img{ margin-top:30px; } .tips { display:inline; font-style:italic; color:#888; } .error-text { display:inline; color:red; } SABnzbd-0.7.20/interfaces/wizard/static/images/classic-th.png0000644000000000000000000004435312433712552024161 0ustar00usergroup00000000000000PNG  IHDR^sRGBgAMA a pHYsodtEXtSoftwareAdobe ImageReadyqe<H[IDATx^]xTG=ݸRܡŝB[w+E;AS؏(R!x&Yg7&}YLm}3=s̼ysHG#F?W#!G3@;g\EwtnA#s9ѹ p>$zm;6PĢ"g:^>u"Q*P()I[x'Yߵqq-u|U38ݻŝ@Q#-KeBmT ~W5CE,vu~wTu9\ Q"e eZhsƕc`o6a֦%ȝzOn󱕰`h Y9!`}9xa[.<#7/'ۄW?k9='u.v8Ƅѝ1~p[37/1旿͊TUذyO 0L?Yeq̉sc1iƴ.aRQ(5uo -$.|#1ֹq}7ՠOy=ٿBX|/v;r_鮟ドbEya:y"|þx0BԏKmdx59s_.xt,Bw-5D!V r?]u?3V-%ɩp3wNzMّ89x\9F꿒f GTHA:EI:m1 0 ^MFGa~$$Iý;V*vpơ9yq^v/=wHX@Tr_|OI$ OcղM8 P2R.wVރ "N="<* $rVĕ~΂MmlԅѬ)m9vZLo`v6&sr7(QrkƎ\F{3[oΠe?m\DGR-N (${C*JU휈bN_K|G<=gI<0#<1 v<JMp._%U0<1ŕ3p/է*hu&=cǯmYlWЮbx9 ,Mp x4i Y}Am_ooOɋt]aZ-9g8}A|Y _|g#u9Bb~ísl_bhh$~uK*-ulѴhɏѴ̌0ѩkgz. T2G޲~ޏAbO['ÚmAP0ԺYmF?Kib;XG rīX'~‹U~o=&Vn,c$}Ća*u^vctl?AH|u'v5Ol=mtEa̟ >GRDCtɫNƒp|=;6u y>B8оU(S)U~jO煀{W^N8 *~EG"wGe%?FYށ$߿F7X{G{Y{o#X?{@b݈E\~tG)^nɆOhMFXz qߑRbG鰥 >g>:De3i5qشrv iQ>.Ms,w5 QǘNȦ]ָ 2ײ~&UŬ9UhÅp "`ԝX?Gs94r8i#:8|42W#G3@;g\EwtnA#s9W###u[Aypt( "evGwr4+s@RCNmZx!8|rΜ|Ŧpvʺ` %9yrP\)|zb gp&!<:Cz|A7ԬxBk8!q{G'HzD KOɹd }e{JF &l$J-_Zg#0^F@9'eBFrh]Ll 2WPB!,=_Vp#XjЌmς% 钾810A-kxÆԲxlY+ې9R;2;{-gT3t ^_rvC@FE Gj;N귡Pk _"l% ]7b@Bc::9Kml0&Ywׄs%ٙ.diׯ︅ٴvHϤzF#).TC:# G?DRD>fOR$~ݎSwbxa,QM̛=.!N ZHGw#!Snn5bFcӺ^ BX_pz!d&Gy殮gvoѬDBV`\k.^<bðۻd-E:#g_b~+e" nFt ~hTb(C} {qw,^E KXz+Og[\܏Ea͚mYj焐C!1qx n[ D7m>}'Af`<TоEMvPbڰx">E689nɽGIдq6(_A".XuOдe0%'a`z%[4OJg^sЀ _%Ns]AR'dApiJgyү2IvC?FѤ3(y  P${98x|uA䣗Prm[| ~$!+  C#FFU$>:c19?];O~ݧoQVZݠ*T+m/:V%qa+*]y W6@e\ٽ vHTfXd !.~ I-^ČUBV1Y a-\\xU%vVW=^.OO؂ep%S欅B#Cż$ N6[oo"XK,AlD~)_s+fNu {-/F Q%f޲hTibӎ^=|{bL^8PٺHxB[h;.él34 vBmr;g] = vl/jfA:[ ~m0௃xZ~,CgBQ Ptd~x@ؗkivh;?{Pjۚ1MQ:~gDQ-/KqѢf|ƞi HA' DR 1:ұJj;zvT[oԊOWG:Nij݌4d 1 G#!# Cqʧm>F:)-(cpeq4EB $.pL6zֿKSܘkblk&=t+ mh*q=el,L#Jz0q oVE*_.t1b%[{ZdKr^> 9l&Rcb8}ceqdi_i휮zӓڦR۞؇h*11dm0M2{do 4S[SׯR*i1.aIMzƟXbPٌq?K+(l.8|%辱u~?nJ/T$8k| i:z|jrhhٞbb֔{FF+Fi*bFfkɍV`WC)m'O.pٲYث@J~b`ɩ4TQL LsWvWX ɐQa/ѫU3~i2w~(`0t,@Tn\M:#B428 ڀ 69Kזu-DPuN@E YH %;ʰƈp)Mߠ[,BjŤ&8 o{Pn,j= -K:1 =(P$؄uhżʹ=؟gfl}>H9 [`:׷Ľ,J޹Kh:|Fsnpp~l2#¶ c(^k~EΡK) ~_m ]O;Qo×;OLc-(m#ؼy ?oG[QkҶ/خg:A}utb:!ytENE ãt5|3ˏ>ƅ+ý˭,y|\G:z:B @s P!ğRSNFm6U97|kDEr}mˢ#㣷鿷E0ەGaT{vBI~`vei')я|ٚBRtMlW/aQ7 Ϭۀ:l|Fi3k -Ar245W'wA=|4.NݎFsdz#v$?D=ױ9P)yh+E{zE-QޫB\Ŋp&,b[q>l;t$j҈=JԪ5g>~ ̃/d {$Íh|OQN kU#]A?=6c=~&3ZuL'ÜaC<~֎3“"=WPQ3g@7KÜI(yUcǾ(]0~vndc#<ݩM|Op-]C볖Omwm:tkK,iS;cX9(8}xL<^X4c_b}qϞb?3n| EH(2@J#6ƱX-)У%f2hbqFd0h!c][Gg]=iŸg?S 'ZKm(N b4!4^'a$i]ɐJPRz^:8".'ONbBuYi|>IhFFG P9%5;R8hA_D2]OX+3dL31guqhG[mičߤ4e|n*ZH"XǤAX =T "5UZ8ؠwwi/Av[P n[| S8--5A|5ɾZQK!m͕L&y:K)<ǜ]f.;;D'7LegV!Et-!xyVM uJZN$x>?yGb<GsG ן#I"`pD/Rx| q90[؆ n[8F?gu sD@; [pY.F;zV?G@2G -"ojgu sD@; [pY.F;zV?G@2G -"ojgu sD@ M%KՕ1cue^Kf\ :A:Ο?{ͩe-XXl49y޼yMwu$HY)cܹ:&OlrgjN\ĮZ9,ΜΜu&SVŌj:u~'39:I'P62;8ө!ɓNPi8(tNt1'^?;:^J!e6|6<,1pD:fJH.2'FNGtNq].Ptk3lXg̵R3F}&h0L*22 Q(R5/:5VwMÎ3cy1acI`tz4r pbX #Ac$#کSN2qU=D|EGtVyD-A^ȥY˗A:SзS$DDNm+>W7ͻcXh:-y;%ZN:B#Eޫ/Py_,;f4@1aEhW5$bֲ޼} -`6mrľgVXm*fǛ>stF„{|g::."kșv1wVok=ۡm͢{˰bHh$,E6xa=}|,D.;tv6BO5 \-Zbt:EgX6#Ti~bޒ 8:mƍZ:mb XhH1j;*l](ũe?r߶MOZVvkM[n ,Oư&-ЗNݪv,C}ѭ[_vf]hA՗yq{aٰtl<~Mw.8ICSq KebygQQ|8nٿFp% GXzt䵵%y;Nw GWw791B-_ta3cæ{LGn.ѭ3"n򝮄W:6|'?IMNPoJ|W`xկnhjpGR\'WbGsy ΆG U|6(;VA&Ѡt y/_>/+p%NȍC"enn F€q+0Zt .soAJq 1t2Bȕ:>^B-CzgOi5>]؄co|a2s쀧~ϑTt _jQ|m-Z0X]8Q _B)>v^+eˎe4/V(f/XlN"""%*Jʸ`^/L2=WOغ Ff30y֡Jk*-Eca8p-櫌DZ|R/[ :v[J=yvQήِqJ쌃kВxfѳA Swn+Č%Vx4MlF(;]"3ңTሓ:@4yrדt*cgKdσ+/pT ۆkY̨ r8B{dHTpCXBwλ;lUrjtzkm]y ]=hKŠ0Ye'g -)*xdwATpZ dtV:{@ P㛙ȕ7?c]{Y]KQS#V#Cl3@HsȑPitt56/p0G]B'+RҔV::Q\;wg`a-rKѷ'NTe]o[+3ʥU&+Rsb tu͒Z6'Z9̃ZttsnuzV:)#:ZcΊ=&w4Km-XX;MG/xr{e3wfhhA ߿jAQДZ.5hO3FB"#v:NWǢzG(yۖm)LKc!TNK! Kѽ# -koƆ^8;p85Ξsx@.Wx8٤24V$tAҪ?D쩍5J^j"$&7B1 siB+{ dvh(=\Ql:*1k0 GJC؂CyWXѳ+=|toHG23'GْE0jb$9ӑ#Q)i41ȑ;-\z ,))rS<͠apGh˦VL(Iy-e2ME)ɄnCȴ(yr8|)T 'nB#~f<#YRO! r CNbp~/l6sIWbQQ{$l FcNޣ^D{|)aQ^i=0md9vBV!Y9<h!mhP=5wT mTe:MSNKeMz߁]K8>.!Yޑ}x%F<[(FfcX\f-QM{YR*U:WXn.[wj2,'|#`3r5ôR;2BSJ7v`?eUk|~,TYYZ~F܉]{#xNuxkP[ݻ /Dtt61;dKOf^ch pGPtEo"Z鵊vaZA gW(DGZ(OBoŸoB`@9їӗe͚nG>r(Gb6d,9_v`6a#gcƒCJ`tx2EJ_a[ m i}33Bvѽ?<(Q f[j5t]BP1Cf.}2;e ttrrM̙J}1Y j;{⠡Wbxac<[+_A+VE<7u2‰"yi,wDOHZxOfϤ-q =,F5I^cjFq-{B+RZtz,_1ᱴP'T( )&~0.<)3WvCdndjKO!rcdc뺶F%#Eov/ %bvPDӯzVN^PF#*bcT2ÿ9?`ȪZpA} %<\d]2dv §nƿtrt,Μ@a{]fC>8>vx`_624IJԃCŕq7GOM2,6 G M7so][\p3z} vN3p[z|(hV !25L0:]DSuwŸSn`DɤRbBA)sHX]wMl)+wg;Fiklvf|Nkx]m%LAy(8v'bҵ6KЯE!'f>&+`7=q**P5{]ޝ)FD8ԪuYn*/ב0άXems%=ysax2-$~^;V-nѣ/`b;$cep"҇`l~= {CP"uk9p:щSoFKO!4:=,iN9MCb9w&)0yFrܐrTdT4 V] q}E-4BNbuS2 ]g/6fOnXYw ksh /ƙx]8;cib-SfkÒ !ڪ{80f vm/%u9:gуnrbl2 sit:gI6gIbMav1aLG1s#hs$,b2XZNrGa&H?z EIkf4IuxNJIO0#(gUbM?C >*i&w Dse(a1EO0#8Ìps}HQR4D6>MG4D~cPf 0 J1 1GKE|P`qZ\9"Xܳ+nSYwިo} GxQR3v 3@fc"p'MHn8Ŧ K0rQ \ 9dȕӍs@vOvBQ ȉC}\G϶Q1;ԏ$r 6c"oZϒwofI,&V{r O| 3Y,l$GDh$<2Hۏ`/&V g?>+А?嗫FV/4Gg30ba,):l1t8:gRB0}ʑN$D6b^7J'0t^\ҡ3hC&/ZrcЩ tdC\]m郖-[ M,)5=4 gRR0 Oa&cMmzns2fsit:g53߬Y,bLX.S:g1tY4o4's1#7 sit:g1,؆1s,bVK3rA1ԝOݳdel-rX!D# 3f/,]2fBb\9ÌaGCͲFkHdn1)))rQa&ڜa&m3's1#7Ŝr"1żff4s1bi9aLsL |ײ5Z@l\y*dHR^0#8Ìp9o~=]JQ:WwxjYgJ9Ì& 3±Nw9Kżw}2m/ijnH)w^Kg*ZFL3Xz 3AI3*)1 .3x o`왈Cy\7q6y 2|5<v!CU`:ʌˈbbf 3(X/^#&$:V q@ ̕ݐ-'(7qX)>Xz 3A)q(5gl?n4Fh4V" 19N0S!&V8aGz=ti.!{ MP^`f>8L*L8Lc9[T0SNS09Ì9L@fn1fB],-P9#u0 ,!9]51dB%EIO0#(C;DAAt,E'~CgIa%5E}4^;ppv}x56r}}Y]9Q+\Wy ,#}PZW2z[aFxqXs樎NP-zNXZ4敀T1#$m5Uē1mhT 4u2KY$G]0myY4C8ÌpX%˙ =dq3q2jƄyW!q^5H diKGN +6Ɯ3XzfH(Ŕ3d|M/TDw>@y"8 L{oRJU,ciE!4,\7[7#0]w,;L|H yL<9rbO(:k=p" 0H7"8f#o5m6Z Xj(h'"gRBr.0#0YѦ(l>ZZmMEb7<ü~(E]][\pS:WDI(@R@IOobyYNe96ޭ')•ac|S(٧ѡo}6뮳ۧSoּƦm7PoA紆wQVdT𛇂cw"v.]kZP[Μva&kfpm!:LxC7пIdn1voS]))rQaF08xѝAeic!r Ø>b] 3 3i9[).9(u0c9LMQh-L"TNKa 10U*Zl0f,i_m-."%"[`-) # |Χ,Z˔ZYF<fm_Xe*-P9--1ĸ.sÎV1 œ-5嵖94Ec:y3̤B3̤m~dn1f0SNS09Ì9L@fn1fB],-P9#u0I_>WļI&=9Ì&e 3±JF,ea1Wvti?3#ˈq9Ìy8ÌpsΙr;~ xWܼUG!Hp,6dXz 3A)щ-Nck7c؈qf`/;A؆m690gf?4+Űf%H6(SZ5Oh4hu"(W%p>Ċo='MpbYrZ*˸Ib%v1L)Xz nXֵ+tlSn`DɤRbfV=\QlHԻ3M“N.gbQQ1NvP)b= $i-Š;e4< {f!`4&ffcSg^LVb0ٻAmSmc@fLb)D\0#%}0#t y3:EձC/їq* =pȎ0ԫV D60myY4Úb)D80#xG 3ڢJٹtO,,ID#ۈa˱av~gAqP7#Oa)J8dnBp y輍1 *o06fD1?>>7O.feɔjv;0dQ=@}6j S/b^(_qW?e^M][VnyRWh֭jgB,=8:VG{}u][!gZ):1JGH.e9\={c3 jk%` C* O,I#J=+Ɋ4Yhj*-ɰ=ȡX@C͜w((?f$Z2 &~5<6o#{?<8>ޭ')DLcrcv.}2;M UW0lmlS0%gkg31's135 sit:g4gI-ƚC(*1}ĺf f6?s23rS]))rQaƈs`c5[:Db\a q$2| RcѼyƱm;,IW KBhjα IW:gq֮rܝ-Y 4b &{dmAX5XH(?e,C(=Z.W@eGbI2zTs؛܋ͩ(]*;sU^g4sKӾi}jL8"+`!@s ֤C}X_6߭g=?-D>/.bK0tv[Ԏ6ou: CB6 P[Q䚃%fRyQnRicCO;}ӳwWˡ1 |m+`B^jΉ^Rȿ #&OKMí~)_N8[1`izjyϊKEr Ѕ̍05j[Dcdnnfb{4Xs~,VP'%}}ve,2XǾ"KyXPiq5W,L۳oTtlXdWv, Jg ʭ5wq"HNfVft;9ǞBܻ뭨#+Lh9z~0!,ƸU #qqiEh`2/.Q1wWR: b3>?|PdZעue{q zwi>Bw g,W4HW7kB s> =F >]P{,>g@ӱogsqt_}%]|+tWn0JRȲʧ,yUΥ,{^o*uSr6Y%|/8j& V$NzUYh4F5_m,(V%KqE'E>F{_mj h!6"TntpORoQߝ)cm1C^b9[ {[!5]G1U&VWb[g#" ( 02Jvk3U TUZKW FPYk`Ыr?yB2XH?CYT1͚$O, 5諾ίԧ+g9pz$62+F] U!vTZ|M߈[2ojXM s"G'lƀҠЎu'Mv ZTRjW1ʅ3ַLV)Db'D!CҶ9KR$@j]A= 0 83&龷vg  ҨI#b\APdj1{Jw {J1$Kn0jԵƹzsveƶMbz=%ZJ:2|.AC̫!6+ZKvU-GUhPJ)Hcͪ-' lUxqϹr˥Htjo<|'"q5/J΀1%g(KҘz%:{K@&H+ߴg'tTͭ_($Џ[/\AvQ0٬C2C3`n ЗW+`.RwS2@]KQ$V+!w w4s\jYېύ `Pqi:rK<'WݲFd N98ZHe@վĽ<٥+jkhUvh~U{dZY7> .A g eɄ)?Zc'ŎFe%>LTe2_l'6R_|'4"NǑTڸI$!#- VsR.@D~̃???{2tvvc! `|/0;_WU1?@e>D O5@P0? \{r?Fs?<.~u}:cx`_>8FIٮ~ZďKޏ2Go|*4> /^iV +Dθ$n ro -勇|ԵoZ\gh"/:~( +Ԭ17gMI1vP6@0C8K-/:K6d4(7N|ʃL3@-҄L!{.`cLb?]]*:[mg!7(p*Gsl!ϣ-!HvhyM%ޑSIA>ʏӊzum*RNYRʿif8l+InnnRy >_9c5c r.5utt4fZ Έ|t8[ri$uW8v&ԫ\,=> cMͲ-KtOO)GR[VX$^i}8_NI:Z @9dvܨ4cc@maL?w(f5'+J jkb>]v ?C}TӀۨ!Ϩc0?@1_ٳ} .'))Vu,O+1`<4htL`u8xbMۓÖ?¨6Қt߯j[(@ר'oa#&{t"WfX@=ztaXt^,M!GrƸ+pK N`99Bu ?v@tIأN; ͚:y{ &P,|Kn?Fl"X] ~3wblEa,ʨՋK+" 1d Y >`vt9WdL'k|hs E {ɿH -YdH<>{HYnOuRi gD=fԮǗ/2_f/>ͥZ~(Քsdr [s$R~ 'uy7ű\V ; =F$ ̷'٫z n/$Kw"Q0@g #nPY}~U;Q}/tSs_~8X^R+'ew 4C *݂ _|Wo륿QWb9~Ζ Ǹq.szS8۠7֦uD?`Q_j:~lam/WؘĊ~k{ ;?No~$4Z /A-,`vzT1?@a>DGo⒗;?nC!8qBn'Kqlqjj9BzҢ?1"SCUuvV|4*Km˧Ⱥ,GFa܄;RfyXBG _Zy ;h_2o۷>)7h-'NͲ^qHVx5O5V+ݧsE=@٬dک#Y Zs!!ƆRI6pm‡ bڍaDsr bۈ@Ժ{`|21*r^(<E\*5s>h:{xxM.~"! ׬@vr;rWEN\dnyB%Yz`5yK5MTcDe[f։o u ,_yǍiK0GVҩ&>GkW8* iл/ 5`z&+rǭwy݌$%/}G>@aiZ9NS6Ŗ/' mcZe3bmDcPK7Y,fzRjW >B+Ul ۲C$i {(jn"ZZ٩^sRػ#M$Oʬ͠'JZ\#&b;k+en.snN,[JO]gG:]o)p7k(ʸg>|%l3ǯgi(_3e+cDOtˠb~Uc{Ů"%Y[1c4H=lp?SnꡚeFaW*| BM[ lAQVnw=bC߲.&12_qi*dz{{¯u\S{^+IjȖۛ, Ŭ>&Bh 'mGy'~]YYɥ1{rm;%/ 4]@:/O)/ M.`p{Y3_V窨Y}I8-Lout;Zks2(4^*SlhCkH4Q~zIM9M><<6伆}9扢#?->B7q- MwȭcɆ S=ij<=yߨyf\YxXEV(5aQ]Pީjޅ@̞L-5֔;6fېɹobXI|qx m~쥖}ukۇ$wMKoUgяbɀb1AnNxh{Tk!gu>}Zf3-~y2Y(R,甋aKT2+?ȹ@DQ{+m;@YvYGS{n!ߟ_24=ߺbصˬ^"CdC~m^EkxjW#u۟5.F=kb+_ 0[) 2ubW<\ S/+ssgfdj޼'CnD<ǚ_;}7Փ ,LGK!qBmHDe ,̃???{ ????gɴ|UQ>c15&BEp-Bc(L< q?ƲqdI}dI{%@D;=qa>DL>{.Ft ,OIa-ЩW?hu @e# 4&*ϻoU${.j@4y!y"U{U9^uo? p{o3e)!p9S<7qFϾq8B&t~|x$2g՝>xѢERfi5\ظ썗4^!u֭S7ٖ#b9vhI`IXWhܲ$j(*_UgCMw߽b<@z#o}%`0<˖,5CLw}W._+gv|+6{T7Zʐ;y2ixVtLv;b !Ԅ @Em̋=E-W$U]/HrѺm R}ͤwo{[6߾̦{<ͷ\;"|~8'pnYE6W{*70f2~$cɢ W6&ܪx[lc_~! 0][Ŧa䏏TZBrB虗[[#XD8}aa"Y`4gpm Y+Db]i~(?o9, p 5, Ao!Ъ^'t9&6XbE#cq!)"ϫµ Iޅ!q!XUn!r{sXt0\^Y)n3[wL&9?0*%<+͡ {Aa(@z G6/?5ǪU o".?څ3s=As ,^u}B/j#ߒO+bm;2}\h"Ṵ:^%go ޢ0b @z !SF|;F=eA)9\0{\5v8gYm4 }O s `AKZBrb 9KE{{U4ԆqUO2~4I VGart0Yxz=0f/ WwS D2̶t ՄHhjBN@A=8%3J D~I\GAĻ@|0Nn3[bKrg+9ޡ|wϱJ,n> QX!G+p V=6Zǯ"Lcx K2eiIk*Z 7O5L9 @衐Ri~Դ_|'CT ϵe<l~j5EyłLYVi-,Uk>\[ЉB%dko>Y.|iɰtSWP<Ϯ2GI…L۳Џ6'}3g U^bo,jWۼ: w J|(Ǿ5z=qlޯV7/FW6}/|⤘ gzFYȶxhŏc?zڥUH"[yhm%qvkf{)`vĥlkN5*n& jMdmX)YH&bx}L^.Z[v{.߬*W<4wUiġAS߱ʌ?,ϕ9Ζ 8+3ื .ۦe{x%dx!+Gvn[O< u~~gDŽO-qܫ;QB=SZOMJSpU+>{ʶm$L[ط/؏Sky&q>6ڗKp*%YWHW/+.v5*/]<&Vz'^4z=U81*[Ɂ=41ݲ1 s %ohJ gsw`nt;w/?,쟽6y2D ?ۨ׋O2S+f~eo: ltv9 ֶˠ,2e׮'~N =,Y~}lyK DŽ񼇲F^}l~$uEb&sPE\pèSE(n8U1Q6>'Z''9_=-jK`&T s\Ơ`K}KZD?M6l\JoVNwH⋁`aưiP6(2GF{+q[Z&s~?MpM]k˗LNN]2b+}Ϟu[̿yoxљG^UȘiR:}/*Fb5fWtef'Xj"-2!S,?JEO6ٽ~GPٳ-:RrQSQ,P,&Q1HGU VM91d]4=6|ʵEvZ1+=diX~.L,RTVJ =)~B?\)Iva6d똶Ec+94 vyp>ڦ1oNYg"؎h t߭ !BFps2j8mkM+0),@O/ ༁$'D#'r.j}e , =f+-&|tM)8菱*yႏyI/Kp  $5225{j9Pk_طRs9֢[ZFܿ0iS-FP SMΒ,\Zb&W+Jg.vB XGaӻlO#) DqȶL՜Iz1OOP]iλvJ =sWLY>e?O݅{6M{$Pݠ m/vJ.jp{٠Γqr~S~Gڽeq׵d>:Zݝ9^C;х,z(_{1Pᄚ33Wh20'M;=|Hgb3bH|*/{[rsRUMO9驁ʤG+WC̴P3(dBCh`3HRpOޏt}48 71ՌNQ&Y+Uq~Pa?D]zCD6QrO I$&xȕ+Qg]Ppr}MgN;dkGfcKK5wvo\'<#8 =-i xhr2?G (I_h)ŵi8~3:ڢ_9:F9b$''_|ws;WL]$Z$??~A̤T!xC󪑩+S@' @X<@b]mZz|ckLBZPx _-0?@a)ji醯_եɱoF/ܟD m=}nogffyy-X`=}N?HmQ;?4o NekеCF-=KS_zomY,#oMۿYwDUV`qؼ78)Z$`?u_kDElj@\cSSH9BzҢPz׎\r<˕h+rN~+''g٢kd>c:!0 [\;bgf<jGEHkX B [@0Dux zFz^#E 8TgmNf40Xys t jRQ%$}kz*lٶ_n^8% lz^ZI1`SֳmH;'~K=ʇ.&\3=}0;R5'IN"26۰RLhoE9ƙ~w]t 4.8\EYU>M.M xhҔC̓FDcY+gsܝ-qV&g6bMqoA\0ַM'J]%BW<xZ(p2R ׏ [⚫Wuwz e}Q;) t;qUވ*eMJSpU+>{ʶm$L[ط/؏Sky&q>6ڗKp*%YWHW/+.v5*/]<&Vz'^4z=U81*[Ɂ=41ݲ1 s %ohJ gsw`nt;w/?,쟽6y2D ?G%kơMOƨa , =`aO6iT I*D+ɍi+4¿e(W?ukoQ+227@iç1a0A&3K 9!QcԠmr4Y+ة8@x6݄rgߋ#p ̓?n# 'psmeY?5=35=r\"ß9]K_=ǿ^GJnP?Jcu&7,=)#\>0xlԬAԻB1}a~KZo:ojkq¤M]U/[<&B) WO5Ug;K ri-ۛZ\(M!Fқ e/`MMve<'KCġz"2FVsv$BdO<==Cmt裏;N)%̑_=|3f=̿?%MϦ?; 1ᦜ Rq]Ֆ6TI:=jɰ^e8ܛa WWzb㢄o&Z4Xvtlt)ThyHh/?9+N2l]CORρHS*g̽2nnjl{>_F!L%V$qHh%|~.oqCMm9J .l,سl۞'=MXl }~lC%VvQu*; (덻=% &z !p"݉.\du'OUds?@J܋9gXL+m+ƿ-\ǔg"%pkE?9k|C*_:~?8ke ~/w~ -kOJ߾( 2Z(_|y9'NCu2&xȕ+Qg4rO.] ulqhyl}yi2=tv׎v_kdgdC![\;0?pu ?49\¤o|J 4@`mQ/GoX/ͫI|\O-x_fWL*@NSd|\O-'#n4adD@cx< H\t7ZX-jio1-kh_4 @aI,|e ~W&Ǫp;h ?m3guݿ͛`9]$#ŷE^м78aZ$B`,MM~[^"?fX6=oGg=WYQvaVDHh^;+n3>>֍7^R=qerҟ;-NM "y iKC![\;0?033syU,Wyޯ̿7AJ:9xeѓz{8lqhx=#=ae2)'lWh|ujz!3$y,S,dkG uMP<͟keffQ+03C`9"PխIڳʒ 8TgmNf40Xys t jRQ%$}kz*lٶ_n^8% lz^ZI1`SֳmH;'~K=ʇX-&iF7fN_Sbu 7>p q)$'cgwMkQ];`6۰RLhoE9ƙ~w]t 4.8\EYU>M.M xhҔC̓FDcY+gsܝ-qV&g6bMqoA\0ַM'J]%BW<xZ(p2R ׏ [⚫Wuwzbk˩vo S^}.]Ri"YdaQTXHcTنOǨvی׮3~*':9 )y檪mN)#j~Ga^-=M@=]& I|zyp`{C}IW2 QNSMHW i؋54ORi|Yb\U˓<V'π>ri6o+,8-p69p\ z o 39ZSɲ$%ɬ'E<\/9r@둞s)IKfs?q&''^lڣL\M2tf?g^ƋtL(kj7 HZaO=w?t>C,juPHm~gݵty8*VK6.ձ 6lܒIΎuGx5ɁW^O&N $=| ֟nr pͪoslpC4H+8$g;=]?NKK7go&D4iXp|m~Oyşohm,mozH4:(KiaS:D1QUԸMkWL5ɰeYFKy͢2 #y|Z9sS0P}ϝ͏_Hdnzt nyJe֡{M*5JVD$ks%Cb d4tWl)vIˡ1[G1؆KZ cSN^p6q:?U|1!Q4v!fEРZho88`?S W{?Q ο)KsmY~ɩ+W5^leOٳ.r뒛7m^w<=@>:sV(ً7="ZIiR:}/76Y9;D2oIq/۠)gc_CԐ+X<=drB-gfئ5;+-5N\CNfd̞p~L2dҼ|j̥pqHQD.MIZM4ɋJc&dqtf`>g;!jL4z=MW.ژ&k;;o&0_`{qy2>'-yDD8Nq," ᧦g?ß4^_NKR$~#VA߰p)#H G_|LQ nf Gh"nq0u̺ӎc&q!ۀ fS= 3tWY2\[7h /T,RTVJ =)~B?\)Iva6d똶Ec+94 vyp ` WU@MjﮖŻ{KA /:m{JL)Zƾ|6}+Okz:dvA-7U\S,+gP7^:Сn79׿qKCh"ՓUR H[ ~sG&;mp3G~D'7WٓW.ܤDllmomVka9UVvyEl3LEHɰ\qmsU]g4vY핕 k+g34ǝ99ܺLd5[+kWg#sBB7ت _F!LZbEKRX~X)\ߖ/⥍rs]0 {6M{$Pݠ m/vJ.jp{٠Γqr~S~Gڽeq׵d>:Zݝ9^C;х,Nr' W^?sƢgZl[Ԅƿ-\ǔg"%pkE?9k|C*_:~?8ke ~/w~ -kOJ߾( 2Z(_|y9'NCu2&xȕ+QgUr}MgN;dkGfc[!ח&3Jg7kh߸VOyFb![\;0?pu ?49\¤o|J 4@`mQ/GoX/ͫI|\O-x_fWL*@NSd|\O-'#n4adD@cx< H\t7ZX-jio1-kh_4 @aI,|e ~W&Ǫp;h ?m3guݿ͛`9]$#ŷE^м78aZ$B`,MM~[^"?fX6=oGg=WYQvaVDHh^;+n3>>֍7^R=qerҟ;-NM "y iKC![\;0?033syU,Wyޯ̿7AJ:9xeѓz{8lqhx=#=ae2)'lWh|ujz!3$y,S,dkG uMP<͟keffQ+03;`9"-G==zȂ??^NIZ2O39ٻ8+tZB\IIwr]S{bƲ[#:& l CwMR+53L -̋"( nHM`BeB 1Xtٷ۽=I޾<쳫 lƟ.ZEe7<+|fiש 9MdQKiܱ[rI{h/>G1\a.6j^ 9 ź7cЮʮgXEg>C`l0Yv)ںtkҪM6{<s8TjCn8].uZjM_-{CoepSX2ƺJ94<#,}ߠkZ&'揫Ӝop>ՖO( "LoYxfU˙9#bc-j l20o5Tk[|SuJg^KZZmCngvq@}8VLr?5٭SoOтy@&2{wGqY$3S8bfDsv>Oq:CƵ[r#{pLWTn]X=_y|=UT֧֗(O7G1# 10:bhQv3[|0l6z>AnYUu7产ӧU+)46LU-諥RL <>E|/VʼQ*JuΕ6(z]|xd6~CƫZ^=id #o(l^spXRQsSRg>c9SEmzTiX.m]2?q~ 0-K`9?'@Kc]^Jlr|G7~=U~Ϸ|iiNS%窥Mm4~|`W(E->kCF?*~gG5CNu$>;ȏm;kLޗrOm{f;}ͥ@?n&!.cV1UK푋CjύpOJ6Wƣxw"Q_C9;[mβ.N|!E||?+OPvZb5 Cٮ=R3}yp-uo/ڴT-7ʋI])NU]>YRv"7o&5]Mi/(@hiUNduXRryTZ[3?d?Ĥ]P~%n_9ES۾=ohžj˩|msAh='>on7oooT:]ϖT֪?*~7zn1?9Vk.sKiu*VXuR7! QCeSPcKrӸk} Ei:s%[x /6T ~& `rsgn0>1~ʣGohݡG`Mů`ʎ2c-#tI*:6}VmHsqq^NblSt}ukG:q&2;B,ޑQ<lDo][OUQOg1O}t.+ݲ7gIKڪӧ_]VqFsn?O?{xG [d4#?>q-i]C{Yw4'^u-VAm;)}ץPL"?JT6K¸)G&\RJΜ:jw `86XŔ˗sڛ_,q ͷ?'?昹-ҝ/u XtXה<޶Ů|`yo>h,X|sO?{\꽊 m˺G꾟 _+_s5yM~nmYwv E2%%%eeeQLh(:|pkRA(v0}QLb Y]D<d(v@>D~WyEa,Z& PJb[>_i=ot햽9+P9^b:·a]eg@)͢ | @>` Jk?+U~y#oK@d`wL$ߓ\ LhHf>pG 9[GOZsm hdiݩ]ES-ӷd_Җ[sJJJzҿ导v.em ܒ5:|p 粴m bduݩ]ES-722=w}JJr\}|sswmG<<|)|K׮ҳmYwv LNN^%'r܏_1wRJO>bŊ/uٗm˺k+ MLLNb"@K,Q,7oIAFcmKb+ 2D|,i^Xeٶ;䟌*넼@ \^}Vv ljeǹ#LN}>pj[Ɋ}8KE]ڶٹ֩VR_TˢR汣;U7 t a;p2WH.Ob1?7-?qO|uT1r|ǂSowiKr]}/\Z]ni[%.ֽxۮmC[=#豖(/$ބV;ZOY"o\6jx7g:o'iMQBT8FULt[p]霜 )bIBȍd;/[O>ĩ|l27~_{9-}.LOQnۥ;_VVT︽ק⥘x8@CrŬ?vUX/E /)vPּܶ\?B\wK'B~:%vR+۶QEվվHj9M毉 A\lZ3nk}£8tIsVͩE5ċ;8 [fnY-f}c2sv%i{,}G{sv6{nŁkDr&C \rP(0=z8'l1?sqԣ ;? Q9q>ucccn/ٌ?\;nxzW'^/W̎ӮSY_bs qsI{h/>G1\!qΗ)/7sƮy%/)ں|S銩7ЮrpSZ_k>jȃc1(&&ݯ]wG.QiƤZ0% )5O`SÅN`ª+@(*}ƯiigPО`?NsT[n?40eW-g#tqF-|zȘÐ,R7zL+oM^+z-.ij5^R =Ł^N/*բUJo.>B+ڻ58bra=!qYWFߜ->,^G]TDt;!P{#zn45X[8&|]w_kQz|.ݎSkR{Xf̼mLLyVǃg"ZK[L;1${\ͨfDh#tQe6}ΈNn+ == bʱc2d14 崾9?iGбȣl/75݆n'^r:z34Tt[ c XE7mس iir ܳhwh$kk眙rto^k.]|y% HxܐN{)~e*K,Q,wN19>1>S&?6՟>տk.V{7_O_<)&Н/dߛ`bvw5}G eeS¶yO~eÿ5vԶ=Fqi|/S8 =FscR-f9}Kq yJW}^ yU+mP:vul݇W3z>~FPټJ6\^I-k6!|rNeҰ;#\3e~g`[>r~ KcnJlKFoȏo?(Q'ۛw7?߽+۔CC$M[p-mZ|ODB~U۶3H:VTRڇk of|UXeY5|X]p ީVTq(˘T˙6D@У7oUG(-4w"Q_CGUҽ6g?jQ)S.BWdmO)\ ܓU{-zh 2m=ܺA|pp|㑻;GFFm|s{oYi%6T'Kzx@z=2M_Z'}A@T1}${ywꙭ;?d'7:>{,<*# <PLL(?{`ݒ7/nwoW4._S&ԋ 2V~Cjp$;Y鬿2.bñϭ0W+VbԮgKQ)2=j4/.Pb.A&+^l]+V(")I1ّF=:5 {oh 5H[PiQHysÓbz>O9&՝m˺k(|`(|XnDsu~U*{Kl[֝]@AW_}ur^ymׯ<& K?}_7Pٶ;"~ټ_;qo[w&4e >Y5 _iP(?X&^sRtQ."O2 _iP P"ok"0`-`(z%XO\毴7vޜ/1 zb.`Yf E> 0\Q޵ԕ 닑ߥ| D2;}&\.z]w?[{&4d3ԣ'^-Y߶GԮ[\^v/}qiˎ9j%%%O=ob_W^;겶n >YsYڶGԮ>{U%%9]>6 ^T^>eSbo%kWWQٶ;&''/]؂\ǯXn;)'_b~S{ˊBpe5&&&'c1%($ 1^kTXLTrzXXn>o4/],Ѳl[֝]@OFuB^ b.S߾⊏[_+;]GN\&',8߱bEy>yOms)g:uN{Kڥܮŵ[}̭5fWMh` ہ#B>py|"w_iC'C\EԔ;/\j.. Tm[[ufEI[^Q-sֺ<Ժ%S?k9">BM*`徣%b&_|εmg:sVs(֟o{%th}NeSkTXAQN%וɰyi t-܈M+_~sM*(sz3뗦;j˽K=SvΗyzESpG6_iFH$ܳEYFy˃k޼)—M =14{e_^Y.ȉC[#r>#\B( 3i-J(f,rvӍOoQv;yZ4|h|T3CGx)&^"ТcY.*NŇZAٺi 7h^9Y:Xg=zJJpsȳ q*c[b wm cLE]>_[1ȫeop!k""C,1̟@@}5!]Ҝ`snEym {.N1NiCmsVYXG/kIڞ);D2TXܭ+4.v}GW(k#EC:}1i}pVkY:8ֵlWE<@s+õ^xd}<޶\LϫX  AmB{a:YSmٻЪO(gk_SZxq ?АR}mJ(틾N3`b޴aZ"~{3[Aw~ȁpVݡגygsf~A>^Qzy-;_tyll 3x"asCʗ>9{nWק9,/D9 zv{)9N0n;|Jr,7EqpF1crfwG{FҟGn1{m*6T5w3kZ*y]{`?"bVW.)+C/C2\Y=~Xz ˼Lfn4I=<^o횲E ͶFe2r6|qȭ">;t r'k[g`k8Ld.D,Hf2 zq̈f| tkmkdF2-7(_p{zZ穬/OQ>:1# TxmÏ+5"=CnRFP`vsƍiVSJ*n[K3sSHil4>&,/:Goi?.!OjO1}2o=JRs徣 Jn.b*{WuٯJb75W܆++eԜv&XTaީ,U}g~K|f̏lry tXsv>CGerэ_?v_ըk?p-_ZT /ĹjiS[5IѽF6/hX_1weģnm Sf(oT]G= UX kmTo$V+ سS1s!F'} +QZ;Nz׭Rc6gv>ֈ">exEp'N( ;-1ey|QOۡc ~ lb|ݺ w7\mZ^GŁyWN.,);gylsЮ&]4zQ 4bHDӪwN w~:QO,Li)<*ꙟ2W`xbbR.OL(?{`ݒ7/n"zm_7b_TZ>6ɹ KO1UQ+me32ܖtV/Qbϭ0f4vjdC+:eԕt+@gKj"Cڣn`z밚?^l]+V(Z'IE˘HӠי{,QݢExT/?o}oh 5H=[v;WW'=xxCE>rT$n/~ nWv<|tk(%HPyvalo@ Ur: g떞;;[; /Љ3ŗ` 8?d z`ߢ}}?e펿겊 3˝wK>8|Z[;n%nW^O◿pO>ͺ'=>ɶ͓=2>Oj|_Y7 fIU7Ȅ^BFz+BrrN{%UtG'ζe5j>`7~4|@,\zy꧟=ugJg~^ERj<ۖugPW_\+W^~ek&O Tb-ή_G6o3gsܛ/֝ e{YGOnM*b#.{>/pל@,]!ȓb#.*oڹ; E ^I,c+ @>| @>|Ȟ+R]RR6 ],N>m+ ( >l'wOc>Tv7Gznyf^-{"5`)qBjCjwVFS:O7%£ısu8aW_68ӶSϕ`^:IxOF6Ϲr<7=ŀbEzԽ~@߾mtM8tmh1K@B?|R3)L}d>&j{*gM pD՝m{hk%? 6]@|)+`{s,&6ggFD:,!Dhy _b83k6뱛gÎ@lU Ӧ%zmxѡu%_f֊/%k媺ӌ`wl5cD$uRs`s hPi7HӑnGԓ%.w3g{Uumt;2p`sZW4 犪;kzzOVgf.if:tvG ީS3ڭ)2(=A>ߠ%g{ϑ!lb`sۦĮZ^cÅN p0<(w>'_; "@T^E_gk7hoH'~F^"90=F9SdH*äCÖQl8~Iާ́9n_w6`RY,8mbG[ GcwOkwߑ#"A% L~nue4N5eT7IgZKn&T 5*6Hm?Uj6]~iժ&?iTy; lΐX<.uexZTul`M6N:*p8U yfl ̼XJhrliKwAYv{Ӹ$tl]EM K'YG9F=W8#hg~DJ[[ "n-jr.YO)ZqBD|񳠈=VR=W&.` #.nvпS&u"lv֛lݝ.#]bV3kʠ.MQ2>,cjt ۜ/T ׈9 C<³;,Evس4VC޶kN%<&%gS@>BbpW&P5pABmFEq֛V Iˑm0!(yԖ+sZR:s>yN!Iz3xmj&!)m\\Ri$ͱI8iL[jݫi1duO\!;a[]Iy ug8tvǬ3ح{:wEuDd#wSU'('}cWڥ\{bv KjGc>~n󷝲n گgkn8t|U?$je'xJ9+}uڏ\x{yEi*4^(7g[|mEŇT}:XRuKt3[βz)Fcw N1zܟX ksK.SΨݘm$Luai]Z -Uڽ?R?Ww,GGzOkwXѓSugw;g[][ 򸨮43=A!q}ב-f[WzQB_L\o? @>| @>E⫙܍^GHZg{g؀$bS_fr "ސGkՇo#g6 COK?b:XhD1M={` ^jyG7$%&`dXk o0(R^^cAmAY2m斶p"]#j mGQ9@{}*V}4=SHuBOg8\Td9SQf(h/N;$mPDdKp$(HEy3hN)7c܇CQ*)Z9ICI*ZNo[0#򇖻wlْx9] `_5۶H-J-t,t{q=6TF5UUUu6bF!H_T4UǪ?T;HU:Z`=qUtj3iUsM lN2O\15 /ʫ jD׹WL93@ CJMS&o֕Ŝl&Q"ctck7"֭?{Mo *y<"NkvD;3\H .g՝nHOVN,Mc+8 f9XWه^6C!i%jC1ͨ5®ľp~#=jS@=?'گv|gʘ[vџd/3p)@uq[}u{m\Ŕ_fe@y\k-;7h&55宱uy6+Bv7ꇚf1y)-WĔU2, lH݁'[@\I}[ͺ+tN!@J@)7 q} @>| @>| @>| @>| @>| @>| @>| @>|| @>| @>| @>| @> @>| @>| @>| @>| @>| @>| @>| @>|| P ?@IENDB`SABnzbd-0.7.20/interfaces/wizard/static/images/favicon.ico0000644000000000000000000000217612433712552023537 0ustar00usergroup00000000000000 h(  4 o \FB_a]Gg FfA]@\2J7OFeW5Loi]"' 9T& oV#3Ke278PU0Cfkkgp+='8lqqqv &6\2H>XgAMA a IDATx[Yl\WSNH!mHHIJ*D( Q / *U ^xPA*T6[&v/%=.;gvS!rι3=h[ɗ?xSPcPIgR87L1SN$~y.?F.8gʠs.^C<5#ܬ9/O^q=R^AV/$lŏfo^@Z-"Rolo˹V=1\zG >tU5%k*o^O9<3ܕYC =xM.O }q!x D;3qEF_ ۓß_bpRq&S8ƋC5!Ok2?pV 7sQ$Po&6$ӊ&7[F .W<3RQ #O&ϏcEG |4y '!JL"@0 "? ='xF &?L2 NPNUL:5:J/j#7Lӱd} pXPSe6O||8'֜9gF+3$>M[D cc.k+pEGI$ DmH&Hs^f>Ynp_*W" 9> <&a|U ,nLBG"yL*eJXXUcVoi^ٺyrlQUztշ˦ylS=Y\eNijv:yd^},(=Q .kw(|J}2k*%idW%1}s/>֑F  5?\ L6aYh @Eی\E ,91t֢${_YoITrKb)F(3cڋWQKj|A&ޖ眗Ո|zS}bAR?gaъ(S-"􊘖Jzh|鱕 J􋌪 }nU6m;07_ |7jRO[ċkWD0Gb Iqt;~7-d55'( DE5L zyv,Q QoA㛴70L^5: R petCK4#~po B{vsbO5x?m8K' S\2pzsë̔`;v@[6 =X,X^+ɚN`\|<^…!-BYv ,0 ChYG Ե'L=;yj+4RP#uUea %􆦘t,0g9S#JGv mԄ}hn>Ϋ ̓bC/rlVצ @H\|IS*o/np oq~>e_~l~yF4ُs͍xuxAp@f:b/y!z -XWeKi |-qQna8B8ma3g1um9l<. gD^~cǙJ=\Zˑ`o9gg|!j7R߻xY$/%s$e$s'{ȶwC zʄFX:.~c_eKkAH1ƛd;҆'>Ve[1A\bli>(zB?ck4{b^6>L*\dMX枛ZH@݋r[>n/½@ML,Ʒ6ygA@K@ 嫷m^K/Ud组'DIC1 K(Md $HŰu eZI]-k toIF3ǟ Ϊ_zz|}u#f4LPn`U#0!e}oKYzUʖVͮ1| ~c3$Ki%=߉޿ -i˗k$E8q^&ϻYxtt_œ_we.nBAuZXx ZP=X0wV.(lo}3Dt% M7lzY&U sڃI"LIENDB`SABnzbd-0.7.20/interfaces/wizard/static/images/plush-th.png0000644000000000000000000006523212433712552023672 0ustar00usergroup00000000000000PNG  IHDRsRGBgAMA a pHYsodtEXtSoftwareAdobe ImageReadyqe<j IDATx^]ŵKčwh)R=ǣ B"KhB=x6uw}?ݻ Lw3g̜93}&8Cg5|9s(PPԄFs. `tvCCwvC-w pPYBIDG;w.QWWU"((6]k{߫-ߧ0 [=5yvh!g?:8i;uꄥKGBBB'SVTT ,,  }4fV:1نy6ڃf/^_}*a;pСCO_"##[$2=wtezNRޘžm; ӆ}4i~o[h _G뢅-EReϹy^0!x)Ӓo״UUU 1-?{)%G*,>Cfa#aGDD6<<|¶ߡ0 )lwy&.7)LOؼ0ya[6lJgOJ&L7|ۂ8o*-t{yaݒaxrQa3qUx$:HypoKl\UJmK=*sNy$R2K/Ԭ#P2'j8,;JӕPdv2 Nwk,aFGG7/ S{*89S%}OLa1Jޘ^ml<Sqt:` Hٴฒf8W||<̼~"F\gGÏZFGp~2|tDE9{nsNQQlm&t z|Ef~yUli DaСCEVs_oqe[Vbe69Gί҅´5 9mOJBx+,bA zx6l{x7Z*ϼ\D˱WL[y1Q.~Hkzj6zkb6}=RVހyCI곸բk @QQQ;pJq!oFc&>on[n1D{8yw^O/_=aT4ӕN㦛n ALك.ts57l{؜wMzճ7U1ǖJĉu'l@ذU`ATl$ *LSتX$zl[ [wO|=i`f{ara(SٷI>V]_V"5(-.DiKkhX@ZYxkxiD==1:i)4*u<1<:H&DW^w~K}%?!72f̘ȑ# ~Ǐc. Æ Ã>{wyg3 yNxСCsT>7<ٵձk0zna(E^qPTԠA!OƁ4@Qq꨿չ󨢈M0{SOꫯ6\xeo&WLly?Sm1w^ +cqocKrETe ߥb\s[j+{@hE>rS1u_ '2h ʑb`9H259o"ɋSw)~?bt04?ʈ$D=ʦN6TL:ۦZbM?7/ex5ٰms`ny-.S PthVt-6l'-TJS%~vSQ ذ0񣻟66^ ¤IC0`[6еsTGQ]8qnˎk-\"vq9ք~)CZ1f?1-)))(..64$S#7/p۷o⹝VLM̺ytn`;0|VY_0\zͅ /ƃCC{x,q^֌C"vt ]bW0#ɹsH;vO>wus%a)sw\0x? %!8h_z($VԻL(rS+M}= nnK/֭[}=ټx}Ǧ3&Mc6KqjRt>yJf4`?C\t1zːQC>XV24š#A-j^2 wD"NFTwϮ]QUG%d|ݹ|ϪwyGT2 U9 GޫAŅ}3]Ta0U֛*TTu pVO؊.P< _1'-d|0)3 /*i(~ )⿅GeĉG"xB9_I3[㯒Mhah:P;SYP JYxbˁOv@K J:+¤jU$q;hpTtCB 7߹i64?B:r{>qC)*WfQsDia$_df sb+GQNAl͵ٜ7G+.GB'&$VOwYQR"5드ıcj8@66x4[@ƜiOF74Ո+'m N*ʒ(qg;NU_ud=˫T^r͢@ lP"QLJi9g𕎜\0 0z-MtnRȳ %N`5g)`.-@j&!Z$ud'>)Ut .6<9vիe3/ΖMmjҕK_f2Au&'(b:1%|5qqQjjHaOW3 'l1 nڰ_o_-JWojuT|=>6-"D7C f<,dCadN5-s,6ZD0iCXoV5) :H=-aq|UNǢt^wBjbН@BΤ+]W#M` gm%落ΉKS Ca+*LudjQw)L ZP8.k  SW2'LҤ-|mZ(L`F ?IH8q!ث{7cB7oڼ0>x`<+x"*:J:r1LN?|϶YYLRftKE%rP(g,*+@@mKi_Ԉ61(Ȃ-fY ME$v&D+boS-qCmKk+N/SlWV+-A()-ui>|"͔Gd14cמyUh*'EYLg8؝Zh34wfk^5)I-1y~=0kx_AXDKbH(;U8ш<4T`Q*ܻQKg<5-aq39تT H+>+q5_W:鯿hr8m-4h_ϥ~1EwB4;JQfvS :ywGMY?GZy#sgk]X*n=qR؞'G^y4Z)6}m~gȪs-{bJE\BYq;D; s@:J(p 4!ЂsyP{̹& m&4rgk[1qpX;9p(p\hͱJ , 1r/`1@ďvgf Eh 1(eP)Kď>cN,i|/'ea@(E+'Z?j]^m\ӌ>g_RW7`%irCDؼwzwxj O.xh]JˢCK19CУt.|O7Uace~)av28cBm8FaԿW=,Y.]N4ݑP37 {\eePg~C_ZPW.BTxffp,ߺ#t‚E{q]Y:Xp:VG[r,js0}r%šcTDƊ]XEXO_glޒm+ ww|6s;G(;:y^|#DwSQTDvLE}Dt_rS'7FɽqIm'?.y>]8A}.l$,0P$"BE")76>R gcy\cfQ3[r%^~e|X%;vc}-+*qΐظz/Lc?P@+! (v’%,yq 5+ 0WJ +ɓ0<ͩ) iz!sLdƌUk`'q%Sp}>k D\N<$%"GnѸIx`%Gb_?$&e"|f+Q#G׶.A>}.G՗l 3[XR ǛO_͗Lt6WF'3[}@yl/0@v`q,AZΐ]萘 pH;1=0 Ţяߙ>~(uHTNaT_lE@e9J$ݓdgfX+g_ԥ{ѧk,B#& >dm'=I9[z.t41L[#+[ %嵸W &yӛF2?M%YؗR0僷"FdiDHPP&y߽BF[YUm::r.'KzʼnH,['-K %x%K  B"en$5}u{D`#w/\ilp?}.֬/ w);v2+*,Eg?Ӯ <2L\Lަ]]J5њLx!aFO;PKDIja:I!uRaE~k#!QqF.**Ctld'!X1BI Xq÷QROJXRQRI gqy Wq.'C&_D Y ʋ|*X] EȌ*^&2'sq0WL.Ar:ql]_96SW@%,\Gj%lB7;zq<hl3 h,OUh3Ht}{IܡC/A-#NP3NO 2!Cg>N*G?IoODeijf}W"Ÿg|ÿ3Uy)A-ňÎ,ߋ=U?O_!\p`Ӓ9K[S#WFuܕَ>ߨ9Uxn?lH߂wX| w jf?Y\juB8u5Ք7HʈU;J "%LV ;xhFGH%" XMMi%S 0m)${ha5!,<p0wiykE/^@n^cQ)Sj7PpmoԈXr((q_hZd_;($ھKEaEԿ wXS8m :/yeR/ 5A-Ԯطp6iexe1m%FgÓitIτrmMBxx$z&;00O)"wK\GlQV? .8{ع/6UOowuL[<sVEZB""+pċ)kgKA&'ݓu<;g~ IjjѾ;Js;q@o/̚1"T<6_XG{=WE@hTwP ")?.b]Hp|'2 i)IjN#.\s5&3eֵXK|߻e+fcMYo\y,c1iA(i jil3A-u[=l;r( iaŶ#A-[%T1~h:]q"0" |S\й $$W}h(2kVlGLm1slpv!PtL>[קHq@7|P?X EmhK 57ct8};]IPK`}eZ!EvXk'u8c :NI4YyBB"xMd"&*f]DI4QU.ރ+INПIN4h@*cţDaRIIQINoZ",LtL%Y/LG'4 Qؙ[1epIXO~92Ks*J.}~ؑ܄"w8T*Q^V#쬃*I/[ %PF8OAP 떹bu텡UPF}}3TK %ktӺjo='B`J~R!j8&LEc!b1hj"NǛ~v񠫆 Ғ_5LrgZhᳫNo |)jGgAh'=/ޟeg(;S jO tPhǩn;\d<j2Y j6L3ߚ[ewԺlGsB8sCK[A-TxYwO!vO=jPK$,./FXp|kKHlJJΉbJx#мLqaA&OOO7A-̾ ԒvP ߝ ~z :t>:ݰb߇P jFJߞճD H)\N<kM\ƍ@d%!"9 ᾁn5=PU #ſpCW̑jGED"BQ6qxš&J@gj(*$+,4R7çahʑ5HKvŢ  TyoǍ7hĀguq;W̭EޕCx{ƗXUW]=?&nsz ATNyxM_7VC֎*Ɋ<cwcX%R/I+ƝS;HN0E1A\k~8eO|z;O*II"7a敨B%i}Psѵ!Y(Ousa H߀D<,R~aز}JAsP%%e~NZ~&\wTji_P \ *"jPA|isn~gV ؗn %LFQAT Aei%#Q+ bTWI}`:G: U#Q*lݙ.)iAq)4.LEANbbC@zNN>ĖEmjo ]J~ѭ;bYԒo⩜k+< aHuVA1RbP/ |VdPR15Wj¡C%1έEO;1]0mTPVQ0֕!T˽ɱ=ETj5 j ɷoۆߘ j6+0ْiÜZt S>De K#َ>Ƣ _ZY77;G邵5d b$i+Rbj4$` jY?~Z؅~dm(CQV. U}pD:2g5YfÌ84UK&DZ_PŠ`S%Pj j=A-5REZ‚$PIPK"Y*\%$HƘfd2o<`2%9Qb:,D,ϫxwJP{OK6g iN, -DŽgH,d߈(38 9o9s71%&J۪b9ޞRk[kr9,Vjg v">k wU`ٸ`XL{+ƌRYxw!tvUj)+n6R|ׂmqAEE} ,S00W-8|:oOBh|" RT}0LB`c}eŪU燚|js҅|%]i*HFYE#$Xfb j9˙=zFP*"ħ | * @BP hĤ=XBYDU'%9 IPHԔG4-N@tF#"< 5xw"xȵhEjrⱃZhO'so&vmFo"vw"}FLߜ;Cg+<7^w.>}5qx}vH ;V()xOl,= v@fx;B.|EPK^f$G:J{R4) A-nX-A-љ޹ $xMNIwmG=F\r9nӈ!>Xj?Wi^|4eB e:(J)lZVEF?/+qOƣ"[R{Q ~ jIm#0^d}TVl*EeMR)Te+Y%Fek@^V&: p)R:DTJKq* .R2#~t7%زCbi{rM{ѱwI}L^()3߄~#[*tsrʐ(m',:q9ɉmάȅ$ CBiJ' . 'JPTRr_m Zq/_|$DOs]|FL#%6bĄkP44`[&7)ر :Iy̭N^{Ls%^]Z.*Pgu 8`Hu"A3{NC, ٩bpI@GDIK)&A,&RM>˼ ]s UI}R _ܰ ̠*hma|oA-ZquCZ4#E' :vmP,@+Fi,e+z [O;1hӔ1pu(Phn6ѝf</ɐ&םs9S^s<!_6GfciOw;̉M{ƝYH=`ÈG"N7Dpq(p(Њi`'da~w;+arO‰e姨V,:tv6"43r1 ȥCaR2(H mb&[y 置wb+ו῔.qH7֢+lW(~ƳQ({>M#0ܯp]Lt`O:46DyQ[o}i?g쪙`_+9՛j3c7b1dnf((OX(MjfNV nQ达(#|{1D\IHԗa5ȭB)S[5an@ݼo8mpo,@߼}R: c^$Eō]~~H`,[ B\(H5W`:?D_ n, yJc܌rq/)Da,H2u 8,\ BUIupQxp7ӺОR#Hj$RbF_Y`CX@A.;yM//DAېbu%@_5J*eA!$H)I/1F?=Ȯo. (\ɨ}dj蜐 UW5sg!#rd5ޒ$5b2)j؄ *ƒYh A}% Q>RJ R(cHlXם[1 O膹oYߎQn% q0hVbl|2臷i Ïr92vÄ}<lG@L # ?Q1㧏AEtID)X`ӂ%r0*Iq ɗxWfq^ eH,~Fw>߿ 9Iz(nr0F_d(V$D ?/Ö~MY;//CٸgSUB"s1zX3fLs /eJ6"%$S/=-])!OIRg4brLM6K2y#^ω=ɷl:%pb,Z b]:l۲waCEԗGV]XP_W#WCmHTG 1yy8Jz1c1$g.6WK ^"H^슣Gfl7߈2#nB)dP?,&gfci_:J=C*.]gWt7g:Ittoj6٦2v`?|uSv@zM\s;͂Q#S0Ή/g3Ǡ&);|>¢Qrv%=ȈPF"&bz@PhWϰJzA8~>뇒Ea}鉢x(\p0 Dln(> H/݆Rxr''G#bב^ "Kmsw3ѷjpe!"&Q>Pt*ifCچ*SQE/&% 6Q _> 7~vS. !7LaXt;a>g0 $W\>W]9&!d'{Tz)+ek|0Nh,&zX!6D\T>UE8|85sF`ϺR,2M=-eKïy?!Җ!7IY=GO0?rI9hɓ4 -}9~6B DŽr^~/^.5JqmנR !1$ o.KAD5cK^/a t0(A RHs{w@dxCPHS1Q%"#DZ\ 8XO,XZD|WeO/ -bmƘooGx#gv*xn&%Sז* u RO/J**j+Q-L 1a wj[V|9#&w@]S W&v>ыẑͥd0dJڪR D.5^~c\G(+.5 .DQM&/sމ_v`*Zw/ROZP#Y4IObV5@DHFH)n9k!_p/R2)e$48Ph+J~]u%|Z-2V),8@`U8/RVƲ(?9^Im#*xrfԖń}B_E/DM_+% >[GT0:WBM4uTعWj=lRHDvR |a#Z+4^ Gt. 0L"IԊ] Ond49ݱ{H` `>}iKJJ`NpPs(Ph>}z&OܴgϞ& bNiwY[gmw-a(,{<ʼnDkй̄.|ċ߷ucG3U$#Amԣ}\jμkSZZUtL0HchޣC#Gޯ<8L&L@wYu su"gt760#L͙҂ڶd̯*F. $Q 7+ 0/=>.`gS6U_%P} >[%_K 0Ica9pKRǂM hUL1/Zo6|I$J42-s"dauOwz 7"C ᒩLڻ*@q801DwbMu vX`'wĕ}]V(ʭ} R{vUl|I mاJqh!؉ҢՎj2Vs芭"NB!0IҀjljVJӡK*#*ZJU0a*TIudPx~f '~ϩRj6Ngdr. ׯP1߳&|NBͶ Uף'! W)V‹P{=nhRaqKL@%m_߼ %@ym& S7تPC#ۯV;&[ [SO!77 3׿W_ dh2׌30j(ø(iϻÇ5^kw}7|M)1۷Y㯢Dʰ&`IJݫd ,NJUFQPJzdg^O)y鹉TI#1Uz Y6<:Fu؆i㭰mWx03<)O|ۂl.ZZ=_ռcĕ9(b)ss76StNv^Rt}ʕ"o[,[ s5=zyÒ=f5K/?y 9x/˖ ?~wR[򫆜ĻBD>';oI -u BRɮ"ߥ҃ #ͭ0 C[&i &F 7| X3Й0MQg"-fTw-](y_vŏ? 2W'.wRe#Ə>/C#Gq16LI\M4ic6(.MX0brB , tV|Z3;;9d[Jv+ϭtUqP<#sL駟\dm:t{5}yaڴiXtQeeeq -( DFFp{ݘLocsۆ2;Mf\`}-҆٥6=SRaIM,(C-OV} s [5w^0VɆMx7t{zVIW[zfMgthG8i}РA{9XdNnĪy@JxFg'uWS U'l :a72q9mڪ$,giۤE>㪖^mjc'.^Bjԩ;# <գڸ= [O l}ƆJJ5JD'g8x[VEC Ẇř2/Z1:wLcp:Ӱ#jfR JfUq3NR{tz's2Dm|J(f$ :E|:<ϊX'\ttQ$Leld~VӅR#D@koD*r!LmuQ-Fk?89TZ0 d{D|y`k`3ȍm"$l?[a-ݙD *vjݛ}N۟`Vs{dPV7cle+Y(Ϩp]q&)6ֲ¦& i|as%&0ya6qVLNo74ȭ6 h8wKͿ盼.O=-h/a9^u{!<6ld[Oؤ[ꦅM7fcX6`۴vhX4/ 1 ' wbμ_C5 Eu\; "6'Bu5b󊻕Sޡ@کԏˏW++0}$w6gv7L͖FL6fb``Xy>ZU]xJR j2HT ]RX0'\s&f[| lK) ˶_&U$li]t&}]0yT|BLNI_ygZ0]Tǂ6c禯#WZ-f^Q=/qjpLZ.(92=/a }%eڤyCf =šk-W"J>-in-GV%'QL1ͯ1-?KJ`0v#Wd#` ٜ#ŝE7 }ILV27ffˆ8ظ5ge[#S3E& SsKvmkM7-,zPi@|&Lg݃ʹp›Vll`kn|ZbNׂ {LK<[kf8Nc_eBa*Rە3o?zc ,:7I*mbӌlz FǪgW L۰(͓DIbL3)9{_'uMyyFߡ+.m3:Lp'〘*v9̸dkU Cq5U|mw>DŽJu&W؞x#E\xxW{=.V;i?^ \8xoOyLgjtW<ڂѻKD%\hUM]DKL^0ۼ8~8N ELu$=cn5{mL1s%(i pNz@jxȴѣ9 g:̛7ϸN0Hg?lv|\fcȻY"7wy GJ T j87_#&*hf: ʿCgB/2]mu+%D&'D˕Rɰ]b}ӺuA6P4nzu뤖(yXD9"~"h^tahqP->oذ0sϞ=qf̚5(AxS~-{|= 9)Bcm|ڨ87oc7w;eND#9X{>AB2șկ~u{1,Y{̘ ˏ?]`\dE 6">Ac<Ga͔W~)H3[h 1ceWx\VeI ˗jRKM.8_dp^n p\wĉ}4I{g5EF2lԧbv"eJeFtY <|ZW ل\[RޯRkMb/PM\-:%Ӭ$)xghu)(醁UKTLVm̼נfgg;;o1L'-[%K.ǢbRLYp4L]/>K7߯E`x-R0~%{0{T̝0}$l^Us+@""a~)\œ¡kƴ+wS?EO1{ߖ+# '(R0A+?I yF@SK,)!~A9g1&|AI$q%"D|ڱ_+W 두:7pʶlaqN=5 ae1imW_ߑË_{!9GAr\$`p;5W^^C:)]JSz1 1pϓ)^<ȋ ma۶mUVv;~~ ȋy$wI*UhK**du>nj`^\:q .Ȓ]Z\+]]2!I(>qxFb\;}R}1o?#">QR*#2ЛW1%덙یf7|>0`09E)M"72%bQqnƪyQ6"rr P\\8֮2b﫩qКX2o9Eá3IDj;2]&gdGct\:R=Dk* ]fkL__'eAι.D4 Ɉ믿eF:ڵkkMI@N8/#tT|W$Uo–Ϧ@€X[/*}/uĮUQֽ|: 9ǡ0Ů(X]=,U|x>isWᜋ'GR7Yr#g"*qH{c>9H똌ŋ֡.;L`k%EmܸQxgMVzPBL ҷAMdnd|;!~?tecz!61^tQ1AR;** Ii){>Kw#ӿ;-u%5l vFǁ`HHn]F8EFK!./i>C#C"_CUO}G: 6 -2 wxTQ(q[/D%_E;2RnYخ#1`hR !H Z<ݒcҫEspťeS&Li6}OIKAi$Z1ƚJdj"lò`͊ 脽0?Aѧkda vyMϩc[ĕ^+^ElL8?8gJvkZ(Ɠ#b9|{M^0۾,E=_Dpwb iX4!pK=1礆JL=Ӏ,J>2d/(}9) 3 3{0 eBn,E p륨XVtO~XnIR-.bm:'PwkҞN&08!sr(PL@+F'kj쵱:C8 )ӌA9해e^|F3ÞB A^ooH|ք"*S\9EIKfD$;{etfٷoJ8j7G'x b"eu Ji+?Auٖjo|*p( 8,{Nޘf;Z9{XX<B3/\SkO1:{P\rF 8{lGsbhl?Jg#c,Wd0J '̂考Ir(GeSYe=J8lIw"d"^6ʒ>xsJPp0g!ċ9zv Rc)i4yx[ >sgT%rzs{=,d|x"i)d#|d .neG͕nDU`Bo:\>¸Ly}soV@ld?e p..߅#'/J6˭;Q<UU=dWei"!(E/k aF!ݙG^d1q(LxtWLOr54(o\Dk&uPyYE쥩͞<;p:U0i༣?9H ~szl 3acϹá7^Ew=S:P)ѝP[@N[8?ӎt'@5O'-| ||fu[1:m :H2S둴3'FϡM;"J߄Y*h;$5\Q@n7ĹҊ9o[z%8y_1p-\\yik_=Q&GCآ]Txjtuh]m?9"6sfiE&3qvmM{ñ{{xoLƄ0Fxi4ne^SFҴ=+R-f蟉%aΟ${= # R.@9yRc+k@NHEDT>~a+grnRaHHWoY\gHRJ_7!8;~G}G0Sb1 :3칫+X4m-ԩDy1NIV#⴮4'?=̺7ߏۂ ig⿯Ĥ|2/^<W߇'Fyy௰? }1g`ڕnعd /|k}X!y=;\)X o$>9"I+Y(YqW<$~_LǴ/K0"-%IlR 1WZ%ß{s.0z)E( .w>u0pI*WI&#ƌcvn&byꩧLqƙȌ(V_g@s5h+ Ѿ?vn\E #}:|0g9\1{mIy_ļŋ_*~$=l0똆szw}7yq^{i2啒_u%ۍ['csG㦛oBxB~%;AKÏ]W>)v].Yħ:-9 F)GFQaIX_/VmB$Z z#v9n,(ۛW׎Oq^y)O|̞ӜT)m1:e_*}nrOܩ,^,L~GFo6##äf֥ ꫯn>Nx&qYJ}]#g\<8U\%4iC.sYK7 $mt&]D7+7aLj=:vt{7qWϾ.4Rk'MEx+S?b#=\>.zCQa(]n?;w,~#7']1Q#R~~~Ŕ{(Tr:6 ϜLII PT7#C4̙=;###E9̙99gvvu R"Q:HC?zzz;<Ñ/& "D!B"${zzElYf̌} _>wo_߅\!{wn.<@Ud jF#S,l B"D!B"Q:v{___vv6QHټys?>{_җ Ά#O3gΜ,D!B"DDžH ylL#6b9R.cXBl*-ΊLq"D!B"DI.~G[l TEӧN*oCM2E5 :[uD!B"DI(Ҭ^i1c\ ^]wu===CCCFúGCW B"D!Bx.)zfk~~>9r$&lGJJJ5D9Rt6Z"z֠QK"D!B9u)K*w=i?͛'?Oѧ0T\Hg"x'D!B"D ŧ~Z_:t9 ~e@,Cc!D!* z1"D!B, SO=5f$00rtfBlvv6 ["DU@Y FB"R#&=i>ZCpvʔ)GRO> 3gD(ʦpĉ Ƨ S?B/ꦚO1gr}}}8sLT8!B@Q J $B)r:IJI#Hd{p%7XA93=*/˱4l}&b{'P6sQ>|5BhB?ڳyKS1"K05-TLvwwO6->KLU=  fB!@=KWWEKHY‘o3=D!\󪫫c!4Rhm #dee [ RL% =c ف17d&n0ټAީGl)B`0?iH\{z{͙eB,d,PXE_IU "1I!ߪH͝>}`h rv{a@ecjPEEHn#ʒUb`^UE*!B8E]NBaK"F^UAԩO.Z7G¢3g47aNDlsf͛ Qm F+µDl&S1z-,Mńo*P)B<7"kY/Y~M1c\H6Lտ=v{lN|z};fe0}d f IcoeI*@9MO"DiMSāa>C[Di$nܸqt=Ci qhԩ܄4o&tttfsQú[\- b6 =Xsh1;'x{*һ-՛ULG2Ĵ3g5O%(A?_{ӿcsszϾiY}5 N#rнj^Y`S*DP#t7p, #U-mbD$p4,L+_QZZ] .]if,͞"T&V ԦꠥFS' |Tg󪩘<µ4uGt=7;_/ ?T$/ "YڪDS={z{ij+ffyyy'Ǡ2r˲37,6vSA95k}5Tx /@9TLtڀ Caf"wŢt=|>P %fo{Ҿ!BLHsKr=EsOtb%k@Ð_Qj^/~񋱡d RIU\O0h"/V]ŵ ټ#ټ.%BWZaޥ$~âpq"Ӭh|2X}~,4-c!̮Ę1q{;'E?a-|{>ʿy-w0%z*uXԟ9rD̕믗TMSjEU!DJ߳g_o*Ÿ}?s\[[0 `}b!BLHsHbhKK=Wn>rqхxW~M`N[FTRͮԀ*8jl6L2ɮ<+fƪ/=-sWW_}wޑMOw}\r%;::yʨjx~ys}/L> EgG>ly빙5uEh*Fw빥J9BH/X PɏnG21-GЏ,ֲLfd=Hj `_m:sT68p@^hj,DAy+w譠DӍ /?t-e*޽T  Cq䢰❧oD˯8ַt ?~T)LOHsh0xM|tC[Ku\JC,s~k_EQr\g $5EgZHQ%kiĕ-od(ʐyR3ĉ*h"5fcLs̥jSiTnܨJzl4a?6{Rt]~[okٴ3ԙnӨ#qĉHT阦tb:4T:3D@+p[-htrK DְR<~O"D#{mtwZ?ñNE4a[ESb1ɷшTkOD!|]S{=_+J\fPPN BWQ3faX B.$Bj%Q2BE.p}( "Zj%ϪD=ZRM,b%2L:DYIcvwm|Al<zQ)3Y:Upgk=.5ĆRX "jg?;wͤ2R[S?c=&g^zikk? /k.Z2uj{祗^zw1I|筷ޒ٣f׿w_],q-zZ||Jtx'"đO,:=#[8OeDzҔS(@0!|l6mNv_"я~$v q˖-1okqHeb;R+ %KjQբC#DԒ(]Yk͢6Q%,֢*Za`_:  Jj5l BTFf@3eX6 -|=Sg?d]]9fJ&۹9sfΜ)g6 8//O(nӔZ= tŋeӍrss?h\PoIG vO}`  oDz!B8rfԻ2(LyN3tf!#n?'Q=jDjv >4Ο?7olر>U*qV{F-G8*CQfQ%H=k’Vgjh wƔy$u1BYc7}Is?%BZ@+Vkٟ ߳zQаB+떕C)ˆ޽{g*i{pB:7t:t;̞=[oU30}$BCCe7!3O8}4s'[~*Q%,S#}>G?X gvo|cC_rj[ơrF㇐To;DG#VCX3KP~JzO%ncƀ~M\_ ZrEQfps=zΊ4Ԣ y=g{U~b&$zH\SO %K+7A _Fܖy\Jokcd 6ISFk[.4L ߻ꍇV>{4m+W_#ya_ʙoyp׮\%ܗ fl +?dئm yz(2sA{N4D }}} 4nQ-r8TB,;?e]D]0@d*k<MƷ}7m\_૾ח^ݦ7[BD!E+raV忋/|Lp-p?GM?ư%¢78#OII.c 1{81 5:t{XSSSÇlMMM8ݔG,30ay5нDpW_}hKXD`4C4]{#ym`Z/3[E j|WX`n2!BLLAeÂHp%(>lfŹɽ7Ɯ?Jq:yr={n;w'OTki4:Kǚկ~n~_y-WF-nذѣyIg -&Vg/V7 KfFPgڋYZC5;/</*WYZ-o}F:g©|-ZiҊ&C}srNj!P|ӟGî]{t c ~hgϞ?t W{{;UΚ5kXE72.y!z%f[?mD!O{,yJ:VtO"Dq[fTk"SڟMkVn:"!n,e]ŘxD/~"޽{pvmK.^"ڕXמ93E[}7.<4/lPCQiau$ 1h5˳ш7&_7 jZIEL#|,kھ'޳hv6>-tu!{mu\=}uUgY`嗋&4+`|ESSOp-?\1pդn>!xBH~Y_֞yn͘57\j'?~S577S/}KW J͛7?C_SO|3WRMDD !b.a㑸3Ko_kzgq?xj|WTGO"D#l6-1i.XGvVP7lH8?]vPFb9uEBO3AJ&qoBQV6mַEL㮻N)۶m[r D4ޖagϞ˗_y4^tE\]}0݈J3Q?K=y$v_uS^^.J#Dk)ƈ: 0dIdf9ZD򕋂QPWz.#RŵT+iZsfLU"DK^!eeu)Q"8j"Tr&R{#*aaƮF'꿺7>ZV4g}e7\+B~]{ܼbL:X^:|Ӛ/,tE ÖZ1+ٙ5Bs5.AA68A5\)+/IKL>k%b.n W]uULG5kV.rDԤnqҩO| 2O1Ay5d|۹҄-_}ݞ`-װ.'AN6o"fkg8o;D"XL%#VkZ4³SLR86CTH JՒyE1`3d;vg?׾r~E')J#@,Z "|k%:qyUUU^Hٳ˚Չ e4~XxypK7yhKwʛ S+,xƝW,yœndϞ=; KXn8}Lo6} (cbg؞am%+咂w!4 y_2Eq4k`ӦM{ջV87_ZTNk0AF2|5v[Wmlޅk4w-s =/XĶ'f|ˉCӧN5oߴS%3"mE?;.=رcAUi4Ƞ4{'a|={1 qljv%w!J}Z?>|k~__~s{7!h@ڿƍ)Q۷tEe/B5O=iOOOƘͫ CkI;]+\{-ۅUNO~K/W2^Xjn|ʓaa~~fF]n 4V +$":SlO^NƖ9cPۣ?z,>}Mt˿#?ؓӦ†2lLUS媫Ff kSO=%(Ν;mnn~voX<\oM2嗫W ي-+X1%}OUm؞+\^(E%,i/=?UWxGvtV.IKӓhX &2KScCf9A:A:_,tS~72E RJS1y-VFrDFZ,JB8 fΜv.o(,, />xIV@D/ʝ lg?{>M/Aps,φY99lɅ&QMʕFc_Bun)r47DOERH]QSzPp %2Za,(nJbWWd GUmo;D%RK~O\xEh2F=(9z3<#:t\S.OX!2ݛP-uF8ehPTaNc9:$N6MnI ǜY`Ϟ=h6VPPtXWcҒ;}PM"-d6p~2>ƺx^6fL7ߖ>a[wg򞳳_n.fHE2VBe-C5DO"DRS/'؇=J$̌O|sfϦֽ{1X&$x46cժU{$R!HJXH -4!9!ecz0]$Щ-nEhRM@9p-V ]]ӧO7Jciʄ88pd&j"M[4=uT\_=kV+M٩+.L.O^o׮]Sn yӶ{;cے :ozJOqܕ75Ďe݃x=:{?vgTu===br/LQbDb*DW:;U D\TSrrd4?}IB"no~!B@1f3i}>SOwwwgeeM:u֬Y Ьo߾}R EHQ4Qh@4jkǀ~\{žJLŢX4 +9Z D49x t@LeKQR"E0|и+w [URU􊈶2dFKRUU'$,Uج>:ydNx>E"¨^΃9v| #779s-ZDXvnvaJe= w}#sѥ!;;$Pgβ?_ӳP!V}O&C吕4P)m`o;Dkumëoo߯mdY" !] O=Ԙ':q!DUQ"dHYjveTkDnp@ӦM[ȳ}UpV f6Fԍq̙11QD ^`sۿ7Z22I[[>vaϿČ4[OO%COur/րň$-威}¼!BL8{֬3fL6S'ԩ'O~GU?bE1]wt=W] s!R/L)HpJ2{3)m~7/1 p3f̰ F4]POll~ެ,K%=F(\9?Ggjqpq%15ډ;?rei?b=G엯5QCuP#("]\A@Y"j+D]3aPVO !?C8~Z~!\T'„8QXj*b;2TBf9"$a b<.Wt_29X-, Bb4TzHUUЏ|3~E5J{MvUiphgPZG, h |MYPamN>-'S=D@NI%!BbdoW{l g?YzδJi% aGB9J9U+d͵i!$7xLd$Ɨ- #lToGga(\2١XG8J)>Cb/ Lyb|_?sX1b`:F &``1D=`|$/lhh4w)cu-+,[ղLKyt}0u p|u@?WSh_2œ7?( c4^\IWW%63~O;]/&`|>gQ!Q{aw/XD])A>nB9̜d,Tͤd{¨V˪2zS]]T7d0X)&yo M2+)|zf(#bb 2kAeT5Rh,v/ HZ~DıcsΜ9hPɀ=zM1z/((8\E#m{=+ZoI!^S#Qa! \BF7Pk~_QXYnpnq+5dh7m+3lU8tPݡU욭cES ;4KU`B$HKK14R2mEdi!EpW7<|ʌ`]+!G,GqyiuÏAh4,QN(E;&Q 2MMM^aaaAAAjHlV:]v,;t *-[SvndUj- , 7?wV}$K0 V;Y'F1snjO?KON;v===h?4ʮ0$q4g6ep^{bap0:J,ɰJ) 'C [`b$e 9h*~|?hl|wnw~~~܅̫jfPXo6\LZ\.!iyp]{ckK6:ZõV1^gQJOjb6d%(Uz"B! 6[ZNDxS&[պwtE-'+%eH>nF<)c&ױXbc'ecB4J!1jΜ9bPǙ3g^-[>|8olj*pF(Z&A̹'l.~Y QΙ珪pͻY"p"ڶ^YkvF8k++m~@m#pTW/?q/)W uJ״;Lٹ=G;_ ;S՛&/l#'juK&%K9ɚoε-*8*N!Qpك + fV*pTȋ4ELt4*XPۘkl튐|ΚW~̾}˿WʭB@9) K\E{:-w_~ KIMet/yB|[E/ȓ0 1Q^X~;_#+<^3wS<2%@Rӭo_E*iWff~D i`MM@oJQLF՘~H7FaI z=Dr3QTrå.n(m6(/+r717 9 ~X~ŋ_|qÒSq#pGq?m\W|c&z rHw҆*=97(N6ůx цA-Hf8ߓa*K2O> *` {{kWy1v2pKئߴ|cGV'J cs8rٟ~60xߌvݿ&qrpNt7S2֦JMa)7[nltUk01WOL\>|XL%Hp\4<^ڕ຋摵($82S֖Ql{qÿEiV+]hIP5JK2!釀yߏA͉&%%e޼y_~H,kۈB8K_ @(6&ihm+1wI,ޠAy2_?m,9kJX^1Kߌ} {5o\;Qž`+(-.f/0v ?T [)=g+%~AŁ^GW~Joߒ$,֍rޣ%˷.%;W=ƵϾ~g؞w~D=X+>R3`#pSV8M(0FDYq;n9y6RQqV4݄EβX mV׌6llk+M%tSyNBZF-`.֢YЂ>JK$A&>XяYf]qW a:S )lyg   Ѵ _(!kAbR^>7o_ 63pO:L) qo3پ쳋oRt'{O( }{nBn42bK}rs7(I\lc{Ye,}oFP4\fChĊը,|"F>CIJ1 !1j0v`4-Q[]m:/KTMǝ Rvc7<֎_wB\L=rwIq0ӲSj>Fݾ<\:+-6ҊX,HF{We\ az4)/^r78r;0;kR.OqΦ6zC2aa ל@ZtlqyW F cZXo=ﲢrCRg?6ղ=YA<YdQ:~h "/փcђ y3ʑtelױJEB#B%K}5ڰEcGG x`r$T0sf2;b SR[8iHၝh* c胦3p-sIinUyQWfhXK|j4[[` e=sSszUa+!X~ jX# ٫(~ޤh3PU c#@4WyrvO-M7PogiE)iIz}+kX D?qWKψ.f-'lJJ+XŚe{q.XL5n2ش\Z]&%]<7^RVq+iue9[ܐ+.bVo߳z斿+ 3Ӫ(Өfȇ@ˮnOvF"X.EE>>! &y&| 2:/\.\҅@ 7r(mlnȤ )Ňum ! IIƭ1$uZ<|0e*s0+A9hbanJxk~KFe7B6/EsSs@&R6o}y܌3 #??20pl1]/xAˈ'YYY'N.1aXNLYj$脅U-+)/,+U_VܒWT|)7 Wh,,G{ə2mKw;⥎jW%AL9y<>tPl X {{LP|}"< 7㏃d٠ikxmsQy5$۵-ɩrWkhN R= 1~3%up-cu>W̎Q7ʴ4K<ѳm߮xnRh4J%iӧEdALq)jş6HUW"lIҢ-khvФdmo Ue(@]*xŮ'\w%^U =ڶspi w>[8i7׭Y޼T~FT&,\ړPN-l%"n_5L4$I878ݻw`AGuǚ5k0ٰk׮1D=~0Vhhk wxX]?ss2mua8%5R_i2zo}063^2q`B,*3f/,r7V,T|v*#̦ MGPVWUWyk(@`& M?|^2;?9-4ٷ<.휽(AO@BLTXbWR_-+,S8wرc9g4(d@{{==dee[ omzU,~$ ===#,ʪ9K׏-}WW5jo ѱ`4a``СC vfrkfXPU"d s 8A-CL–l 1gĮ츾C_E*ODcUap`"UCJ@bRUC]pDJŕbZDa5lf{aVWh,opL.*\mW_td;woM 0Yu֥K.Yf]\e 橩m,(@RЏ4[z:MЧ$!@bG-!ôţ))@˲hU1e6*ӽ 8E5hX9P;vL-3d}?z{{{‚Fu(uV5 u#-]Y J)o;7`5ݖWn \TQQdO,$,X[_fmxfjKc!)!hǖF@Zf3 1-c0w FUCACQgg;v.ܞ`^P 4Dž"g}0otukiа(\~/&s8\3U< Y8zmz,V5;~㵕no`?6rރ>i~ぢBr4uKǗj[pK$UKNIe13aC7e 5͆F ou<66ܒ->5, kgiC9UIDdj``@O8A$dҥ\rq :gw8Y͹ŁSG)$"<{}vEݬJ.yq&Xjsm#T] /7 ^3wz{ʔ9EGzZ[ Nw5徟ln%*Zch,o`⠶_\تmx5>b*)E;%TD7?nhrjzky9qAe -2[v+ƺ6 \1& LH!`cPsIII7o_>uԸ o# ,~-Ax[ۘ-Hl%p&{nX|>f zz~ju4~Yv;s iRVhM{Zu`۾%WMY{O`mݸ/WS8ɺ%;W=ƵϾ ۳ߏFfVZ2RU}jf ~候wFtΦ@t|<<{V|{@N()E4&a:/lyg   Ѵ _(!k {f%6~Cnh{{V,m3xDXǶt1+Xnl'lc{*~2~V%V j=Ĭb)sIbH2Ti!PK3U ۑ3ZKT}=Xǫ~"ʜfW'%n?,r2xR\(̴Ôtٲ,R H+j;b q'p# HX jŋW\y7{L.q{ԻKyܲ)a@5'5k']eTQ}Nh*)? 22-4h}D.BXܻ'+–W%%FUIbQT7D-c`$d>&yq@U) W8\H=5z@4@9b'CM:.`1xWp`a\Xq+_t[rg^XXnڹT_8D^îz'܀h 23{̴*=4Y=!+;<nƌo `8m6[ssԩSsrrӱGb100uĉ2CMθ > NX_ղ"²b]eE-yZ*_ ˋ;_15%t'pʂ~Dm|5-mu[yQy^\m꿺d2h 'OLJm+!5zpI𻻻-[c4p6la͙0mWU{yyϗPixd- +&,B "Tw{=+Zh—h#vw^9'ջ @ώ4X# tI(XS2VcyxuL[K=>[0nRחroMM掓L7-3)xT+[8Tڡ 5 D53(޼T~FA+p[.I(G Nۉ&z$H\S|~@?ݻ|0٠ƣ:wc͚5hzlصkЏ64Lpyj迻SROa9:Q+Ve,YÕzySwEk8:~D'5R_M][wTx8BH|9YThg^X قRYiv*CP cu2O;Rɦ7V{뭯TWjՍ~|G0+u, yo M2+4SzG E嬶6pJf&RF9["l$TzO]!ՍbWRˊdGD;v>̙ hoo?xѣGѿU[%Df[n3AcyZ 8K׏-3:䍤mj.2Ԛx:V[>|chC@?0e׌+" XE#|Fә[̟?44L!6t^0-3 [f5Hbǜ9s{ }M۫<k#UQqT ):(E|EZZZJQ bFQb7p_Rqo ",m|-aLTzɼw;ޚ$-3$ac֭K.]d6»<SSXQiit OIBr4[BiWYEGh+G x.[xVa4v)?K<~L9 sR3e|# ȹc$z2AF+,,,((!j$]RgU3_aΰ]jqJ)o;7`5ݖWUb;K+>G,$,X[_fmxfjKc!)!hǖFY2`42< -3l 1xLT!`wikksqns0?BfBaYr+T:Vr I ȃ54xv퍭vXxhX.ـ ʵ1l0:Y{uc>_캌l[n!g4-0wX뫷Sb.oOE4OD??nYXX.Z" -2YIt㓷6 \(`VE%'ȫ2!釀yߏA͉&%%e޼y_~ԩS.(ux[ۘHl%n! X} ؠyjua'Y?dg{{8Gݸٗa{A{z+\+Jj6]Yq;n9y6RP[aӨ9b)3tķg !G:[ڊqSI=Ty ~e-Սr RhUDr~̚5+p8F/؇fdW=_GDH40old |@a1"T!~+>t-8<Ӄ1ap쯤צomoЊ%Muc~b6.{֍-mlo_ŏ}XϪĊ00a[ٓW5'!1!LW3c P);䎆@M#8.G̷ː<9!e';㡡h iDfWENC adfQ7"Jh˄pϢX,H q:I^qQXxʕ+oƑsށ%no}UnOl.Ol)adh,. imH(x`o =r4]Tob/>#a9/!bծc"!jBp/`|БWRW0yu8}/#;q4<'P_gpN88gя4k;7jltȋqW'2Ej-mh jjopF+–W%'« X )(NoP[I^E}=MgGSqbVyrvO-M7PogiE)iIz}+kX 驺/XXa9nWݸ6\)Vcv}0U155WAFI$%7 =D詯gon޾03J2eZ@hBK$<(*rrQTҀ# y&|M|G}$ny+⼷Zafz|͎!iɄRٌéo7`*[g6mMe*s0+A9hbanJ_m+JM,dKqbDzUIrl޼93fG~~90plSdggcߏb`` ++ĉebS9%M=-脅U-+)/,+U_VܒWIrJx^*|ԔЛcTVc\%폻n+/ݽ7*Ћ:_WLw-3ɓСC-`%B0I@~wweR5{M#p[k[SyϗAZ˴\< evMXxDzV~8;;9mdnbFoo/}vtt)\U ;z[TZ[},Xޱ]≞}hvחroMM掓L7-3)x{pm? *"ӫQZtU` ͎JӏsȘHZSڮ<+e 0ѶMk-*{)G݁s-!׭RK[nҞrja+yYt`!1L<~ā#_޽ j"---pSVq1km:J b[M쮀7ae9 m\Tzɼw;ޚ$-3$ac֭K.]d6»<SSXQiit OIBr4[BiWYEGhAs:$g\b?K  Lv=rB)r1^odnQmjjz hI׹Y\3ԍte;- nUvOy۹U \4(|"DYZQQdO,$,X[_fmxfjKc!)!hǖF@.9H<``SK[%$gQybMCzgLࣨҵ_! $#l @0JAY/W|n wqC\q2vBq$t$,I{NNw'dX٪TuN#ݱɫUfhՀ>2e˘_oDWAua&vymmJ]jD `} *ѹTkr%YN|!E;èmS`-JV#p}L][2nP.^x۷:u4IsrSBVZK) NcKoH˚P `tpiv]Dsm^}zj /VkptyO/IM[u~J~KqΝ%^:EKZ 3KC̔&PI)c)'+8<)pr!0*w|YgbXoۇ4w7Hu Do3? e tY!u魿`I҂Û/e/EϽtX"$ԅzlpYJ}kձjeO6Z#Ȣ5;")[yƅf5i &j򃞡7|aqWܨ0o#(h/j 8KɢEne^lHdǓVZ2硚$ CZ3.^=X8!oo/K%E'~~ih~Y(A̓v-;wkޫSl6$σF;fɊö%&=Ϥ0)wO߿NEx?g~=W%YlpRoK/gw2kpiT͒) v5~vg_{uJmnyYZ"y-?[VcN)8؉/_yp4 G?"<[HC(Bkxe^F9_sw():)e+XPI9ŝ2m} q]3!7F鍫򣒖p{?Ej#˶*8r:ލlMZB~jH~\wuzkxx33! og[~pE %XĀ z-ge3/rKb:@g]v?l4th̲ߟ-' yv! ћ鏾'H}pƛ={ k[! ˲Q▧'+'ߟɅQU=ɻekd(r!I[˭޲ 5 vq2 ȭ9p .e#ᅨŷԷM/]6\cܙHHIC%`d0-Metֆ1#ZႳZf4".mSz;#H[V]%!wy=|eZgg'ƗKODK$yYYYo_Rb3/ 5piH<\0lg.?M6Kᩣ[9v_eBQA91>GV Q"ꏝ}SlɊUjG$Ԑ(y<ɐlm;Pβs>`nT5qFKk30lY0C\d!f"Mf .$)tV!WmI⹓bLK4\}$-eދpQWfXY ˭LA&WVi/Zչqqq>DcHlUd.K%V~eD@CQ*{9\ Kf^M|Iӓl !+)wNJm|sWY/~[|%T ^[&4\{kl𕘱 {NY';o)fS9CzQuu<:% rmXLr"J-Ʀ gAFCx\`qHmgfn /˾2J0"EuSVW&>K_O~Qo6* z9\A ;DGduk)IPy),T\s)sp>$}.˕~#"^*.Muzr@>RRR\O){V] UF׮]}}}tҹsg???|eihhԩSyyyS ]z]'Jc$7*6_Z;h!QLɦkxm!8WFXȏ-=3gOM:ЛcnJskF\RQQ{"G==555 TY':ŭ0!(2|Z.҂|fv q_; t\LyMۨkB8ΝCU%bwDk':Ϯ l5a B[D+}^ceW\I|\tt5rf :0$#aX.P_V"#phkL=FZ<󕯎=ZCUɏ'lQXX~Z {?L&:{ŋb [|||P-עjz?pݽzl:SAAaT>}o BLOO'Aۻvd=ИcQ?לW7k7~1]]IףǡC!?R*«{c>kH~`Uڃ]`_R,̩&Raۖa2xb1wΰPϫ_c]tOy}𮒴zr+k*}.kRɕmR˗/r˖-ʔKI&YIHs,2,AJk^V;_9X!/z?$ZXY Bْ;(Z}߈vW:rN^z?"R|srr d ;vLG^Iqѽz OFIӄ͚)6Fɓ)r8G-=YSlM<0o'bᲀkR„cJЃk>(E++BEB>P14A[A9^]\q|_Ělhz{KTvzԋ{(^79fe(B,~!*%(/Q`65i.Tk8-1b%Z#{]^0*prt***$Uˣ?8K ϫ/BJU\o.Y=MsX ~ھG7 R)}y*- Lk>+27{1>2lx+ʶ= H[K<)eAsJNriޏ?]$ N^(. :'+y1 [I^BS{NZU^%7. Wvm%7,ᇆڼq;LarAWW[sM3z⃞S\7GޙpG7\YE>G`i(ޡ)s(( %}$*޷%%qmj\hcr]9s_E7y4P! [ψD=dž9SLH"vq0կ'D#z؞ Ox񳯽:S|[\6)rB%dH3ׄ<2 _l j{TԤݹD(l:YDG.?NE$Ǝ+RN8?3S5-y\eo" "F9vÚVKem=5M[D0ٱB&UUU{;Z{7W4H4b[+̋i33dv \EȶCn}[Cħ?f77?~*O f)oONM dο}j{; 6v9 Lݲͼw\ټ@J/s)nCcXD?j# sQ{Wk&{F!DIMmR3L }b9f2J{Ddwt!!QZ!qջcחjBB̙V 1;EylO!!xKUW~og҂v܅B١϶(5|G0i1*Ǜ; 0A7jIǫi',x0RpbPXQ{X?̣wiFZHHtxh /Ԣ۶o߿?'ߖGn?\̗nhg{6Aj[RJ3ּUP VWl܊Lz} ֯5nO4{纙qq{Op"Ef ^/9n>; 6K Yܺ-]{2Ig03Ω¦M{3&8=)tPsp'{Egw*r*bY^9lB%%^:MXƼa,/ƄC&Jӈ)㹱- +EhDGGyV%kb&<3;bqav:˕V"a!yT!yz1 鏲ۍ!/OqMXYYeHջҰOXwYwG[E9p+1^ MQpJ"*uwʴ\$mόjj߷~g \!bgx@||$e2מ<iQHr"q錢|A`M\OT"1KO(#dT +?-ܳ!8mqUZZztuf"?xB`6&9?l+33C_sAGz?{lݚgVf5<ܿ︉yo<&>MiLQCM!>OP|/!x~Z-PMS^~wQΝ;ϟ?axS:kV[+%%ԑ7>>>!Ɖo8AAA-+»P5gIG $9&|atipP>! hطo'Ξ=۩S>}s>P;h]N}nPިz?~9[uGxyy:طo_ȏ@uuu}k׮rS &L0a„ &m6SGFF766]*$/^ &L0a„ f5wËݒ-0=HrxYX:Vyb &L0a„ f5۠cȑPKλDЙ&L0a„ fG1oq{9((E0a„ &L0alofs&MYpԭ܄ &L0a„ rz&O\WW'?vdP &L0a„ [li1jԨEBWU(\90a„ &L0;_I6ks&Ä &L0a„ |Mȏ)S8îB֩2oonݺUSNL&/ҥ dCCΝo&L0a„ f7on1uK.;=\WW'crMHg&ܤgI€E׏˗;w̧pRywNy=T$P]̢cGd.\ejĭ^3*Sh ItCCC]IBRTz6a„ &L0ۧiӦ6ӦMfʁ|P@ɺDXYFaWB KNiJz@ܹs$Ws3ߗ4 883uH ICR`mhNp񎡪wkGTt^K&H>/ILuF0a„ &L$Ǖ(r!׈BYxKybю]kGn$mxVƍ@~?glmkKtlja4`hRR4bC}bp+;7\pE*Lr$UjJV'#:q㊨6Ixg2ypTT bGTг &L0a¼ZMXC OUu1rP@i4 )wK/@~gϞ\bi`ciD {l iw֍w)U$Vrf} (v<e(Q*{nb:`WwLPP[JЅs:@TC >v&L0a¼*M$Kr2 %&$L8relGUTLb"ʤ]wM~##]F:m۶1cק]",M~P:KBĪSJ\4IQWncCCBBZ:$8IEaB^2_K 00I0J zG&L0a„ 05"!HW]nqI6\,qqGkj mKڃO-C哓̜Z[>63g$ל 2ΊG2y/9]tanb5^vtR|V E"mP T gn>a(ɫzWLrs~TI^6o[>uѹ%ռ\8_NȿKvAD|O)S,%F`„ &LWI%9xWl8B1drb; \bH@VT5 km ?f͚|zA.?T]Rlrήg:ЈaѝLUQQAysw툎+> u88ʫ|쫎E++dy &L0a¼:L_rx8?}<y8swgpjTEe~./yqb;iBDy.Ѻu@~L2O1C'<z.?&O=W:%+W:I>vpWuE6P)| 'ΫN_n˗ۍbC` &L0a^&yz۩t`[FS$9QliYWv$v\vGu L+V%~ᙻ&@R[9kPsg}<|S=6&TGl KMK&$ɵʕ6y,3er$)KX/+Wb驞cMtAIQv *Rb6NhfywE&L0a„j dRh#ebJvEll AI%߃`'G;&nqb#x1gΜ 6{dlMUp 'O~>ы|y7^ɧD{,a;ud6B^ {p|˿zzϊqj/=Ä &L0av {ofQY%K;ܩ/{{DQͮگrlח>uhh͚5m0&!X9Ȼ2O~"swzz<1wU[PIJaf:|+C_`t"T?H^RP2NPCSUTbă &L0a„y#|}gW|"o irGuWZZȓMF9s&%[lٶmyMu ERÆ cvUPPL&OŠTfdzhѢ_U+(1Y~=EɿWdI6+DzkdgFO:Wh WY+q0a„ &LH9s֎IY,Uծ(Ϗ:;{\6+Gcj7?cs?<6&L>@nde(s[3ِCO<Bb{a E T2`Nq)*Aڗ`̋5j~U$&t+ylnݺ9kĤ!*8/Y~F:rHrr2E͟?'O؍7xꫯ0.ڦnܸqk޼yھ;y n/7lYX](0}%sbUsU_cTLyW\WռM6~ *t /.O̤Ha6444a„ &L0ۿ-Mfˁy'pA יM%wqG>ޔA>o/=~lUoη* `AteG͑>\ܼy341i .t滰P,e_g&]ɓ)ɤ{&%%^0p@?cfffzzh+"@/SWWGEou֭]sѡd}w)ϛI=a֭͆ƒ3M?a„* l3=<;Av ,'f'tR5Lyl_pEban<*/bx<;_0a„ &̎eoIN3 Y_]reG]ve4`~ss.̛vQ߆]f-tK|-q"ks3@{Q]'/JM6yr=$_Qcx uw9pH*o#""-[vu): f3̙3_\/_P.*!**J\[n *#bl†~͞=i!EG1T^-#ؗ+Ic(Y'f7k{I0a„ &+aV_D ˄Zdg\jj\QYyy@@ D\  .ט}]Yo \.Q KDbؕ\rEB-ZĆ $t[o1o~9$f 11H 0`<>H:;^2ʇ4 , )Րv=/X( B0a„ &k,//'ҹshcJI)uqGi~^x5@u-^Zjs|5qEVJIIP^Ϩm(*l iXsIrXw?V)d3OU\]m9+$dR!~ff=3oUm)b_7Iyd/rW_[SRcyQ ?V汊KQbwMVbGf`~sTrcCCs&L0a„ Ù' ||O DPJJ`pkGeEZԋOr2艥fA)}||J Ϩͦ_oY΢`99_# A X&V\9[eSkjS+O94:::3ͽ?n闠1cƼ+QXX,pCEZY'O&[nL<igfeeQ󦧧ƟK.PˏD^[W%V5好40w]9 6m._̎гbWپrXVs&L0a„ #f y=##;ng U_ڦ XJ_b0xj}~>g^ƍx[A!Nҭ3j˹l /~ i>/˗@SODEE6 u_PS &Q'|$"mմoFaGRޝ;wRzJLLd~і3l|uZ(>H,^&(JZ)(blfd &L0a^fCcCK j#GN8qi)D\^…_+O{{#򺳲;wܿ;{~KBKVQ~8ZgeJ} ն=$LhmSE `yYYɾ|y\PL'yP1Eɼb}H]]]^ b7nHnF"977QmR ұc~=z}?rBlcR^J|ԩ_~vz 7={v`AK.dYe&OL:fsƲEbMY^2ڐ'frE51&S\X:fբ\1IXDzbgƳ &L0a¼ ̊sj._.5;s4_XW_߂;"'A¦͆qySGFF'x"//df@n%lɎj+ˇWUVVR,E&i敊fUHQ,[N/QRRzĮ̃E1.VV9Kw<1KjbG]Es T`Ht$y*YNʾTcم{*"00г &L0a„ٶ'|VO>$ )@LWdj4rX+Xsrd:S ݻwW'ЪuD;"bU=rfp[VV)}Q|(?}H7`cɹ3[+vUGO祓"="=~0a„ &L駟>}4yβE,jbb+>%3Pyvԉi&ܹ3Ix\rȎuGnɕ&1lm@TyrRuIOsSUU&L0a„ #ovȏ :uJ>m $^>+GBqΝ/^tFwޝ-+ /' Zd[QoXn&I@Tkճ1gORQ^6yՑZq6tlНS}qŭ`„ &L0a7hc, 1W>ΊWb&bI*N9PML-Ϗ/% ľ;E&2IE(Jf.X޽ ?₴ sݩzd"Q^&?W]*Ūsn^I0a„ &gm ?,Y#vE#((ߟ;1}BN9;=@H 3Wu4<1UF LoyEry]}L~.]?H@>{vV_T#= ʧ./yQN-a„ &L0;ﶁx犊X Pn]"ARWfz0G_" q]512 dkZyzi| :`.u0&L0a„ jȏ-((`Sσ&DTo;[@T_;zO}wlrn[} T2JIu/5t cfs?3 &L0a/cҥ+[ņ]rkkk=q[S]?^Xo[ZxbxppLtMs=:.S0&L0a„ 2-[c…%%%31s% !lZ3_ Ԧ˝]GSiW@M8q2\lßTWUz^RnMvT Lޠ/9f0a„ &L\tiȏ_zHffP׮ޒlz9ȍ&Gqz.Joҫ~󋕕e.8]eJ3y^U ` q%q#:2Sul(yyE+euwj_W0a„ &L0\bEȏW^y%??I2(,Fi!{D>~Vml|W|ηpəoM_d](V:HA+ &L0a„ M kLJ]1D@`V &L0a„ &L/nz:)fy ֵ,sq!a„ &L0aX>Cӝ:uJ!9|&|ve..$L0a„ &L\`AȏwyСClK_O` `U`„ &L0a /<峙k -\Ռ@ϒ]7[9ny97g J`YLƚ oN i-J$hzv3OSO +V4hXۨa,}U@~.}ƌ$]7l@b櫯2h1qm۶RkM& ooaÆf)*%%eСMT䶯e_q Ҋ7ƚ> jjj|}ccci ///zUVVx{1|!2x^,jРA|[/_Xj޽:Obё7pCzz:zԊzMF\3@CT=HiГeQl )Bÿ+b/_.^s .څE$%% @Gvvo6zxpРA,jٲe?S^nݺ[9ry@F$E5&X:@d,%‧p*)A= T Qv_b4=tɺ,^ِ0JQF4jسgOmm-Iz<%۽{7ٻwo]]+Lo>>>ezGIgR fw0*VKCG8vByYQZZ?O8qڴiĤ$HKK;p@CCӧ=ޑ&,\(i! 2Fl\DjvQЊJrSZfEj$+9-qN#=ۓWP)NkndyfBbe Z$ׅɧ]JѦԥFM 4^O ^ EϮǏF}}}VVBjr5J0"-KYkI~7tϴU#OP1lsT fVe.ɚ {K"ws~";aa}|JI f5((&L9sfQQ7{G7;3TJHH%njib偯2=^J0r"%2 R2fHC""i*{kH%KScC16>=KcjR˧;_hDx¹sx'`k~GWްaɓIC`0/ԅ\x0)ž՗.]|2SN]Kz.'+>?ٓJ|*Z_Y9zA`y`[s۶jE4C?S!۬7`27 MQY ܴЭ[7@n?_NbŊn(T}dm&kě=rQ*,uK+..NAwI McGkè8Zg  }~aħ~~%7JX$AF.?.^xBJB/_:vHOc%-^$ ?6s!q\LBش'L,p[\\L҂׀cR g̘1W3?ɵ|J #.4j 4⫦0 r[ی~<)me&(o8Ք$YXmV#((bA£^Dv &HX2_ uhѢJzITTԲe˺vR7x5Y"CSAk `|6t: \f.e:xغO. gKr>aVR,*1r]v֞;w)SN8q]wQgϞ & <8++K=IBD$|eL,GdDFrq!>S 7flJ-N*Q#y#0C՞>}Z.Q2 fQl\\RPPp̙%KPS#lvwyDH_tD:b:#.Δб~sGG8i*聪^.ONDy^lN e&m*guExҪbH)_'%%\pa$9bccF#Hر{e5jo=Tlx4ɶP"Cܹ-{Gm Yka%t"1\.Qʌ?Mgf-+#}G:BtBڃl0*A/_=zO?M۝;wn˗8AOm}"η_H٪tY.m񑬝3C~j.,''@`<Ψ,fA"BPd/p'$]ѣG͛7O:UիgϞ]w_ 6DFFtMOăL|&%h}qpK.w3-{m?y^Gׯ_NNСC{z$>(::7܌/S}Hݿ)mCM\tRO*0yRD*E Χwxˍ!"S/]eyyjgD9,uSGFFm5z=)F[Γ&MA]?|_M d ɓ'ϝ;> %{뭷( IRVVFL??#G.X/@oɓ'ۗExR}u|M&Ӎ7E/_@~EJ`<SϏ=ZCnɏ'lQTT~Z ***BCCZmbbb`` ȏcϞ=۶m.//ohh...ޱcԩSIh>_~3LgΜꫯN:5{l8CÇs{sVTTx{{0}[lSYYwGy/^S__ܹ[n&MB' ׯgO3$vJ7^{AѓM5={vU^^~ETNccѣG)}݇_%ٳgmV[[KzL6, 5H!UUU)))Cp^~.9K͕ qtm gX2;NqN So,LiͫzԩK.ݻ9Fd++rߓ'ON>}ƌ$]7l@b}@ ˏ{`0r-x 7ޠo=55Z U rW겯iEIcM[v?O 555⃱[=HTVVx{1h}@ ˏ~mѤ+ eQ˖-駟1ӧϺunztA)# v R/_&AzIEI89|رc&~Ja)Y/fR9$N\ ?yĉӦMcuuu5m$&&&%%FZZځU>}юHXkL -Kg8)52JJ/qOa B9s+cyݗ3Msx*<].G6$zR':h;C*`= ޽uݻ .?_&?,P2W~dD٣yxZ;%ۡ#\n};!9ע : L+ٓ8V… ###CBB(;҄ %a#-YшH.5 ZQ)5P\V~VˬX`Ӓ4ҳ=yU ¹vAWj&*V֠EKM|]|]ޕ1mJ]jD-^'] Rjhh9~8mC,+ ;;j`*E.Z(2\גo'曟i2Gmb0 hnͭ7\5AO DrDwb.Q#_=֭S r/S`' XbinQ32on_;ezaEJd( e.ԇDDTא^J F b,Mm^}zj /$GY(Ο_Dx¹sx'`k~GWްaɓI`0\ԅ\x0)^TWW_tˤCN:u-鹜DLKgO*<@ky|eRmm % LmV.On܀4qF>))opɓԩ5qqq۶m{<:j( xGzI_ցBxDIv^. OԈj$9-Wg=x36X3Ҭ%N-͛_z%S7tO<ќfLR&|9k #"Ր^bHPbuA 8.\ܐf^)r?./?~Ν;kkkCth_zL<9r]t!n۶[n|{£(W~;keϺqNqK-PogTDti'LdJR+JEGh=щ bRAx#@]@ǻEJy7ƍwYj};w|AZ\jKJJ7|}3!N/I]YoMSț2Đ|yMLɐ>vX\$uSfl]Q՘nUfZݛ`l_yyyP;)Wll޽{ oKÐL111+))9}W{Ngy@֋m䯞l&9.Jxw;'"ko˜&H@]@Ƿ ~ga޺u^֚74i5W"/+0J(Tb7KYY;v]}8)\\*{9\ K,}k^M|Iӓl'2)wVxy /]m&`=zh~rrrߓ >|xQQQtt4陛oy}P}Hݿ)mCM\tP*0yRD*E M͢p;'"C"Ej<^8<ΈgQ;0/JIIq=udd$n%t'|פ@H6 '""t{u6 ¨}zWD~RoȮ$СÐ1LuuueeeFLFA@]ݸ=XCpKܠĉ'O$o߾wqGll,j ? ?]]J[^ r, 믿hZTkmL0wYzt%*ci#1vyIĠ%{6̎ );f0qΰPG'O:mMmNJkZ5Q*5~߶c#-tM^xRn3sE}ZKSF=׺"jM}pj=*T .^.,ٓᴍ<ر3,,==Kcs|8M8fs9kY#c) :=KY:b.l|diFKa{1z w-P5&IZ Bv&W[j\]:y ___bkv_CAƓ&SnXlb?“Giv2>Y~dВݳzHq=f}~lX]4o<]v`cǎI9eaҜ5ga s 7 6I9N ,ea±c?V*_ϋcUfW-uǎ(.^=d'h$Oe~rm ߧ eglWTiiI-zR})/֒ a P)+i:{qū/8q ]G}%߿۶ml;888$$~!JHHxw***X%KPڸtҗ_~ɒ+//߸<c\\g}o\$!XTNN&wseggSz2jԨ}T.E'_X,$Qji>ə.#m?œJ1ѽ"e $5?!F f|m.;}vsS6)A_"!<`BbBJ^a!yaa\) Ib8v-)]0Y?. e,׆ 9LӊYGُf"Lb'/e }-kmn#/f'9݃P./{J,&ÜFlKxĈ_q6޼ y]]zڛS}Y˖ҥcነЮMt%}(;2lذcFw #0lz\T0e|g .&ݍ(XCbekJZhh,B;sνgνwa>ι{;s{ΙinBM-7}eaq$]-E}3gKe?G?^ߛy07a28Jծx:Pl?~B|e0=u*]NK{>SnBp3mb( #Q(Dϟ܏Ʒ{Vŵ,gro/n] WIIh=(?; jz4-oL{wHJwgN$}YuOt3IāӨɛ |5%??nkIt)?~RuB.Ϛ5+DE㦛n#hnn欝F0{l!N>NF믿n+l&6cNū-SO5wb%ߛhd0ΩyrIй*-n{駟ϫrCŽx2Xv^Z53O:*45֏e*4645YOoڦ1 ~xVh`!\?iu >x~ozY| ti2=\T,!L*ݾ7CcP_)ݗqz(}do}w{Q%*7\(4J7_C9߽mҸ`iۥ+6+Ѳ 3rMڜQ .mٸ?t•W^04U(B?doRy饗n'Y;C)S\ve6ns*8}jxrY?yr䒾ܿP4lQϺ9mn@58b&*V\9\7 ֮YT*P7j  -kW[I[LpPgu7׏91* ҙ+|)8, 9KxG2%wGеLhuO:!<5wnܸlmwa}Qڵ{/0sGlwl/Z䨸ΆR}ڕ %D{{  Qg>Bʳxq=l%KwT3ٖ4Z$<}rorp:6s=zrߜu40Aܴr]-G?L{π A#{!3fdsDiBBd1s0.[r|xv5/|/?çɮOFܹ+_|-z+2JfxlqiiۓF} K4kZBԳr0 /Qa/-\hmUe_3_~[M:۱/_nTdwAw$\, ڱ#'- CݞRSGGS7/,Z˟elVqmii7bE1?P+_!].]X3b^1]rG6O©W˩aZ##܊@~biU/VhcrrU#Oɶ^<:#ǖ,B5 K 1No-ZOMCCLcOlVNO(Ꮁ@hK,#9RhӿQF{CwcUshǎsfsaӾb͚5=a`Pg?YtiH>[o5U~z"ˏ뮻.)%FȫP#Q6 02,ܴyOÂ%ѵjhMZ>XCJG36%3mўB}]>h\U9b uJ-ʃm\>èT(x-U#0moFdÆ%lHwuK} d[zeߍwhq;.s%<*ntS֐IEGT<ꊃ;ynȄHGs@ ,;wg}.ꪫœ=cǎڵ+;1=wyg?0[l#GdȆ <bvqsO:rd_}Ψ;i=s7ϯF~Qֹㆥ<{[V{ {moپ9{ ӚWSL8V^y0JV˯~ugr>07|]vոgUR^n~sN+NgU+<8_[e`|q kX/?N`u0ر'OZp ]o/&+p ]G|7~/S.dK-A p"xwxxI pi -`bH~KߥIENDB`SABnzbd-0.7.20/interfaces/wizard/static/images/smpl-th.png0000644000000000000000000005623412433712552023514 0ustar00usergroup00000000000000PNG  IHDR^sRGBgAMA a pHYsodtEXtSoftwareAdobe ImageReadyqe<\ IDATx^]\TM]* *v`w7-gwbݍ݅t~86gwvgg'D1 bƀ_;s"D Pv@tt4 P< 7ok(+#4, UWGܹ3nDpPFeh*C lyML'AnƎK.@]]?}µ;w@ igJ~"W3\uB #w<5k"[o`dl \PX #D'cHeꊻyi_EW._bbb ӂ)JJJD3݃P^Hp0j֪ael Us(ӹ7** ˔ɖ# DS8{eX;o^M--ߎpT23KH‡E1 3:HL *K~t~|}Ѧ|<[)Ү(/:Zn??0hp^?ۈe+T@%/W>>P$vqx-<~,켕TA"E~OCe N;C##ܦcǏN ^|)%K҅ w;wbI®044L*}ǀ\}3VXȈA"'"g}t특FG{{8:8y[%% ׯ8p pA,rOlپsg+Z\I(E[(Q5A}njcn -gΠufB\VVC$+^& ¯tٲsz;#Zݺ SKlmѶ]$ܼa7oFQEP=]mK2qAp Ne3u%   ȸO"b-Ém5n\ _dM.<$hҡ<]C+H֥D ris;ȡCvHNPէ 8{c<ωօ-|W ˅fvy)ܼqChߝuÿoNK 'FԶ={BM\?/'G \bhְ!0p ^Z.'ڵk';xJH4t d:/_X*s"6[L 4aKv_ jnGٓ/ ^ uԽwg_^?7}:ӽz)b/wy>΂? awʕ8H xy< ")p"^}o_ZzRpN $ 8^8{Z|8!-ΉYjU(R>qܴ]M.]5V-yBTO5r۟J d*'.8H+sthF9ݦMOgIM"6| /zWb/n۾C>Hz>.-d#E߉-^ K>g9p"(\h BYG$H˯bN::gdx|ępyT0xs&tf$F T%7o@8pNb -R}ybϙrGqs4J4p+>ɮ y~)cu 9':> v,pb֣GW-9Q$Bgr|R«gÝ|4gWYbw:RH1)e.rԟҙ/2\ωC MZ<ÿ ?R=E0.EY_)oVT9Qo)䓞8>Uq5'靴4 ^IϬ;! F=@[$[d 6v0j]=|X+p)0a_eK $ I/F\uz:!p~)M̛hs o,i-(12GWg%2e+?Kd|DwySr;q+˟q*<́NZW.qڽW{I8ťz")CZV:VB^f͸Ies~]:N3E6 q@A-ң*­[ lĉquqN?o$u%W>zKG )Hȏ5m'@){tą`\ĉ6|nR ,Ie-Ms9.-[ gׯ^ W_=:k`ۑ`/\;/$|ҜIQkI[7~ 5k`ٳ1\:cŒ%Ow!fBJ9?6 1ԧ\SFN\|7 ɹDg/ع 1rq Źv&7*ΆpJ TL>qB hN88'<299Z~}aN'd9W_DD\W_0d|蚍 U'&~I9;&;}Z|˟I?\u}<𚴀vr_Ȇnb"Ǯt8pNץs5_8bZǏ w/Es4݆_}qn.\\=)q)d΅k(pɺ =K!:pW.\U1Q/JJ,>xT R*|r_q)y4-d\sߡKS*̩Snȁs#b?\0)$_bE "Ib9"/b Ϩ/cT1%ب( (H@| ȍurAؚL E{[C@_ڕC#LBgGVR!P d]{z2)/4la;a³+O~b^iGVe5MX~СY1Z,15i6[ben]vLNi#SJ jj\=o޼Ӵ.OȜ='j8c6Mێɪ̰}:gw|rX῁~h6l ѲY#0fE_tt;6yyp`IQvr_by@<@=c(чs)YM\:0ā :7^7_in{)V/`@nEΘ$H!čiݱ%f-B0Mw0(j7J&P"g8~I ŰE-U] KQqȑz[y' +ð0l\S˜%ƅ= b 1 7]ww\Vn1bBM|&~C3>h NΒT^Gqy Sل3.;cK4nj%:H8 Y xsKv9'`@nQ'Bωb@nb""g-1# Zõ32sV bP̟]0 ݡo:w [>HmϞfp]ݙF}z|Cg(,oҘ3gǁPɪ폷F: 0ijs0KݝS`4a`粍e<==ㅼM~8CJS?"#ˡlPW^顬x_կXP6ȝ Tȟ Ҭ:6a9pcڌʤ 4jjЖ?͸s,DF¢A+/݆IpZyBأi70He)(L׻AVDP{4% jc廣]K0bγ2K BƉ-QZ lٛҳZ.ɪ 7ok8hFRsZ΂V}VlC6o0f}4M)sw˅=겾&^:3J֢(֤ߓupcX)?Cj~?~BԫwgFàF0翕R$tyw v\˻E)w2<0>RJeo[#?B(n$uwF- +ߡ{Z!-eRW,z {Q&v"`ktn\Ć_W<8ç`'I]ed"D 뾡GSF!5vx'![0x[ï\]P{)튣Ax{>DY(%9xiܛI93k=0++o mGOaU9DvCcZG %G { )LZ? y#LO@Vac]gQOH?:iBJ3S۟Lh$]Ҁ<7+.Nr'"[gڗDGI܅7Ny8K{vŽPУ Zx% }=;w073~!Ц닐hh)k&I Fn*' >G0nۢeȺg*zӈ3Zad S1 U\ ^nR.zpp=JwfX5wēGiS}!zFXFFc`X9X?aثδ=] U*,: O+f}Fc3LG a`KhU%:t%E|0\[d"J%}~}{aQwh;C ]q'q#oP8"D HJЉEhX1*<yT#_6tF[B GaGB[K_cĉxlR +YB5BKHj \~+Dԩ_qeX^ eێa8V)ݸ vAh[J&Fv0*9*v)W [8wK%KxćFayskV3r M'[cOQw``Z]G,kKUw @Q a5PϴhQ`Mf@_2 ˠ7B1 >#4sVJ~(#($gLDd|?k˗Bb m&2Z>D1"B+e' zvz 86 }iH=6E$NZ脪U(4 S'\Fw΃X);~z=Wx(ă-$[`RQ&X[ Hdu#7`AߡkH![aVC5-Ze:kD{;%EVizUWÏPG�=hs 3ax BP㕰,5h K5UᙟнxAPrYL9ZttZơ1?9/>S[P>h~*3wYg7w.큸y;z][g˭p91E4璊f!`"^BQoo?ƬQaf}$lieqa-mdTa~ M47ֿ3ޅcæVlyڑ@:7EznC z7[LeRoNrW=KZ v.#5ͅ~cڬ{)o@$? ''+tl 7g}%t[ ӍyJ:6xEw-fRMֶ!Mf~*vg͛eEtY2UuxϙM6bBKfeْ+٬ig;=Yסk1F+~&z7ciV`1ۏN,%7=xqMY8jb€܄qT{б3} SFɐ/r$<9]a̮5Lk'wI -1ܪ?ZVVhzCBL~>s2EZNڽMxj: +lJ!wLctr'v5r5InU*O'a!ΫEej\3fN[ZUeU5;~.NCàIs&|>DalA<<"4s^~]OTz{ ZUJ 2;4nkGƌ~T֯aURaL6=qnF *ã e2ZJ$}A 7*G*jaDU~X|kbb""*wYfJNX heS FS[WO`ʊ1RTsR—2T}TGʛ~a 2(KQx=o-K7Y4s}qm^ؾѥc4yBi2W28 [Q-UT oWlil"̞ _^5n cAw(xjta..7|Q#\?_qP[wsIhuU1jYPb#-rY?߂rȰPqYO !,& Ѡ#j+&*܎ S̓o6#XR^0(h x5 A\0k=[9=s'qjjP26{ٚ8;ȡaxQhШ~M!=7bH^#u2GqdA,N{V 8KG+^l):_a5cZޗE7i4*D:Uˆ(mJ?N 1+B[ʵ6`p1l>Z R *! O;`s~~(_4*U1 i^z:jLx54}H%֜ ư!Ԓ!E|,nߺh>lw(kˑi ;vDЮw/8g( ^׈eXyx 7BXmt 'utm~:~]Hn;>BQǧíoԷ%Xu<^“.Av9t@-^zN+W`Ȯ^` +m(j C8axBػ֌qe%:~rLm3'Ah!?ƞ1pð9jVM8>u;g{6^q%|BK]]~\͞IG{7ѝ4C ӨA+GhKqd+''%*̤Cao sY%#f%AZ5ɩj2Zt,97:X/2BrݔyVvu~:&S"AݧM=G2_֢?}?fC&g[aO2k/Z/WszD5[,1 78R1@PoG{bb˦TFE'4zok~>#'COw& hMqem9إ%s!W=b0殍"IzB97oK625IPPPDDD .##CDG'P]IHb?T e|ttt{{@1%00Pp%7BŋDT#/N*c5Ep_ҁ/\a1e:JO~T.!%DNA&Ql!<I $D)yc^4]5!*J@ouPтIJ=S-Ż?Ѝ6.\ ˹ղϣ[BZd^8w>{x!bJ\eI7BWVQwPH ˔%).<ឣaնLqB`VJ%I3.H #AZbk1!I;ЌO)Sq͌i{r~Uԯcd=?qNZ^K?Ҭ:ɝov]˦LgERÍFDIYb;4,|. {@wVJ+ 3 YVz BHeFYZnP0ShbdjI(_yH:g<~y^=འ$:^/W(I9tN̴+;7@NPeE;v_Snhjn.[ϥ6ɂw52 ܟ0jBԁvj 0ҀIMGrҒ~1 Ņ;N̍ ny'&7H1zr5ʮFwrt\BѸzcF;p,ʗ<-FwqUztaZ 'ODe$yz`[pA0nu۱o/<6k yhd+F67Ե(> opr cG1||T 1'{0k-9 f>RYj9 "H͟/?}%#:Oajp1y=>iT'CiS(.kT2@;IH&ёAP-7siak-8qs',)l6{%(2#&s8X )V{E%V:"G?$ _ 7sW#a֚t{5=G:~4*ƈS!wQLM{{ޡƋl7m,Hk"t#0MY,{޴s&Q-[)9P2WyUB^R5.oL4J(E"lFkHF?$6U.p$q )b0г?p7 lcq"_JOxy\^>'~t}Vqc|sswbAT)aybk(Qbp͖zH{7Ѵyqho]*h++R ]z[ڵ Ú|K>^'ݺX1;t SV,wѫw7wyB} NWl؏ C;˩8~uZtX6CAv2k ٤Mj*aO? DIZ_Fe+ A] ~I[bjy9uNH^kYy>\>F,"(0"y&PJDD!PD [ѤkH2]4)hѽ2M(43'vK{PYfz<$]IוT_f}N;)DgU+j"ER~Q$)v0ZGzӽl)*t'HZҪU`sbU`ɒ.ux)*Oʉ631RKS,, 1 @;h"^#RѨ%u <6,!-,㝫ncҒX: @{ɘhz]d=ָH4jɸqM-s==Il"uT,m`3eZ,ciދ|jBG ’E KOb ['}&'%fDZZ͙dKJ7F(W )U47|B.S6Q卹eIܲT[8F-v!j&Dn݊H;;:%Rgjʐg)`8QP&,A -_,Xas!GAy w)2 zoT膾kzyxo5M0dTκ>wqo\d1FZOf=&'ضD?¨%4X6O9 Q0C!6[ Lxha}f浠a=hcYvr0w6իiz&y鎖[$_bAcѨ%c( _kItUfZ*ZI->:_yL.ύaV@J֩0,r]݊Q,3⯽er#ܴ⏔f80᤺G2WF-lD s[W( t0ô=߱O[\.]Z.h.SPxT3 pwsE+R4ʈy$Z>nIl9b& (VaȣxGR4k.]6|21==CȓFRɺy5kl:(cN4j"xK92R ,aI .mo=62!s2cH)xl6jk+ ڰkdѡq>Tj l?`p!]zrF-9g\Z|ƥ?{t{qt[=lVưNI007n7{QβdfӨ9>Hvw$4LQBIpI:G˖ L^䐲.N}Tu(X|-RgVOuᅲx>ڟΝ:#Ykr~DX|S .^v TrA%FCێ=yspi21+Y%'e?a<Ǣ_zLٍrR) ljxݩ.=xZ丄Y'4}5i5Cex[5k1{tis+hj=9|M ZuiѨ%gW dhصà8j-j]y>E N 0G̼U s;N 3q|"XAj`X.. Rx얥~]]4jZ$8VfLZ쀲eJchnGfx>);ӉĐ6>ؓ7N䉆r0`&gYX<-Edh*>羘@$ Z:g2#}Fd鎾pBQ4I1((:`a~P4@9TF-j չor~]uDBUW΍`bc:I#TNS##aFAk,RD}1RKFIZOH-YJ1YF =uk]OhQj)! N* o?x] ^!Qγ\oܹ+7QEq}2#e߽-QŬ2")?Ej1!wBtBϟ+߸xϕ`+ 7SO]veft7q폔cNZLÎ [9&97)qA4jIʂZOHOv0jI bs VwWA*H4j#|Lڈo{%$QY9 Ŋ6F 2LCy$ RKjf3o c%WZH-Q> #C#WA IT}n;.9GǧYg 7Kl|&[zx&j-CdOv0ji4i,B^p)<dV98{=r?`L@p p`I!Q tUY@~:WԈʺʴ"}X0ԞsabgXqd/0=%1Pk`vƼ nh0k2qo$XU@IЮ=2#rLRzbszM4j3H3SSFzZ4,6}F*Sdt:H Хh0GڍDLҤᅲ(4]a& ^XBL*uTJ1)H+jjɬ?{Iq[4jII&yZ.d s|)QKB50DeĹd7JZ$#Z$IѨE4js4#Z=%xᡚ>j"n Ĺ /3mR`s(Fjᅲ'Fj`IJa3cLMp#O?jdx8&toI05Ox<P"'Nu}ٷ r=:kݫ/27~vGƕ)K 1RKF)kEfa E̚7)chU v̑Xeivb㬅PM!8s5a;N_| U55 .ãad1ڗ[UXb[isxuHed1ZO8=f^NZŒ)wrBp-*4Рz>C&QbGfHP*u_((rj:uxI%#W/Fjd斔Q8/-_ JЊ ǝÑ  U/F4@F-֯{+Q2< ~ iPS =p< "B45Sd$UJp *)(Ya^ВU6CxQK h"cbX `ה,<1_$]Ů؎f'J}r|}Y%a Kw ᮺ)Va1 !//a#x|m9hҰMU:ieuG#)$g)NC!fL |pژqWYBoEF41L4H[>Y5FJ $@YW*kBx"y.yg=x)g'.CPs֯"Eh~M;΅x;6`5{ HC. byJKBJWNT"ydҎZRi|PNbKV]e|dbk)QW%MQ8m#F-YZ3/F-ǏaCa82t0 ACbq=v4 l豨j7 J޷ފ{ 1hԒIKF-Y 6=:l@m_Z̲#F-"YT>[L;oc> IӘSd49&oenn\g 2!qE?O{*оy\ `_1lU F-\af [^ fo"KT@q~,ܙW8.]@ZEDY)xO`P6xNei\:؟1s LfcG1b}-&5dUZd#Z$XV~W NOS1#NĮhTP *BIOMMQ 5Q-H-!51Ov@gGo;h"Z.iE1RKfLF-*iE4jI1ehjjfڮͰ$8RJ|&"EәOm~xY`8b 4ɿIRnYZDY-Z4ZBSM]ذKh %/a…X.>Fނqm=N=8$C0<0xtލ}7 @ Ma$0dj1E5\ JdOYhԒ1䷪}ǙԂ\Kmܟ``&ǹ/56Ĺ.x>߂w cԩ0"vF˿B0isј1 ~q0kił,QKE']6ޞX#bdEn׷Jay$Kƅ:o.MWGB¨%@6iA=7.R3:h[8\1f]ӄUi9)$\9}| ŸL:v.)Ҧ6tE]B al7ǭ6x~MuΌ2Uaw.`~oc/߁x }\}^N5]Z="dfb rv.yk`{ z7x} 8bE+& #XI!S==dKxq#7CBB& 2GgKDYCF#$~t߭[(V o%[}EJ7(B[Y8Z>&Ey$Z͔#F-z#$]k>t+hsCXxw(d2ڴ/a1+%8Z<#="N'gن3sF-QKϲ?Wd5e_4j{W4jIlaԒyÝ1%˪+d8ѨE3A`` YZV2$I@!ExXI:ߡV!<:N0]kg̀iac`Z & JC7+.Ǒ8y'RY&0iOйPJ)BxDSѳlԲ,~9NĢQ6s=ƾc湱3 ǰ7ue}Gm_llBsG>O+_LUkB(`@^WI.zUt,sGGj7`6GɣG&.-[95BQMUfiLw@ )J_QPS$ߧ.,Pix!8G,b#E dЛO^1c\^V"apyn "} |fצH4 b@ϙ#P?(+D?8zZLcJPCX4T+CB``z ͚ViFxi8ϧ~ø)3ReQ"9YJ9% O"RO$TIL0# ]^x ]^l d=;'/b@Ār$ohZ)k6C2 ^""a@n 1|/Fk/v(Ʈw_8u;,;u ! [mUn/p[6mx3=q~#h%W:7!߱ 6hg )") 뮿KǞ7XDF=vV{8c3f3*3fb+tn^wYKٞclc,~-jԕwI2ezV[Aaf㡇궨0*4r䶣r %y5_P=SiZn+/hհSD ]-xǰH#߻ M&.!آ^CaeP8:M[g=?1 7BvpM1ybO^W BȑDKZxE1*Xp D/BԖ3&"2\ >`bO4GSQzcDtwnL C}*Y_s vfٱ iDT4b$~C?7"/1F/r /ںJ }+BGaIa&ڹ(IXD")jt0T5(?+7:oSO ^!}N= $~;EBω&9) ȍu/b@@a@$ýXa@n^l{ `"Q%rg#iKqX$5Qϴ}%N9ME l ȍ',ۣcXq|_4ҮyqnLXvEΟR}+X S1v.ޠsv0"tAu#A}]r1 ȍLj6T"W}}M&sZEPySbr#trj,b;LJ ]2Ῡ((5E^BB8 u"W&³\y!kU ,P*(/]ݐkGzZȝׄBסeUThѻLb2r#t ?ZFRGT;Qަ'.UB9&Z@/G`<biP,Xo+8wG`-RkѮRk 4~GA'N R,T@vƀ---QDRHy Q*0"pPR]L"HE_HƸpQh=ƒ-ɥT](FFDC jPgaF]u-Uc"ޣ Mbzfya/|^N~/.ѯWO_Df RS*1a6@&ƭH虍a|ya@gtyuIGĀR ŚfyxCgqD FJ1}lWkk8MWOAf}w VPvz׸53O ԫW/x%AĀ4`ggIENDB`SABnzbd-0.7.20/interfaces/wizard/static/images/smpl.png0000644000000000000000000017227712433712552023111 0ustar00usergroup00000000000000PNG  IHDRutEXtSoftwareAdobe ImageReadyqe<aIDATx ` w_x"H}AZ)-O/hO;"Z_.jZhh$6ժ9@r ʋ v}ٻ]x77;;f@&cd z~]1N@jM4=q춏?N;MvM7M>4.g>lYgGG>\[[W]OdNֿR+ 8P >|s,i*Ϸxo*"vmH 8c?ãL>ly uuVC$2 ޲s[iSЏ;vԩ ɛ/Vӓť]ֿ܃.U뜪~l( "CFV+-$Zv ^oۖ9hPf<ԩSvYg2226^l8qb= !Q;;;/2f Zү8>UgrWUW8I*A(H>M:'Oٯ_?6ɓ^PطOq铲 "Io߾اOɸ X`uxKU; [~y$l*EՂ.BSyJa>ӏAJJJ(ڔ?)$$$}år%~!ecjұj`!pX,L>4}z铛eollGS&L>bD"󵵵=AO4 `  _"\gu٢//*)+oE>P(O"1<: ⰽ_Wr/uQ1b؝1&@ś@_(g,! IWN7nnC w?޲cGEWgy }6]YgO@!;^Gvwux}c>a%!sDٗ*RT6GVR9HX/.с$oX9>a|G:sF>sһ୻vq<^  rkIt L: oMbzuJ|X6:\FUl&Q;őu)~`ICDf% bhJ3}yn}SÆ J ?l޽:M3=3vX>{N3z{eOη>񹅒jQpgk8"^ tVMI<6,g;C?SĎUt;::ƌ7jԨDfcWKˑ#G!;4ҭrwyuo5~6ǹ0C^p/ǹ_Wɖz8!;'O;M+jO@aSѩFP@+~εc~R'g|$秞8;KB@*@slv2I3X}I@W'^`Wt Fp.ɱ.oW/le`dY9c|7 ҈sϫݘS|' ݭ884ko^:֝tUn#:)~n}۶/سC ;srr\tјc-Eظm[ T{;?$!CyY$&L8|6?=ԳO?=m}̸q+WDz[~CD7~tʫ }ĉXT}L3̙ד'On~w7o޽kÇɯ&ꫧϘa5&k]lWC}E5IKk_:Glܸ}?ԩS5rK/9gΐCîݻ?ܺ{z' t&N?jHNW}≐KOJ$ F= $'6!M 8O5NΦMߺDI㾒6%Z%K.|ڴW^yw˖GLQMP4\.23'>F+T^'q蚏6IsZ]}$&qWK˲8SD'OAO|Xݳ;#C6I_]t]Cg|?9$ܫرc?XMOd4 TCHHK.!oE?-x߾${Ğ-;wnܰᅿ9 ېBmcűy Na{Dvĉ'##F.nH⸾$ak'&q~l} 0`03(Çw&*o{K"_R!3pȑ#G<|unp;QƏ'_<ꕐNqm=dV6ҞV3Ǟ{/oIWd C}]ˊ~ hI*o6?&Zg|{NMG4sH}}x<˗1)nK5{5D $Ntuv=zh")zC]V/D!:Сtѕ\tW^IdYRD#v[6o&hbDD$:ֹL[ժC- 8yiݫS}32 2dH67ܴqm; O8Q3Co߾Gmkk3 ?4cji r-FHy,DCAܞ{R-1ήs-z;9Z5ky;Vuuu8qo߾D7GD"|g}t!.]֯_?vJ B?uvdVLKǎ1sՅo߶CQ$bQ$W$q1KDzֽ }:K5kݡCN8qر'O^.DJz &%E23=w$eRpIr(fc$±c*W6ÿ=ɰo@rB$V%ɒ->9QFcu,z=!g!*\' .:uD}-;wnڰ<GrCeeVW<+%0+;9gsO2DCƏqdB$*|ڌYYYDa8p`(hP|ucצL$JaC {g}ַx[g#'|K&#n@H?Aחww?fٹcILLMzG?+_Lߺᣏȱd)Α#G.V|zJ[ӭ|OLsy_9srn.Ip}^o]9#6;%b^I&hCӇ\;vjia#^Dv+G|Ǩn%|QГt[uu):*-ѨKT[wǏ_>m/nYNa+UHٷoqB:-Wk7r/=&-Hu5?B:3D?>͡]״o?74tjM>03NWTT~ݻCZw / vՊ:A/ssq񷯻N}9{?n"333)+榦O d'ڳg~'׿Nt0+>真}N0j Iva+A\)rYwwxW?P#KZ -gP_ڟo]Fb۶m UfР.=/RM7nit^Φp?>8{-C6}g EzYYu~d7iNbAQWtk~}gL?=]QA٭mN<.)Ch:ikl$"[̩SEq= ߪgyȑZQ.ӟLo?v.SȌ֭[]Ŝ㴵 2D>-;v' R LK|utf*ҟĤ/^l􂸞'2*~YCNg>?v6"e'&twu3zap><:dHڠ?O. )~;u2'ְo#]sĉgu.涆 Q7:O ffŷƭinܾ8G?qtD&4yInzիIH@Dq? wE=L!5)lDmj~wLm˧OsdIo,RpiњW_}tɒ wD~v6սf"Kp7uo<묂o}K%YOG~vÉ{47}ǎwwu5|:Ύ{NNvwwuZ=l&sg'g5j.з}γz{3&g8~\7~n鞧N*}@l6ژ1c>DI B|k\s9zT9rV'Jdf655骠3+;[JTP~}n"O07#' 7=jt?w|zJvܩ9Fn`o>3=9џ46e҅zf~/=I&zɓvS/lgmnn&&w~[/лH\$ZC3\ʒf3#7 yHG.I$cǏϲۗ>G#Vg_et2"fO%9o?߳{E5|ɾt=CtE"> ؿ?C\HMḦ́Iґ|XT3XKWZ~yhA2-7`Zdwk_\[܍gСX /djVVge∑#^o~]6*m M4Zt &k'y>ydv.j]:Nd,9׫ѮIرcIi.}'ĉ)ҿkB_q;vLWY ooܨ[OSP:G6tcO>)uV8NڿR^llw#p/Л.U뜊ۊΞʋWp| ^73ir,_:=9i}P*;j<#N:{[eMDֳs~nY$]8`4hmۼEq+QFaÆ^%[HW\un8SrAyό^)l Oz e[IDO]xo?Ν;Idv윾m?dcGvnJCG{/g<nAOAt1s!{M]Dy"??>HA|+#R/spTY]]i_W]LzpmrX/Jle勜qzlIYcNcIk_z~覛vHQUqYwtgn'DSѡEhzL'*Çu)SA9lwC_~%`o.7x455醫I'LhܴhSM|1Y>; Rpѯ}K{,'niѽv`=ʲڪpu10'Np}wO x*>|x_k>>Oz!yH_{[u@Rbxgy.;9u㍿~3ox7Z.ŵkɟnyJʛ2kӴLIMNn}- vclӽ{%;K;ZY _(VOIC)~@EB_Wb!\PKWIY g;P_W\*pbf uՊ. >ʞFÍZr Uv.^#JyU3M_+FOVDpܩ*4_!CI5jf'< 0 $.z Dkjii% N1<9aDM7ٽ{nާD\3vp7',m۶i}Wנ!C~uoG_W{9okw[͛u&"F~dXN8uS F5`]eծhTun#澸hm}Ϟ=7-tnQ0@dv@jý))Rr} ;6*c4,|Qp{1Bɪl=%u; R&\5b}cjjCbOCzBw%\tţnj8p`ɞ=&#biTALj+++w0p`ݛotLl}?HL"ed=*#!# +Ӈmh;$)O($D#VU}woaYs Q;rэQ 8qDvԹ귿5Db(Iy{GZ b{?,PC2H {/'}K.XeW669nKKAG;~<) \ㆆ]FJGooHl2կ|;Ik' @Hq_AEt"Tkm%Q$P7T|W<݃G.* 3x Uʲ&S_{\ ӋBI'+s}uũdM[ oVᇫ'HcGvuw{|[lU3g _9#JQu|rwM4ӸJF~Dgwvu3H[uI~g'`<1bĽee\wu/Ycƌy'йd>LC}ff 9va]I:?OO=%М@c\7kğ7',g$@;<Onb{CDit1ĉDIźS+8n؆Jy1Y9 ѣD/>}s4?CԶq=hIg` vУGOMbLD$'eexXhn&/Оh>;)wC%ΩG'L0n@A (NK;~Uz;ԯ'ɘs%;|}aÇE>vٹ$'lDJ799ipΫ띝nz'Ͷh=}ʛ-LIW*uQgN%橣Gyl4'eHcQa0mƌǗ/9 YZJz'_jk# ~8~\{!fTKu}bg @(4ת,dF]2ih^Vʱ 20 Id4ำB)]zYtˀ]SC&X{Çd"ifBwWW(UnjC .=:i h ʕNo> ~xyQ4@;oȠQfy]]}5j䷯.gkw~LUJ[ y f-[W'lҽQC~WǏpo~|Oa>⠾TpvH#.9^{ԩOҥ[tG:p~qKR~ji?$j.:OSt[̞8y+|q"4P{Mj>ǭ'd x駏?>oʔ˦Mm6Idav{W$W9zI9pktK=zMmݽ~q 8&{yy`eY?-[0%9M:;;_~n( /!oƎf=eCr皮JjH}N"$)?aD .0[>uosǎǏwO2il_WlAFuA B-ٙX^~9[Ehoo!y#HOJQBz+3dwҏΎ:<#OجgJכ @Ӄt&MM@MR"B~yS楩 sK%Z1E2jUaL7;1s R y Ӄ)0;'Oolj5ȣsrJ̮[kL!s,M :\]d,48XENR'2WVT( (B]W!Η[&'Iw#W0%-+ml3DΓ7Ϫ(txDeVaGr41* JYsPq@(uK] :-IJBuM@7%[R&j'wu+ msHLg qv9m Vf[Xo@n~EU&zП޸$KJ .Y-.Va'~.i Ϊ/ƙT4=+il0ɺ7o~n4_xa#GԥL4=M4=MMH^Me/ſ_oG&Ka\hz4=hz4=hz4=M4=C @i2 -z+EՁ(Qi$y$A_We׉[Zlٵ"< @S<oxIUCUy%vUIz*Ub@\& PrTexTZXO%}lmxB:V_CyGcz+ȎGӻ '_]sg\W@*֞`?{|8J^"ó.DgAemE\BGvM\:rUrgUٖ ciD%G|)#; @kdV>Jp/1sX=Mg^0ˤVMկ 7 !W-[,Ores]g/In3m#< @ӛ ^?[PYp'GVn"BU*IQ+8;lzѰEvH l~VH[l"3WU%{~vy%%vK"6쪘zl (@蓈<*t8="º7DHm2`zIsiw7F@W gV?kcvlW&Nc/wlΚ9v~u$[C\fyq6-{TDpT ]\WUBCcDEAVLMoQүJ6ι.Z6E?K7q5`m@'{#EBRWb2o=fRq ЏD>jR]a"LR,)^ ]xg/ݨzNN+u[5Sd M uGid߹퐆`> Hqv]_`qvO3E,Λԥ.T%Z`J(B Gb2˕W,&ݧA)ҞisKVAj6^? >!#xKȄI@G"gY*0JCU.o u!N8.ʍ)8^ ,!>vd)txNIknAu`"D81ӧ>\Vϰ#dy EEjc6٨* M1\9*(^>D5iy )ucaל7K:?ز#DwBgD7ZH@R(o|rFuJdh.)gEd Tp>N?I >x[]]Y u+;'O[.\ߤX`>L)0pwg4aC+jGU Y]T$XQ%P &{dRDKRU7Bsޔ/8ʸ$ڱiLkUPD} ;.([ʠc4%5\9/Sn.޺ULsJ;w+WJ¥04}|TI73}E|r?- ]Hsێ U.)NoW_?#2MJ9$& @1ϲ0x^JR~0R")4wc>)x!Og%?8sr ɹ9Qꗾ3,1hAoJ @H Onb)䡇JH+ MoU)7:)B=z̤i(}nٹ(xS2;&Lh:ƃ(uNyܬ;*y)=n u!'/)ҥtW࿣_`c5x!O"ġyG+g5B?TMi7hN 3ϧiS~Zp-73 MclfB2)YXwPt_蔡PP\Usa$)ԃ`eSz [(YWeL&  yU`ڃ@QBLb)a[H tc&HՅPmy qGrc4 *3CT ܁1tcP,s+CҋJC>/u'Z$)DQ'XuBLHRjO񹉮ݚy%=@jPdVk*]칁rmHzxrqzғ"oMKT t7 pEfX=,i؟IPMHWw"n'{(>6^J |&RTI 1N@z _vQ4d/YGKEIi?nkH]pK֗&d@ͽJz5O2ePZOnhLqn@hzmK}W|lsŵӑd %r3j8Q:L^#弤؁[ ;Dw$1,,ơQ,FƞZJk(hUdI-{`=r%#ޢju5$z't62VJ7KL[c0yE3x5gY\@/ŸK$/7oҌ*"ѩC(=LaяWC dohQjWljD6hg)@B,bKg#hUP幟5k`jϬC\ r8:$qz@"ޥomz.u=;x|# BAb9U9]7be3*E'ߨҰPhL3RD}ڵ>NUB#$44HK uyB# Ms,K%D+Hȅ 'UW TQ?vܗf:x~'{^5I'2#΍u8IzFLG2mV.>>Dqzi"wa1o+!#' M M5xt% Tg_n\J+TwhӴ`pXTך+Лna$5Y?]śgʘ̦ݼ3R<\Y%_(2#*?&Y L"Tϑ5NQ[̋݌e〷jiȚ)yS~T.aKN >#S]M@RxӳaD)2(e8^ު#= 7=+M 4=EPz[tUò`tad\9< opo)zkzgEU`نq|^K0n`t8~W3ы-8XuᵜR_(7E8=H MO7{@uVe:?g7fRPwrslkiߦzl31KbB(6ȭsI*|Bv)# ޟ =4t' wo;WS%v9ekvN݁>/ǙG'و?\0NR f*PngfQ3^~ͫ,}nRgIº3of^\i~%ԇa92 8NJWGnXk@3i&pujڭ.;oj336)ZH2fvƐqXoYK)]&Ywrq7}] ]U@6}Ft>*W`c`Yk&y!%{YHA#ɔfcODC0$lH*U,O(|/,Uf@?i;:ab~:cNF`+w_MՍ\y a~1b2?**}2Ȱbm3lZ'Ks5CrGTٝs]tH^C$RBee}З'ysɃ0 FZ|OP]^]`Y MmQOX/(R]T^桯Ŕ_>FFtdUQ?9gfkskL{-A d*4 LsœBcI?wNP=<#~(g8C|_ުDΉ|T`Z["LDRS~h\V{YkwUFc)L?U?Fe24f,Tq$u73ss*\ӻ嗗W<ΖH6Wa0HI/~&-^շ9^煢8 9U\Yp.xI A٣E&k,.O˕aa앗R2Ig'?+ZJ\iU8m=:j_@¨RŻ^`U_*/mFsTVeD |o–`/ig!BMNy-NƎ%?] A7Q,\IvVҀz 9p /q+XH:0H+/Nupt#-m s{ 2וPoA, &1qH[[1YgNev+dC5kb,d,Tq舶4mcv"ɮ}#(^lz<-zѽ%G_Qӧh/'Nր?=HU]8krQp$)!>8$Wz;>{$,!C&*dXPKqEOMJdpW2%/X)f?WAD=O[Rca}x~PƥɬRɍQ[Č,@nMd_ÍxɛYSg']q$,) GUřkT,~,nLTx'y֍e҇Vuz|S;\ZPOEIsO2BI1L"h(ooJ}ۭIkZch#RΛ!Ψh*N;K@t<MA !=-d;!*ggt`sUeLL:|WH& 9tRٙj(Q4^+7)q-y2(+I:Y!h̀kEڂs"ref7zxAI˜7=&KY54DO\Pyfa;M-;cKBp_ږՌ(؍KP9N%%'9+P3ί=6T~ֻ'L)͹ӎꗰ6`5F/!/D010а^nfvz.L;T0uzəKkTj+^CXvll쳶TV3L5knfaΑt|43Ws8P5o:MAuk&5e1Gl qzxM@jOzfWPLĴ ~'e2RhGp֤ ξ/EgY1tn^d $y>լc o@jzgE4%s -,GWSsWiMXo$F/\٦ߑIsV0ƈa 8)[K]PVY+NE)eK{+:J| AlqE"n_V5gQƜkj`[P|ƦF I9Jǐsn.#ŋS~_v(#:I*=]FSy>" ydsnsg@DQ莿E. mX/HO'8⋂^p*,9@ZhzS%k9(}hwu:paJ&uE#xы`%%w~0tC lA U뛔)+gR!_Y) {PYY/,h*_z 89[@_E9nР #UnGo6-] :Yk̷JɣD{=yrowQ_8}§+i]sU͡y_3F̺f4GfZYbqa{y !ƩZ M.%M>>fy3 mXr= Clܲ(?5i#</VXf~?6+N-++Ij+Sӭ-X;/ί~!'e)ް\׈W/׌_2\e UDXk<§~ &һ5+00c¬Vko\z![BHbZflcbXaU+VRQJ3_gkd% "nVFiZLW'im;㪙B-LjR[)7$Ng~݋g xD߱5´&=7Kٳ AؼjkpHz3h;*0azL3Ϸ ¸.蓢־qetrkҜfMRM1V{g|*)i8~TJ&Fh6m7ZKzÆM3f=lkhYeA[^% ofm5N5 ž0^Y͘T06h#X&}W_xd]'lxsXxY0,+%2UOHfю-T go͖ TO,l?C{k 7M~{-YUCz,@Lp{M+Nܣ3?0+f8OK6 ERk^{K^i̦ʃ>Ь3~!:>%7S1MdXDžKbJ3"nI6˵zvôbj^(ZI-nj{Ao/ a[o}=ӲUŷ(ʯum7C?T# XP.ݻfwyZ4cEr4ZH vf[}P_#eFɥ [vju\=I֭>7Sla' }ˌʃ+ LClF>jkLV%SkóbG<ӴsEnstyHQ'q&جg-?üRz>wCf0˲$k4x% ~CHQFQҋk>Xɪͻ2v7nіDD lFb45Ծ^6ꡠgyH6c~]#/RҺf/ѥD|7"Йp Jq̓G7+DۺIudQuʶkSh.4FYsHtޖ[E)V%uK,u7x$ }hڛٱb5K6L[\|#Z<"=kxX5c 4{{}vܼ!򘬎7DXHAo!X,)zJL[m129"g`3fi)NvlMݳU M: f\gE+2-+N=^PՉjDYn,K'Ym+_eps">Y!2IVLЮzhF#AKC I Z̥cH\<*U;+\ޒe፵75 y9/c %{NóK=EwE%a}:ޟ`ĉ#]\kYK:9'O(YW]6ؤQS`w7XWc+W2q„f ;[&9gNM T>.Oge=ǀ7O^S!V"o7nӦaj2gwndW GM61O*fȤEV̞^\vEsѿ)Sdg ?|pѦMX$#m'3o1_@8yRho~9ӟ{woEGgNVWQNExV qw3@#_{癩 v0~pp  .|zEMfzq[f pKl:G$(5YhδCMՒp)Zs1@~,7-O5ȴaڬ"H ~@I,KyȺA1RķP-hbo b˖-QJ6ry o/S;>+(3㏏5J8N >[bS _NpLk,̦N| nx uЙxz hӔ;[IٺT%6+66EnIJׯU~uV^^Y+\,dmToYAu9ӢdѴL>}?5#<{f?\7,֕\)5V'r3{$,n٣a~364}8=.5W^+.w2$2|ndYY%jAot|!DD•W Ctwuux?>TؼYhl]}z{ݢc/ܰ7FuT_S;D1-"ZI\4-ao|&B#,SZ|%Tɗ̖`5k%Iz ԗE<= šn\^t<$,6%7{#r^xb!7jfrL&,J4r(]$ =NR!"gGxE[a 0lVki驰g/ԈMX0q>D3NOrsD}=@$\mILml'O$Mwwuw۳K/ ?/- 7.WE<_Wb4o.HBWɗ[>AmԢ:_2^6]_*IǠ@pHK eMV٘zF[5]*c<+ 饰aߘ:ږFm?ʍAt֥өÃ#鯽^].Tq0JMmɂ;usKĠ%:6.DteԈ'"dM .1/B=;b(#uAټ^YG.u} Cִ!bsq &)<& ֘zL/M̸}Baų&?%On_yއZ*} !IÇZ>l]Us[fm\ Q!CllpU_p/WLu.r3(@'F.#wHz͈@ksUŒK]M2IkLSi({* /^>.Eۓ~$''}l1쨰9%sN56ޱ$5%{Q3~I{b u uK cc/Yڢ=mScF@Hr$֟x}+ zd. qi zwҰ`5uުͺ1N6n5I(sV5dɚo;pc޸I`as͒ =Rh#Q{N[oY 'ٟ-@'?$%7AllʄN?]xB!3S1#;I+; %ĮKf>8 j3Ko"'dJuY βn$ORɵ϶RLq)7Z蟭ny4)38Re]wneI-i`^5պ7QDVjFlW% tut|!l/o& 99C3e?G:ǧT xsW^Vb֟1FgpZ:1o3<RE m?&^~ EMtpGDW~Q!vmqˋq[+ 퇌 W(]=QǶ$4]USgsz`a6y0fp9&3S8t'_]SUUJ{ #CFP'4u6Q9\.֟^T V[/غ1_m(^ȣUy\PYSʧ/Z;[6],?6nlX걶151E:/,~^}s Ӄg'=cʠm4$}Iil t@+aKl+*Yv8]@*NxៃV J݉:y0*ɲ JlYf ˵JK-JBRXSH,]$Y?g49p,|XD@rW?o+I&B2qĉ^\ (^Yl?`%W;5}k9jxm$45ܓ'mH+|s +{WmӕVY ^]d+n2a%F %V!=7N/w7.UPe=Q&ϸj=Ooh a%8}/blvv~ߜqcwTͷtwC#F@.xHEM/rXskTǙY\|}[^%~y_ bR'̮%'-oA=[mc&yN?{=c-Cl]]ɓ!өnBӋ~y!yL)K?A\|suÆv{vgs!>G KY8$fvR,lrM}\njz{<UOg1$5N5=ɞ:/ zp3Va1X mjj׽OX hzR 1X[x708,+ MrVM=zo^zq}rG6f)i 2aU SM@o4}.\C6gEnAi!y ȒqAĜ7H@˘fDPe0̺;Eyul[۱_8aB~sgKv$̩*@Ӄuo^S!V"o7nӦaj2gwndLTW⟭mU@a\JnL CjH'L6K5Mdh & ftv X mV3s3s;y̹{gLCݻ?|矟p&Ƙ@bhz.oWx}Ӳz|JwV4Yj6v!ZUέjK\eꭧ򩵚2޲6>L OG<'w:eU8 q[**н{}Ld=nzG^|#G~Zsp&Ƙ@X5-G zEOqg֠a #s _#OmgҥϪWjۅNz:=[m'T4"t-w%/ vlQyR_vL޾}3'&f#;w(@j5z9ˣ/~j %w5QP`D=>Uo SЭTia#\Ȟc/42xMuOtZ觕kZ:ݺtRS1%OeW֦F!pc߾EO=zAc'$_WD̙rjpvX|(3fbSt]Ɋ U8J#zLK<Snm5JzPm..nض% :^\{dIWҵ#//S62@7IJfUG[&jn_}>;5V.P|#h{>5#s`:+vAV䓈>Z//.e=I=qUb"MZ9^oIpd\3!J~_/$?ZuNMM }stj:Gk2UMWUnʮZDpM3j)-c66TYZ*Vog@R<ЭZfJل2nV8BUi#zdUbP_;KzS~zw0Btst(G۝T y3=|_}YjT^Kى}^V^E'p5^_(Zk}.KtP7|r?Md3i||ؘ{9sd$IڊмyNآ1hCe+ w {ݹʘ\ݱ/#4f|\*%K5*Q̪^EO-VV%6yY}!|<;ɐt?$wupwY{R>@~rrz۾E Z1+$ݻЃx zRt*ڳ-XjjHn=y>=K7W]\.DaW%Y2cyo1*YXOcoTOUNe<39r459%Zo/x)ժGkj/ܚ$VrWmnJ[a1M77c*kX$H6^%xa~ Ugi$DMûu)tzJ2n S  uԡzd' vV}!v s`ru@Q'zW𿮰m70`x{'oH~f'&zʼnI[.Y%%=iU_״BPgڲ\%DfDK[TŨ*C} ~=X|zegcI/PkD¯6:y&}"Ud˚!c "8,LR%}t [ilCt#zp?QssJ3$d(67^K/O5!lW Ͻuc~pVA3C~%BD N m ".o!LW7py>Chrat:s͛36oVgEI.~Xe2;7ث6Ge{NLXdwpY`6GÛy3_FoT;9ރl y<,k`k$_il Y 2޲Xfuqy|J8Ԧ14~-Lʨ %&L|,=bǪͧhv OAs;Zx:ja.rױa0՜S\ f9L֨<zy Jm)TiԻKYmmnJ/W&འL16s%vn'IX!} }-]RATҟ;A3@JfZ8l_#c 黍S_o'/IŢdqUTŽt M:/MO3>(J ̓;`|Ӳzsq^G $<γ24nJcj^_Sϭ;zk]5uir u%c%} ] #$HIX?۹F}s'ӧVܑFZ0O\9ѿ$I;s%1R͔v?e#ƧI!ynUu_5IqpkCS[Ff{[p8x LW^ZO5uN\]984PU/Fp繁eit?֗33}nELfdkΧ\] UXwJ}x%1.K"wc7/89Euv{fhiXydh f3fM/뚸oki@ڮ׵P%}iaCqzk | `Du5jސ,?(]n" w^ۿE>4Ԋ>CXUHԻ,ȼcZ&>ȏӟt:wd#? (i>&u8Ǒض mWCA~(ykx&[YI0ݪN>)}74}tRH*GcX" + 7584z+Dnۗhz@>{ =$Dʕh<ל9S.Z~1͔eLt]ɚ~<>q|uЌ+eZ!rksQӀjsYvqcǶM-Q(#KzUGyyy͟zT Gvy}A`VRz W;(oʯWw֟EHޮn?XN`@)z#D(qZkEԗueZO~- }&dxߏ ZFGUO|%DXh*4wsjjnW_矣W9Zjz -4tWv՚ k),rHz[]%r :*[z-o0tNQGee|rJK U4Oh9]w-5SO&4Akn5*^Y/ykuIs~.S`04}J+i^av%[s  P~B?tv6ykj -\qOl3" KFdT0`=oQP!{d$ȑ%"3fky!#wE . `WV XNBg'䔴< F`ss&h%\Ȓ=X$Z_ _q9]!T @Wս{ lt&s/s:g$Bc4ntϏzsH]:-f9T"O[aDŽxWf 27}q/v\jA%ա. ӐGKnRվIXWq`~'HIcv#)Ty ؀NR2*+Jm8!IHOǗ<ߔ]fx|"|+U} f)鳓}:cxڍ2ϙ量mխױ>OwPHңB%@%R1Dfܺl6ds ճϒT͞ڸ=5 -ZM 3Ҫ; fݣ`ݓRlsCEF1wGnZtasxJ|=~(+ED b=hW.~{2uoM}-ZLzJ-SCQN/ zn$̧S8 8"\9uUkt]eOf[KUJ3EBT#yv!7Du蒃 ϙ黍SV+T13e}qzQ|'*b&ylƕEI+htK]=zY"Wߣ О=β24{6z nҪY{leAh vʱALA~7*|v*XWR|49D9Ǹ |.yI[#\w+L%꘼k6M;[0tI$CM*!QC/M,:[ Qb`hIz,Ι;/ٯi^g'/ǂKE%~\z*KNمsB5`xGv޸AL@kd޿u -YCrwʼzbUa/-(s_c-3zSAT*!=uK3g,ß}k{ڀ/Ml ^ K^C/N_,m73@lu<9˜XyLֻUV;H/O\{^(TW3YӧZiuO1u;0[ո1ҟd键O*n|Df@Hqz&&`HK0L-^+R€^jbB3;Çhrat:s͛36oVJDh0_7bϦywoV䌿w}̄2=ߛJϦ49ZU^1Q LD_x&9"-ldȓ7|QYa6f-XMrCKkpy<T hI᥻<= >Q!X'wI犫v{a4 ZI=;Uk_¼UZr}BD^VY$"'`=/>mWah'c,ϙdF.it;ۨo긘}UM}iqޘNk:^)\}wIԧ}S[FR+4>M"E(#q(LFe`KA K?W_}|tt~v6Z-^LRnfFSS3nt7,G^rR{Ubjx@\RߋLʨu!Lp{MCqa wKq.MB-̥_Tcӱa0՜S\ f9L\zy JHxMv7*͓z })M%6p^PyqzK;7FZ'ܣmt 2G)釚Bj8x0iqӊj;&} F|X%TB~ȉ+(KFykI-,jpug9eeSH~D7nJ#A_5>6w=?iS@k¦_GNU=?>>ϭʃnx +9%k4YT=9QtN\|99yIc& fYAMTe L>F4*xNa бD 4kaHDyvu湡yzk|?IVOڮ׵P2M#CO+Rf=z7tu9g"j}TCAA{=p!x HT<.t1I z]nRֳqwa?glDյXOzk9UgF:f9sd֌q^ 3QuQSVk 8L%}p5q@!@@|3\ӃܑK@bFHy5Qs*x*<.Gk "|?iSLǢ] "@1hz (X.,ufњd]~@Gc[-Suu~ V$x (ޛClM+iiX6s[̕8U\<{8hc̀ A4}QߒQ1덒^9)z_d)Sd5cڀѓ'~uT1MJBww~Oqc")z`SWl|ڦztқp:eŸ76>Ws**PJ 9=zA4cZ_LimOM1~xꁖ,g_[t멿=ѻ]sajۏ}?{PneVonuC 1N߿@P_ν.9lcэ۷ovĬrѠtt%HFO<1/y?t@B]M36p0ŃB$Ф! 4N   XP-=KFe^\q$@|-2qEkmvKB;˕ /°l;nsI)S.hdOQivZyC7-ZO5oۮϐ³L!ynUU>ET៑Z>C[tԻAmHq-ÊvE Cp pZSM#.vC4ƾ}z1hr+Wy\sL\h~?{8[O3Vy|8* IWʴC0P>ƎmZP%Gty *]< q1_h?𳖈We7"U%e"b߾iN8npcwX)9ne=;ϟU}Id?:?nlsv]+|aUf}fVWi[ E]EgM蓬^;~K#b 3y:ɷU??DaY?UܹΩ ]C^ 8ԚLUU+>foQp/\ Oa@tj[]%r :*[z-o0tNQGee|rJK U^yv$,k4n+%ՠ0g5mwW ,e-UF!X_u=tMLۡchdhPZFzﴩe& e#$+t]Zt%[_W5P8'Io'l.…h6/olDV+?pvQU/D%ⓑīsȌIpn厅7"7P5 SYN-< q\F?6c Ma.쾯۾Iyi "\[i")̦SzMr4r&i1!;JIIfm) kŷsDTW<؄+% C\X^ȫnB~ߩ@$e 4VIAPo$ ue3Iӓ uϤ4*JM tt7C1^Q@kq7u6T[yLwi 3}S'bom19^@j= y$ၾ-9 <>%(&D6[O FR=aN*N-dTV pB/7x)y jVbpߵ*|+Uo4{M!8T_jN~錥+i7rϙT][[G؂w[r̚V:<*L*yYI?]ɮ};N2sKTV]7qLJpF_~jk?nr]3nB6W_9g采я?fVm܈x͚-Bs&YiUq¬5=fݣ`ݓRl3ᒸ;Dcx4* 3*̽ ղN*wӇg7[\zJ[?u֕"r%<6j{-)< r.l@f)n0EԺaӻE䱽zW?j@+hr;!tK]=zYNWߣ О=β24{6z nҪ?cY{leAf{h vʱAƌBC'AAc!OxcSm0{՚.|%WNC3y^U䥩wKvuIRIfwgZ$S ⅡK !$$4Pn"̧j5tN=CWnh_j=%%U3C&#r>Rm?Wܳ^[7e<wdABc9W_*IB՛! ^y~7_G--ى ^|qbryփKpwII)0 WW5p6,ztctD.dō6̘ϥn:\"Vks;gZػ.l]QQr!aeu+OϜql3l;%uPkD6:y&ȻxljL kaaz`ޠh]3RG^!y6 DYi&cD [7g]93~5z-tSn" !T@"K`,A>Y 0K_UW;Ti,ItT3w)%BH?PK:؅0@j.<T^Fvnx̬ &B/F:H/O5A{^|b番} QN('c^rūjm r[3Bӓ7H s Ӛ" &Y n@VW\_㣣ҥhbgFSS3nt7,G^rR{Ubj<4>E~'ب;A^"EmLq ;شUUڠt^-/.h.IqT?$0~Q90j8u9rPk$3z^^mMJ-^rSz͸>~-aӏ~K;7FZ/跥ҽK*J3r'(zHI?zGq$pHfBn+y58It$b>ӈR \i gMx_d{*Qo5W>g7ف{ONOZ|6^?r*o}蘭~nWvkHW^ɹw/Yq͚z!̙RsK77 m. T͛3Qo`d`0BW |'5+kѣxcAWs,wMM%9?d w:L^aiǴy|72g̚1nG|kT395Eedg1Usݡ'CŊ D->Q4Nnˉ/򭛷47׋?61þ EKͫ~<{u2> n7y&+2Ƕ[$֟G.>h? I9J|FXD|UbQO+ /j!qD~S 6uE'6L.)E18};߂c%}`FtjRLZh9.H+D%4"K@!b(N}Za=65v#c^bQL#3Nw͔ao1>w^ {?fܣyVXK,Wތ~G6+GIxLFe@G<&op1>Dg_tCeiBuwX;HC6oJ(7ӦBlW€}L02p87iܚHyqN?K>MJ44Јӏetq!7 f3֬L$2>ȯ{Pj{-1# G$FbQL:f+((m\9NK?VƲ?ݪdĉЬKAcz~nSuF˺&fZϊ4E1q)21mɓ ?|:*&%w;??'M1~^ET~[[OՉE1qzSV6ƥnͪ@Qr2ŋyşqhhsca!jל:]xba[T{ݻ<x }ogNL*/G JOGwQ71jsG/_C'. >nDB13-Po SeF8)%N߱،&4Dʃ@5]b-Ш%a4ƾ}˧x c'Dv;z!r%;tjuw_{饰uxFi' 3~'QsD~Xcۦ[6^)sxދչ9l:]tPbCz&Y҅*=;cAfu u;gu GvyL l 5mSk1jRR>H{շH_!ccݧTH: zzwJFͺ[Y5L~8_j4::~/ ?ZsjjnW_矣W9Z i<>3?^Uk(Vx >@ J`uT,Z` m D 8%QY|$Zu SZlmT6΀yđ'P-WiJm6w[M; ˫D:s+p@4}sҥ}E[YKr*wq?ZR鯾%ueZ P~B?tv6ykj -\qOl3" KFdT0`Ǔ)#*9g$^x#Dfx:،MAAqgVQ67yuEgk5YN-< q3_:6wǘ-,4 5pin^^ZOזrH ")|ԉ^:2GC/Wkrh֖"˙ܰV|;͕GuẸ0^踹gޅ%P;X<˅/:w*:; 79%y/e3A-E/ _ZK߅鯸d-_\{phr9I3˜Ι##I'OV44KGHDwlVӡHJyw.p嶲>r_3SsJ躈?Nt=~"7u6anzV*]y-L EJDG CPsi# %o)j$,;$zd0rTy ؀NR2*+Jm8!IHOǗ<ߔ]f8Pe)B+{4c͊_AE`_鳓}:c骬|vs&h%8,E_~jk?nr3nB6I+<R=,y?0G٪OYТEhܤ=#+;NYw-wOrHuL?IЈ:f6qw QO y많ҺRDT.Vy.~{2$}6KG_59]J69&(g{cxKS4 \59 uIRIfwkZ$M0tI$CMqv%`"n!6}JeВ:;{GKK f)WtΌcM?ܺ]V>!j.rJy .x=SU++Up3  ܜ7= f\##[hɒSD { x [XKdƌQw>~l:JW3ώ=m&6a$\H\zxq:Le~b9ĚNaS|IRA(fLx,` Wm"J/vup8·SuOVWpJZj.KrQkK/}51qwKL|90uV:?ܹs7+$3x:to߻t>fzC!$}$F%3Q2w-% b6XH(,0~cwI^\{hpfxGDk3yܳ~{tjkFKjN\ J610๫`a-a+<*D_"'`=/>?pN&ϙd"B~GVH2FJW\_㣣ҥhbr3{6qa>z+㬚SJ,3!*{hrdP9(P(~\N{ fk0jΩc_]]kPk$3z^^mMJ-H_jksSzSʦ_g,s=OjԨ )q=HޖJ. *ɝ s ~!=#j4o@YK-xSpN/i}]bVlȉ+(KFykI-^qsfQ)xc]? F֩E-M Z>e|NqNST]Acw)̇?yaS#ׇ٪qAl7Ќ|啜{5׬Yr͜(u:'._qo~y X&*aipy F&x v\ #dxn迌l4fo jd ~f! 6M @E;Z8k,':jʷnhb܀_/^TLM/ V5Y߹Gw(MV4NtѼʣwQ7.㍑k(T۸l>_M,fToPu3C#$>/WD ]Gp8!wYN37@i:(  ƒ8=Z/qc%} ] #$`95xswd#[Ge L7@GH* I"] "@1^O}@v|d,[7ʅ\|3,Z2 ohz@q}͡cߦϕS봴Che,?9ݭJNJ*.d 37#IȠ,ejFˀѓ'g[,K~x 򗛻4+ }/0c[t[=Klߧn".]&NY1n}՜ fD=|͘/~SZ[8nf̀ 5=ŵUiuOEcOC-P(/P}@۱Ec7~;sbbVy9hPz:s V'q 9N5X.d p a6 р.Z|HlГOI\s͙3r=.s(3fo!qTЌ+eZ!rksQӀjsYvqcǶM-Q(#KzUGyyy͟zT GvySDwj@]!.ׁZPku`}>=;5V.P|ZQ qW S9cD۪^|4:e*3RZzp7ԇc+BΧ_EUxZjTAV;DT`jmj~IUPa|[ T#gw>CK#Za_/.GK /շ$TYLk>ѡqO矓nN&/\pMM ќ9Im_$a)؈Vt~8gvQUK|rߢ?nHU9BdƌI\K|1z ~mp_Go"泵,` RBrlaW:օ|4 7/ԧkK9C$ٔb>yBA^p#MS36f3d{G))I=<Ь-E3<avꊘGa;7K=v-~^D kJ zS~zw0B}-jYoüĦrS[3ȗ")})NUs{.'䱽zW?'d!I/ĚߣgEII$i~nтhgY==KZgL^;+~l7h.Q96И b\qʊ*-+!OB2G~#՚.|%WNC3y^U䥩wK.ܚw溃\)$q;Z2SlV%}t B;2[,Aku ET jQ*)<BT-I/1\93A4=BOmtg1Y3ߞ;Vkp_>;7J ;+|_R9Zh /"~zg_} BznWm,R nΛ}trxyf3yjvbo~{-d%)2t*^kP;DfțZ [LX?'fsI,UzϜ v/oi4 3{%/^TJ.y =8~b~2?YRGcbMaOy?&m&;T>CJ/O\{^(TWi3FӣZ=M?ӹ7;Q}&:žkJ>vȆ֢{/\%%Š?t'|JX#i <"?2jW,;q*ps.{Xpw@|$ŝ{ /*k0jΩc_]]kPk$3z^^mMJ߲G.e)f~n *4<?@?Qo37Xri1zߟԨQR{ܑ-]RATғ;A( %PCH{G&,h~ӄZb<@gP_"'܍SMݻ'?9?m h-O^Txȩ_cu\y 4#7_y%޽d5kꡇ\3g"G}GSˌ]3'ro$oc>֟C{t;ϒ/j&NaKxke˚Υ%.Co5ejsuMȎ|e4}D/N?2xMTxY瞝6F@~Mos=sҨ zc:.NJdQ rfӲz|^M\<`CSD6*fCS[Ƨ `d@“Vﰲghgի| B'V\j>9<-*|0@M vS!dBD/N90x/>D=hzY}iwRC#&3dV mZPNӧiW.t=V55nB* jG |RH({024lѲZΚ1- bMڦ zI!L56m`Y3p[QGIծd Ie͢<V0ފY  Ck.[s6Mqz 5}ֺ2:A)a!rtDњP,BYW5ugy"hUqz 5=oV6j՛$pVw0 )Xeo;5KH!M\j g{>@;y@P6_tվEQUlF:yz@RZSŢ@Z6[+ oY_]ֳjZM6!5T. .]3Mb ̂>@ @ 2{o8=7(آ V^C7Fڥ`-r'UUUvG'^AMg\d6oR:۱EcXrګŴϪyE@iueZ'~U6'&\$ˇ">2TUO@|jz:f7*#'ˬTB>JpɃ+}%;@'woo$ACSMOd;⿳|k#|9FQs}J@eUla !y =OOEóTPU䵛!&@PJ]$=7 /@-k[lO.]3MRY?so\Q-{ LZPB qM 2@P@|qqz@! Nq-*/ OSGCGMO~Id{4TNqf"dwMGGCHMIߜpK^mwì@HMP"Jk v^ xU\Ϥu}NV &^l&GE?\VJDGVEn^K[. /ȪyZÎ8=,bM]Jh8jZH*Kz?_WӷV BE٫is4Ҫ"C엯/A N$evRnS-s-6buoo;-dBH,M_tܩ\a$BZ@T8VhXR]ckM-$ _t^$PtR\.x!\t d=g^RE~`L7̽qEu4ol\3l++ۤIrKڋ-.@B7ChĽЛ P ն\aYl6jbF$ܽ[ќ\I"ǒeٖ%[;gqAyCgN̽hcC:QhSouzDu属ؚNʃzh,uz"gC]3LfFz8G-ߍNL?;==z*Q~>x~{bzvW:=Q٪ >x)7X5SrKП &zc=c5]\vmOq O/<9VޢoݩL3| _7dwX8%'\nk 94^ pDΠ2gk(2AwR!/-t^dpuN@3}!&ӗZz/Oˉwv__&SӃT85Z*Ճb?q,> ?;?X:^u):=>3=q<ۥNBf1/}65ya9&vEz~(D0Ӈsk'ՄB~hi4A<_k~X2xd_^XDAfp~DoէPǎUY',e6;ٳC [) ?9&;ɅjN@3}27V˷Og. M@?YㅂgnTs ↟-_W'S LTPCP'\.g`~~^ b>Ee@M17ԉ:=D:}P'm N@@7:=uNѦN ԉ:=D:}P'm N@@7:=uNѦN ԉ:=D:}P'm N@@ձN?; >-_ay^eڦN@_`ri9HD2XAayi!K[}RS!7@=ԱNVw*HlXrb\t,j%N@2}~+(G奅xX_XZ.blvMV,so`ǒA1/_ V0ya򃮃WgC]3xyZ(f0gdS~+UĦ>4UL_kSLU-5&ztΌ.'&&:JI,Xb؛:νmԉ7m{ AcP'm N@@ճN<[o`v:=u'gr >ԍ N@sei9=c喞$raa]ijy};o:=U}v >5S=LPS|su&&󅭒~W];^JD4'K!`{ض${X2XX*F3uoozwvW/3]%s;l:=,{u$:ؾ+lX}R2o;:=Mk*5Qc}/`J4Qo?LLgNOlRq_[ad>dmURN>&3=X,\\0=qj;MVa|D~ b\(4X@2}\2cq>}n9m>=ub DCԉ:=D:}P'mWn.S}ךzƖr`LrgbL陮xSz7 ꙾Fhwj1..H\l/=3>L mVN>/_L%O'xSWNO~P*y,LTwg| :=QU=әɍ'v@L_lf;&N@3}Y޴=1]Mxuz%k/ӵ˗iMcxnf  K4T{uz$k+Gء~yg'--uYYr:ccTwg ٝZ}ؑ~yd&W<3Vwb<7uf'uK Aң](ԫ#3}^jB)^4^, Ԗ>zזrſgli>5f_Z')㡨#3}>N/P}3S)ߥ\?LND|ǃ󅥮ʛPb|&= K[M2_[uzvd/ܛ0h+ݣ*@͇b*5T ZJ}t;t9f }Q`GfفXb.Ǚȷ#thy}.wipFu>P_ؙ>1韬L9ә)~LkxUK४ : M[f£ h4OЙ(-P=? X..Yz]?N?<ϋC=w̮f>=lF>lvN@7luoMO P'm N@@7:=uNѦN ԉ:=D:}P'm N@@7:=uNѦN ԉ:=D:}P'm N@@=:XOl`qcڻ:=Mw%7x G:=͘ EZcyk.W-ofP@|(Lb=uz1Ӈ&&󹼙djl!uk&leFz7t +|m|?^Y>SIC]>'3}&3Ar&wi}:=͚ s.%Srx$ǒͫSrO'SB}Ah~:=͚<FTwg:Wo7⥩5᜛YᾩЬ~]֔kT*-ά)O< Mݒé5&Iә*+th&WumV{㥅7׆⼂ٳwpvU:H['smݝrhdbLrgweծzcgFϏXbH?XՐY=*k<fSacLovw=xPmO_һ0z*^OƋNdPSb:y&,_^:}33 餆Jz' "}{1MONWq9o<-Ϋ5xtrLxaI>杜\^-+]fc+3K!Of&dF [E1wq_ko.v[W9AUgG|-ٳCAUgN5DsOM/=bc>{HDq~ o@*Uz=̺rݺRPYJڊ՛kɚ:\n_;uOL#}*l?jyo}d|zDMAuz6uQN D:Qhu属XIr}}N@fفX|?+%?oi)3ؙ̥L25tvZ&&Scx.7(uSr 5r*J6sv > &zkvhLYLuw7.L]3)9|>1/4&IxeL%O -3 ry<Nmo? ԩ̤)H3;)ۀ㹙X<6T|)Ocp{4s+3Xor2K=} =o6PNb\Nhy'xzۦlyzcC@6{:}P'm N@@7:=uNѦN L?;+-6,ZzƖ׭\y5V\[qmk_U'7kyU#3@o0 a|];>Ulɝ^dف\F3㮡㥠Og:3\erj;jzP`fp[W0{r^>P'{ix.3^Y^XZ핔 X7| 7\쮬u0\oy;XWOKl2cC}'Œ*7q,; U/:=u OzFOkxqt jRvj"8V,_g:τKõtf5~T}U:.gyUOAUat>/L=ҼS իt~+u,<}qey)Ɍڄh0yayH_8R.k~*W~<ȡ#3(p>{v(Jl=1]B]鵩>QlVW~b(uoq^A H%?ࡪP/G3S_YײP[W**+Yi_[zr-͛7~_|1_xނ3sO ow}B~7.+lpx}KvwV dHy"\vӸnG7n?ҋgү?{/O=sϼW^x_-³Ņg^x>\S @~KO˾Y!ͮ3k6dRVН;w }~=K/gO)R_Ija_^Yn''-0?_6ٯ[zR}5~+g*ay2d ;o~3_?}'zlvL?w)g7€LD>ƫmwg.}z\.Ghsdz b>~-{~832==W}@p.7Օo~k?ޟ D\v;KmGO8ܒ_HOL^[uԬnvqÆr?Vl@@oD':|*=LMrxgۧ&W>l$ˮ^Կ23 7J6$ICfk[[cg;w\{}@oN-wF ?tP8ɾwV 6nsobhq)T,Wbtbi ic랯\ixx\Ym}З_ҿ@#.=5({olɷ˾Y[(MTP;uv_ځX,gs>S 7Hx8-}4Aet_7XW39so7sox\>[oct7<(v}@ܾukS32=Y}j>S QtΝ/> ϻ@$]7_j~aOg dz br]?_> 2=9L\ @\ګ 7^~{og@Ν{pPp_GuCv-A\ʆ$;t}@-S(,L.>Qjy/}/ VYK鵕`'(gj}OE6r(FF& پo[[:Z*jn[Z>S W.G4tZX?\yNi;z'34;wn}s>{32nv[ZdK >;&|?7vag˕k7 5 Һ¿ӹn}n@>Mstͮhi)Gk>=un.{J+IL}?g@rfE\27ŋT.qSt|Ͼyj}ި׮^}=ß/xGL6h_mo?o]~Yze z|w)H k_/?7 Sdz b׿}dz bܹ^|k?O32=1"LLDQ.>S k}5\ @2~@.7?4 ^驑چMZBٹsm #WT_D=O>QLPGu_RngHash?߿h4@:6\cx͹sݽDvPLo4>{}L~6 v*|ѓ}ᣖÇ[q-%W.GO,f^++_W0gΝ{DWkkۡ{OrA`}?yg F\z\ni9p9ϝ4dZXw) KGV)^#]/;׽jy[?~l@`̽`]z٧|_{¥]?A U%@Tgo[2=1++}@֭Ϟ{駟z}@"Rw)/ܝ{vgi@@"rnL?3 s׾?vck!hb驑ێ:8Ğ=3uNߴٕo;:MW>TK_1<c`۩7-ŬO ӳSdjVWy-'skh7|G^}[ asUTWWΧX:גi^+tGTc}GwȞCXaFɉD\"_"}o嵿~/-wF.ˇELT( ~ Q=3-s?\ w\2=ə\L7/]loY85L^(属ZwU9,խJSʚzŠM,>QhXx:5Jlw60\^s <]L.uT׺/pqdV>+ɷLgל] [w.jg}U*x"*' + result.value.message + ''; $('#serverResponse').html(r); } ); }); $(".validate-text").blur(function(){ if (this.value || this.checked){ $(this).removeClass("incorrect"); $(this).addClass("correct"); } else { $(this).removeClass("correct"); } }); $(".validate-text-required").blur(function(){ if (this.value || this.checked){ $(this).removeClass("incorrect"); $(this).addClass("correct"); } else { $(this).removeClass("correct"); $(this).addClass("incorrect"); } }); $(".validate-numeric").blur(function(){ if (this.value && isFinite(this.value)){ $(this).removeClass("incorrect"); $(this).addClass("correct"); } else { $(this).removeClass("correct"); } }); $(".validate-numeric-required").blur(function(){ if (this.value && isFinite(this.value)){ $(this).removeClass("incorrect"); $(this).addClass("correct"); } else { $(this).removeClass("correct"); $(this).addClass("incorrect"); } }); $("#connections").bind('keyup blur',function(){ if (this.value && isFinite(this.value)){ $(this).removeClass("incorrect"); $(this).addClass("correct"); $("#connections-tip").removeClass("hidden"); $("#connections-error").addClass("hidden"); checkRequired(); } else { $(this).removeClass("correct"); $(this).addClass("incorrect"); $("#connections-tip").addClass("hidden"); $("#connections-error").removeClass("hidden"); checkRequired(); } }); $("#port").bind('keyup blur',function(){ if (!this.value || isFinite(this.value)){ $(this).removeClass("incorrect"); $(this).addClass("correct"); $("#port-tip").removeClass("hidden"); $("#port-error").addClass("hidden"); } else { $(this).removeClass("correct"); $(this).addClass("incorrect"); $("#port-tip").addClass("hidden"); $("#port-error").removeClass("hidden"); } }); $("#host").bind('keyup blur',function(){ if (this.value){ $(this).removeClass("incorrect"); $(this).addClass("correct"); $("#host-tip").removeClass("hidden"); $("#host-error").addClass("hidden"); checkRequired(); } else { $(this).removeClass("correct"); $(this).addClass("incorrect"); $("#host-tip").addClass("hidden"); $("#host-error").removeClass("hidden"); checkRequired(); } }); });SABnzbd-0.7.20/interfaces/wizard/static/javascript/jquery.js0000644000000000000000000015336212433712602024174 0ustar00usergroup00000000000000/* * jQuery JavaScript Library v1.3 * http://jquery.com/ * * Copyright (c) 2009 John Resig * Dual licensed under the MIT and GPL licenses. * http://docs.jquery.com/License * * Date: 2009-01-13 12:50:31 -0500 (Tue, 13 Jan 2009) * Revision: 6104 */ (function(){var l=this,g,x=l.jQuery,o=l.$,n=l.jQuery=l.$=function(D,E){return new n.fn.init(D,E)},C=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;n.fn=n.prototype={init:function(D,G){D=D||document;if(D.nodeType){this[0]=D;this.length=1;this.context=D;return this}if(typeof D==="string"){var F=C.exec(D);if(F&&(F[1]||!G)){if(F[1]){D=n.clean([F[1]],G)}else{var H=document.getElementById(F[3]);if(H){if(H.id!=F[3]){return n().find(D)}var E=n(H);E.context=document;E.selector=D;return E}D=[]}}else{return n(G).find(D)}}else{if(n.isFunction(D)){return n(document).ready(D)}}if(D.selector&&D.context){this.selector=D.selector;this.context=D.context}return this.setArray(n.makeArray(D))},selector:"",jquery:"1.3",size:function(){return this.length},get:function(D){return D===g?n.makeArray(this):this[D]},pushStack:function(E,G,D){var F=n(E);F.prevObject=this;F.context=this.context;if(G==="find"){F.selector=this.selector+(this.selector?" ":"")+D}else{if(G){F.selector=this.selector+"."+G+"("+D+")"}}return F},setArray:function(D){this.length=0;Array.prototype.push.apply(this,D);return this},each:function(E,D){return n.each(this,E,D)},index:function(D){return n.inArray(D&&D.jquery?D[0]:D,this)},attr:function(E,G,F){var D=E;if(typeof E==="string"){if(G===g){return this[0]&&n[F||"attr"](this[0],E)}else{D={};D[E]=G}}return this.each(function(H){for(E in D){n.attr(F?this.style:this,E,n.prop(this,D[E],F,H,E))}})},css:function(D,E){if((D=="width"||D=="height")&&parseFloat(E)<0){E=g}return this.attr(D,E,"curCSS")},text:function(E){if(typeof E!=="object"&&E!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(E))}var D="";n.each(E||this,function(){n.each(this.childNodes,function(){if(this.nodeType!=8){D+=this.nodeType!=1?this.nodeValue:n.fn.text([this])}})});return D},wrapAll:function(D){if(this[0]){var E=n(D,this[0].ownerDocument).clone();if(this[0].parentNode){E.insertBefore(this[0])}E.map(function(){var F=this;while(F.firstChild){F=F.firstChild}return F}).append(this)}return this},wrapInner:function(D){return this.each(function(){n(this).contents().wrapAll(D)})},wrap:function(D){return this.each(function(){n(this).wrapAll(D)})},append:function(){return this.domManip(arguments,true,function(D){if(this.nodeType==1){this.appendChild(D)}})},prepend:function(){return this.domManip(arguments,true,function(D){if(this.nodeType==1){this.insertBefore(D,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(D){this.parentNode.insertBefore(D,this)})},after:function(){return this.domManip(arguments,false,function(D){this.parentNode.insertBefore(D,this.nextSibling)})},end:function(){return this.prevObject||n([])},push:[].push,find:function(D){if(this.length===1&&!/,/.test(D)){var F=this.pushStack([],"find",D);F.length=0;n.find(D,this[0],F);return F}else{var E=n.map(this,function(G){return n.find(D,G)});return this.pushStack(/[^+>] [^+>]/.test(D)?n.unique(E):E,"find",D)}},clone:function(E){var D=this.map(function(){if(!n.support.noCloneEvent&&!n.isXMLDoc(this)){var H=this.cloneNode(true),G=document.createElement("div");G.appendChild(H);return n.clean([G.innerHTML])[0]}else{return this.cloneNode(true)}});var F=D.find("*").andSelf().each(function(){if(this[h]!==g){this[h]=null}});if(E===true){this.find("*").andSelf().each(function(H){if(this.nodeType==3){return}var G=n.data(this,"events");for(var J in G){for(var I in G[J]){n.event.add(F[H],J,G[J][I],G[J][I].data)}}})}return D},filter:function(D){return this.pushStack(n.isFunction(D)&&n.grep(this,function(F,E){return D.call(F,E)})||n.multiFilter(D,n.grep(this,function(E){return E.nodeType===1})),"filter",D)},closest:function(D){var E=n.expr.match.POS.test(D)?n(D):null;return this.map(function(){var F=this;while(F&&F.ownerDocument){if(E?E.index(F)>-1:n(F).is(D)){return F}F=F.parentNode}})},not:function(D){if(typeof D==="string"){if(f.test(D)){return this.pushStack(n.multiFilter(D,this,true),"not",D)}else{D=n.multiFilter(D,this)}}var E=D.length&&D[D.length-1]!==g&&!D.nodeType;return this.filter(function(){return E?n.inArray(this,D)<0:this!=D})},add:function(D){return this.pushStack(n.unique(n.merge(this.get(),typeof D==="string"?n(D):n.makeArray(D))))},is:function(D){return !!D&&n.multiFilter(D,this).length>0},hasClass:function(D){return !!D&&this.is("."+D)},val:function(J){if(J===g){var D=this[0];if(D){if(n.nodeName(D,"option")){return(D.attributes.value||{}).specified?D.value:D.text}if(n.nodeName(D,"select")){var H=D.selectedIndex,K=[],L=D.options,G=D.type=="select-one";if(H<0){return null}for(var E=G?H:0,I=G?H+1:L.length;E=0||n.inArray(this.name,J)>=0)}else{if(n.nodeName(this,"select")){var M=n.makeArray(J);n("option",this).each(function(){this.selected=(n.inArray(this.value,M)>=0||n.inArray(this.text,M)>=0)});if(!M.length){this.selectedIndex=-1}}else{this.value=J}}})},html:function(D){return D===g?(this[0]?this[0].innerHTML:null):this.empty().append(D)},replaceWith:function(D){return this.after(D).remove()},eq:function(D){return this.slice(D,+D+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(D){return this.pushStack(n.map(this,function(F,E){return D.call(F,E,F)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=n.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild,D=this.length>1?I.cloneNode(true):I;if(H){for(var G=0,E=this.length;G0?D.cloneNode(true):I)}}if(F){n.each(F,y)}}return this;function K(N,O){return M&&n.nodeName(N,"table")&&n.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};n.fn.init.prototype=n.fn;function y(D,E){if(E.src){n.ajax({url:E.src,async:false,dataType:"script"})}else{n.globalEval(E.text||E.textContent||E.innerHTML||"")}if(E.parentNode){E.parentNode.removeChild(E)}}function e(){return +new Date}n.extend=n.fn.extend=function(){var I=arguments[0]||{},G=1,H=arguments.length,D=false,F;if(typeof I==="boolean"){D=I;I=arguments[1]||{};G=2}if(typeof I!=="object"&&!n.isFunction(I)){I={}}if(H==G){I=this;--G}for(;G-1}},swap:function(G,F,H){var D={};for(var E in F){D[E]=G.style[E];G.style[E]=F[E]}H.call(G);for(var E in F){G.style[E]=D[E]}},css:function(F,D,H){if(D=="width"||D=="height"){var J,E={position:"absolute",visibility:"hidden",display:"block"},I=D=="width"?["Left","Right"]:["Top","Bottom"];function G(){J=D=="width"?F.offsetWidth:F.offsetHeight;var L=0,K=0;n.each(I,function(){L+=parseFloat(n.curCSS(F,"padding"+this,true))||0;K+=parseFloat(n.curCSS(F,"border"+this+"Width",true))||0});J-=Math.round(L+K)}if(n(F).is(":visible")){G()}else{n.swap(F,E,G)}return Math.max(0,J)}return n.curCSS(F,D,H)},curCSS:function(H,E,F){var K,D=H.style;if(E=="opacity"&&!n.support.opacity){K=n.attr(D,"opacity");return K==""?"1":K}if(E.match(/float/i)){E=v}if(!F&&D&&D[E]){K=D[E]}else{if(p.getComputedStyle){if(E.match(/float/i)){E="float"}E=E.replace(/([A-Z])/g,"-$1").toLowerCase();var L=p.getComputedStyle(H,null);if(L){K=L.getPropertyValue(E)}if(E=="opacity"&&K==""){K="1"}}else{if(H.currentStyle){var I=E.replace(/\-(\w)/g,function(M,N){return N.toUpperCase()});K=H.currentStyle[E]||H.currentStyle[I];if(!/^\d+(px)?$/i.test(K)&&/^\d/.test(K)){var G=D.left,J=H.runtimeStyle.left;H.runtimeStyle.left=H.currentStyle.left;D.left=K||0;K=D.pixelLeft+"px";D.left=G;H.runtimeStyle.left=J}}}}return K},clean:function(E,J,H){J=J||document;if(typeof J.createElement==="undefined"){J=J.ownerDocument||J[0]&&J[0].ownerDocument||document}if(!H&&E.length===1&&typeof E[0]==="string"){var G=/^<(\w+)\s*\/?>$/.exec(E[0]);if(G){return[J.createElement(G[1])]}}var F=[],D=[],K=J.createElement("div");n.each(E,function(O,Q){if(typeof Q==="number"){Q+=""}if(!Q){return}if(typeof Q==="string"){Q=Q.replace(/(<(\w+)[^>]*?)\/>/g,function(S,T,R){return R.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?S:T+">"});var N=n.trim(Q).toLowerCase();var P=!N.indexOf("",""]||!N.indexOf("",""]||N.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!N.indexOf("",""]||(!N.indexOf("",""]||!N.indexOf("",""]||!n.support.htmlSerialize&&[1,"div
    ","
    "]||[0,"",""];K.innerHTML=P[1]+Q+P[2];while(P[0]--){K=K.lastChild}if(!n.support.tbody){var M=!N.indexOf(""&&N.indexOf("=0;--L){if(n.nodeName(M[L],"tbody")&&!M[L].childNodes.length){M[L].parentNode.removeChild(M[L])}}}if(!n.support.leadingWhitespace&&/^\s/.test(Q)){K.insertBefore(J.createTextNode(Q.match(/^\s*/)[0]),K.firstChild)}Q=n.makeArray(K.childNodes)}if(Q.nodeType){F.push(Q)}else{F=n.merge(F,Q)}});if(H){for(var I=0;F[I];I++){if(n.nodeName(F[I],"script")&&(!F[I].type||F[I].type.toLowerCase()==="text/javascript")){D.push(F[I].parentNode?F[I].parentNode.removeChild(F[I]):F[I])}else{if(F[I].nodeType===1){F.splice.apply(F,[I+1,0].concat(n.makeArray(F[I].getElementsByTagName("script"))))}H.appendChild(F[I])}}return D}return F},attr:function(I,F,J){if(!I||I.nodeType==3||I.nodeType==8){return g}var G=!n.isXMLDoc(I),K=J!==g;F=G&&n.props[F]||F;if(I.tagName){var E=/href|src|style/.test(F);if(F=="selected"&&I.parentNode){I.parentNode.selectedIndex}if(F in I&&G&&!E){if(K){if(F=="type"&&n.nodeName(I,"input")&&I.parentNode){throw"type property can't be changed"}I[F]=J}if(n.nodeName(I,"form")&&I.getAttributeNode(F)){return I.getAttributeNode(F).nodeValue}if(F=="tabIndex"){var H=I.getAttributeNode("tabIndex");return H&&H.specified?H.value:I.nodeName.match(/^(a|area|button|input|object|select|textarea)$/i)?0:g}return I[F]}if(!n.support.style&&G&&F=="style"){return n.attr(I.style,"cssText",J)}if(K){I.setAttribute(F,""+J)}var D=!n.support.hrefNormalized&&G&&E?I.getAttribute(F,2):I.getAttribute(F);return D===null?g:D}if(!n.support.opacity&&F=="opacity"){if(K){I.zoom=1;I.filter=(I.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(J)+""=="NaN"?"":"alpha(opacity="+J*100+")")}return I.filter&&I.filter.indexOf("opacity=")>=0?(parseFloat(I.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}F=F.replace(/-([a-z])/ig,function(L,M){return M.toUpperCase()});if(K){I[F]=J}return I[F]},trim:function(D){return(D||"").replace(/^\s+|\s+$/g,"")},makeArray:function(F){var D=[];if(F!=null){var E=F.length;if(E==null||typeof F==="string"||n.isFunction(F)||F.setInterval){D[0]=F}else{while(E){D[--E]=F[E]}}}return D},inArray:function(F,G){for(var D=0,E=G.length;D*",this).remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(D,E){n.fn[D]=function(){return this.each(E,arguments)}});function j(D,E){return D[0]&&parseInt(n.curCSS(D[0],E,true),10)||0}var h="jQuery"+e(),u=0,z={};n.extend({cache:{},data:function(E,D,F){E=E==l?z:E;var G=E[h];if(!G){G=E[h]=++u}if(D&&!n.cache[G]){n.cache[G]={}}if(F!==g){n.cache[G][D]=F}return D?n.cache[G][D]:G},removeData:function(E,D){E=E==l?z:E;var G=E[h];if(D){if(n.cache[G]){delete n.cache[G][D];D="";for(D in n.cache[G]){break}if(!D){n.removeData(E)}}}else{try{delete E[h]}catch(F){if(E.removeAttribute){E.removeAttribute(h)}}delete n.cache[G]}},queue:function(E,D,G){if(E){D=(D||"fx")+"queue";var F=n.data(E,D);if(!F||n.isArray(G)){F=n.data(E,D,n.makeArray(G))}else{if(G){F.push(G)}}}return F},dequeue:function(G,F){var D=n.queue(G,F),E=D.shift();if(!F||F==="fx"){E=D[0]}if(E!==g){E.call(G)}}});n.fn.extend({data:function(D,F){var G=D.split(".");G[1]=G[1]?"."+G[1]:"";if(F===g){var E=this.triggerHandler("getData"+G[1]+"!",[G[0]]);if(E===g&&this.length){E=n.data(this[0],D)}return E===g&&G[1]?this.data(G[0]):E}else{return this.trigger("setData"+G[1]+"!",[G[0],F]).each(function(){n.data(this,D,F)})}},removeData:function(D){return this.each(function(){n.removeData(this,D)})},queue:function(D,E){if(typeof D!=="string"){E=D;D="fx"}if(E===g){return n.queue(this[0],D)}return this.each(function(){var F=n.queue(this,D,E);if(D=="fx"&&F.length==1){F[0].call(this)}})},dequeue:function(D){return this.each(function(){n.dequeue(this,D)})}}); /* * Sizzle CSS Selector Engine - v0.9.1 * Copyright 2009, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){var N=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|[^[\]]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,I=0,F=Object.prototype.toString;var E=function(ae,S,aa,V){aa=aa||[];S=S||document;if(S.nodeType!==1&&S.nodeType!==9){return[]}if(!ae||typeof ae!=="string"){return aa}var ab=[],ac,Y,ah,ag,Z,R,Q=true;N.lastIndex=0;while((ac=N.exec(ae))!==null){ab.push(ac[1]);if(ac[2]){R=RegExp.rightContext;break}}if(ab.length>1&&G.match.POS.exec(ae)){if(ab.length===2&&G.relative[ab[0]]){var U="",X;while((X=G.match.POS.exec(ae))){U+=X[0];ae=ae.replace(G.match.POS,"")}Y=E.filter(U,E(/\s$/.test(ae)?ae+"*":ae,S))}else{Y=G.relative[ab[0]]?[S]:E(ab.shift(),S);while(ab.length){var P=[];ae=ab.shift();if(G.relative[ae]){ae+=ab.shift()}for(var af=0,ad=Y.length;af0){ah=D(Y)}else{Q=false}while(ab.length){var T=ab.pop(),W=T;if(!G.relative[T]){T=""}else{W=ab.pop()}if(W==null){W=S}G.relative[T](ah,W,M(S))}}if(!ah){ah=Y}if(!ah){throw"Syntax error, unrecognized expression: "+(T||ae)}if(F.call(ah)==="[object Array]"){if(!Q){aa.push.apply(aa,ah)}else{if(S.nodeType===1){for(var af=0;ah[af]!=null;af++){if(ah[af]&&(ah[af]===true||ah[af].nodeType===1&&H(S,ah[af]))){aa.push(Y[af])}}}else{for(var af=0;ah[af]!=null;af++){if(ah[af]&&ah[af].nodeType===1){aa.push(Y[af])}}}}}else{D(ah,aa)}if(R){E(R,S,aa,V)}return aa};E.matches=function(P,Q){return E(P,null,null,Q)};E.find=function(V,S){var W,Q;if(!V){return[]}for(var R=0,P=G.order.length;R":function(U,Q,V){if(typeof Q==="string"&&!/\W/.test(Q)){Q=V?Q:Q.toUpperCase();for(var R=0,P=U.length;R=0){if(!R){P.push(Q[T])}}else{if(R){Q[T]=false}}}return false},ID:function(P){return P[1].replace(/\\/g,"")},TAG:function(Q,P){for(var R=0;!P[R];R++){}return M(P[R])?Q[1]:Q[1].toUpperCase()},CHILD:function(P){if(P[1]=="nth"){var Q=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(P[2]=="even"&&"2n"||P[2]=="odd"&&"2n+1"||!/\D/.test(P[2])&&"0n+"+P[2]||P[2]);P[2]=(Q[1]+(Q[2]||1))-0;P[3]=Q[3]-0}P[0]="done"+(I++);return P},ATTR:function(Q){var P=Q[1];if(G.attrMap[P]){Q[1]=G.attrMap[P]}if(Q[2]==="~="){Q[4]=" "+Q[4]+" "}return Q},PSEUDO:function(T,Q,R,P,U){if(T[1]==="not"){if(T[3].match(N).length>1){T[3]=E(T[3],null,null,Q)}else{var S=E.filter(T[3],Q,R,true^U);if(!R){P.push.apply(P,S)}return false}}else{if(G.match.POS.test(T[0])){return true}}return T},POS:function(P){P.unshift(true);return P}},filters:{enabled:function(P){return P.disabled===false&&P.type!=="hidden"},disabled:function(P){return P.disabled===true},checked:function(P){return P.checked===true},selected:function(P){P.parentNode.selectedIndex;return P.selected===true},parent:function(P){return !!P.firstChild},empty:function(P){return !P.firstChild},has:function(R,Q,P){return !!E(P[3],R).length},header:function(P){return/h\d/i.test(P.nodeName)},text:function(P){return"text"===P.type},radio:function(P){return"radio"===P.type},checkbox:function(P){return"checkbox"===P.type},file:function(P){return"file"===P.type},password:function(P){return"password"===P.type},submit:function(P){return"submit"===P.type},image:function(P){return"image"===P.type},reset:function(P){return"reset"===P.type},button:function(P){return"button"===P.type||P.nodeName.toUpperCase()==="BUTTON"},input:function(P){return/input|select|textarea|button/i.test(P.nodeName)}},setFilters:{first:function(Q,P){return P===0},last:function(R,Q,P,S){return Q===S.length-1},even:function(Q,P){return P%2===0},odd:function(Q,P){return P%2===1},lt:function(R,Q,P){return QP[3]-0},nth:function(R,Q,P){return P[3]-0==Q},eq:function(R,Q,P){return P[3]-0==Q}},filter:{CHILD:function(P,S){var V=S[1],W=P.parentNode;var U="child"+W.childNodes.length;if(W&&(!W[U]||!P.nodeIndex)){var T=1;for(var Q=W.firstChild;Q;Q=Q.nextSibling){if(Q.nodeType==1){Q.nodeIndex=T++}}W[U]=T-1}if(V=="first"){return P.nodeIndex==1}else{if(V=="last"){return P.nodeIndex==W[U]}else{if(V=="only"){return W[U]==1}else{if(V=="nth"){var Y=false,R=S[2],X=S[3];if(R==1&&X==0){return true}if(R==0){if(P.nodeIndex==X){Y=true}}else{if((P.nodeIndex-X)%R==0&&(P.nodeIndex-X)/R>=0){Y=true}}return Y}}}}},PSEUDO:function(V,R,S,W){var Q=R[1],T=G.filters[Q];if(T){return T(V,S,R,W)}else{if(Q==="contains"){return(V.textContent||V.innerText||"").indexOf(R[3])>=0}else{if(Q==="not"){var U=R[3];for(var S=0,P=U.length;S=0:S==="~="?(" "+U+" ").indexOf(Q)>=0:!R[4]?P:S==="!="?U!=Q:S==="^="?U.indexOf(Q)===0:S==="$="?U.substr(U.length-Q.length)===Q:S==="|="?U===Q||U.substr(0,Q.length+1)===Q+"-":false},POS:function(T,Q,R,U){var P=Q[2],S=G.setFilters[P];if(S){return S(T,R,Q,U)}}}};for(var K in G.match){G.match[K]=RegExp(G.match[K].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var D=function(Q,P){Q=Array.prototype.slice.call(Q);if(P){P.push.apply(P,Q);return P}return Q};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(J){D=function(T,S){var Q=S||[];if(F.call(T)==="[object Array]"){Array.prototype.push.apply(Q,T)}else{if(typeof T.length==="number"){for(var R=0,P=T.length;R";var P=document.documentElement;P.insertBefore(Q,P.firstChild);if(!!document.getElementById(R)){G.find.ID=function(T,U){if(U.getElementById){var S=U.getElementById(T[1]);return S?S.id===T[1]||S.getAttributeNode&&S.getAttributeNode("id").nodeValue===T[1]?[S]:g:[]}};G.filter.ID=function(U,S){var T=U.getAttributeNode&&U.getAttributeNode("id");return U.nodeType===1&&T&&T.nodeValue===S}}P.removeChild(Q)})();(function(){var P=document.createElement("div");P.appendChild(document.createComment(""));if(P.getElementsByTagName("*").length>0){G.find.TAG=function(Q,U){var T=U.getElementsByTagName(Q[1]);if(Q[1]==="*"){var S=[];for(var R=0;T[R];R++){if(T[R].nodeType===1){S.push(T[R])}}T=S}return T}}P.innerHTML="
    ";if(P.firstChild.getAttribute("href")!=="#"){G.attrHandle.href=function(Q){return Q.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var P=E;E=function(T,S,Q,R){S=S||document;if(!R&&S.nodeType===9){try{return D(S.querySelectorAll(T),Q)}catch(U){}}return P(T,S,Q,R)};E.find=P.find;E.filter=P.filter;E.selectors=P.selectors;E.matches=P.matches})()}if(document.documentElement.getElementsByClassName){G.order.splice(1,0,"CLASS");G.find.CLASS=function(P,Q){return Q.getElementsByClassName(P[1])}}function L(Q,W,V,Z,X,Y){for(var T=0,R=Z.length;T0){T=P;break}}}P=P[Q]}Y[S]=T}}}var H=document.compareDocumentPosition?function(Q,P){return Q.compareDocumentPosition(P)&16}:function(Q,P){return Q!==P&&(Q.contains?Q.contains(P):true)};var M=function(P){return P.documentElement&&!P.body||P.tagName&&P.ownerDocument&&!P.ownerDocument.body};n.find=E;n.filter=E.filter;n.expr=E.selectors;n.expr[":"]=n.expr.filters;E.selectors.filters.hidden=function(P){return"hidden"===P.type||n.css(P,"display")==="none"||n.css(P,"visibility")==="hidden"};E.selectors.filters.visible=function(P){return"hidden"!==P.type&&n.css(P,"display")!=="none"&&n.css(P,"visibility")!=="hidden"};E.selectors.filters.animated=function(P){return n.grep(n.timers,function(Q){return P===Q.elem}).length};n.multiFilter=function(R,P,Q){if(Q){R=":not("+R+")"}return E.matches(R,P)};n.dir=function(R,Q){var P=[],S=R[Q];while(S&&S!=document){if(S.nodeType==1){P.push(S)}S=S[Q]}return P};n.nth=function(T,P,R,S){P=P||1;var Q=0;for(;T;T=T[R]){if(T.nodeType==1&&++Q==P){break}}return T};n.sibling=function(R,Q){var P=[];for(;R;R=R.nextSibling){if(R.nodeType==1&&R!=Q){P.push(R)}}return P};return;l.Sizzle=E})();n.event={add:function(H,E,G,J){if(H.nodeType==3||H.nodeType==8){return}if(H.setInterval&&H!=l){H=l}if(!G.guid){G.guid=this.guid++}if(J!==g){var F=G;G=this.proxy(F);G.data=J}var D=n.data(H,"events")||n.data(H,"events",{}),I=n.data(H,"handle")||n.data(H,"handle",function(){return typeof n!=="undefined"&&!n.event.triggered?n.event.handle.apply(arguments.callee.elem,arguments):g});I.elem=H;n.each(E.split(/\s+/),function(L,M){var N=M.split(".");M=N.shift();G.type=N.slice().sort().join(".");var K=D[M];if(n.event.specialAll[M]){n.event.specialAll[M].setup.call(H,J,N)}if(!K){K=D[M]={};if(!n.event.special[M]||n.event.special[M].setup.call(H,J,N)===false){if(H.addEventListener){H.addEventListener(M,I,false)}else{if(H.attachEvent){H.attachEvent("on"+M,I)}}}}K[G.guid]=G;n.event.global[M]=true});H=null},guid:1,global:{},remove:function(J,G,I){if(J.nodeType==3||J.nodeType==8){return}var F=n.data(J,"events"),E,D;if(F){if(G===g||(typeof G==="string"&&G.charAt(0)==".")){for(var H in F){this.remove(J,H+(G||""))}}else{if(G.type){I=G.handler;G=G.type}n.each(G.split(/\s+/),function(L,N){var P=N.split(".");N=P.shift();var M=RegExp("(^|\\.)"+P.slice().sort().join(".*\\.")+"(\\.|$)");if(F[N]){if(I){delete F[N][I.guid]}else{for(var O in F[N]){if(M.test(F[N][O].type)){delete F[N][O]}}}if(n.event.specialAll[N]){n.event.specialAll[N].teardown.call(J,P)}for(E in F[N]){break}if(!E){if(!n.event.special[N]||n.event.special[N].teardown.call(J,P)===false){if(J.removeEventListener){J.removeEventListener(N,n.data(J,"handle"),false)}else{if(J.detachEvent){J.detachEvent("on"+N,n.data(J,"handle"))}}}E=null;delete F[N]}}})}for(E in F){break}if(!E){var K=n.data(J,"handle");if(K){K.elem=null}n.removeData(J,"events");n.removeData(J,"handle")}}},trigger:function(H,J,G,D){var F=H.type||H;if(!D){H=typeof H==="object"?H[h]?H:n.extend(n.Event(F),H):n.Event(F);if(F.indexOf("!")>=0){H.type=F=F.slice(0,-1);H.exclusive=true}if(!G){H.stopPropagation();if(this.global[F]){n.each(n.cache,function(){if(this.events&&this.events[F]){n.event.trigger(H,J,this.handle.elem)}})}}if(!G||G.nodeType==3||G.nodeType==8){return g}H.result=g;H.target=G;J=n.makeArray(J);J.unshift(H)}H.currentTarget=G;var I=n.data(G,"handle");if(I){I.apply(G,J)}if((!G[F]||(n.nodeName(G,"a")&&F=="click"))&&G["on"+F]&&G["on"+F].apply(G,J)===false){H.result=false}if(!D&&G[F]&&!H.isDefaultPrevented()&&!(n.nodeName(G,"a")&&F=="click")){this.triggered=true;try{G[F]()}catch(K){}}this.triggered=false;if(!H.isPropagationStopped()){var E=G.parentNode||G.ownerDocument;if(E){n.event.trigger(H,J,E,true)}}},handle:function(J){var I,D;J=arguments[0]=n.event.fix(J||l.event);var K=J.type.split(".");J.type=K.shift();I=!K.length&&!J.exclusive;var H=RegExp("(^|\\.)"+K.slice().sort().join(".*\\.")+"(\\.|$)");D=(n.data(this,"events")||{})[J.type];for(var F in D){var G=D[F];if(I||H.test(G.type)){J.handler=G;J.data=G.data;var E=G.apply(this,arguments);if(E!==g){J.result=E;if(E===false){J.preventDefault();J.stopPropagation()}}if(J.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(G){if(G[h]){return G}var E=G;G=n.Event(E);for(var F=this.props.length,I;F;){I=this.props[--F];G[I]=E[I]}if(!G.target){G.target=G.srcElement||document}if(G.target.nodeType==3){G.target=G.target.parentNode}if(!G.relatedTarget&&G.fromElement){G.relatedTarget=G.fromElement==G.target?G.toElement:G.fromElement}if(G.pageX==null&&G.clientX!=null){var H=document.documentElement,D=document.body;G.pageX=G.clientX+(H&&H.scrollLeft||D&&D.scrollLeft||0)-(H.clientLeft||0);G.pageY=G.clientY+(H&&H.scrollTop||D&&D.scrollTop||0)-(H.clientTop||0)}if(!G.which&&((G.charCode||G.charCode===0)?G.charCode:G.keyCode)){G.which=G.charCode||G.keyCode}if(!G.metaKey&&G.ctrlKey){G.metaKey=G.ctrlKey}if(!G.which&&G.button){G.which=(G.button&1?1:(G.button&2?3:(G.button&4?2:0)))}return G},proxy:function(E,D){D=D||function(){return E.apply(this,arguments)};D.guid=E.guid=E.guid||D.guid||this.guid++;return D},special:{ready:{setup:A,teardown:function(){}}},specialAll:{live:{setup:function(D,E){n.event.add(this,E[0],c)},teardown:function(F){if(F.length){var D=0,E=RegExp("(^|\\.)"+F[0]+"(\\.|$)");n.each((n.data(this,"events").live||{}),function(){if(E.test(this.type)){D++}});if(D<1){n.event.remove(this,F[0],c)}}}}}};n.Event=function(D){if(!this.preventDefault){return new n.Event(D)}if(D&&D.type){this.originalEvent=D;this.type=D.type;this.timeStamp=D.timeStamp}else{this.type=D}if(!this.timeStamp){this.timeStamp=e()}this[h]=true};function k(){return false}function t(){return true}n.Event.prototype={preventDefault:function(){this.isDefaultPrevented=t;var D=this.originalEvent;if(!D){return}if(D.preventDefault){D.preventDefault()}D.returnValue=false},stopPropagation:function(){this.isPropagationStopped=t;var D=this.originalEvent;if(!D){return}if(D.stopPropagation){D.stopPropagation()}D.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=t;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(E){var D=E.relatedTarget;while(D&&D!=this){try{D=D.parentNode}catch(F){D=this}}if(D!=this){E.type=E.data;n.event.handle.apply(this,arguments)}};n.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(E,D){n.event.special[D]={setup:function(){n.event.add(this,E,a,D)},teardown:function(){n.event.remove(this,E,a)}}});n.fn.extend({bind:function(E,F,D){return E=="unload"?this.one(E,F,D):this.each(function(){n.event.add(this,E,D||F,D&&F)})},one:function(F,G,E){var D=n.event.proxy(E||G,function(H){n(this).unbind(H,D);return(E||G).apply(this,arguments)});return this.each(function(){n.event.add(this,F,D,E&&G)})},unbind:function(E,D){return this.each(function(){n.event.remove(this,E,D)})},trigger:function(D,E){return this.each(function(){n.event.trigger(D,E,this)})},triggerHandler:function(D,F){if(this[0]){var E=n.Event(D);E.preventDefault();E.stopPropagation();n.event.trigger(E,F,this[0]);return E.result}},toggle:function(F){var D=arguments,E=1;while(E=0){var D=F.slice(H,F.length);F=F.slice(0,H)}var G="GET";if(I){if(n.isFunction(I)){J=I;I=null}else{if(typeof I==="object"){I=n.param(I);G="POST"}}}var E=this;n.ajax({url:F,type:G,dataType:"html",data:I,complete:function(L,K){if(K=="success"||K=="notmodified"){E.html(D?n("
    ").append(L.responseText.replace(//g,"")).find(D):L.responseText)}if(J){E.each(J,[L.responseText,K,L])}}});return this},serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?n.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type))}).map(function(D,E){var F=n(this).val();return F==null?null:n.isArray(F)?n.map(F,function(H,G){return{name:E.name,value:H}}):{name:E.name,value:F}}).get()}});n.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(D,E){n.fn[E]=function(F){return this.bind(E,F)}});var q=e();n.extend({get:function(D,F,G,E){if(n.isFunction(F)){G=F;F=null}return n.ajax({type:"GET",url:D,data:F,success:G,dataType:E})},getScript:function(D,E){return n.get(D,null,E,"script")},getJSON:function(D,E,F){return n.get(D,E,F,"json")},post:function(D,F,G,E){if(n.isFunction(F)){G=F;F={}}return n.ajax({type:"POST",url:D,data:F,success:G,dataType:E})},ajaxSetup:function(D){n.extend(n.ajaxSettings,D)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(L){L=n.extend(true,L,n.extend(true,{},n.ajaxSettings,L));var V,E=/=\?(&|$)/g,Q,U,F=L.type.toUpperCase();if(L.data&&L.processData&&typeof L.data!=="string"){L.data=n.param(L.data)}if(L.dataType=="jsonp"){if(F=="GET"){if(!L.url.match(E)){L.url+=(L.url.match(/\?/)?"&":"?")+(L.jsonp||"callback")+"=?"}}else{if(!L.data||!L.data.match(E)){L.data=(L.data?L.data+"&":"")+(L.jsonp||"callback")+"=?"}}L.dataType="json"}if(L.dataType=="json"&&(L.data&&L.data.match(E)||L.url.match(E))){V="jsonp"+q++;if(L.data){L.data=(L.data+"").replace(E,"="+V+"$1")}L.url=L.url.replace(E,"="+V+"$1");L.dataType="script";l[V]=function(W){U=W;H();K();l[V]=g;try{delete l[V]}catch(X){}if(G){G.removeChild(S)}}}if(L.dataType=="script"&&L.cache==null){L.cache=false}if(L.cache===false&&F=="GET"){var D=e();var T=L.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+D+"$2");L.url=T+((T==L.url)?(L.url.match(/\?/)?"&":"?")+"_="+D:"")}if(L.data&&F=="GET"){L.url+=(L.url.match(/\?/)?"&":"?")+L.data;L.data=null}if(L.global&&!n.active++){n.event.trigger("ajaxStart")}var P=/^(\w+:)?\/\/([^\/?#]+)/.exec(L.url);if(L.dataType=="script"&&F=="GET"&&P&&(P[1]&&P[1]!=location.protocol||P[2]!=location.host)){var G=document.getElementsByTagName("head")[0];var S=document.createElement("script");S.src=L.url;if(L.scriptCharset){S.charset=L.scriptCharset}if(!V){var N=false;S.onload=S.onreadystatechange=function(){if(!N&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){N=true;H();K();G.removeChild(S)}}}G.appendChild(S);return g}var J=false;var I=L.xhr();if(L.username){I.open(F,L.url,L.async,L.username,L.password)}else{I.open(F,L.url,L.async)}try{if(L.data){I.setRequestHeader("Content-Type",L.contentType)}if(L.ifModified){I.setRequestHeader("If-Modified-Since",n.lastModified[L.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}I.setRequestHeader("X-Requested-With","XMLHttpRequest");I.setRequestHeader("Accept",L.dataType&&L.accepts[L.dataType]?L.accepts[L.dataType]+", */*":L.accepts._default)}catch(R){}if(L.beforeSend&&L.beforeSend(I,L)===false){if(L.global&&!--n.active){n.event.trigger("ajaxStop")}I.abort();return false}if(L.global){n.event.trigger("ajaxSend",[I,L])}var M=function(W){if(I.readyState==0){if(O){clearInterval(O);O=null;if(L.global&&!--n.active){n.event.trigger("ajaxStop")}}}else{if(!J&&I&&(I.readyState==4||W=="timeout")){J=true;if(O){clearInterval(O);O=null}Q=W=="timeout"?"timeout":!n.httpSuccess(I)?"error":L.ifModified&&n.httpNotModified(I,L.url)?"notmodified":"success";if(Q=="success"){try{U=n.httpData(I,L.dataType,L)}catch(Y){Q="parsererror"}}if(Q=="success"){var X;try{X=I.getResponseHeader("Last-Modified")}catch(Y){}if(L.ifModified&&X){n.lastModified[L.url]=X}if(!V){H()}}else{n.handleError(L,I,Q)}K();if(L.async){I=null}}}};if(L.async){var O=setInterval(M,13);if(L.timeout>0){setTimeout(function(){if(I){if(!J){M("timeout")}if(I){I.abort()}}},L.timeout)}}try{I.send(L.data)}catch(R){n.handleError(L,I,null,R)}if(!L.async){M()}function H(){if(L.success){L.success(U,Q)}if(L.global){n.event.trigger("ajaxSuccess",[I,L])}}function K(){if(L.complete){L.complete(I,Q)}if(L.global){n.event.trigger("ajaxComplete",[I,L])}if(L.global&&!--n.active){n.event.trigger("ajaxStop")}}return I},handleError:function(E,G,D,F){if(E.error){E.error(G,D,F)}if(E.global){n.event.trigger("ajaxError",[G,E,F])}},active:0,httpSuccess:function(E){try{return !E.status&&location.protocol=="file:"||(E.status>=200&&E.status<300)||E.status==304||E.status==1223}catch(D){}return false},httpNotModified:function(F,D){try{var G=F.getResponseHeader("Last-Modified");return F.status==304||G==n.lastModified[D]}catch(E){}return false},httpData:function(I,G,F){var E=I.getResponseHeader("content-type"),D=G=="xml"||!G&&E&&E.indexOf("xml")>=0,H=D?I.responseXML:I.responseText;if(D&&H.documentElement.tagName=="parsererror"){throw"parsererror"}if(F&&F.dataFilter){H=F.dataFilter(H,G)}if(typeof H==="string"){if(G=="script"){n.globalEval(H)}if(G=="json"){H=l["eval"]("("+H+")")}}return H},param:function(D){var F=[];function G(H,I){F[F.length]=encodeURIComponent(H)+"="+encodeURIComponent(I)}if(n.isArray(D)||D.jquery){n.each(D,function(){G(this.name,this.value)})}else{for(var E in D){if(n.isArray(D[E])){n.each(D[E],function(){G(E,this)})}else{G(E,n.isFunction(D[E])?D[E]():D[E])}}}return F.join("&").replace(/%20/g,"+")}});var m={},d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function s(E,D){var F={};n.each(d.concat.apply([],d.slice(0,D)),function(){F[this]=E});return F}n.fn.extend({show:function(I,K){if(I){return this.animate(s("show",3),I,K)}else{for(var G=0,E=this.length;G").appendTo("body");J=H.css("display");if(J==="none"){J="block"}H.remove();m[F]=J}this[G].style.display=n.data(this[G],"olddisplay",J)}}return this}},hide:function(G,H){if(G){return this.animate(s("hide",3),G,H)}else{for(var F=0,E=this.length;F=0;G--){if(F[G].elem==this){if(D){F[G](true)}F.splice(G,1)}}});if(!D){this.dequeue()}return this}});n.each({slideDown:s("show",1),slideUp:s("hide",1),slideToggle:s("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(D,E){n.fn[D]=function(F,G){return this.animate(E,F,G)}});n.extend({speed:function(F,G,E){var D=typeof F==="object"?F:{complete:E||!E&&G||n.isFunction(F)&&F,duration:F,easing:E&&G||G&&!n.isFunction(G)&&G};D.duration=n.fx.off?0:typeof D.duration==="number"?D.duration:n.fx.speeds[D.duration]||n.fx.speeds._default;D.old=D.complete;D.complete=function(){if(D.queue!==false){n(this).dequeue()}if(n.isFunction(D.old)){D.old.call(this)}};return D},easing:{linear:function(F,G,D,E){return D+E*F},swing:function(F,G,D,E){return((-Math.cos(F*Math.PI)/2)+0.5)*E+D}},timers:[],timerId:null,fx:function(E,D,F){this.options=D;this.elem=E;this.prop=F;if(!D.orig){D.orig={}}}});n.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(n.fx.step[this.prop]||n.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(E){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var D=parseFloat(n.css(this.elem,this.prop,E));return D&&D>-10000?D:parseFloat(n.curCSS(this.elem,this.prop))||0},custom:function(H,G,F){this.startTime=e();this.start=H;this.end=G;this.unit=F||this.unit||"px";this.now=this.start;this.pos=this.state=0;var D=this;function E(I){return D.step(I)}E.elem=this.elem;n.timers.push(E);if(E()&&n.timerId==null){n.timerId=setInterval(function(){var J=n.timers;for(var I=0;I=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var D=true;for(var E in this.options.curAnim){if(this.options.curAnim[E]!==true){D=false}}if(D){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(n.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){n(this.elem).hide()}if(this.options.hide||this.options.show){for(var H in this.options.curAnim){n.attr(this.elem.style,H,this.options.orig[H])}}}if(D){this.options.complete.call(this.elem)}return false}else{var I=F-this.startTime;this.state=I/this.options.duration;this.pos=n.easing[this.options.easing||(n.easing.swing?"swing":"linear")](this.state,I,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};n.extend(n.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(D){n.attr(D.elem.style,"opacity",D.now)},_default:function(D){if(D.elem.style&&D.elem.style[D.prop]!=null){D.elem.style[D.prop]=D.now+D.unit}else{D.elem[D.prop]=D.now}}}});if(document.documentElement.getBoundingClientRect){n.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return n.offset.bodyOffset(this[0])}var F=this[0].getBoundingClientRect(),I=this[0].ownerDocument,E=I.body,D=I.documentElement,K=D.clientTop||E.clientTop||0,J=D.clientLeft||E.clientLeft||0,H=F.top+(self.pageYOffset||n.boxModel&&D.scrollTop||E.scrollTop)-K,G=F.left+(self.pageXOffset||n.boxModel&&D.scrollLeft||E.scrollLeft)-J;return{top:H,left:G}}}else{n.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return n.offset.bodyOffset(this[0])}n.offset.initialized||n.offset.initialize();var I=this[0],F=I.offsetParent,E=I,N=I.ownerDocument,L,G=N.documentElement,J=N.body,K=N.defaultView,D=K.getComputedStyle(I,null),M=I.offsetTop,H=I.offsetLeft;while((I=I.parentNode)&&I!==J&&I!==G){L=K.getComputedStyle(I,null);M-=I.scrollTop,H-=I.scrollLeft;if(I===F){M+=I.offsetTop,H+=I.offsetLeft;if(n.offset.doesNotAddBorder&&!(n.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(I.tagName))){M+=parseInt(L.borderTopWidth,10)||0,H+=parseInt(L.borderLeftWidth,10)||0}E=F,F=I.offsetParent}if(n.offset.subtractsBorderForOverflowNotVisible&&L.overflow!=="visible"){M+=parseInt(L.borderTopWidth,10)||0,H+=parseInt(L.borderLeftWidth,10)||0}D=L}if(D.position==="relative"||D.position==="static"){M+=J.offsetTop,H+=J.offsetLeft}if(D.position==="fixed"){M+=Math.max(G.scrollTop,J.scrollTop),H+=Math.max(G.scrollLeft,J.scrollLeft)}return{top:M,left:H}}}n.offset={initialize:function(){if(this.initialized){return}var K=document.body,E=document.createElement("div"),G,F,M,H,L,D,I=K.style.marginTop,J='
    ';L={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(D in L){E.style[D]=L[D]}E.innerHTML=J;K.insertBefore(E,K.firstChild);G=E.firstChild,F=G.firstChild,H=G.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(F.offsetTop!==5);this.doesAddBorderForTableAndCells=(H.offsetTop===5);G.style.overflow="hidden",G.style.position="relative";this.subtractsBorderForOverflowNotVisible=(F.offsetTop===-5);K.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(K.offsetTop===0);K.style.marginTop=I;K.removeChild(E);this.initialized=true},bodyOffset:function(D){n.offset.initialized||n.offset.initialize();var F=D.offsetTop,E=D.offsetLeft;if(n.offset.doesNotIncludeMarginInBodyOffset){F+=parseInt(n.curCSS(D,"marginTop",true),10)||0,E+=parseInt(n.curCSS(D,"marginLeft",true),10)||0}return{top:F,left:E}}};n.fn.extend({position:function(){var H=0,G=0,E;if(this[0]){var F=this.offsetParent(),I=this.offset(),D=/^body|html$/i.test(F[0].tagName)?{top:0,left:0}:F.offset();I.top-=j(this,"marginTop");I.left-=j(this,"marginLeft");D.top+=j(F,"borderTopWidth");D.left+=j(F,"borderLeftWidth");E={top:I.top-D.top,left:I.left-D.left}}return E},offsetParent:function(){var D=this[0].offsetParent||document.body;while(D&&(!/^body|html$/i.test(D.tagName)&&n.css(D,"position")=="static")){D=D.offsetParent}return n(D)}});n.each(["Left","Top"],function(E,D){var F="scroll"+D;n.fn[F]=function(G){if(!this[0]){return null}return G!==g?this.each(function(){this==l||this==document?l.scrollTo(!E?G:n(l).scrollLeft(),E?G:n(l).scrollTop()):this[F]=G}):this[0]==l||this[0]==document?self[E?"pageYOffset":"pageXOffset"]||n.boxModel&&document.documentElement[F]||document.body[F]:this[0][F]}});n.each(["Height","Width"],function(G,E){var D=G?"Left":"Top",F=G?"Right":"Bottom";n.fn["inner"+E]=function(){return this[E.toLowerCase()]()+j(this,"padding"+D)+j(this,"padding"+F)};n.fn["outer"+E]=function(I){return this["inner"+E]()+j(this,"border"+D+"Width")+j(this,"border"+F+"Width")+(I?j(this,"margin"+D)+j(this,"margin"+F):0)};var H=E.toLowerCase();n.fn[H]=function(I){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+E]||document.body["client"+E]:this[0]==document?Math.max(document.documentElement["client"+E],document.body["scroll"+E],document.documentElement["scroll"+E],document.body["offset"+E],document.documentElement["offset"+E]):I===g?(this.length?n.css(this[0],H):null):this.css(H,typeof I==="string"?I:I+"px")}})})();SABnzbd-0.7.20/interfaces/wizard/static/javascript/pagetwo.js0000644000000000000000000000104212433712602024306 0ustar00usergroup00000000000000function toggleWebPass() { var web web = $('#enable_webpass').attr('checked') if ($('#enable_webpass').attr('checked') == 1) { $('#web_user').attr("disabled",""); $('#web_pass').attr("disabled",""); } else { $('#web_user').attr("disabled","disabled"); $('#web_pass').attr("value",""); $('#web_pass').attr("disabled","disabled"); $('#web_user').attr("value",""); } }; $(document).ready(function() { toggleWebPass(); $('#enable_webpass').bind('change click focus', function() { toggleWebPass(); }); });SABnzbd-0.7.20/interfaces/wizard/static/javascript/restart.js0000644000000000000000000000065012433712602024330 0ustar00usergroup00000000000000function complete(){ $(".hidden").fadeIn("slow"); $(".disabled").removeAttr('disabled'); $('#restarting').addClass("hidden"); $('#complete').removeClass("hidden"); $('#tips').removeClass("hidden"); } $(document).ready(function() { $.ajax({ type: "POST", url: "../tapi", data: "mode=restart&apikey="+$('#apikey').val() , complete: function(result){ setTimeout(complete,7000); } }); });SABnzbd-0.7.20/licenses/License-CherryPy.txt0000644000000000000000000000403412433712601020720 0ustar00usergroup00000000000000The module CherryPy-3.1.2 is (c) CherryPy team. The module has been stripped of its Tutorial and Test directories. We embed CherryPy in SABnzbd, because CherryPy releases lack backward compatibility and cannot be installed as parallel versions into the system's Python installation. Home of the module: http://www.cherrypy.org It is covered by the following license. ------------------------------------------------------------------------- Copyright (c) 2004-2007, CherryPy Team (team@cherrypy.org) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the CherryPy Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------- SABnzbd-0.7.20/licenses/License-configobj.txt0000644000000000000000000000363312433712601021117 0ustar00usergroup00000000000000The module configobj.py is written by Michael Foord and Nicola Larosa. Home of the module: http://www.voidspace.org.uk/python/configobj-api/pythonutils.configobj-pysrc.html It is covered by the following license. ------------------------------------------------------------------------- Copyright (c) 2003-2007, Michael Foord and Nicola Larosa All rights reserved. E-mail : fuzzyman AT voidspace DOT org DOT uk Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Michael Foord nor the name of Voidspace may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------- SABnzbd-0.7.20/licenses/License-feedparser.txt0000644000000000000000000000321112433712601021267 0ustar00usergroup00000000000000The module feedparser.py-5.1 is (c) Mark Pilgrim and Kurt McKee We use only the feedparser itself, all additional material was removed. Home of the feedparser module: https://code.google.com/p/feedparser It is covered by the following license. ----- begin license block ----- Copyright (c) 2010-2011 Kurt McKee Copyright (c) 2002-2008 Mark Pilgrim All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.""" ----- end license block ----- SABnzbd-0.7.20/licenses/License-gntp.txt0000644000000000000000000000246512433712601020131 0ustar00usergroup00000000000000The module gntp is (C) Paul Traylor Home of the module: https://github.com/kfdm/gntp/ It is covered by the following license. ------------------------------------------------------------------------- Copyright (c) 2011 Paul Traylor Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------- SABnzbd-0.7.20/licenses/License-json.txt0000644000000000000000000006425012433712601020132 0ustar00usergroup00000000000000The module json.py is written by Patrick D. Logan. Contact mailto:patrickdlogan@stardecisions.com The home of the module is: http://sourceforge.net/projects/json-py It is covered by the following license. ---------------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ---------------------------------------------------------------------------- SABnzbd-0.7.20/licenses/License-kronos.txt0000644000000000000000000000350312433712601020466 0ustar00usergroup00000000000000Kronos.py is written by Irmen de Jong. Retreived from: http://www.razorvine.net/download/kronos.py Quote from the module: """ This version has been extracted from the Turbogears source repository and slightly changed to be completely stand-alone again. Also some fixes have been made to make it work on Python 2.6 (sched module changes). The version in Turbogears is based on the original stand-alone Kronos. """ It is covered by the following license. http://www.opensource.org/licenses/mit-license.php -------------------------------------------------------------------------------------------- The MIT License Kronos.py is Copyright (c) Irmen de Jong. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------------------SABnzbd-0.7.20/licenses/License-listquote.txt0000644000000000000000000000356712433712601021216 0ustar00usergroup00000000000000The module listquote.py is written by Michael Foord. Home of the module: http://www.voidspace.org.uk/python/configobj-api/pythonutils.listquote-pysrc.html It is covered by the following license. ------------------------------------------------------------------------- Copyright (c) 2003-2007, Michael Foord All rights reserved. E-mail : fuzzyman AT voidspace DOT org DOT uk Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Michael Foord nor the name of Voidspace may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------- SABnzbd-0.7.20/licenses/License-msgfmt.txt0000644000000000000000000000026712433712601020454 0ustar00usergroup00000000000000The file tools/msgfmt.py was taken from the Python for Windows distribution and is covered by the general Python license. Written by Martin v. Lwis SABnzbd-0.7.20/licenses/License-OrderedDict.txt0000644000000000000000000000245512433712601021350 0ustar00usergroup00000000000000The Backport of OrderedDict() is coming from ActiveState's Python recipe website. It has been written by Raymond Hettinger. Home of the module: http://code.activestate.com/recipes/576693-ordered-dictionary-for-py24/ It is covered by the MIT License. =================== (c) 2009 Raymond Hettinger Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. SABnzbd-0.7.20/licenses/License-pynewsleecher.txt0000644000000000000000000000057312433712601022034 0ustar00usergroup00000000000000The original author of SABnzbd based his work on Pynewsleecher by Freddy@madcowdesease.org. Few parts of Pynewsleecher have survived the generations of SABnzbd in a recognizable form. Still, we wish to thank Freddy for his inspiration. The home of the Pynewsleecher project: http://www.madcowdisease.org/mcd/pynewsleecher The software does not carry any license information. SABnzbd-0.7.20/licenses/License-Python.txt0000644000000000000000000003245712433712601020446 0ustar00usergroup00000000000000A. HISTORY OF THE SOFTWARE ========================== Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others. In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software. In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.com). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF. All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. Release Derived Year Owner GPL- from compatible? (1) 0.9.0 thru 1.2 1991-1995 CWI yes 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes 1.6 1.5.2 2000 CNRI no 2.0 1.6 2000 BeOpen.com no 1.6.1 1.6 2001 CNRI yes (2) 2.1 2.0+1.6.1 2001 PSF no 2.0.1 2.0+1.6.1 2001 PSF yes 2.1.1 2.1+2.0.1 2001 PSF yes 2.2 2.1.1 2001 PSF yes 2.1.2 2.1.1 2002 PSF yes 2.1.3 2.1.2 2002 PSF yes 2.2.1 2.2 2002 PSF yes 2.2.2 2.2.1 2002 PSF yes 2.2.3 2.2.2 2003 PSF yes 2.3 2.2.2 2002-2003 PSF yes 2.3.1 2.3 2002-2003 PSF yes 2.3.2 2.3.1 2002-2003 PSF yes 2.3.3 2.3.2 2002-2003 PSF yes 2.3.4 2.3.3 2004 PSF yes 2.3.5 2.3.4 2005 PSF yes 2.4 2.3 2004 PSF yes 2.4.1 2.4 2005 PSF yes 2.4.2 2.4.1 2005 PSF yes 2.4.3 2.4.2 2006 PSF yes 2.5 2.4 2006 PSF yes 2.5.1 2.5 2007 PSF yes Footnotes: (1) GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't. (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, because its license has a choice of law clause. According to CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 is "not incompatible" with the GPL. Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible. B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON =============================================================== PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 ------------------------------------------- BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software"). 2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. 3. BeOpen is making the Software available to Licensee on an "AS IS" basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 5. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the "BeOpen Python" logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. 7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 --------------------------------------- 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013". 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia's conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 -------------------------------------------------- Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. SABnzbd-0.7.20/licenses/License-PythonParts.txt0000644000000000000000000000027112433712601021445 0ustar00usergroup00000000000000pystone.py and msgfmt.py have been copied from the Python sourcecode. They are covered by the same license as Python itself, that license is contained in the file "License_Python.txt". SABnzbd-0.7.20/licenses/License-rarfile.txt0000644000000000000000000000171012433712601020575 0ustar00usergroup00000000000000The module rarfile.py is written by Marko Kreen. Home of the module: http://grue.l-t.ee/~marko/src/rarfile/ It is covered by the following license. ------------------------------------------------------------------------- Copyright (c) 2005 Marko Kreen Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. SABnzbd-0.7.20/licenses/License-rsslib.txt0000644000000000000000000000060512433712601020451 0ustar00usergroup00000000000000The module rsslib.py is written by C. Mallory. cmallory /a t/ berserk /dot/ o r g Home of the module: http://berserk.org/rsslib/ It is covered by the following license. ----------------------------------------------------------------------------- You may freely use this code in any way you can think of. ----------------------------------------------------------------------------- SABnzbd-0.7.20/licenses/License-ssmtplib.txt0000644000000000000000000000271112433712601021010 0ustar00usergroup00000000000000The module ssmtplib.py is written by Matt Butcher. Home of the module: http://aleph-null.tv/downloads/ssmtplib.py It is covered by the following license. Author: Matt Butcher , Feb. 2007 License: MIT License (or, at your option, the GPL, v.2 or later as posted at http://gnu.org). Begin License Copyright (c) 2007 M Butcher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. End License This is just a minor modification to the smtplib code by Dragon De Monsyn. SABnzbd-0.7.20/licenses/License-systrayicon.txt0000644000000000000000000000051612433712601021543 0ustar00usergroup00000000000000On http://www.brunningonline.net/simon/blog/archives/001835.html, the author licensed SysTrayIcon.py under a variant of the WTFPL: > Any road up, help yourself. Consider SysTrayIcon.py to be under an > "Aleister Crowley" style license - "Do what thou wilt shall be the > only law". > > Err, but don't sue me if it doesn't work. ;-) SABnzbd-0.7.20/locale/da/LC_MESSAGES/SABnzbd.mo0000644000000000000000000022570612433712600020467 0ustar00usergroup00000000000000?o?M@d^ABC D2EFGH*H'HI4IMI fIIII IIIJJJJJJJJJKK?KK[L_LgLRwL[L&M#,MPMmMMM M MM'MMMN NNN &N 3N>N PNZNpNaNNNNO.O7OIO)iO*O O OOOO/Ph3P PPPAQ(TQ0}Q*QQQQ QQR .R8RQReRlRRS S'S2GS zSS SSST!/T6QT-TTTTU U)U.2U'aUUUUBUVVS-VV VV5VVVV"W6W8c(occHcsc ]d gdtd d d(d.d)d&e,Fe<sebe&f:fUf7hf'ffffg 2g Sg&^g-gggg gh h h%h ;hIhahhhhh%h!hh+i Aibi!}ii!iFi&j0;j-lj'jj"jkk/kMkmkuk kkkkkkkklAlRl'il!lllll-lm"m(mCm3Xm/mgm $n0n&8n"_nnnnn n n nn nnnoo)o 9oGoYoao wo oooo o o oo opp (p 5p@pEpMp cppp upppp-p6p.q@q EqPqbqfq6kqq3VrGrr_stt3tE6t |ttt>u,Pu}uu%u#uuvv ?vKvTv2pv%vv"v+ w6wNw'eww7ww"Wx zx<x x3x9y=yEy%Jypyyy~yyIy5y(z -z9zq?zzczH'{op{]{)>| h|s|{| |||| |$|||0|&}+}?})P}z}}} } } }} }}}}}}~~ ~~6~L~]~*n~.~~#~(161FAx 1" 3>C J,V  ˀ/ـ .1Kek oyc"A*,l3 !,!N"pу (/ 4 ?K T*b0 Ʉ΄ ք ( *4EXmͅ  Ma#|R< M[`"҇9O-W' ݈ .ENTi~ ʉ #+1F cpw يۊߊ$* /9H&d ?   ) 0; Uc4vō2̍  *+Vs)M07 >H Q]c s}֏ #9N an Ȑې. DPl Ƒϑ# +2 :H `4  ŒВJ323f.ɓ)/@O V(w$""2&U|o)'Qq3   (2C S `k9z "ȗ  $'2 Zgl-q(Ș ͘ ٘//-E-s&&ș$$393m11Ӛ   +3IPX ^ j u  ɛ қݛ .6E JTY s~ "g2AמN>=D W,ȡ ѡ>ۡ#+1"$AB E .(WwĤ ڤ2.6Vip 3˥-"-P,j#.#*EL0fb$ 814" Wd|% ɩѩש 76R:ݪ  7%Ag@lR!"').*A$l10ìZ#O)sJĭ#&7'^  Ϯ&ݮ "$+/4 9GJNQTY9s ůʯү q&i?K޹غ'*@Vj #%ջ  $: ޼  0AFʽ} ]^p&w ڿ) ? Jk s  gpv{7!-&4 [ it>o\p"4&W-~ " ! B\c| ."@Q%"! 4%U@{44&"8[ z.'F- tV# B9|.B ", CQY p~ . !&1#X|  .A(Y  ()C+Xa 36?vA~"!/8h'w9;/ 3>To#@BC,p(  /:@If! (*<M \j(%. Tb!s"''Ck2""Lec~+68E.~ M (()&;(b=o09'j!A*!.;*j) 4/Lf   *%%D&j--8)&)P.z*1NUFm?*'#G!k+"  .39?FYpV#'"8#[099<uv.,1^e| $&;K_h  "3O ^jox " 8G+?s 20FYJ)1M.('A!i 8%9*_$7# ;:E 47Bz=C %#IOVh?2oeLy`W2 OYaetw "1!8)Isz     !<Sg*z.#$5S Z:hD ;)Oy .  **Uj n#Z~E/ !24g{$  *<BQar *2-1:W ]'g   " ?J `On'YZ1m'%6Ue!|-  /+ [g~" > LX q"| ' 0FM S ao  ! 6W`2t  &3;I ?  !%Gd(E,  )4 <HO `lu    4 G Z j  {       "  7 !C e          (    8 ?  G T  g 5     R 3C :w 4  ) , K \ l %s /   ' $8 J"X({l&,*S~ 5 / IW_h {  ;. 6C S't  7(&.@7T755,0,]**==;\; 6< DNe|    &= ERXah  )x /@PQK<B  Z=-&,4A<~ ag)}(G ( / ;JH:$, 4>C%Ek$= ! 7 K Q o x  5 / *!C!.b!*!4!! """7"<"W"_";{"j""#&# #9#5/$7e$ $$ $$,$ %%#%*%0%?% U%`% q%:{%6% %%%:& B&L&']&&&&.&&'&N'"]''''')','7'8,(\e(&(-()2)VG)))()*)* 9*F*K*M*Q*V*h*#x************** ***++<$+a+h+ q+{+++++ SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAcceptAccessAccess deniedAccount infoActionAction when encrypted RAR is downloadedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAudioAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatic FeedbackAutomatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)CancelCannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.CommentComplete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable OZnzb IntegrationEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enhanced functionality including ratings and extra status information is available when connected to OZnzb indexer.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you do not have an account it can be created at If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesIndexingInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOZnzbOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOtherOther MessagesOther SwitchesOther problemOut of retentionPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!Refer to https://www.oznzb.com/profileRefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.ReportReport-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSendSend GroupSend RSS notificationsSend automatically calculated validation results for downloads to indexer.Send email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...Site API KeySizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key provides identity to indexer. Refer to https://www.oznzb.com/profile.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVideoView Script LogView script outputVirus/spamWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2014-07-02 18:01+0000 Last-Translator: Jonas Bæk Language-Team: Danish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:53+0000 X-Generator: Launchpad (build 17082) SABnzbd kan ikke finde sin webgrænseflade filer i %s.
    Venligst installer programmet igen.

    SABnzbd opdagede en kø og historik fra en ældre (0.4.x) udgivelse.

    Begge køer og historiker vil blive ignoreret og måske gå tabt!

    Du ønsker måske at stoppe SABnzbd og færdigøre køen med det gamle program.

    Klik på OK for at gå videre til SABnzbd SABnzbd har fundet gemt data fra en anden SABnzbd version
    men kan ikke genbruge dataene fra det andet program.

    Du ønsker måske at afslutte din kø først med det andet program.

    Efter dette, start programmet med "- rene" valgmulighede.
    Dette vil slette den nu værende kø og historik!
    SABnzbd læser filen "%s". SABnzbd opdagede, at filen sqlite3.dll mangler .

    Nogle dårligt designet virus-scannere fjernede denne fil .
    Tjek venligst din virus-scanner, du kan prøve at geninstallere SABnzbd og klage til din virus-scanner leverandør .

    SABnzbd er ikke kompatibel med visse software firewalls.
    %s
    Beklager, men vi kan ikke løse denne uforenelighed lige nu.
    Du kan indsende en klage til din firewall leverandør.

    SABnzbd har brug for en ledig TCP / IP-port til sine interne webserver.
    Port %s på %s blev forsøgt, men den er ikke til rådighed .
    Nogle andre programmer bruger porten eller SABnzbd kører allerede.

    Genstart venligst SABnzbd med et andet portnummer. SABnzbd brug for en ledig TCP / IP-port til sin intern webserver .
    Port %s på %s blev forsøgt , men den konto, der anvendes til SABnzbd har ikke tilladelse til at bruge det.
    På OSX og Linux systemer, skal brugere normalt bruge porte over 1023.

    Venligst genstart SABnzbd med et andet port nummer. SABnzbd har brug for en gyldig vært adresse til intern webserver .
    Du har angivet en ugyldig adresse.
    Sikkert valg er localhost og 0.0.0.0

    Venligst genstart SABnzbd med en gyldig host adresse . SABnzbd kommer med ABSOLUT INGEN GARANTI. Det er gratis software, og du er velkommen til at videredistribuere det under visse betingelser. Den er licenseret under GNU General Public License version 2 eller (efter eget valg) enhver senere version %s -> Ukendt kodning%s => mangler fra alle servere, afviser%s artikler havde ikke-matchende dubletter%s artikler misdanned%s artikler mangled%s artikler blev fjernet%s mappe: %s adgang mislykkedes%s filer i %s%s er ikke et korrekt ciffer værdi%s er ikke en godkendt e-mail adresse%s mangler   Server løsning eller Report ID 
    SABnzbd genstart færdig.
    Vent i ca 5 sekunder og klik derefter på knappen nedenunder..

    Opdater
    Fejlfinding+ Info+Slette+Reparere+Udpakke.nzb Backup mappe1x05 Episodemappe1x05 SæsonmappeOBS: Mapper vil blive oprettet automatisk, når du gemmer. Du kan bruge absolutte stier til at gemme uden for standardmapperne.Data vil ikke blive flyttet. Kræver SABnzbd genstartet!Læs Feedhenter det nuværende feed indholdet. Tving hent vil hente alle matchende NZBs nu.AlderAPI-nøgleAPI nøgle QR kodeForkert API-nøgle, anvend api-nøglen fra Konfiguration-> Generelt i dit tredjepartsprogram:API-nøgle mangler, indtast api-nøglen fra Konfiguration-> Generelt i dit tredjepartsprogram:AfbrydAfbryd job, der ikke kan færdiggøresAfbrudt, kan ikke afsluttesAfbrudt, kryptering registreretAcceptereAdgangAdgang nægtetBrugerinformationerUdførHandling når krypteret RAR er downloadetHandlingerAktivere et alternativ udseende.TilføjTilføj feedTilføj filTilføj NZBOpret planlægningTilføj serverTilføj nye downloadsTilføjet NZBAdministrativ mappePåvirkede KategorierEfter SABnzbd har genstartet vil du være i stand til at få adgang til det på følgende placering: %sAlderAlleTest også udgivelserAltidPåfør maksimalt antal forsøg kun til valgfri servereAnvend på markeredeEr du sikker på at du vil sletteEr du sikker på at du vil genstarte SABnzbd?Er du sikker på du vil lukke SABnzbd?Er du sikker?ArgumenterCache størrelse af artiklerArtikel identifikatorAudioGodkendelse mislykkedes, kontrollere brugernavn / adgangskode.Brugeroplysninger mangler, indtast brugernavn / password fra Konfiguration-> Generelt i dit tredjepartsprogram:Automatisk genoptagHent bogmærker automatiskAuto-pause, når ledig plads kommer under denne værdi.
    I bytes, evt. efterfulgt af K, M, G, T. For eksempel: '800M 'eller '8 G'Automatisk tilbagemeldingHent automatisk bogmærket poster.Henter jobs fra bogmærker automatisk.Sortere automatisk efter (gennemsnits) alder.BTilbageSikkerhedskopiBackup serverForkert tidsplan %s ved %s:%sForkert udformet yEnc artikel i %sBåndbreddeBloker genopfriskninger ved HoverHåndtering af bogmærkerBundenCRC Fejl i %s (%s -> %s)Cache artikler i hukommelsen for at reducere diskadgang.
    I bytes, efterfulgt af K,M,G. For eksempel: "64M" eller "128M"Cached %s artikler (%s)AnnullérDet lykkedes ikke at ændre rettigheder på %sKan ikke tilslutte til registreringsdatabasen HKEY_CURRENT_USER.Kan ikke tilslutte til server %s [%s]Kan ikke oprette %s mappe %sKan ikke oprette backup fil for %sKan ikke oprette mappe %sKan ikke oprette endelig mappe %sKan ikke oprette temp fil for %sKan ikke finde e-mail skabeloner i %sKan ikke finde webskabeloner: %s, forsøger med standardskabelonKan ikke starte browseren, sandsynligvis ikke fundetKan ikke åbne nøgle i registreringsdatabasen "%s".Kan ikke læse %sKan ikke læse overvåget mappe %sKan ikke skrive til INI fil %sKategorierKategoriÆndringerne er ikke gemt og vil blive mistet.Ændringer kræver genstart af SABnzbd!Tjek før downloadKontroller for ny versionTjek resultat af udpakningTjek resultat af udpakning (skal være slukket for nogle filsystemer).KontrollererOpdaterings intervalKontrol af interval (i minutter, i hvert fald 15). Ikke aktiv, når du bruger skemaer!Vælg et Web-grænseflade udseende.Ryd listenFjernelse af %s mislykkedes.Oprydning af par filer (hvis kontrollerede / reparation lykkedes).RydNulstil tællerKlik nedenfor for at teste.Klik for at teste de indtastede informationer.LukLukning af alle browservinduer / faneblade vil ikke lukke SABnzbd.KommentarFærdig download mappeFærdig mappeFærdigFærdig download mappeKonfigurationKonfigurations filOpsætningBekræft Historik-fjernelseBekræft Kø-fjernelseTilslutning af%s@%s:%s mislykkedes, besked =%sTilslutning lykkedes!ForbindelserBeholder BreddeKunne ikke slette newzbin bogmærke %sDet lykkedes ikke at tilslutte (%s)Aktuel planlægningTilpasseTDUPLIKEREDagligDaglige mapperDato sorteringMånedsdagÅrtiAfkodning af %s mislykkedesStandardStandard Base FolderStandard efterbehandlingStandard prioritetStandard bruger scriptsDefinerer post-behandling og opbevaring.FjernSletFjern alleSlet kompletteSlet mislykketFjern FeedsFjern efter downloadSlet alle afsluttede emner fra historie?Slet alle hentede filer?Slet alle mislykkedes emner fra historie?Fjern alt fra køen?Slet alle mislykkedes emner fra historiken?Fjernelse af %s mislykkedes!Find identiske downloadsFind identiske navngivne NZB filer (kræver NZB backup) og dobbelt titler på tværs af RSS-feedsDeaktivere API-nøgleDeaktiveretHTTPS fejlede på grund af manglende CERT og KEY filerKassérAfbryd fra usenet-serverne når køen er tom eller sat på pause.Afbryd når køen er tomPåmindelse når harddisk er fyldtDiskfejl ved oprettelse af fil %sDisken er fuld! Pauser...Udfør en ekstra kontrol baseret på SFV-filer.Download ikke.Har ikke gyldig godkendelse til feed %sKræver ingen API-nøgle.Bliver kvota nulstillet hver dag, uge ​​eller måned?Har du ingen usenet leverandør? Vi anbefaler at prøve %s.NedDownloaderOverførsel fuldførtMidlertidig download mappeDownload mislykkedesHastighedsbegrænsning for DownloadHentning mislykkedes – Findes ikke hos din server's retention?Overførslen kan mislykkes, kun %s af det krævet %s tilgængeligeHastighedsbegrænsning for Download (i KB/s - kilobyte per sekund).Download hastighedHentetHentede i %s med et gennemsnit på %sB/sHentet indtil videreDownloaderHentede filerFlerskærme1Flerskærme2Eks.F.eks. 119 eller 563 for SSLF.eks. 8 eller 20KRYPTEREDEFEJL:FEJL: %sFEJL: CRC mislykkedes i "%s"FEJL: stien for lang (%s)FEJL: lykkedes ikke at finde "%s"FEJL: skrivefejll (%s)Tid tilbageRedigerÆndre NZB detaljerE-mailE-mail kontoinstillingerE-mail påmindelse når job er fuldførtE-mail alternativE-mail modtagereE-mail sendereSendt E-mail!E-mail-mappe skabelonerE-mail testresultatE-mail adresse hvor den skal sendes til.E-mail afsendelse mislykkedesTomTom NZB fil %sTom RSS post blev fundet (%s)AktivereAktivere datosorteringAktiver Fil Sammenføjning (Filejoin)Aktiver GrowlHTTPS AktiveringAktiver HTTPS-adgang til SABnzbd.Aktivere filmsorteringAktivere MultiCore Par2Aktiver NotifyOSDAktiver OZnzb integrationAktiver Par rensning (Par Cleanup)Aktiver hurtig tjekAktiver SFV-baseret kontrolAktivere TS Sammenføjning (TS Joining)Aktivere TV sorteringAktivere UnrarAktivere UnzipAktiver adgang til interface fra en HTTPS-adresse.Aktivere indbygget Unrar funktion.Aktivere indbygget Unzip funktion.Aktiver klasser af meddelelser der skal indberettes (ingen, én eller flere)Aktiver mappe omdøbningAktiver til mindre brug af hukommelse. Deaktiver for at forhindre langsom job fra at blokerer køenAktiverer sortering og omdøbning af filer.Aktivere hvis ikke download er flyttet til egen mappe.Aktiverer sortering og omdøbning af datomarkeret filer.Aktiverer sortering og omdøbning af episoder.AktiveretSlutter stien med en stjerne *, vil forhindre oprettelse af ​​job mapper.Udvidet funktioner inklusiv anmeldelser og ekstra status information bliver tilgængelige hvis forbundet med OZnzb indekseringen.URLEpisodenavnEpisodenummerEpisode.NavnEpisode_NavnFejl "%s" når du køre file_join på %sFejl "%s" mens par2_repair kørte på %sFejl "%s" når du køre rar_unpack på %sFejl "%s" når du køre unzip() på %sFejl %s når du køre par2_repair på %sFejl %s: Du skal angive et gyldigt brugernavn og adgangskode.Fejl ved hentning af msgid %s fra www.newzbin2.es - Kontroller, at dit brugernavn og din adgangskode er korrektFejl ved oprettelse af SSL-nøgle og certifikat.Det lykkedes ikke at hente TV info (%s)Det lykkedes ikke at importere %sMislykkedes med importering af OpenSSL modul. Tilslutter uden SSLDownloadnings fejl %s, ødelagt fil fundetFejl ved fjernelse af %sDet lykkedes ikke at fjerne arbejdsmappen (%s)Det lykkedes ikke at omdøbe "%s" til "%s"Det lykkedes ikke at tilføje %s, sletteFejl ved lukning af systemKun ved fejlFejl: Ingen sekundær bruger grænseflade defineret.Fejl: Køen er ikke tom, kan ikke skifte mappe.Fejl: Fejl sessionsnøgleFejl: Kræver sessionsnøgleFejl/AdvarselAltEksempelAfslut SABnzbdendelseEkstra PAR2 parameterUdpakning...Ved fejl på yEnc CRCMislykkedesDet lykkedes ikke at logge på serveren %sOprettelse af (%s) mislykkedesDet lykkedes ikke at flytte %s til %sGodkendelse til mailserver mislykkedesDet lykkedes ikke at lukke databasen, se loggDet lykkedes ikke at lukke e-mail tilslutningDet lykkedes ikke at kompilere regex for søgestreng: %sDet lykkedes ikke at tilslutte mailserverDet lykkedes ikke systemet at gå i dvaleDet lykkedes ikke at importere %s filer fra %sDet lykkedes ikke at initialisere %s@%s:%sDet lykkedes ikke at initialisere TLS tilslutningKunne ikke indlæse efterbehandle kø: Forkert version (kræver:%s, fundet:%s)Kunne ikke flytte filerKunne ikke læse nøgler i registreringsdatabasen for specielle mapperDet lykkedes ikke at fjerne nzo fra efterbehandlings køen (id)Kunne ikke omdøbe lignende fil: %s til %sDet lykkedes ikke at omdøbe: %s til %sMislykkedes at hente RSS fra %s: %sDet lykkedes ikke at sende e-mailDet lykkedes ikke systemet at gå i standbyKunne ikke starte web-interfaceKunne ikke opdatere newzbin job %sMislykkedesFejl i tempfile.mkstempAlvorlig fejlFeedFeedsHenteHenterHenter %s block...Henter ekstra block...Fil %s er tom, springer overFiltypeFil, der indeholder alle passwords. Vil blive brugt på password beskyttede RAR filer.Filsammenlægning af %s mislykkedesFilnavn eller sti til HTTPS Certifikat.Filnavn eller sti til HTTPS kæde.Filnavn eller sti til HTTPS Nøgle.Fil sætFilnavnFilterFiltrerer prøve filer (f.eks. video eksempler).FiltreFørstMappen "%s" findes ikkeMappe konfigurationMappe, der indeholder bruger scripts til efterbehandling.Mappe, der indeholder brugerdefinerede e-mail-skabeloner.Mappe til at gennemsøge for. Nzb filer.
    Skanner også for .zip .rar og .tar.gz arkiver efter .nzb filer.Mappe/SøgestiMapperBrugernavn for e-mail som kræver godkendelse.Password for e-mail som kræver godkendelse.TvingeGennemtving afbrydelseGennemtving downloadForumLedig tempdiskpladsLedig diskpladsForekomstFredagØvrig hjælp kan du finde på voresGBGenereltGenerel konfigurationGenerere Ny NøgleAlmindelig sorteringHent bogmærkerHent bogmærker nu.Hent NZBHenter Newzbin bogmærkerGå til SABnzbdGå til guidenGruppe / Index tagsHTTPS CertifikatHTTPS kæde certifikaterHTTPS NøgleHTTPS PortHTTPS SupportHjælpSæt computer i dvaleSkjul bogmærkerSkjul RedigeringsalternativSkjul detaljerSkjul filerHøjHistorikHistorik (de 10 seneste poster)Størrelse af HistorikHjemStartsideVærtAdresse som SABnzbd ska lytte på.Time:MinutHvor meget der kan downloades i denne måned (K / M / G)Jeg ønsker at SABnzbd skal være synlige fra enhver pc på netværket.Jeg ønsker kun at SABnzbd skal være synlige fra min computer.VenterUfuldstændigIONice parametrarIRCInaktivHvis tom, vil standard-porten kun lytte til HTTPS.Hvis du er medlem af newzbin eller nzbmatrix, kan du indtaste dit brugernavn og password her, så du kan hente deres nzb's. Denne fase kan springes over, hvis du ikke bruger nogen af disse tjenester.Hvis du ikke har en konto, kan den oprettes på Hvis du får denne fejlmeddelelse igen, prøv et andet portnummer.
    Hvis du har en konto til www.newzbin2.es, kan du angive din konto info her. < br / > dette vil låse ekstra funktionaliteter op.Hvis du har en konto til www.nzbmatrix.com, kan du skrive dine bruger informationer her.
    Dette er nødvendigt, hvis du ønsker at bruge RSS-feeds på nzbmatrix.Ignorer Sample-filerIgnorerer identiske NZB "%s"Ligger iI tilfælde af "Pause", skal du angive en adgangskode og genoptage jobbet.I mappeI minutter (mindst 15 min).For at hente fra usenet kræves der adgang fra en udbyder. Din internetudbyder kan give dig adgang, men en præmie udbyder anbefales.Inkompatibel feedØdelagt queuefile fundet, kan ikke fortsætteUfuldstændig mappeUfuldstændig NZB fil %sUfuldstændig sekvens af joinable filerForkert RSS-feed beskrivelse "%s"Fejl parameterFejl værdi før %s: %sForkert kodet password%sIndex-siderIndekseringForbereder genstart...
    Ødelagt NZB fil %s, springer over (årsag=%s, linje=%s)Ugyldig kodning af e-mail skabelon %sUgyldig nzbmatrix legitimationsoplysningerUgyldigt nzbmatrix rapport nummer %sUgyldig PAR2 filer, kan ikke kontrollere eller reparereUgyldig server adresse.Ugyldige serverdetaljerForkert loggning i historiken av %sInvertereDet er sandsynligt, at du bruger ZoneAlarm på Vista .
    Det anbefales, at du højreklikker og bogmærker denne placering, og bruger dette bogmærke for at få adgang SABnzbd, når det kører i baggrunden.Job "%s" er genoptaget i køenJob afsluttetJobs markeret med '*' vil ikke blive hentet automatisk.Sammenlægger filerSammenføjer filer, der ender med .001, .002 osv. til en fil.Sammenføjer filer, der ender med, 001.ts, .002.ts osv. til en fil.SammenlæggerKB/sBehold løse download i ekstra mapperSprogSidsteSeneste advarslerStart web browser ved opstartStart webbrowseren med SABnzbd's siden når programmet startes.Starter standard web browser når SABnzbd starter.VensterHastighedsbegrænsningLinksListe over filtypenavne, der skal slettes efter download.
    . For eksempel: .nfo or .nfo, .sfvDownloadning af %s mislykkedesPlacering for kø administrativ og historik database.
    Kan kun ændres, når køen er tom.Placering af logfiler for SABnzbd.
    Kræver genstart af SABnzbd!Sted at opbevare færdige, fuldt forarbejdede downloads.
    Kan tilsidesættes af bruger-definerede kategorier.Sted at gemme uforarbejdede downloads.
    Kan kun ændres, når køen er tom.Sted hvor .nzb filer gemmes.Log mappeLogningLavSmå bogstaverMBHovedarkiv mangler...MatchedeMax hastighedMaksimalt antal forsøg per serverMaksimalt antal forsøgBetyderMinimum fri plads til midlertidige download mappeDiverseMangler sessionsnøgleMangler artiklerManglede forventet fil: %s => unrar fejl?MandagMånedMereFilm NavnFilm.NavnFilm_NavnFlytterFlytter...Multi-operationerMulti-del etiketteNZB nøgleNZB tilføjet i køenNavnNavngivningAldrigNy Feed URLNy version %s tilgængeligNy version tilgængligNewsbin adgangskodeNewzbin BrugernavnNewzbin giver udokumenterede fejlkode (%s)Newzbin giver udokumenterede fejlkode (%s, %s)Newzbin rapporterede %s ikke fundetNewzbin server ændrede sin protokolNewzbin server mislykkedes at give information til %sNæsteGod parameterIngen PAR2 program fundet, reparationer ikke muligt
    Ingen unrar program fundet, udpakning RAR filer er ikke mulig
    Ingen e-mail skabeloner fundetIngen mappeIngen efterbehandling på grund af mislykket bekræftigelseIngen modtagere givet, ingen e-mail sendtIngen resultaterIngenNormalMatchede ikkeIkke nok diskplads til at fuldføre downloads.Matchede ikkeNotification CenterNotifikation sendtNotification klasserMeddelelserSekunder mellem skanninger for .nzb filer.NzbMatrix API-nøgleNzbMatrix BrugernavnOKVALGFRIT Bruger passwordVALGFRIT konto brugernavnOZnzbSlået fraVed afslutningNår køen er færdigPå hvilken dag i måneden eller ugen (1 = mandag) nulstiller din internetudbyder kvota? (Valgfrit med tt: mm)Kun artiklerne fra starten af køenKun for ekstra servereKun udføre efterbehandling af jobs som har bestået PAR2 kontrollen.Bruges kun ved Growl fjern server (vært: port)Åbn informations URLÅbn kildekode URLÅben et terminalvindue og tast linjen (eksempel):Åben færdig mappeValgfriValgfri Supplerende NZBValgfrit password.Valgfrit brugernavn.Valgfri adgangskode til Growl serverAngiv et valgfrit filnavnMulighederRækkefølgeOriginalfilnavnOrginal MappenavnAndetAndre beskederAndre parameterEt andet problemUdenfor retentionPAUSETSideParameterDelnummerAdgangskodePassword-filPassword maskeret med ******, forsøg igenPassword beskytte adgangen til SABnzbd (anbefales)Behov adgangskodeStiMønsterHjælp til SorteringsstrængPausePause altPause downloading under efterbehandlingPause intervalPause iPause 1 timePause 12 timerPause 15 minutterPause 24 timerPause 3 timerPause 30 minutterPause 5 minutterPause 6 timerPause i hvor mange minutter?Pause i...Pause efterbehandlingSat på pausePauser downloadet i begyndelsen af efterbehandling og igen når den er færdig.Pause duplikeret NZB "%s"Tilladelser til fuldførte overførslerVær opmærksom på at 0.0.0.0 værtsnavn har brug for en IPv6-adresse for ekstern adgangAngiv et helt tal.Angiv detaljerne fra din primære usenet udbyder.Plush InstillningerPortPort som SABnzbd ska lytte på.Efterbehandling mislykkedes for %s (%s)EfterbehandlingEfterbehandling kun verificerede jobsEfterbehandlings scripts mappeEfterbehandlingEfterbehandling i gangEfterbehandling blev afbrudt (%s)Før kø bruger scriptForudindstillingerTryk Startkey + R og skriv linjen (eksempel):ForegåendeForrigePrioritetSandsynligt delt kontoProblem at få adgang til nzbmatrix server (%s)Problem medBearbejdede bogmærkerForarbejdede resultatForløbForløbs parameterProgrammet startede ikke!FremgangSletRens komplette NZB'erRens mislykket historieRens mislykket NZB'erRens mislykket NZB'er & slet filerTøm historikRens NZB'erRens NZB'er & slet filerRens køenVil du virkelig tømme historiken?Tøm køen?Python-versionQR kodeKøKø (de første 10 poster)Automatisk opdaterings interval af kø:Kø reparationKøenHurtig kontrol...Hurtig kontrollerendeAfslutKvotaKvota tilbageKvota periodeKvote brugt, pause downloadingRRSSRSS Opdaterings intervalRSS-konfigurationRSS Feed %s er tomKørte %sOmfangSjældent anvendte indstillinger. Deres betydning og forklaring, klik på knappen Hjælp for at gå til siden Wiki.
    Ændre ikke disse uden at kontrollere wiki'en først, da disse kan give alvorlige side følger.
    Standardværdierne er mellem parenteserne.Læs alle Feeds nuLæs FeedLæs RSS feedsLæs mere om dette på Wiki Help!Se https://www.oznzb.com/profileOpdatereOpdateringsintervalopdaterings interval af kø-siden (sek, 0= ingen).OpdateringsfrekvensAfviseRelative mapper er baseret påTilbage/TotaltTilbageværendeSletFjern NZBFjern NZB & slet filerFjern serverFjern mislykkede jobsFjern fra bogmærkelisten når downloadning er gennemført.Fjernelse af%s mislykkedesOmdøbeReparererReparation mislykkedes, ikke nok reparation blokke (%s mangler)ReparererReparation mislykkedes, %sReparerer...Erstat ugyldige tegn i mappenavn.Erstat mellemrum i mappenavnErstat punktummer i mappenavnErstat punktum med mellemrum i mappenavnErstat ugyldige tegn i mappenavn med modsvarende tegn (ellers fjern).Erstat mellemrum med understreg i mappenavn.RapportérRapport-idKræverKræver CatGendanNulstil kvota nuNulstil dagGenstartGenstart uden loginGenstarter SABnzbd...ResultatGenoptagGenoptag efterbehandlingTilgængelighed i dageForsøg igenKøre scriptKør script...Kør bruger script %sS01E05 EpisodemappeS01E05 SæsonmappeSABnzbd %s startetSABnzbd AdresseSABnzbd passwordSABnzbd PortSABnzbd Hurtigstart’s GuideSABnzbd brugernavnSABnzbd versionSABnzbd WebserverSABnzbd fandt en alvorlig fejl:SABnzbd lukning udført.SABnzbd vil nu køre i baggrunden.SMTP-serverSQL Kommando mislykkedes, se loggSQL Commit mislykkedes, se loggSSLSSL typeLørdagGemGem ændringerGemtGemmes %s mislykkedesGemmer..Scan overvåget mappeTidsplan for ikke-eksisterende server %sPlanlægningPlanlægningskonfigurationscriptScriptsSæsonnummerSekundær udseendeVælg et web-grænseflade sprog.Vælg kun hvis din udbyder tillader SSL-forbindelser.UdvælgelseSendSend gruppeSend RSS meddelelserSend automatisk kalkuleret validerings resultater for downloads til indekseringen.Send e-mail når en RSS-feed tilføjer job i køen.Send e-mail når harddisken er fyldt og SABnzbd er pauset.Send gruppe kommandoen, før du anmoder om artikler.Send meddelelser til GrowlSend notifications to Notification CenterSend meddelelser til NotifyOSDSendt %s til køSerie sorteringServerServer %s kræver brugernavn/passwordServer %s vil blive ignoreret for i %s minutterServerdetaljerServeradresseServeradressen "%s:%s" er ikke gyldigt.Kræver serveradresseServerkonfigurationServer definitionServerkodeordServer afslut under login-sekvens.Serveren kræver brugernavn og password.ServerSæt pause intervalAngive tilladelses mønster for afsluttede filer.
    Anvend ciffer. For eksempel: "755" eller "777"Indtast API-nøglen til NzbMatrix her.Indtast ISP's server for udgående e-mail.Indtast dit password her.Indtast dit brugernavn her.IndstillingerInstallationen er nu fuldført!Skal download genoptages efter kvotaen er nulstillet?Vis AltVis bogmærkerVis RedigeringsalternativVis mislykketVis logVis navnVis Navn på mappeVis webblogVis detaljerVis filerVis grænsefladeVis tider i AM / PM notation (påvirker ikke skemalægger).Vis.NavnVis_NavnViser %s til %s af %s resultatViser et resultatLuk nedLuk computerAfslut SABnzbdPåbegynder lukning af SABnzbd..Signal %s modtaget, gemmer og lukker...Sidens API nøgleStørrelseSpring overSpring par2 kontrol over, når filerne er 100% gyldige.Some files failed to verify against "%s"SortereSorteringsstrængSortere efter alderSortera efter Alder (Nyeste→Ældst)Sortere efter Alder (Ældst→Nyeste)Sortere efter alder Nyeste→ÆldstSortere efter alder Ældst→NyesteSortere efter Navn (A→Z)Sortere efter Navn (Z→A)Sortere efter navn A→ZSortere efter navn Z→ASortere efter Størrelse (Størst→Mindst)Sortere efter Størrelse (Mindst→Størst)Sortere efter størrelse Størst→MindstSortere efter størrelse Mindst→StørstSortere efter alderSortere efter navnSortere efter størrelseSorteringSorteringskonfigurationKildeSpecielHastighedHastighedsbrgrænsningHastighedsbegrænsningSæt computer i standbyStart guideStarter reparationStart / LukningStatusTrin femTrin fireTrin etTrin treTrin toStopStandserOpbevaringEmneSøndagParameterParameterkonfigurationSysloadSystemmapperTEKSTFOR STOROpgaveMidlertidig download mappeTest E-mailAfprøv notifikationTestserverTester serverdetaljer..."Reparation" knappen vil genstarte SABnzbd og lave en komplet
    rekonstruktion af køens indhold, bevare allerede downloadede filer.
    Dette vil ændre køens orden.Det automatiske usenet download værktøjAfkrydsningsfeltet ud for feed navn skal afkrydses for at feeds vil være aktiveret og automatisk kontrolleres for nye emner.
    Når et feed er tilføjet, vil det kun hente nye informationer og ikke noget, der allerede findes i RSS-feed, medmindre du trykker på "Force Download".Værtsnavnet er ikke indstillet.Antallet af forbindelser tilladt af din udbyderDer er ingen forbindelser angivet. Angiv mindst én forbindelse.Der er forældreløse jobs i download mappen.
    Du kan vælge at slette dem (herunder filer) eller sende dem tilbage til køen.Dette fælt kræves.Denne nøgle kobler profilen til indekseringen. Se https://www.oznzb.com/profile.Denne nøgle vil give 3. parts programmer til at tilføje NZBs til SABnzbd.Denne nøgle vil give 3. parts programmer fuld adgang til SABnzbd.Denne månedDenne ugeDette vil forhindre indhold i at blive opdateret når musens markør kører hen over køenKnappen vil genstarte SABnzbd..
    Andvend den hvis du oplever stabilitets problem.
    Downlodning vil blive sat på pause før genstart og genoptages automatisk igen efter genstart.Dette vil sende en test E-mail til din konto.TrådTorsdagTimeoutTimeout: Forsøg at aktivere SSL eller tilslut via en anden port.Resterende tidTidsudløbTitelTo: %s From: %s Date: %s Subject: SABnzbd rapportere Disk Fuld Hej, SABnzbd er stoppet med at downloade, fordi disken er næsten fuld. Vær venlig at give plads og genoptage SABnzbd manuelt. I dagVis/Skjul Tilføj NZBFor lidt diskplads tvinger system i PAUSEFor mange tilslutninger til server %s:%sAlt for mange forbindelser, pause en download eller forsøg igen senereØverstTopmenuTotaltFejlfindingForsøg igenPrøv at forudsige en vellykket afslutning, før selve download (langsom!)Forsøger SFV verifikationForsøger at hente NZB fra %sForsøger at sætte status på ikke eksisterende server %sForsøger unrar med adgangskode "%s"TirsdagJusteringTypePUNC søgning "%s" er ikke tilladt herURL hentning mislykkedes; %sANDVEND PÅ EGEN RISIKO!Fjern bogmærker efter downloadning.Ingen adgang, kontroller din newzbin brugernavn / adgangskodeOphæv blokeringUkendt fejl under afkodning af %sUkendt handling: %sUdpakUdpakket %s filer/mapper i %sUdpakkerUdpakning mislykkedes, %sUdpakning mislykkedes, CRC-fejlUdpakning mislykkedes, en ventet fil er ikke udpakketUdpakning mislykkedes, arkivet kræver passwordUdpakningen mislykkedes, stien er for langUdpakning mislykkedes, se loggUdpakning mislykkedes, disse fil (er) mangler:Udpakning mislykkedes, kunne ikke finde %sUdpakning mislykkedes, skrivefejl eller disken fuld?Fejl, Ubrugelig arkivfilUbrugelig RAR filOpOpdatering tilgængeligSendUpload: .nzb .rar .zip .gzOppetidBrug 12 timers ur (AM / PM)Anvend V23 hvis ikke din leverandør (ISP) kræver andet!Brug midlertidig navne under efterbehandling. Deaktiver når dit system ikke kan håndtere det ordentligt.Brug 'Gruppe / Index tags' kolonnen til at kortlægge dine grupper og tags til dine kategorier.
    Jokertegn understøttes. Brug kommaer for separate vilkår.Brugt før, en NZB kommer ind i køen.Brugt chaceAnvedes når efterbehandlingen er bestemt efter kategori.Anvendes når ingen prioritet er bestemt af kategori.Anvendes når bruger scripts er bestemt efter kategori.BrugermapperBruger definerede kategorierBrugernavnVærdierKontrolleret korrekt ved hjælp af SFV filerBekræfterBekræftelse...UdgaveVideoVis scriptloggVis script udlæsningVirus/spamVENT %s sekunderADVARSEL:ADVARSEL: afbrudt job " %s" på grund af krypteret RAR filWARNING: Paused job "%s" because of encrypted RAR fileADVARSLERVenterAdvarselVarning: Localhost er tvetydig, bruge numerisk IP-adresse.AdvarslerOvervåget MappeSkannings interval for overvåget mappeWebgrænsefladeWebserver godkendelseOnsdagKontroller for ny version af SABnzbd hver uge.NårAnvend backup-server ved yEnc CRC fejl.Når under download det bliver klart, at for meget data mangler, afbryd jobbetHvem skal vi sige sendte e-mailen?WikiXÅrÅr-Måned mapperDu har ingen kredit på din konto NewzbinDu har ingen tilladelse til at bruge port %sDu skal aktivere JavaScript for at få Plush til virke!Du skal bruge en nzbmatrix VIP konto for at bruge API'ENDin unrar version kan ikke anbefales, hent UNRAR fra http://www.rarlab.com/rar_add.htm
    [%s] Fejl "%s" under filsammenlægning[%s] Fejl "%s" under udpakning af RAR fil(er)[%s] Sammen lagte %s filer[%s] Ingen par2 sæt[%s] PAR2 modtog forkerte indstillinger, tjek din konfiguration->Skifter indstillinger[%s] Hurtig kontrol OK[%s] Repareret i %s[%s] Bekræftelse i %s, alle filer er ok[%s] Bekræftelse i %s, kræver reparation_yenc modul... IKKE fundet!sag-justeretSletddagdagedeaktivere serveraktivere serverhenter msgid %s fra www.newzbin2.esfilmappehtimetimertilbagemmanueltminutmin.minutterikke installeretfraslået frapåellersidepar2 binær... IKKE fundet!pyopenssl modul mangler, du skal installere for HTTPS-adgangsekundsekunderse logfiltekstUkendtunrar binær... IKKE fundet!unzip binær... IKKE fundet!ugeSABnzbd-0.7.20/locale/de/LC_MESSAGES/SABnzbd.mo0000644000000000000000000023563112433712600020471 0ustar00usergroup00000000000000<\>o]>>d?CA=B C2DQEEF/G*FG'qGGGG GHH6H VHaHhHHH2I:IAIIIQIYIlIII?JXJJJJRJ[JKK#KKK LL L &L3L':LbLjLLLLL L LL LLLaMfMjMnMM.MMM)M*N >N LNVNjN/}NhN O"O7O(O0O*P@PBPGP NP\PuP PPPPPPoQQ2Q QQ R7RRRpR!R6R-RS5SDSbS ~SS.S'SSSTB/TrT{TSTT TT5UIUOU^U"sUU8U UU UUV V )V7VQV&iVV VV$V*VW%W,W .W8W >W LW YWfWmWWWWWW$WWX XX %X 3X?X(UX~X%X X-XY$Yf?YYY4YY?Y]H]b]|]]]]]]]$] ^^ )^ 6^B^Y^#k^^^^^^^^ ^ __7_L_b_s_____ _ _4_$$`$I`An``S`-a5Ga0}a(aaHa (b 2b?b Nb [b(hb.b)b&b,c<>cb{c&cd d73d'kddddd d e&)e-Pe~eee ee e ee ff,f3fNfaf%xf!ff+f g-g!Hgjg!gFgg0h-7h'ehh"hhhhi8i@i \ihimisiyiiiiiAij'4j\j|jjj-jjjjj3k/5kgek kk&k"l+l1lBlQl Wl cl nlxl llllll llm m m .m;mQm cm mm xmm mmm m mmmm mn nnn4n-=n6kn.nn nnnn6n3oGo/ppeqtqqEq qqrr,rrr%s#)sMsas|s ss2s%st";t+^ttt'tt7t u"u u<u v3#v9Wvvv%vvvvvIv5Fw|w wwqwxcxH{xox]4y)y yyy yyyy z$ z1zAz0Izzzzz)zzzz z z z{ {{#{4{<{O{T{[{ a{n{{{{*{.{|#8|(\|||1|A|} '}12}"d} }}} },} }}} ~ ~/-~]~o~~~~~ ~~c~";^Ax,3BW`!z!" 3BQX ] ht }*0  (9 HRcvłق *M1#R<. ky~"Є7Wm-u'Ӆ  -8Lclr φ ݆ !2AIOd  ɇ և%;BH: MWf ? ׉  '2 LZ4m2Ê  *"Mj)M0 .8 AMS cmuƌՌی)> Q^ o|ˍ. 4@\w{ #ӎ " *8 P4q 3ҏ3.:i)ϐ (@O$^‘"ґ&$o7)ǒ1:3Q ȓғ  9 T ^"h  Ĕ'Ҕ-(2[ ` l/x/-ؕ-&4&[$$3̖3141f Ɨܗ   0A H R\ epy ~ɘؘ ݘ  #/I"27Aj1>I= Ɯ ќWۜ3,؝ >^gou)/">$aAȟ̟՟ ۟ E8P.làʠϠѠ 2?rz ԡޡ3-C"q,#ۢ..@CU\w~0bɣ,$ ޤ81"4T %  &27;6s:æ 0> X%b@RΧ!!CHJO*b$10Z#p)өJ0D&X' ªЪ֪تܪ &%*138>CELPU Zhkoruz9Ϋҫ ګ (-ĭ=M'&N01Ybն;ܷ3(Lu1ո $,5 <]r * 1 ; GRdyU6)/>nNj (52-h' ʽҽ786AxϾ&U<;*1&\ My>;FACK \j *$,R+:~ ,+'35[3O^5t0!  %C/2s"$W_pZ* $LE: E]o  *" :,#g 54 ,.7@Q f s} !>#bk t 2( :3,nHv  E i+r&,-; \(p JC I Tb r|&0L9YiFy  ,;J R]o  8HWiy3( EP%p,34I!`%(9 8F8O&<H HT1K! %3 C Q0_;1,2+M^~9+,eK643Q))&/P@%* 5 Bc'r)1L-cL:&0@'q(b"%CHO<)/C!s-'6")D[`fnv%2 Z!U*w* 5&-IW^8 p|;: *50f {3 / IUq $$-Rdv{% / =EU4:AMW? *KKN #F8%Jp $;*3"^'E /$ T5`8'`OtFL"o~>=:9 t!:eA~!Gi z 0 ,46 ky0  4R"a  =AB!1=D,Tq :3-ary8%28k  n>bh=$byE+/;)k#  &1 7 AL U8c4 /6 ?Mbv)& >TI&j$N>s/*& )6 #`   & !  B K S  [ &f 5        4 @ G %]  )      0 F U  ] ,k #       & 1 J 4^        .  /:!J lvf , B N XeM  'O2  *#2'fZ7  (G Ye} "=Tj  11"G jAvA  .: Wd)~+;X `nLH9""\4&&5!(W% "3<p!wi!+%!Q&s &P .#Cg{ B G U5c + E.7t 888N8+++ +D ;p < ; <%!b!w!! !!!!!!!!":"N"c"s" z" " " " "" " """"" " ###"#*# F#T#n#$##.$$"%6%M*&x&'U2'N' ' 'l'](%')M) T)_)Ms) ))))**.*&&+^M++ ++ ++^+K,#f,<,$,,,--$ -"/-R-3o-L- -%- . 6."@. c.m.$.D.8.*-/5X/0/1/F/80 N0X0 q0{00 0@0n 1z1I522E2@2D3]3m3 33+3 3333 4 !4.4>746v4 444L4 55'15Y5!i55G55-5O6#_66666/666<7>E770 8/:8j88Y8'8#90891i99)999999:!:;:A:H:J:Q:Y:^:`:h:p:u:}::::::":B: ;;;<; A;#K;#o;; SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAcceptAccessAccess deniedAccount infoActionAction when encrypted RAR is downloadedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)Cannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.Complete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOther MessagesOther SwitchesPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!RefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.Report-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSend GroupSend RSS notificationsSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogView script outputWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2013-12-10 20:10+0000 Last-Translator: Clément Meur Language-Team: German MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:54+0000 X-Generator: Launchpad (build 17082) SABnzbd kann die Dateien für die Web-Oberfläche in %s nicht finden.
    Installieren Sie bitte das Programm erneut.

    SABnzbd hat den Verlauf und die Warteschlange einer älteren Version (0.4.x) erkannt.

    Beide werden ignoriert und können verloren gehen!

    Es wird empfohlen, SABnzbd anzuhalten und die ausstehenden Downloads mit der älteren Version fertigzustellen.

    Wählen Sie OK, um fortzufahren. SABnzbd hat die gespeicherten Daten einer anderen SABnzbd-Version erkannt,
    kann diese aber nicht wiederverwenden.

    Es wird empfohlen, die ausstehenden Downloads mit der anderen Version fertigzustellen.

    Starten Sie dieses Programm danach mit der "--clean"-Option.
    Dies löscht die Download-Warteschlange und den Download-Verlauf!
    SABnzbd hat die Datei "%s" gelesen. SABnzbd hat erkannt, dass die Datei sqlite3.dll fehlt.

    Manche unausgereiften Viren-Scanner löschen diese Datei.
    Bitte überprüfen Sie den Viren-Scanner, versuchen Sie eine Neuinstallation von SABnzbd und beschweren Sie sich beim Hersteller des Viren-Scanners.

    SABnzbd funktioniert nicht in Kombination mit manchen Software-Firewalls.
    %s
    Dieses Problem können Sie zur Zeit nicht selber lösen.
    Beschweren Sie sich bitte beim Hersteller der Firewall.

    Für seinen internen Web-Server benötigt SABnzbd einen freien TCP/IP-Port.
    Port %s auf %s wurde probiert, ist aber nicht verfügbar.
    Entweder verwendet eine andere Software den Port oder SABnzbd läuft bereits.

    Starten Sie SABnzbd bitte mit einer anderen Portnummer neu. Für seinen internen Web-Server benötigt SABnzbd einen freien TCP/IP-Port.
    Port %s auf %s wurde probiert, aber das für SABnzbd verwendete Konto darf ihn nicht verwenden.
    Auf OS X und Linux-Systemen müssen normale Benutzer Ports über 1023 verwenden.

    Starten Sie SABnzbd bitte mit einer anderen Portnummer neu. Für seinen internen Web-Server benötigt SABnzbd eine gültige Rechner-Adresse.
    Sie haben eine ungültige Adresse angegeben.
    Sichere Werte sind localhost und 0.0.0.0

    Starten Sie SABnzbd bitte mit einer gültigen Rechner-Adresse neu. Für SABnzbd besteht KEINERLEI GARANTIE. SABnzbd ist freie Software, die Sie unter bestimmten Bedingungen weitergeben dürfen. Sie steht unter der GNU GENERAL PUBLIC LICENSE Version 2 oder (nach Ihrer Option) jeder späteren Version. %s -> Unbekannte Kodierung%s wurde auf keinem Server gefunden und daher übersprungen%s Artikel hatten nicht übereinstimmende Duplikate%s Artikel hatten ein ungültiges Format%s Artikel fehlten%s Artikel wurden entferntZugriff auf das Verzeichnis %s fehlgeschlagen: %s%s Dateien in %s%s ist kein gültiger Oktal-Wert%s ist keine gültige E-Mail-Adresse%s fehlt  Adresse wird aufgelöst... oder Report-ID 
    SABnzbd wurde beendet.
    Warten Sie 5 Sekunden und klicken Sie danach auf folgenden Knopf.

    Aktualisieren
    + Fehlersuche+ Info+Löschen+Reparieren+EntpackenNZB-Backup-Ordner1x05 Episoden-Ordner1x05 Staffel-OrdnerHINWEIS: Ordner werden beim Speichern automatisch erstellt. Sie können absolute Pfade angeben, um Ordner ausserhalb der standardmässigen Ordner zu verwenden.Es werden keine Dateien entfernt. Benötigt einen Neustart von SABnzbd!Feed lesen ruft den momentanen Inhalt des Feeds ab. Download erzwingen lädt sogleich alle passenden NZB-Dateien herunter.AlterAPI-SchlüsselAPI-Key OR-CodeAPI-Schlüssel ungültig. Bitte API-Schlüssel aus Einstellungen->Allgemein in die externe Anwendung eingeben:API-Schlüssel fehlt. Bitte API-Schlüssel aus Einstellungen->Allgemein in die externe Anwendung eingeben:AbbrechenJobs abbrechen die nicht abgeschlossen werden könnenAbgebrochen, kann nicht fertiggestellt werdenAbgebrochen, Verschlüsselung vorhandenAkzeptierenZugriffZugriff verweigertKonto-InformationenAktionAktion wenn eine verschlüsselte RAR Datei geladen wirdAktionenGestaltung der sekundären Web-Oberfläche verändern.Hinzufügen einerFeed hinzufügenDatei hinzufügenNZB hinzufügenRegel hinzufügenServer hinzufügenNeue Downloads hinzufügenHinzugefügte NZBAdministrativer OrdnerBetroffene KategorienNach dem Neustart von SAbnzbd können Sie über folgende Adresse darauf zugreifen: %sAlterAlleAuch Test-VeröffentlichungenImmerDie Anzahl Wiederholungen nur auf optionale Server anwendenAuf Auswahl anwendenMöchten Sie wirklich löschenMöchten Sie SABnzbd wirklich neu starten?Möchten Sie SABnzbd wirklich beenden?Sind Sie sicher?ArgumenteBegrenzung des Artikel-CachesArtikelbezeichnerAuthentifizierung fehlgeschlagen. Überprüfen Sie Benutzername und Passwort.Authentifizierung fehlt. Bitte Benutzernamen und Passwort aus Einstellungen->Allgemein in die externe Anwendung eingeben:Automatisch fortsetzenLesezeichen automatisch abrufenSABnzbd hält automatisch an, wenn der freie Speicherplatz unter diesen Wert fällt.
    In Bytes, gefolgt von einem optionalen K, M oder G. Zum Beispiel: "800M" or "8G"Mit Lesezeichen versehene Beiträge automatisch herunterladen.Automatisch Aufträge basierend Ihren Lesezeichen erzeugen.Einträge automatisch nach ihrem (durchschnittlichen) Alter sortieren.BZurückSicherheitskopieErsatz-ServerUngültige Regel %s um %s:%sUngültiger yEnc-Artikel in %sBandbreiteAktualisierung durch Mauszeiger verhindernVerarbeiten von LesezeichenGanz nach untenCRC-Fehler in %s (%s -> %s)Artikel werden zwischengespeichert, um die Anzahl der Zugriffe auf die Festplatte zu reduzieren.
    In Bytes, gefolgt von einem optionalen K, M oder G. Zum Beispiel: "64M" oder "128M"%s Artikel im Cache (%s)Rechte von %s konnten nicht geändert werdenVerbindung zu Registry-Umgebung HKEY_CURRENT_USER konnte nicht hergestellt werden.Verbindung zum Server %s kann nicht hergestellt werden. %sKann kein %s Ordner %s erstellenKann keine Sicherungsdatei erstellen für %sVerzeichnis %s konnte nicht angelegt werdenKonnte Download-Ordner %s nicht anlegenTemporäre Datei für %s konnte nicht angelegt werdenIn %s konnten keine E-Mail-Vorlagen gefunden werdenKonnte Web-Vorlage nicht finden: %s Versuche die Standard-Vorlage zu verwenden.Der Standard-Browser konnte nicht gestartet werden, da er wahrscheinlich nicht gefunden wurde.Registry-Schlüssel %s konnte nicht geöffnet werden.%s kann nicht gelesen werdenÜberwachter Ordner %s kann nicht gelesen werdenKann INI-Datei %s nicht schreibenKategorienKategorieDie Änderungen wurden nicht gespeichert und werden verloren gehen.Änderungen benötigen einen Neustart von SABnzbd!Vor dem Herunterladen überprüfenAuf neue Version prüfenResultat des Entpackens überprüfenResultat des Entpackens überprüfen (muss bei manchen Dateisystemen deaktiviert sein).Wird überprüftÜberprüfungs-IntervalÜberprüfungs-Intervall (in Minuten, mindestens 15). Nicht aktive wenn Regeln aktiv sind!Gestaltung der Web-Oberfläche verändern.Unerwünschte DateienAufräumen von %s fehlgeschlagenPAR-Dateien entfernen, wenn die Überprüfung und Reparatur erfolgreich war.LöschenZähler zurücksetzenUnten Klicken zum Überprüfen.Klicken um die eingegebenen Informationen zu überprüfen.SchliessenDas Schliessen des Browser-Fensters oder -Tabs beendet SABnzbd NICHT.Fertige DownloadsFertige DownloadsFertiggestelltOrdner für fertige DownloadsEinstellungenKonfigurationsdateiEinstellungenLöschen von Verlaufeinträgen bestätigenLöschen von Downloads bestätigenVerbindung zu %s@%s:%s konnte nicht hergestellt werden. %sVerbindung erfolgreich hergestellt!VerbindungenBreiteNewzbin-Lesezeichen %s konnte nicht gelöscht werden.Die Verbindung konnte nicht überprüft werden. (%s)Aktuelle RegelnBenutzerdefiniertLDUPLIKATTäglichTägliche OrdnerSortieren nach DatumTag im MonatJahrzehntFehler beim Dekodieren von %s.StandardStandardmässiger Basis-OrdnerStandardmässige NachbearbeitungStandardmässige PrioritätStandardmässiges Benutzer-SkriptBeeinflusst die Nachbearbeitung und Speicherung von Downloads.LöschenLöschenAlle löschenFertige entfernenFehlgeschlagene entfernenFeed löschenNach dem Download löschenAlle fertigen Downloads aus dem Verlauf entfernen?Alle heruntergeladenen Dateien löschen?Alle fehlgeschlagenen Downloads aus dem Verlauf entfernen?Alle Elemente in der Warteschlange löschen?Möchten Sie alle fehlergeschlagenen Downloads aus dem Verlauf löschen?Löschen von %s fehlgeschlagen!Doppelte Downloads erkennenNZB-Dateien mit identischem Namen sowie doppelt vorhandende Titel in RSS-Feeds erkennen (benötigt NZB-Backup-Option).API-Key deaktivierenDeaktiviertHTTPS wegen fehlenden Zertifikats- und Schlüsseldateien deaktiviert.VerwerfenVerbindung zu Usenet-Servern trennen,
    wenn die Warteschlange leer ist oder SABnzbd angehalten wurde.Bei leerer Warteschlange Verbindung trennenBenachrichtigung bei voller FestplatteFestplatten-Fehler beim Anlegen der Datei %sFestplatte voll! Downloads werden angehalten.Zusätzliche Überprüfung mittels SFV-Dateien durchführenNicht herunterladenKeine gültige Berechtigung für Feed %sKeinen API-Schlüssel verwenden.Wird das Kontingent jeden Tag, jede Woche oder jeden Monat zurückgesetzt?Wenn Sie noch keinen Usenet-Provider haben, empfehlen wir Ihnen %s.Nach untenHerunterladenDownload fertigDownloadsDownload FehlgeschlagenBegrenzung der DownloadgeschwindigkeitFehler beim Herunterladen. Ist die Datei zu alt?Download wahrscheinlich fehlgeschlagen, nur %s von benötigten %s verfügbarIn KB/s, Kilobytes pro Sekunde.GeschwindigkeitHeruntergeladenHeruntergeladen in %s mit einer Durchschnittsgeschwindigkeit von %sB/sBis jetzt heruntergeladenAm herunterladenDownloadsDualView 1DualView 2Z. B.Z.B. 119 oder 563 für SSLZ.B. 8 oder 20VERSCHLÜSSELTFEHLER:Fehler: %sCRC-Fehler in %s.Fehler: Pfad ist zu lang (%s)%s konnte nicht gefunden werden.Fehler beim Schreiben: %sETABearbeitenNZB-Details bearbeitenE-MailE-Mail-KontoeinstellungenEmail-Benachrichtigung beim Fertigstellen von AufträgenEmail-OptionenE-Mail-EmpfängerE-Mail-AbsenderE-Mail gesendet!Ordner mit E-Mail-VorlagenResultat des E-Mail-TestsE-Mail-Adresse, an die die E-Mails gesendet werden.E-Mail erfolgreich versendetLeerLeere NZB-Datei %sLeerer RSS-Feed gefunden: %sAktivierenSortieren nach Datum aktivierenZusammenfügen von Dateien aktivierenGrowl aktivierenHTTPS aktivierenZugriff auf SABnzbd über HTTPS ermöglichenFilm-Sortierung aktivierenMehrkernprozessor-Unterstützung von PAR2 verwendenNotifyOSD aktivierenPAR-Dateien aufräumenSchnelle Überprüfung aktivierenSFV-basierte Überprüfung aktivierenZusammenfügen von TS-Dateien aktivierenTV-Sortierung aktivierenunrar aktivierenunzip aktivierenZugriff auf die Oberfläche über HTTPS-Adressen erlaubenEingebaute Entpack-Funktion für RAR-Archive aktivieren.Eingebaute Entpack-Funktion für ZIP-Archive aktivieren.Benachrichtigung für Nachrichtengruppen aktivieren (keine, eine oder mehrere)Ordner-Umbenennung aktivierenFür geringere Speicher-Verwendung aktivieren.
    Deaktivieren, um zu verhindern, dass langsame Aufträge
    die anderen Einträge in der Warteschlange blockieren.Allgemeines Sortieren und Umbenennen von Dateien aktivieren.Aktivieren, wenn Downloads nicht in ihre eigenen Ordner abgelegt werden.Sortieren und Umbenennen von Dateien mit Daten im Dateinamen aktivieren.Sortieren und Umbenennen von Episoden aktivieren.AktivEin Sternchen * am Pfad-Ende verhindert die Erzeugung von Auftrags-Ordnern.URLEpisoden-NameEpisoden-NummerEpisoden.NameEpisoden_NameFehler "%s" beim Ausführen von file_join auf %sFehler "%s" beim Ausführen von par2_repair auf dem Satz %sFehler "%s" beim Ausführen von rar_unpack auf %sFehler "%s" beim Ausführen von unzip auf %sFehler "%s" beim Ausführen von par2_repair auf %sFehler %s: Sie müssen einen gültigen Benutzername und ein Passwort angeben.Fehler beim Abrufen msgid %s from www.newzbin2.es - Bitte stelle sicher das Benutzername und Passwort korrekt eingestellt sindFehler beim Anlegen des SSL-Schlüssels und -Zertifikats.Fehler beim Abrufen der TV-Informationen: %sFehler beim Importieren von %sFehler beim Importieren des OpenSSL-Moduls. Stelle Verbindung ohne SSL her.Fehler beim Laden von %s. Beschädigte Datei gefunden.Fehler beim Entfernen von %sFehler beim Entfernen des Arbeitsverzeichnisses %s.Fehler beim Umbenennen von "%s" nach "%s"Fehler beim Hinzufügen von %s. Entferne.Fehler beim Herunterfahren des SystemsNur bei FehlernFehler: Keine sekundäre Oberfläche angegeben.Fehler: Ordner kann nicht geändert werden, da die Warteschlange nicht leer ist.Fehler: Sitzungs-Schlüssel ungültigFehler: Sitzungs-Schlüssel wird benötigtFehler/WarnungenAllesBeispielSABnzbd beendenEndungZusätzliche PAR2-ParameterEntpacken...yEnc-CRC-Fehler nicht ignorierenFehlgeschlagenAnmelden beim Server fehlgeschlagen. %sErstellen von %s fehlgeschlagenVerschieben von %s nach %s fehlgeschlagenAuthentifizierung beim Mail-Server fehlgeschlagenFehler beim Schliessen der Datenbank. Beachten Sie das Nachrichtenprotokoll.Schliessen der Mail-Verbindung fehlgeschlagenKompilieren des regulären Ausdrucks für den Suchbegriff %s fehlgeschlagen.Verbindung zum Mail-Server konnte nicht hergestellt werdenFehler beim Wechsel in den RuhezustandImportieren von %s Dateien von %s fehlgeschlagenInitialisierung fehlgeschlagen %s@%s:%sAufbau der TLS-Verbindung fehlgeschlagenLaden der Nachbearbeitungs-Warteschlange fehlgeschlagen: Falsche Version (benötige %s anstatt %s)Dateien verschieben fehlgeschlagenLesen der Registry-Schlüssel für spezielle Ordner fehlgeschlagen.Fehler beim Entfernen der NZB-Datei von der Nachbearbeitungs-Warteschlange (id)Umbenennen der gleichen Datei von %s nach %s fehlgeschlagen.Umbenennen von %s nach %s fehlgeschlagen.Abrufen des RSS-Feeds von %s fehlgeschlagen: %sSenden des E-Mails fehlgeschlagenFehler beim Wechsel in den BereitschaftsmodusFehler beim Starten der Weboberfläche.Aktualisieren des Newzbin-Auftrages %s fehlgeschlagen.FehlerFehler in tempfile.mkstempSchwerwiegender FehlerFeedFeedsAbrufenAbrufen%s Blöcke werden abgerufen...Abrufen von zusätzlichen Blöcken...Die Datei %s ist leer und wird daher übersprungenDateiendungDatei mit allen Passwörtern, die bei verschlüsselten RAR-Dateien probiert werden sollen.Fehler beim Zusammenfügen von %sDateiname oder Pfad des HTTPS-Zertifikats.Dateiname oder Pfad des HTTPS-Schlüssels.DateimengeDateinameFilterBeispieldateien herausfiltern (z.B. Videoausschnitte)FilterAnfangOrdner "%s" existiert nichtOrdner-EinstellungenOrdner, der benutzerdefinierte Skripts für die Nachbearbeitung von Downloads enthält.Ordner, der benutzerdefinierte E-Mail-Vorlagen enthält.Ordner, der auf neue NZB-Dateien überwacht werden soll.
    Erkennt auch ZIP-, RAR- und TAR.GZ-Archive mit NZB-Dateien.Ordner/PfadOrdnerFür authentifizierte E-Mails wird der Kontoname benötigt.Für authentifizierte E-Mails wird das Passwort benötigt.ErzwingenVerbindung trennenDownload erzwingenForumFreier Speicherplatz (Ordner mit temporären Dateien)Freier SpeicherplatzHäufigkeitFreitagWeiterführende Informationen finden Sie in unseremGBAllgemeinAllgemeine EinstellungenNeuen Schlüssel generierenAllgemeines SortierenLesezeichen abrufenJetzt Lesezeichen abrufenNZB abrufenNewzbin-Lesezeichen abrufenSABnzbd anzeigenAssistent öffnenGruppen/Indexer-TagsHTTPS-ZertifikatHTTPS-SchlüsselHTTPS-PortHTTPS-UnterstützungHilfeRechner in den Ruhezustand versetzenLesezeichen ausblendenBearbeitungs-Einstellungen verbergenDetails verbergenDateien verbergenHochVerlaufVerlauf mit den letzten 10 EinträgenGrösse des VerlaufsStartseiteStartseiteAdresseHost, auf dem SABnzbd auf Anfragen warten soll.Stunde:MinWie viel kann in diesem Monat heruntergeladen werden (K/M/G)?Alle Rechner in meinem Netzwerk sollen auf SABnzbd zugreifen können.Nur mein Rechner soll auf SABnzbd zugreifen können.LEERLAUFUNVOLLSTÄNDIGIONice-ParameterIRCLeerlaufWenn leer, hört der Standard-Port nur auf HTTPS-Anfragen.Wenn Sie Mitglied von Newzbin oder NZBMatrix sind, können Sie hier den jeweiligen Benutzernamen und das Passwort angeben, so dass NZB-Dateien von diesen Seiten abgerufen werden können. Wenn Sie keinen dieser beiden Dienste verwenden, können Sie diesen Schritt überspringen.Wenn Sie diesen Fehler wieder erhalten, probieren Sie eine andere Nummer.
    Wenn Sie ein Konto bei www.newzbin2.es haben, können Sie hier Ihre Zugangsdaten eingeben.
    Dies wird Zusatzfunktionen freischalten.Wenn Sie ein Konto bei www.nzbmatrix.com haben, können Sie die entsprechenden Informationen hier eintragen.
    Dies wird benötigt, wenn Sie RSS-Feeds von dieser Seite verwenden möchten.Beispieldateien ignorierenDoppelte NZB "%s" wird ignoriertInIm Fall von "Pause" müssen Sie ein Kennwort setzen und den Job fortsetzen.In OrdnernIn Minuten (mindestens 15 Minuten).Um aus dem Usenet herunterladen zu können, benötigen Sie Zugriff auf einen Usenet-Provider. Ihr ISP bieten dies möglicherweise an, jedoch werden kostenpflichtige Provider empfohlen.Inkompatibeler RSS-FeedInkompatible Warteschlangen-Datei gefunden. Fortsetzen nicht möglich.Unfertige DownloadUnvollständige NZB-Datei %sUnvollständiger Ablauf beim zusammenführen von DateienUngültige RSS-Feed-Beschreibung "%s"Fehlerhafter ParameterFehlerhafter Wert für %s: %sUngültig kodiertes Passwort %sIndex-SeitenNeustart wird durchgeführt...
    Ungültige NZB-Datei %s wird übersprungen: %s auf Zeile %sUngültige Kodierung der E-Mail-Vorlage %sFehlerhafte nzbmatrix AnmeldedatenUngültige nzbmatrix.com-Bericht-ID %s.Ungültige PAR2-Dateien. Überprüfung oder Reparatur nicht möglich.Ungültige Server-Adresse.Ungültige Server-AngabenUngültiges Stufen-Protokoll im Verlauf für %sInvertierenSie verwenden wahrscheinlich ZoneAlarm auf Vista.
    Es ist empfehlenswert, diese Seite mit einem Lesezeichen zu versehen und dieses verwenden, um SABnzbd aufzurufen, wenn es im Hintergrund läuft.Auftrag "%s" wurde wieder zur Warteschlange hinzugefügtAuftrag ausgeführtAufträge, die mit '*' markiert sind, werden nicht automatisch heruntergeladen.Dateien zusammenfügenDateien, die mit .001, .002 usw. enden, zu einer Datei zusammenfügen.Dateien, die mit .001.ts, .002.ts usw. enden, zu einer Datei zusammenfügen.ZusammenfügenKB/sUnbestimmte Downloads in einem zusätzlichen Ordner speichern.SpracheEndeNeuste WarnungenBrowser beim Start öffnenSABnzbd in meinem Webbrowser öffnen, wenn es gestartet wird.Den Standard-Browser öffnen, wenn SABnzbd gestartet wird.VerbleibendGeschwindigkeit begrenzenLinksListe der Dateiendungen, die nach dem Herunterladen gelöscht werden sollen.
    Zum Beispiel: .nfo or .nfo, .sfvFehler beim Laden von %sOrdner, der die für die Warteschlange und den Verlauf verwendeten Datenbanken enthält.
    Kann nur geändert werden, wenn die Warteschlange leer ist.Hier werden Protokoll-Dateien von SABnzbd abgelegt.
    Benötigt einen Neustart von SABnzbd!Hier werden fertige, verarbeitete Downloads abgelegt.
    Kann von benutzerdefinierten Kategorien ausser Kraft gesetzt werden.Hier werden noch nicht verarbeitete Downloads abgelegt.
    Kann nur geändert werden wenn die Warteschlange leer ist.Hier werden NZB-Dateien abgelegt.Protokoll-OrdnerProtokollGeringKleinschreibungMBHauptpaket nicht gefunden...EntsprichtMaximale
    GeschwindigkeitMaximale Anzahl wiederholter Versuche pro ServerMaximale WiederholungenBedeutungMinimaler freier Speicherplatz im temporären OrdnerVerschiedenesSitzungs-Schlüssel fehltFehlende ArtikelErwartete Datei %s nicht gefunden. Unrar-Fehler?MontagMonatMehrFilm NameFilm.NameFilm_NameVerschiebenVerschieben...Mehrfach-FunktionenMarkierung für mehrere TeileNZB-SchlüsselNZB zur Warteschlange hinzugefügtNameBenennungNieNeue Feed-URLNeue Version %s verfügbar unterNeue Version verfügbarNewzbin-PasswortNewzbin-BenutzernameNewzbin gibt einen undokumentierten Fehler-Code zurück: (%s)Newzbin gibt einen undokumentierten Fehler-Code zurück: (%s, %s)Newzbin-Bericht %s nicht gefundenDas Protokoll des Newzbin-Servers wurde geändertNewzbin-Server konnte keine Informationen zu %s bereitstellenWeiterNice-ParameterKein PAR2-Programm gefunden. Eine Reparatur ist nicht möglich
    Kein UNRAR-Programm gefunden. Das Entpacken von RAR-Dateien ist nicht möglich
    Keine E-Mail-Vorlagen gefundenKeine OrdnerKeine Nachbearbeitung wegen fehlgeschlagener ÜberprüfungKeine E-Mail gesendet da keine Empfänger angegebenKeine ErgebnisseNichtsNormalEntspricht nichtNicht genug freier Speicherplatz für fertige Downloads!Entspricht nichtBenachrichtigungscenterBenachrichtigung gesendet!BenachrichtigungsartenBenachrichtigungenAnzahl der Sekunden zwischen zwei Überprüfungen.NzbMatrix-API-SchlüsselNzbMatrix-BenutzernameOKOptionales Konto-PasswortOptionaler Konto-BenutzernameNeinWenn fertigWenn fertigAn welchem Tag des Monats oder der Woche (1=Montag) setzt Ihr ISP das Kontingent zurück (optional mit hh:mm)?Nur Artikel für obersten Warteschlangen-Eintrag herunterladenNur für optionale ServerDie Nachbearbeitung nur für Aufträge durchführen,
    die alle PAR2-Überprüfungen bestanden haben.Nur für entfernten Growl-Server verwenden (Rechnername:Port)Open Informational-URLOpen Source-URLÖffnen Sie ein Terminal und geben Sie folgende Zeile ein (Beispiel):Öffne ZielverzeichnisOptionalOptionale ergänzende NZB-DateiOptionales Passwort für Authentifizierung.Optionaler Benutzername für Authentifizierung.Optionales Passwort für den Growl-ServerWahlweise einen Dateinamen angeben:OptionenReihenfolgeUrsprünglicher DateinameUrsprünglicher OrdnernameAndere NachrichtenAndere SchalterANGEHALTENSeiteParameterTeilnummerPasswortPasswortdateiPasswort ist als ****** maskiert. Bitte erneut eingeben.Passwortgeschützter Zugriff auf SABnzbd (empfohlen)PfadMusterMuster-SchlüsselAnhaltenAlle anhaltenDownloads während der Nachbearbeitung anhaltenAnhaltenAnhalten fürEine Stunde anhalten12 Stunden anhalten15 Minuten anhalten24 Stunden anhalten3 Stunden anhalten30 Minuten anhalten5 Minuten anhalten6 Stunden anhaltenWie viele Minuten angehalten werden soll.Anhalten für...Nachbearbeiten anhaltenAngehaltenHält die Downloads zu Beginn der Nachbearbeitung an
    und setzt sie danach fort.Doppelt vorhandene NZB "%s" angehaltenRechte für fertige DownloadsBitte beachten Sie, dass der 0.0.0.0-Hostname eine IPv6-Adresse benötigen wird für den externen Zugriff.Bitte geben Sie eine ganze Zahl ein.Geben Sie bitte die Informationen zu Ihrem Usenet-Provider an.Plush-EinstellungenPortPort, auf dem SABnzbd auf Anfragen warten soll.Nachbearbeitung von %s fehlgeschlagen (%s)NachbearbeitungNur überprüfte Aufträge nachbearbeitenOrdner mit Nachbearbeitungs-SkriptsNachbearbeitungNachbearbeitung gestartetNachbearbeitung wurde abgebrochen (%s)Benutzer-Skript vor WarteschlangeVoreinstellungenDrücken Sie Start+R und geben Sie folgenden Zeile ein (Beispiel):ZurückZurückPrioritätMöglicherweise wird das Konto geteiltProblem beim Zugriff auf den nzbmatrix.com-Server: %sProblem mitVerarbeitete LesezeichenErgebnisVerarbeitenVerarbeitungs-SchalterProgramm wurde nicht gestartet!FortschrittLeerenFertige NZBs löschenFehlgeschlagene aus Verlauf entfernenFehlgeschlagene NZBs löschenFehlgeschlagene NZBs und Dateien löschenVerlauf leerenNZBs löschenNZBs und Dateien löschenWarteschlange leerenVerlauf wirklich leeren?Warteschlange leeren?Python VersionQR-CodeWarteschlangeWarteschlange mit den 10 obersten EinträgenWarteschlange automatisch neu ladenReparatur der WarteschlangeIn der WarteschlangeSchnelle Überprüfung...Schnelle ÜberprüfungBeendenKontingentVerbleibendes KontingentKontingents-PeriodeKontingent aufgebraucht, Downloads werden angehaltenRRSSRSS-ÜberprüfungRSS-EinstellungenRSS-Feed %s war leer%s ausgeführtBereichSelten genutzte Funktionen. Bedeutung und Erklärungen finden Sie per klick auf den Hilfe-Button um auf die Wiki-Seite zu gelangen.
    Änder nichts ohne vorher das Wiki gelesen zu haben, da sonst schwerwiegende Nebeneffekte auftreten können.
    Die Ursprungswerte stehen zwischen den runden Klammern.Jetzt alle Feeds lesenFeed lesenRSS-Feeds lesenLesen Sie dazu die Hilfe im Wiki!Neu ladenAktualisierungsrateZeitintervall zwischen dem erneuten Laden der Warteschlange (in Sekunden). 0 schaltet die Funktion ab.AktualisierungsrateVerwerfenRelative Ordner basieren aufVerbleibend/InsgesamtVerbleibendEntfernenNZB löschenNZBs und Dateien löschenServer entfernenEntferne fehlgeschlagene JobsLesezeichen aus der Lesezeichenliste entfernen, wenn der Download fertig ist.Entfernen von %s fehlgeschlagenUmbenennenReparierenReparatur fehlgeschlagen. Nicht genug Reparatur-Blöcke vorhanden (%s zu wenig)ReparierenReparatur fehlgeschlagen. %sReparieren...Ungültige Zeichen in Ordnernamen ersetzenLeerzeichen in Ordnernamen ersetzenPunkte in Ordner-Namen ersetzenPunkte in Ordner-Namen durch Leerzeichen ersetzen.Ungültige Zeichen in Ordnernamen durch äquivalente Zeichen ersetzen
    (oder ansonsten entfernen).Leerzeichen in Ordnernamen durch Unterstriche ersetzen.IDBenötigtBenötigt KategorieZurücksetzenKontingent jetzt zurücksetzenTag zurücksetzenNeu startenNeustart ohne AnmeldungSABnzbd wird neu gestartet...ResultatFortsetzenNachbearbeiten fortsetzenRückhaltezeitErneut versuchenAusführen des SkriptsAusführen des Skripts...Ausführen des Benutzer-Skripts %sS01E05 Episoden-OrdnerS01E05 Staffel-OrdnerSABnzbd %s gestartetSABnzbd-HostSABnzbd-PasswortSABnzbd-PortSABnzbd-EinrichtungsassistentSABnzbd-BenutzernameSABnzbd-VersionSABnzbd-WebserverSABnzbd hat einen schwerwiegenden Fehler erkannt:SABnzbd wurde beendetSABnzbd läuft nun im Hintergrund.SMTP-ServerSQL-Befehl fehlgeschlagen. Beachten Sie das Nachrichtenprotokoll.SQL-Commit fehlgeschlagen. Beachten Sie das Nachrichtenprotokoll.SSLSSL-TypSamstagSpeichernÄnderungen speichernGespeichertFehler beim Speichern von %sSpeichern...Überwachter Ordner lesenRegel für nicht existierenden Server %s.PlanungPlanungSkriptSkripteStaffel-NummerSekundäre WeboberflächeWählen Sie die Sprache der Weboberfläche.Nur auswählen, wenn der Provider SSL-Verbindungen erlaubt.AuswahlGruppe sendenRSS-Benachrichtigungen sendenE-Mail senden, wenn ein RSS-Feed einen Auftrag zur Warteschlange hinzufügt.E-Mail senden, wenn die Festplatte voll ist und SABnzbd angehalten wird.Gruppen-Befehl senden, bevor Artikeln angefordert werden.Benachrichtigungen an Growl sendenBenachrichtigung an Benachrichtigungscenter schickenBenachrichtigungen an NotifyOSD senden%s wurde an die Warteschlange gesendetSortieren von TV-SerienServerServer %s benötigt ein Benutzername und ein PasswortServer %s wird für %s Minuten ignoriertServer-DetailsServer-AdresseServer-Adresse "%s:%s" ist ungültig.Server-Adresse wird benötigtServer-EinstellungenServer-DefinitionServer-PasswortSever beendet beim Anmeldeverlauf.Server benötigt ein Benutzername und ein Passwort.ServerEine bestimmte Zeit lang anhaltenRechte für Dateien und Ordner festlegen.
    In oktaler Notation. Zum Beispiel: "755" oder "777"Hier den API-Schlüssel eingeben.ISP-Server für ausgehende E-Mails angeben.Hier das Konto-Passwort eingeben.Hier den Konto-Benutzernamen eingeben.EinstellungenDie Einrichtung ist nun abgeschlossen.Soll wieder Heruntergeladen werden, nachdem das Kontingent zurückgesetzt wurde?Alle anzeigenLesezeichen anzeigenBearbeitungs-Einstellungen anzeigenNur FehlgeschlageneProtokoll anzeigenSendungs NameOrdner mit Name der SendungWeb-Protokoll anzeigenDetails anzeigenDateien anzeigenInterface anzeigenZeiten in der AM/PM-Notation anzeigen (betrifft die Regeln nicht).Sendungs.NameSendungs_NameEinträge %s bis %s von insgesamt %s werden angezeigtEin Resultat wird angezeigtBeendenRechner ausschaltenSABnzbd beendenBeenden...Signal %s erkannt. Speichern und beenden...GrösseÜberspringenPAR2-Überprüfung überspringen, wenn die Dateien 100% korrekt sind.Überprüfung einiger Dateien mittels %s fehlgeschlagenSortierenSortieranweisungNach Alter sortierenSortieren nach Alter Neuste→ÄltesteSortieren nach Alter Älteste→NeusteSortieren nach Alter Neuste→ÄltesteSortieren nach Alter Älteste→NeusteSortieren nach Name A→ZSortieren nach Name Z→ASortieren nach Name A→ZSortieren nach Name Z→ASortieren nach Grösse Grösste→KleisteSortieren nach Grösse Kleinste→GrössteSortieren nach Grösse Grösste→KleisteSortieren nach Grösse Kleinste→GrössteNach Alter sortierenNach Name sortierenNach Größe sortierenSortierungSortier-EinstellungenQuelleSpezialGeschwindigkeitGeschwindigkeitsbegrenzungGeschwindigkeitsbegrenzungRechner in Bereitschaft versetzenAssistenten startenBeginn der ReparaturStarten/BeendenStatusSchritt 5Schritt 4Schritt 1Schritt 3Schritt 2AnhaltenBeenden...SpeicherortBetreffSonntagSchalterVerschiedene SchalterSystemlastSystem-OrdnerTEXTZU GROSSAufgabeTemporärer Download-OrdnerE-Mail testenBenachrichtigungen testenServer überprüfenServer-Angaben werden überprüft...Ein Klick auf den Knopf "Reparieren" startet SABnzbd neu
    und baut die Warteschlange neu auf, wobei bereits
    heruntergeladene Dateien bestehen bleiben. Die Reihenfolge
    der Warteschlange wird dabei verändert.Automatisiertes Programm für Usenet-DownloadsAktivieren Sie das Feld neben dem Feed-Namen, wenn automatisch auf neue Einträge geprüft werden soll.
    Wenn ein Feed hinzugefügt wird, werden nur neue Einträge verarbeitet und nicht diejenigen, die bereits im RSS-Feed enthalten waren, ausser Sie klicken "Download erzwingen".Der Hostname wurde nicht angegebenDie Anzahl der Verbindungen, die der Provider erlaubt.Keine Verbindungen angegeben. Bitte geben Sie mindestens eine Verbindung ein.Der Download-Ordner enthält verwaiste Aufträge.
    Diese können gelöscht (zusammen mit den Dateien) oder zurück in die Warteschange verschoben werden.Dieses Feld wird benötigt.Dieser Schlüssel erlaubt Drittprogrammen das Hinzufügen von NZB-Dateien zu SABnzbd.Dieser Schlüssel gibt Drittprogrammen uneingeschränkten Zugriff auf SABnzbd.Dieser MonatDiese WocheVerhindert, dass die Inhalte aktualisiert werden, wenn sich der Mauszeiger über der Warteschlange befindet.Ein Klick auf den Knopf \"Neu starten\" startet SABnzbd neu.
    Benutzen Sie ihn, falls ein Stabilitätsproblem vorliegt.
    Die Downloads werden vor dem Neustart angehalten und danach fortgesetzt.Sendet eine Test-E-Mail an Ihr Konto.ThreadDonnerstagZeitüberschreitungZeitüberschreitung: Versuchen Sie, SSL oder einen anderen Port zu verwenden.VerbleibendZeitüberschreitungTitelTo: %s From: %s Date: %s Subject: SABnzbd meldet eine volle Festplatte Hallo, SABnzbd hat mit dem Herunterladen aufgehört, da die Festplatte fast voll " ist. Bitte geben Sie manuell Speicherplatz frei und setzen Sie die Downloads " danach fort. HeuteNZB hinzufügenAngehalten wegen zu wenig freiem SpeicherplatzZu viele Verbindungen zum server %s:%sZu viele Verbindungen. Bitte halten Sie die Downloads an oder versuchen Sie es später erneut.Ganz nach obenHauptmenüGesamtFehler suchenErneut versuchenVersuche die erfolgreiche Fertigstellung noch vor dem Herunterladen vorherzusagen (langsamer!)Versuche SFV-ÜberprüfungVersuche NZB-Datei von %s abzurufenVersuche Status für nicht existierenden Server %s zu setzenVersuche entpacken mit Passwort "%s"DienstagFeinabstimmungTypEUNC-Pfad "%s" ist hier nicht erlaubtAbrufen der URL fehlgeschlagen; %sAUF EIGENE GEFAHR VERWENDEN!Lesezeichen entfernen, wenn der Download fertig istZugriff verweigert. Überprüfen Sie den Newzbin-Benutzernamen und -PasswortFreigebenUnbekannter Fehler %s beim DekodierenUnbekannte Aktion: %sEntpacken%s Datei(en)/Ordner entpackt in %sEntpackenEntpacken fehlgeschlagen. %sEntpacken fehlgeschlagen. CRC-FehlerEntpacken fehlgeschlagen. Eine erwartete Datei wurde nicht entpackt.Entpacken fehlgeschlagen. Archiv benötigt ein Passwort.Entpacken fehlgeschlagen, Pfad ist zu langEntpacken fehlgeschlagen. Beachten Sie das Protokoll.Entpacken fehlgeschlagen. Diese Dateien fehlten:Entpacken fehlgeschlagen. Konnte %s nicht finden.Entpacken fehlgeschlagen. Fehler beim Schreiben oder volle Festplatte?Ungültige NZB-Datei.Nach obenNeue Version verfügbar!HochladenHochladen: .nzb .rar .zip .gzZeit seit Start12-Stunden-Uhr verwenden (AM/PM)V23 verwenden, ausser wenn der Provider etwas anderes benötigt.Temporäre Namen während der Nachbearbeitung verwenden. Deaktivieren, wenn das System nicht damit klar kommt.Verwenden Sie die Spalte "Gruppen/Indexer-Tags", um Gruppen und Tags mit Kategorien in Verbindung zu setzen.
    Wildcards werden unterstützt. Terme können mit Kommas getrennt werden.Wird verwendet, bevor eine NZB-Datei zur Warteschlange hinzugefügt wird.Verwendeter CacheWird verwendet, wenn die Kategorie keine Nachbearbeitung vorschreibt.Wird verwendet, wenn die Kategorie keine Priorität vorschreibt.Wird verwendet, wenn die Kategorie kein Benutzer-Skript vorschreibt.Benutzer-OrdnerBenutzerdefinierte KategorienBenutzernameWerteÜberprüfung mit SFV-Datei(en) erfolgreichÜberprüfenÜberprüfen...VersionSkript-Protokoll anzeigenSkript-Ausgabe anzeigenWARTE %s SekWARNUNG:WARNUNG: Job "%s" abgebrochen wegen verschlüsselter RAR DateiWARNING: Paused job "%s" because of encrypted RAR fileWARNUNGENWartenWarnungWarnung: localhost ist mehrdeutig. Verwenden Sie eine numerische IP-Adresse.WarnungenÜberwachter OrdnerGeschwindigkeit der Ordner-ÜberwachungWeb-OberflächeAuthentifizierung für Web-ServerMittwochWöchentlich überprüfen, ob eine neue SABnzbd-Version verfügbar ist.WannBei yEnc-CRC-Fehlern Ersatz-Server verwenden.Job abbrechen falls während des Downloads klar wird, dass zuviele Daten fehlenWer soll die E-Mail versandt haben?WikiXJahrJahr-Monat-OrdnerIhr Newzbin-Konto verfügt über keine Credits.Sie haben nicht die Berechtigung, Port %s zu verwendenSie müssen JavaScript aktivieren, damit Plush funktioniert!Sie benötigen einen NZBMatrix VIP-Konto, um die API zu nutzenDas verwendete UNRAR-Programm wird nicht empfohlen. Laden Sie UNRAR stattdessen herunter von http://www.rarlab.com/rar_add.htm
    [%s] Fehler "%s" beim Zusammenfügen der Dateien[%s] Fehler "%s" beim Entpacken der RAR-Dateien[%s] %s Dateien zusammengefügt[%s] Keine PAR2-Sätze[%s] Ungültige PAR2-Optionen. Überprüfen Sie die Angaben in Einstellungen -> Schalter.[%s] Schnelle Überprüfung erfolgreich[%s] Repariert in %s[%s] Überprüft in %s. Alle Dateien fehlerfrei.[%s] Überprüft in %s. Reparatur wird benötigt._yenc-Modul nicht gefunden!Groß- / Kleinschreibung berücksichtigenLeerentTagTageServer deaktivierenServer aktivierenHole msgid %s von www.newzbin2.esDateiOrdnerhStundeStundenrestmManuellMinutenMin.Minutennicht installiertvonAusAnoderSeitepar2-Programmdatei nicht gefunden!pyopenssl-Modul fehlt. Bitte installieren für SSL-Unterstützung.SekundeSekundenBeachten Sie die Protokolldateitextunbekanntunrar-Programmdatei nicht gefunden!unzip-Programmdatei nicht gefunden!WocheSABnzbd-0.7.20/locale/es/LC_MESSAGES/SABnzbd.mo0000644000000000000000000023231312433712600020502 0ustar00usergroup00000000000000L|>o}>>d?cA]B 1C2>DqEeFOG*fG'GGGG H'H6HVH vHHHHHRIZIaIiIqIyIIII?8JxJJJKRK[jKK#KK L*L1L 8L FLSL'ZLLLLLLL L LL LLMa$MMMMM.MMM) N*3N ^N lNvNN/NhN 6OBOWO(O0P*5P`PbPgP nP|PP PPPPPQQQ2Q QR 6RWRrRR!R6R-S6SUSdSS SS.S'S TT5TBOTTTSTU UU53UiUoU~U"UU8U UV VV6V =V IVWVqV&VV VV$V*W3WEWLW NWXW ^W lW yWWWWWWWW$WX"X )X4X EX SX_X(uXX%X X-Y0YDYf_YYY4YZ?Z\ZvZZZ,ZZ,[0[1L[5~[[[[ [[[1\59\5o\\ \'\\ \ ] ] ]#](] @] M]W] ^]h]]]]]]]]]$^ +^9^ I^ V^b^y^#^^^^^^^ _ _ *_7_W_l_______ _ `4`$D`$i`A``S`-9a5ga0a(aaHa Hb Rb_b nb {b(b.b)b& c,1c<^cbc&c%d@d7Sd'ddddd e >e&Ie-peeee ee e ff &f4fLfSfnff%f!ff+g ,gMg!hgg!gFgh0&h-Wh'hh"hhii8iXi`i |iiiiiiiiiAi=j'Tj!|jjjjj-jk kk.k3Ck/wkgk ll&#l"Jlmlslll l l ll llllmm $m2mDmLm bm pm}mmm m m mm mmn n n+n0n8n Nn[n `njnonn-n6n.n+o 0o;oMoQo6VooGAppqqqqEq 3r>r\rr,s4sFs%]s#ssss st2t%Qtwt"t+ttt'u;u7Buzu"v (v<5v rv3}v9vvv%vw'w,wE c pz  4NJ2 PZ o*|ċ)ߋM 0W   njό  /5DVm  ɍ֍%E._ юՎގ #- Q\u|  4ˏ 3,3`.Ð)ߐ ):I P(q$ݑ ",&Ov~o)!Kk3ߓ  ",= M Ze9t "”  ',TY-^( ƕ/ҕ/-2-`&&$ܖ$3&3Z11  6=E K W b mz  ʘӘ ؘ#2 7AF `k }"Twx2Aě>= +W5,2_f o>yɞϞ"$A"&/ 5 BEL.Ơ$)+Jb x2̡ԡ .8M3i-"ˢ,#5.Yѣأ0b#$ 88C1|4 % > HU]m 76ͦ :Xap  %@R(!{*$1 0>Zo#ʩ)-J?&'٪ *026; J&X «ūɫ̫ϫԫ9(, 4@EMg'6w߯WhJGm  .-5#c$ 7KT[s /< BL UcMB . :Dg_[Ǽ#,+!Xzƽ.ν%-@ P\s ȾY޾8=C];e %ڿ$% 6Aa>|l (6S9U0>(:,Iv<&YG."3!N#p-.PFB,&&  $//(_*p T`ZvC^fz/@& 7#Bfn$!)  ,57b   0?[v4  $29J)=*0H`~ <& cIm#%7= u6#A7 =G[k ~WA59o %  .9 @1J|  #"F Y fp!=  + CMi|' -$Gl(8'(*LS#n:3@nE0 &G1y&2*2']2A,z(5$?/R &= N!o  $$CW/n3(-))S&p'`>DV9.# %Dj ,  $>$[N+8-/fE 7FREh xLF3C H U cn&v  ;H Xy  '8 = Gh~+ /B:H ;fJZwOzG'+Dp);&1%X.~9# :*e9nz+#OA` BH<D(IryRAIRdl"zWn1&>S Xd"g * A 5AX:r  ",CJSYn;?(N,w: 8K3(C,)8@ G9UB;Rgo c;4-pS:-F8W+.%T]c{  2:9ty * *9K\)kK#3fW)B+='Dl(' (D _;j . 3 KVj# % ERi| !, $*0AUrtx   1*  \ g L   #  * 3  <  I j | F    S  Y c  } 5 . $ ? mT F     , 6 P  l v        #C^z&$*O3k '* /#8 \%i+ *#8N  ?O7I0!  ')*Q|3&!9*Q+| |*L6w% !># bo "A3 u ! ,&?-0m== ;I;,,**FCqCAA;}   )6H^m t     17HNn~#2/C+ o !Q!Kq!! !_!2"*" ###B$#g#v###^$b$($'$K$%'%6%<%R%Sf% %%7%/0&`&g&o&t&)v&&&2&<' L'-X'' '*'''(N(Al(.(%(2)-6)Ld)))))) **5:*qp**A++p+8H,@,,$,,-6- P-\-k-t----<-7--. 4. >.<J. ..+. .&. /6/K/TR/Q/-/'0,0.0307H0)08060c1 ~1,111Y2Z2r232*2233$3&3+313G3)Z333333333333 33 33333A4S4W4`4s4 y4444 SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAcceptAccessAccess deniedAccount infoActionAction when encrypted RAR is downloadedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)Cannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.Complete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOther MessagesOther SwitchesPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!RefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.Report-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSend GroupSend RSS notificationsSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogView script outputWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2013-01-29 04:34+0000 Last-Translator: Juan Garcia Language-Team: Spanish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:55+0000 X-Generator: Launchpad (build 17082) SABnzbd no puede encontrar sus ficheros de la interfaz web en %s.
    Por favor instala el programa de nuevo.

    SABnzbd ha tecetado el Historial y Cola de una versión anterior (0.4.x).

    Tanto la cola como el historial serán ignorados y eliminados!

    Puedes optar por parar SABnzbd y finalizar la cola con la versión anterior del programa.

    Haz clic en Aceptar para continuar con SABnzbd SABnzbd ha detectado información guardada de otra versión de SABnzbd
    pero no puede ser reutilizada por la otra versión.

    Tal vez quieras finalizar primero tu cola actual con la otra versión.

    Tras ello, ejecuta este programa con la opción "--clean".
    Esto eliminará la cola e historial actuales!.
    SABnzbd leer el archivo "%s" SABnzbd ha detectado que el fichero sqlite3.dll no existe.

    Algunos virus de de pésima calidad eliminan este fichero.
    Por favor revisa la configuración de tu antivirus y quéjate a tu proveedor del AntiVirus. Tras ello reinstala SABnzbd.

    SABNZBD no es compatible con algunos cortafuegos.
    %s
    Lo sentimos, pero no se puede resolver esta incompatibilidad en este momento.
    Por favor contacta con el proveedor de tu cortafuegos.

    SABnzbd necesita un puerto tcp/ip libre para su servidor web interno.
    Se ha intentado en el puerto %s en %s, pero no está disponible.
    Puede que otro software ya esté utilizando este puerto, o que SABnzbd ya esté en ejecución.

    Por favor reinicia SABnzbd indicando un número de puerto diferente. SABnzbd necesita un puerto tcp/ip libre para su servidor web interno.
    Se ha intentado con el puerto %s en %s, pero la cuenta utilizada por SABnzbd no tiene permisos para usarlo.
    En equipos OSX y Linux, los usuarios normales han de usar puertos por encima de 1023.

    Por favor reinicie SABnzbd con un número de puerto diferente. SABnzbd necesita una dirección IP para su servidor web interno.
    Has especificado una dirección inválida.
    Valores seguros son localhost y 0.0.0.0

    Por favor reinicia SABnzbd con una dirección o nombre de host correctos. SABnzbd se entrega SIN NINGUNA GARANTÍA. Este es un software libre, y eres bienvenido a redistribuirlo bajo determinadas condiciones. Está licenciado bajo la versión 2 ó posterior de GNU GENERAL PUBLIC LICENSE. %s -> Codificación desconocida%s => faltando de todos servidores, desechando%s artículos contenían duplicados inconexos%s artículos estaban mal formados.%s artículos no encontrados%s articulos removidosDirectorio %s: Error al acceder a %s%s archivos en %s%s no es un valor octal correcto%s no es una dirección de correo electrónico válida.Falta %s  Resolviendo sitio  ó ID de Reporte 
    Apago de SABnzbd exitoso.
    Espere unos 5 segundos y entonces seleccione el boton abajo.

    Refrescar
    +Depuración+Info+Eliminar+Reparar+DescomprimirDirectorio de Backups de .nzbs1x05 Episodio Directorio1x05 Temporada DirectorioNOTA: Los directorios se crean automáticamente al guardar. Puedes usar una ruta absoluta, exterior a los directorios predefinidos.Los datos no se moverán. Requiere queu SABnzbd sea reiniciado!Leer Fuente recogerá los contenidos actuales de la fuente. Forzar Descarga para descargar ahora cualquier NZB coincidente.ANTIGÜEDADClave APICódigo QR de la clave APIClave de API erróneo, favor ingresar la clave correcta desde Config->General en tu aplicacion externa:Falta clave de API, favor ingresar la clave desde Config->General en tu aplicacion externa:AbortarTrabajos abortados no pueden ser completadosAbortado, No puede ser completadoAbortado, detectamos cifradosAceptarAccesoAcceso denegadoInfo de cuentaAcciónAccion cuando un archivo RAR cifrado es bajadoAccionesHabilitar una piel alternativaAñadirAñadir una fuenteAñadir ficheroAñadir NZBAñadir planificaciónAñadir servidorAñadir nuevas descargasNZB añadidoDirectorio de administraciónCategorías AfectadasDespués de que se reinicie SABnzbd, podrás acceder a él en la siguiente dirección: %sEdadTodosTambién libera de pruebaSiempreAplica un máximo de reintentos a los servidores opcionalesAplicar a seleccionados¿Está seguro de querer borrar?¿Seguro que desea reiniciar SABnzbd?¿Seguro que deseas detener SABnzbd?¿Estás seguro?ArgumentosLímite de cacheo de artículosIdentificador de artículoAutenticación fallida, compruebe el usuario o la contraseña.Faltaron datos de cuenta, favor ingresar usuario/contraseña desde Config->General en tu aplicacion externa:Auto reanudarAuto-Descargar los favoritosParar automáticamente cuando el espacio libre esté por debajo de este valor.
    En bytes, opcionalmente seguido de K,M,G,T. Por ejemplo: "800M" ó "8G"Automáticamente descargar posts marcados como favoritos.Automáticamente se conecta y recibe los trabajos que se encuentren en tus favoritos.Automáticamente ordenar elementos por antigüedad (promedio).BAtrásCopia de seguridadServidor de BackupPlanificación incorrecta %s a las %s:%sArticulo yEnc corrupto en %sAncho de BandaBloquear actualizaciones al pasar por encimaProcesar FavoritosÚltimoError CRC en %s (%s -> %s)Cachear artículos en memoria para reducir el acceso a disco.
    En bytes, opcionalmente seguido de K,M,G. Por ejemplo: "64M" o "128M"%s artículos cacheados (%s)No se puede cambiar los permisos de %sImposible conectar a la clave HKEY_CURRENT_USER del registro de WindowsError en inicio de conexion a servidor %s [%s]No se puede crear %s la carpeta %sNo se puede crear copia de seguridad del archivo %sNo se pudo crear el directorio %sImposible crear directorio final %sNo se puede crear el archivo temporal para %sNo se pudo encontrar plantillas de email en %sNo se puede encontrar la plantilla web: %s, intentando con la plantilla estandarImposible iniciar el navegador, probablemente no se le haya encontradoNo se puede abrir la llave de registro "%s".No se puede leer %sDirectorio Watched %s no se puede leerNo se puede escribir al archivo INI %sCategoríasCategoríaNo se han guardado los cambios, y se perderán.Los cambios requieren reiniciar SABnzbd!Chequear antes de descargarBuscar Nva VersiónChequear el resultado de la descompresiónChequea el resultado de la descompresión (necesita deshabilitarse si tienes un sistema de ficheros muy grande).VerificandoFrecuencia de chequeoIntervalo de Chequeo (en minutos, mínimo 15). No toma efecto si utilizas el Planificador!Elije una pielLista de elementos a limpiarHa fallado la limpieza de %sLimpiar ficheros par (si la reparación/verificación es correcta).LimpiarResetear contadoresHaga clic debajo para testear.Haz clic para probar los detalles introducidos.CerrarSi cierras las pestañas o el navegador, SABnzbd NO se cerrará.Dir para completadosCarpeta CompletaCompletadoDirectorio de descargas completadasConfig.Fichero de ConfigConfiguraciónConfirmar eliminación del historialConfirmar eliminación de la colaConexión %s@%s:%s ha fallado, mensaje=%s¡Conexión exitosa!ConexionesAncho del contenedorImposible eliminar el favorito %s de NewzbinNo se pudo determinar el resultado de la conexión (%s)Tareas Programadas ActualesPersonalizarDDUPLICADODiariamenteDirectorios diariosOrdenar por fechaDía del mesDécadaDescodificación %s falloPredeterminadoDirectorio base por defectoPost-Procesado por defectoPrioridad PredefinidaScript de Usuario predefinidoDefine tareas de post-procesado y el almacenamiento.BorrarEliminarEliminar todoEliminar completadosEliminar FallidosBorrar fuenteEliminar tras descargar¿Eliminar todos los elementos completados del Historial?¿Elimiar todos los ficheros descargados?¿Eliminar todos los elementos que han fallado del Historial?¿Eliminar todos los elementos de la cola?¿eliminar los elementos fallidos del historial?¡Error al eliminar %s!Detectar descargas duplicadasDetectar ficheros NZB de nombre idéntico (necesita de la opción de NZB habilitada) y títulos duplicados de entre las fuentes RSS.Desactivar Clave-APIDeshabilitadoHTTPS deshabilitado debido a la falta de archivos CERT y KEYDescartarDesconecta del servidor de Usenet cuando la cola está vacía, o pausada.Desconectar si la cola está vacíaNotificaciones de Disco LlenoError de disco al crear el archivo %sDisco lleno! Pausando la colaRealiza una verificación extra basada en ficheros SFV.No descargarNo se encontró autenticación válida para el feed %sNo solicitar clave API.¿Cada cuánto se resetea la cuota?¿No tienes proveedor de Usenet? Nosotros recomendamos probar %s.AbajoDescargarDescarga CompletadaDir de DescargaLa descarga fallóLímite de velocidad de descargaError en la descarga - ¡Tal vez está fuera del límite de retención de tu proveedor?La descarga fallo, solo %s de los %s requeridos estan disponiblesLímite de descarga (en KB/s - kilobytes por segundo)Velocidad de DescargaDescargadoDescargado en %s a una media de %sB/sDescargado hasta ahoraDescargandoDescargasVista Dual 1Vista Dual 2Por ej.P.ej. 119 ó 563 si es SSLP.ej. 8 ó 20ENCRIPTADOERROR:ERROR: %sERROR: Ha fallado la comprobación CRC sobre "%s"ERROR: via es muy larga (%s)ERROR: Imposible encontrar "%s"ERROR: Error de escritura (%s)Tiempo estimadoModificarEditar Detalles de NZBCorreoAjustes de E-MailNotificación por email al terminarOpciones de e-mailDestinatarioRemitente¡Email enviado!Directorio de plantillas de EmailResultado del email de pruebaDirección de correo electrónico a la que enviar el mensaje.Email exitosoVacíaFichero NZB vacío: %sEntrada RSS vacía (%s)HabilitarHabilitar ordenar por fechaHabilitar FilejoinHabilitar GrowlHabilitar HTTPSHabilitar HTTPS para acceder a SABnzbd.Habilitar Ordenado de PelículasHabilitar Par2 Multi-núcleoHabilitar NotifyOSDHabilitar limpieza ParHabilitar Chequeo RápidoHabilitar verificacion basada en SFVHabilitar Unión TSHabilitar la ordenación de Series de TVHabilitar UnrarHabilitar UnzipHabilia el acceso a la interfaz con una dirección HTTPSHabilitar funcionalidad nativa de unrarHabilitar funcionalidad nativa de unzip.Activar clases de mensajes que deben notificarse (ninguno, uno o múltiples)Habilitar renombrado de directoriosHabilitar para usar menos memoria. Deshabilitar para prevenir que trabajos que se ralentizen bloqueen la cola.Habilitar ordenado y renombrado genérico de los ficheros.Habilitar si las descargas no quedan en sus propios directorios.Habilitar ordenación y renombrado de nombres de ficheros con fechas.Habilitar ordenación y renombrado de episodios.HabilitadoTerminar la ruta con un * previene que se creen directorios de trabajo.Introduzca la URLNombre del capítuloNúmero del capítuloNombre.capítuloNombre_capítuloError "%s" al ejecutar file_join en %sError %s al ejecutar par2_repair en el conjunto %sError "%s" al ejecutar rar_unpack sobre %sError "%s" al ejecutar unzip() sobre %sError %s al ejecutar par2_repair en el conjunto %sError %s: Necesitas introducir un usuario y contraseña válidos.Error al obtener msgid %s desde www.newzbin2.es - Por favor asegurese que su nombre de usuario y contraseña estan configuradosError al crear la llave SSL y el certificadoError al recuperar info de la serie (%s)Error importando %sError al importar módulo OpenSSL. Conectando sin SSLError al cargar %s, archivo corruptoError al quitar %sError al eliminar el directorio de trabajo (%s)Error al renombrar "%s" a "%s"Error al añadir %s, eliminandoError al apagarel sistemaSólo ErroresError: Interfaz secundario no iniciadoError: Cola no esta vacía, no se puede cambiar el directorioError: Clave de sesión erróneoError: Clave de sesión requeridoErrores/AdvertenciasTodoEjemploSalir SABnzbdExtensiónParámetros PAR2 extraExtrayendo...Fallar si hay errores de CRC en yEncFallidoRegistraccion fallo para servidor %sError al crear (%s)Error al mover %s a %sNo se pudo autenticar con el servidor de correoNo se pudo cerrar el base de datos, vea el registroNo se pudo cerrar la conexión de correoCompilación de regex para término fallo: %sNo se pudo conectar al servidor de correoError al hibernar el sistemaError al importar %s ficheros desde %sInitializacion %s@%s:%s falloNo se pudo inicializar la conexión TLSError al cargar la cola de post-procesado: Versión incorrecta (se necesita:%s, se encontró:%s)Error al mover ficherosFalla al leer las llaves de registro para los directorios especialesError al eliminar nzo desde la cola de postprocesado (id)Error al renombrar ficheros similares: %s a %sError al renombrar: %s a %sError al recuperar RSS desde %s: %sNo se pudo enviar correo electrónicoError al suspender el sistemaError al iniciar la interfaz webError al actualizar el trabajo %s de newzbinFalloFallo en tempfile.mkstempError graveCanalFuentesObtenerRecuperandoRecuperando %s bloques...Recuperando bloques extra...El fichero%s está vacío, omitiendoExtensión de archivoFichero que contiene todas las contraseñas a usar en ficheros RAR protegidos.Error al unir el fichero %sNombre de archivo o ruta al Certificado SSLNombre de archivo o ruta de acceso a la cadena de HTTPS.Nombre de archivo o ruta a la clave privada SSLConjunto de ficherosNombre de archivoFiltrarFiltra la descarga de ficheros de ejemplo (e.g. un sample de vídeo).FiltrosPrimeroLa carpeta «%s» no existeConfiguración DirectoriosDirectorio que contiene los scripts de usuario para el post-procesado.Directorio que contiene plantillas de email definidas por el usuario.Directorio a monitorizar en busca de ficheros .nzb.
    También escanea ficheros .zip .rar y .tar.gz en busca de ficheros .nzb.Directorio/RutaDirectoriosPara correos electrónicos con autentificación, poner el nombre de usuario.Para correos electrónicos con autentificación, poner la contraseña.ForzarForzar desconexiónForzar DescargaForoLibre (Temp)Espacio libreFrecuenciaViernesPuedes encontrar más ayuda en nuestroGBGeneralConfiguración generalGenerar nueva claveOrdenado GenéricoObtener FavoritosDescargar favoritos ahoraObtener NZBObtener favoritos de NewzbinIr a SABnzbdIr al AsistenteGrupos / Etiquetas del indizadorCertificado HTTPSCadena de Certificados HTTPSClave privada SSLPuerto HTTPSSoporte HTTPSAyudaHibernar PCOcultar FavoritosOcultar opciones de ediciónOcultar detallesOcultar FicherosAltaHistorialHistórico últimos 10 elementosTamaño del HistorialInicioPagina principalEquipoDónde debería escuchar el Host de SABnzbdHora:MinutoCantidad de descarga permitida este mes (K/M/G)Quiero que SABnzbd sea visible para cualquier ordenador en mi red.Quiero que SABnzbd sólo sea visible desde este ordenador.INACTIVOINCOMPLETOParámetros IONiceIRCInactivoSi se deja vacío, el puerto estándar escuchará por HTTPSSi eres miembro de Newzbin ó NzbMatrix, puedes introducir tu usuario y contraseña aquí para que podamos recibir sus nzb. Esta etapa la puedes omitir si no usas ninguno de estos servicios.Si obtiene este mensaje de error consecutivamente, por favor inténtelo de nuevo con otro número.
    Si tienes una en www.newzbin2.es, puedes introducir tus datos de cuenta aquí.
    Esto desbloquea funcionalidades extra.Si tienes una cuenta en www.nzbmatrix.com, puedes introducir sus datos aquí.
    Esto es necesario si quieres usar las fuentes RSS de este sitio.Ignorar SamplesIgnorando NZB Duplicado "%s"EnIn caso de PAUSA, necesitara escribir una contrasena para continuar el trabajo.En directoriosEn minutos (al menos 15 min).Para poder descargar de Usenet, necesitas acceso con un proveedor. Tu proveedor de acceso a internet te lo puede dar, aunque recomendamos proveedores premium.Canal IncorrectoSe ha encontrado un fichero de cola incompatible, no se puede continuarCarpeta IncompletaFichero NZB %s incompletoSecuencia incompleta de archivos a uniriaDescripción de canal RSS incorrecta "%s"Parámetro incorrectoValor incorrecto para %s: %sContraseña incorrectamente codificado %sSites de búsquedaReiniciando...
    Fichero NBZ inválido: %s, omitiendo (razón=%s, línea=%s)Codificación de plantilla invalido %sCredenciales de nzbmatrix incorrectasNúmero de informe de nzbmatrix incorrecto: %sFicheros par2 inválidos, no se puede verificar o repararDirección del servidor no válida.Detalles de servidor invalidosRegistro de etapa invalido para transferencia terminada %sInvertirParece que estás usando ZoneAlarm con Windows Vista.
    Se recomienda que guardes esta ubicación como favorito y la añadas a tu navegador para acceder a SABnzbd cuando quieras.La tarea "%s" ha sido re-agregada a la colaTarea finalizadaTareas marcadas con un '*' no serán descargadas automaticamente.Unir ficherosUne los ficheros terminados en .001, .002 etc en un sólo fichero.Une los ficheros terminados en .001.ts, .002.ts etc en un sólo fichero.UniendoKB/sMantener descargas en directorios extra.IdiomaÚltimoÚltimas advertenciasLanzar navegador al ArrancarLanzar mi navegador de interner con la página de SABnzbd al arrancar el programa.Ejecuta el navegador por defecto del sistema al arrancar SABnzbd.RestanteLimitar VelocidadEnlacesLista de las extensiones de fichero que deberían ser eliminadas después de cada descarga.
    Por ejemplo: .nfo ó .nfo,.sfvCargar de %s no se pudo completar.Ubicación de la base de datos de historial y administración.
    Sólo se puede cambiar si la cola está vacía.Ubicación de los ficheros de log para SABnzbd.
    Requiere reiniciar SABnzbd!Ubicación donde guardar descargas finalizadas, totalmente procesaddas.
    Puede ser obviado debido a categorías definidas por el usuario.Localización donde guardar descargas incompletas.
    Sólo se puede cambiar si la cola est&aa; vacíUbicación donde se guardarán los ficheros .nzb.Directorio de HistorialRegistros de sucesosBajaMinúsculasMBPaquete principal no encontrado...Encontrado(s)Velocidad máx.Máximo número de reintentos por servidorReintentos máximosSignificadoEspacio libre mínimo para el directorio de descargas temporalesMisceláneaFalta clave de sesiónArtículos no encontradosFalta el siguiente archivo: %s => ¿Error al descomprimir?LunesMesMásNombre de PelículaNombre.de.peliculaNombre_de_peliculaMoviendoMoviendo...Op.MúltiplesEtiquetaClave NZBNZB añadido a la colaNombreNombradoNuncaURL de la fuente RSSNueva versión %s disponible enNueva versión disponibleContraseña de NewzbinUsuario de NewzbinNewzbin ha devuelto un código de error no documentado (%s)Newzbin ha revuelto un código de error no documentado (%s, %s)No se encuentra el informe %s de NewzbinEl servidor Newzbin ah cambiado su protocoloEl servidor de Newzbin no ha devuelto información para %sSiguienteParámetros NicePrograma Par2 no encontrado, reparacion no posible
    Programa Unrar no encontrado, descomprimir de archivos RAR no posible
    No se encontraron plantillas de correo-eSin DirectoriosNo se ha podido post-procesar debido a un fallo en la verificaciónSin destinatarios no se pudo enviar el emailSin resultadosNingunoNormalNo encontrado¡No hay espacio suficiente para completar las descargas!No encontrado(s)Centro de Notificación¡Notificación enviada!Clases de notificaciónNotificacionesNúmero de segundos entre pasadas en busca de ficheros .nzb.Clave API de NzbMatrixUsuario de NzbMatrixAceptarContraseña de usuario OPCIONALNombre de usuario OPCIONALApagadoAl terminarAl finalizar colaEn qué día del mes o semana (1=Lunes) resetea tu proveedor la cuota mensual? (Opcional con hh:mm)Sólo obtener artículos para el primer elemento de la ColaSólo para servidores opcionales/alternativosSólo realiza el post-procesado en trabajos que han pasado todos los chequeos PAR2.Usar sólo para un servidor Growl remoto (servidor:puerto)Abrir URL de informacionAbrir URL FuenteApre una ventana de Consola y teclea la línea (ejemplo)Abrir todo el folderOpcionalNZB Suplementario OpcionalContraseña opcionalNombre de usuario opcionalContraseña opcional para el servidor GrowlOpcionalmente especificar un nombre de ficheroOpcionesOrdenNombre fichero originalNombre directorio originalOtros mensajesOtros parámetrosPAUSADOPáginaParametrosNumero de ParteContraseñaArchivo de contraseñasContraseña protejido por ******, favor reingresarProteger el acceso a SABnzbd con contraseña (recomendado)RutaPatrónPatrónPausarPausar todoPausar Descargas Durante el Post-ProcesadoIntervalo de ParadaPausar durantePausar 1 horaPausar 12 horasPausar 15 minutosPausar 24 horasPausar 3 horasPausar 30 minutosPausar 5 minutosPausar 6 horas¿Por cuántos minutos realizar la pausa?Pausar durante...Pausar post-procesamientoEn pausaPausa las descargas al principio del post-procesado, y reanuda al terminar.Pausando NZB duplicados "%s"Permisos para descargas completadasTenga en cuenta que el nombre de equipo 0.0.0.0 necesitará una dirección IPv6 para el acceso externoPor favor introduzca un número completo.Por favor introduce los datos de tu proveedor principal de Usenet.Opciones de PlushPuertoPuerto en que SABnzbd debería escucharError al post-procesar %s (%s)Post procesadoPost-procesar sólo trabajos verificadosDirectorio de Scripts de post-procesadoPost-ProcesadoProcesamiento posterior empezadoSe ha abortado el PostProcesamiento (%s)Script de usuario Pre-colaPreajustesPresiona la Tecla de Windows+R y teclea la línea (ejemplo)AnteriorAnteriorPrioridadCompartiendo de cuenta probableError al acceder al servidor de nzbmatrix (%s)Problema conFavoritos procesadosResultado del procesadoEn procesoProcesando SwitchesEl programa no ha arrancado!ProgresoPurgarPurgar NZBs completadosPurgar historial de erroresPurgar los NZBs fallidosPurgar NZBs fallidos y sus ficherosPurgar historialPurgar NZBsPurgar NZBs y Eliminar FicherosLimpiar Cola¿Vaciar el historial?¿Limpiar la Cola?Version de PythonCodigo QRColaEncolar los primeros 10 elementosIntervalo automático de refresco de la colaReparar colaEn colaChequeo Rápido...Chequeo RápidoSalirCuotaQuota disponiblePeriodo de la cuotaQuota gastado, pausando colaRRSSIntervalo de chequeo RSSConfiguración de RSSEl canal RSS %s estaba vacíoSe ejecutó %sIntervaloOpciones usadas raramente. Para su significado y explicación, haga clic en el botón de Ayuda para ir al Wiki.
    No cambie esto sin chequear primero en la wiki,ya que algunos ajustes tienen severas consecuencias.
    Los valores por defecto se muestran entre paréntesis.Leer todas las fuentes ahoraLeer FuenteLeer entradas RSSLee la ayuda en la Wiki (inglés) acerca de esto!ActualizarFrecuencia de actualizaciónIntervalo de refresco de la página web de la cola (en segundos, 0= ninguno)Frecuencia de actualizaciónRechazarLos directorios relativos, lo son aRestante/TotalRestanteEliminarEliminar NZBEliminar NZB y Eliminar FicherosEliminar servidorEliminar trabajos fallidosElimina de la lista de favoritos el elemento descargado correctamente.Error al eliminar %sRenombrarRepararHa fallado la reparación, no existen bloques de reparación suficientes (%s short)ReparandoLa reparación falló, %sReparando...Reemplazar caracteres no admitidos en los directoriosReemplazar espacios en el nombre de directorioReemplazar puntos en los directoriosReemplaza los puntos con espacios en los nombres de directorio.Reemplaza los caracteres inválidos del nombre del directorio por lso equivalentes (si no puede los elimina).Reemplaza los espacios con guiones bajos en los nombres de directorio.ID de reporteNecesitaRequiereCatReiniciarReinicializar Quota ahoraDía de reinicio del conteoReiniciarReiniciar sin sesión iniciadaReiniciando SABnzbd...ResultadoReanudarReanudar post-procesamientoPeriodo de retenciónReintentarEjecutando scriptEjecutando script...Ejecutando script de usuario %sS01E05 Episodio DirectorioS01E05 Temporada DirectorioSABnzbd %s comenzóHost de SABnzbdContraseña de SABnzbdPuerto de SABnzbdAsistente de Configuración de SABnzbdUsuario SABnzbdVersión de SABnzbdServidor web de SABnzbdSABnzbd ha detectado un error grave:Cierre de SABnzbd terminadoSABnzbd ahora quedará ejecutando en segundo plano.Servidor SMTPComando SQL ha fallado, vea el registroCompromiso SQL ha fallado, vea el registroSSLTpo de SSLSábadoGuardarGuardar cambiosGuardadoGuardar de %s no se pudo completar.Guardando...Escanear directorio bajo observaciónPlanificación para servidor %s inexistentePlanificaciónConfig. de PlanificaciónScriptScriptsNúmero de la temporadaInterfaz web secundariaSelecciona un idioma para la interfaz web.Selecciona sólo si tu proveedor permite conexiones SSL.SelecciónEnviar GroupEnviar notificaciones RSSEnviar email cuando una fuente RSS añade un trabajo a la cola.Envía un email cuando el disco se ha llenado y SABnzbd se ha tenido que parar.Enviar comando group antes de solicitar los artículos.Enviar notificaciones a GrowlEnvía notificaciones al Centro de NotificaciónEnviar notificaciones a NotifyOSDEnviado(s) %s a la colaOrdenación de SeriesServidorServidor %s requiere cuenta/contraseñaEl servidor %s se ignorará por %s minutosDetalles del servidorDirección del ServidorLa dirección del servidor «%s:%s» no es válida.Se necesita la dirección del servidorConfiguración del servidorDefinición de ServidorContraseña de servidorEl servidor se ha cerrado durante el loginEl servidor necesita usuario y contraseña.ServidoresAjustar Intervalo de ParadaAjustar patrón de permisos para ficheros/directorios completados.
    En notación ocal. Por ejemplo:"755" ó "777"Introduce aquí tu clave API de NzbMatrix.Indica los ajustes de tu correo electrónico saliente.Introduce aquí tu contraseña.Introduce aquí tu nombre de usuario.Preferencias¡La configuración ha terminado!¿Deberían las descargas resumirse tras reiniciarse la cuota?Mostrar TodoMostrar FavoritosMostrar opciones de ediciónMostrar los FallidosVer LoggingNombre de la SerieCarpeta de la serieMostrar Logging de la webMostrar detallesMostrar archivosMostrar interfazMuestra las horas en notación AM/PM (no afecta al planificador).Nombre.serieNombre_serieMostrando %s a %sde %s resultadosMostrando un resultadoApagarApagar PCApagar SABnzbdApagandoSeñal %s capturado, guardando y saliendo...TamañoOmitirIgnorar chequeo de par2 cuando los ficheros son 100% correctos.Han fallado algunos ficheros al verificarse "%s"OrdenarOrdenar cadenaOrdenar por antigüedadOrdenar por Fecha (Más nuevo→Más viejo)Ordenar por Fecha (Más viejo→Más nuevo)Ordenar por Fecha Más nuevo→Más viejoOrdenar por Fecha Más viejo→Más nuevoOrdenar por nombre (A→Z)Ordenar por nombre (Z→A)Ordenar por nombre A→ZOrdenar por nombre Z→AOrdenar por Tamaño (Más grande→Más pequeño)Ordenar por Tamaño (Más pequeño→Más grande)Ordenar por Tamaño Más grande→Más pequeñoOrdenar por Tamaño Más pequeño→Más grandeOrdenar por antigüedadOrdenar por nombreOrdenar por tamañoOrdenaciónPreferencias de ordenaciónFuenteEspecialVelocidadLímite de velocidadLímite de VelocidadSuspender PCIniciar AsistenteIniciando reparaciónInicio/ApagadoEstadoQuinto PasoCuarto PasoPrimer PasoTercer PasoSegundo PasoPararDeteniendo...AlmacenamientoAsuntodomingoSwitchesConfiguración de SwitchesCarga del SistemaDirectorios del sistemaTEXTODEMASIADO GRANDETareaDirectorio de descarga temporalEmail de pruebaNotificación de pruebaProbar ServidorTesteando información del servidorEl botón "Reparar" reiniciará SABnzbd y hará una reconstrucción
    completa del contenido de la cola, preservando las descargas ya terminadas.
    Esto modificará el orden de la cola.La herramienta de descarga automática para usenetLa casilla junto al nombre de la fuente debería marcarse para habilitar la fuente y que se marquen automáticamente los nuevos elementos.
    Cuando una fuente se añade, sólo se cogerán los elementos nuevos y nada de lo que ya exista, salvo que presiones "Forzar Descarga".El hostname no está definido.Número de conexiones permitidas a tu proveedorNo se han configurado conexiones. Configure al menos una conexión.Existen trabajos huérfanos en la carpeta de descarga.
    Puedes escoger por eliminarlos (incluyendo los ficheros) o enviarlos de nuevo a la cola.Este campo es obligatorioEsta clave permitirá acceso a programas de terceros para añadir NZBs a SABnzbd.Esta clave le permitirá a programas de terceros acceso completo a SABnzbd.Este mesEsta semanaEsto evitará que se actualizen los contenidos cuando el cursor del ratón esté sobre la cola.Esto reiniciará SABnzbd.
    Usalo cuando creas que el programa está colgado.
    Las descargas se pausarán antes de reiniciar, y se reanudarán a continuación.Se enviará un email de prueba a tu cuentaHiloJuevesTiempo agotadoTiempo agotado: Trate conectar en puerto diferente o encender SSL.TiempoRestanteExpiración del plazo (Timeout)TítuloPara: %s De: %s Fecha: %s Asunto: SABnzdb reporta Disco Lleno Hola, SABnzdb ha detenido las descargas, porque el disco esta casi lleno. Por favor has espacio y resume SABnzdb manualmente. HoyActivar-desactivar Añadir NZBMuy poco espacio en disco forzando PAUSADemasiadas conexiones al servidor %s:%sDemasiadas conexiones; pause las descargas o inténtelo de nuevo más tardeSuperiorMenú superiorTotalResolver un problemaInténtelo de nuevoIntenta predecir si la descarga actual se completará con éxito (ojo, esto tarda!)Intentando verificación por SFVTratando de buscar NZB de %sIntentando cambiar el estado de servidor inexistente %sIntentado descomprimir rar con contraseña "%s"MartesAjustesTipoURuta de acceso UNC "%s" no permitido aquiError al recuperar la URL; %sUSALO BAJO TU RESPONSABILIDADDesmarcar como favorito si la descarga se completaSin autorización, chequea tu usuario/contraseña de NewzbinDesbloquearError inespecifico mientras descodificando %sAcción desconocida: %sDescomprimirDescompresos %s archivos/directorios en %sDescomprimiendoError al descomprimir, %sError de CRC al descomprimirError al descomprimir; se esperaba un archivo que no se ha podido descomprimirError al descomprimir; El archivo está protegido por contraseñaAperture de archivo fallo, la via es muy largaError al descomprimir, chequea el logError al descomprimir, faltan este(os) archivo(s):Error al descomprimir; Imposible encontrar %sError al descomprimir; ¿Error de escritura, o tal vez el disco está lleno?Archivo NZB inusableEncima¡Actualización Disponible!SubirSubir: .nzb .rar .zip .gzTiempo en ActivoUsar reloj de 12 horas (AM/PM)¡sa V23 salvo que tu proveedor indique lo contrario!Usa nombres temporales durante el procesado. Deshabilitalo si tu sistema se vuelve inestable con ello habilitado.Usa la columna "Grupos / Etiquetas del indizador" para enlazar grupos y etiquetas a tus categorías.
    Se aceptan comodines. Usa comas para separar términos.Se usa precediendo a la entrada de un NZB en la cola del sistema.Caché utilizadaEste es el post-procesado a utilizar cuando no se ha definido nada especial según la categoría de la descarga.Se usa cuando la categoría no impone ninguna prioridad.Usado cuando la categoría no imponte ningún script de usuario.Directorios del usuarioCategorías definidas por el usuarioNombre de usuarioValoresSe ha verificado correctamente utilizando ficheros SFVVerificandoVerificando...VersiónVer bitacora de ScriptsVer salida del scriptESPERAR %s segAVISO:AVISO: Abortadeo el trabajo "%s" por un archivo RAR cifradoNOTICIA: Transferencia "%s" pausado por archivo cifradoAVISOSEn esperaAdvertenciaAlerta: LOCALHOST es ambiguo, use dirección de IP numéricaAdvertenciasDirectorio a vigilarVelocidad de escaneo de la carpeta vigiladaInterfaz webIdentificación contra el Servidor WebMiércolesChequear semanalmente por nuevas versiones de SABnzbd.CuandoCuando un artículo tiene un error de CRC, intentar conseguirle desde otro servidor.Cuando este bajando, si es claro que mucha data esta faltando, aborte el trabajo.¿Quién quieres que aparezca como remitente?WikiXAñoDirectorios Año-MesNo tienes suficientes créditos en tu cuenta de NewzbinNo tienes permisos para usar el puerto %sDebes activar JavaScript para que pueda funcionar Plush!Necesitas una cuenta VIP en nzbmatrix para usar la APISu versión de UNRAR no está recomendada, obténgalo desde http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" al unir archivos[%s] Error "%s" al descomprimir ficheros RAR[%s] %s ficheros unidos.[%s] No hay conjuntos par2[%s] PAR2 ha recibido opciones incorrectas, chequea tus ajustes en Preferencias->Switches[%s] Chequeo Rápido OK[%s] Reparado en %s[%s] Verificado en %s, todos los archivos correctos[%s] Verificado en %s, se necesita repararmódulo _yenc... NO encontrado!ajustado a mayus-minuslimpiarddíadíasdeshabilitar servidorhabilitar servidorObteniendo msgid %s desde www.newzbin2.esarchivocarpetahhorahorasRestantemmanualmínmín.minsno instaladodedesactivadoactivadoopáginapar2 binario... NO encontrado!Falta el módulo pyopensll, favor de instalarlo para acceso httpssegsegundosver fichero de logtextodesconocidounrar binario... NO encontradounzip binario... NO encontrado!semanaSABnzbd-0.7.20/locale/fi/LC_MESSAGES/SABnzbd.mo0000644000000000000000000023566712433712600020510 0ustar00usergroup00000000000000?o?M@d^ABC D2EFGH*H'HI4IMI fIIII IIIJJJJJJJJJKK?KK[L_LgLRwL[L&M#,MPMmMMM M MM'MMMN NNN &N 3N>N PNZNpNaNNNNO.O7OIO)iO*O O OOOO/Ph3P PPPAQ(TQ0}Q*QQQQ QQR .R8RQReRlRRS S'S2GS zSS SSST!/T6QT-TTTTU U)U.2U'aUUUUBUVVS-VV VV5VVVV"W6W8c(occHcsc ]d gdtd d d(d.d)d&e,Fe<sebe&f:fUf7hf'ffffg 2g Sg&^g-gggg gh h h%h ;hIhahhhhh%h!hh+i Aibi!}ii!iFi&j0;j-lj'jj"jkk/kMkmkuk kkkkkkkklAlRl'il!lllll-lm"m(mCm3Xm/mgm $n0n&8n"_nnnnn n n nn nnnoo)o 9oGoYoao wo oooo o o oo opp (p 5p@pEpMp cppp upppp-p6p.q@q EqPqbqfq6kqq3VrGrr_stt3tE6t |ttt>u,Pu}uu%u#uuvv ?vKvTv2pv%vv"v+ w6wNw'eww7ww"Wx zx<x x3x9y=yEy%Jypyyy~yyIy5y(z -z9zq?zzczH'{op{]{)>| h|s|{| |||| |$|||0|&}+}?})P}z}}} } } }} }}}}}}~~ ~~6~L~]~*n~.~~#~(161FAx 1" 3>C J,V  ˀ/ـ .1Kek oyc"A*,l3 !,!N"pу (/ 4 ?K T*b0 Ʉ΄ ք ( *4EXmͅ  Ma#|R< M[`"҇9O-W' ݈ .ENTi~ ʉ #+1F cpw يۊߊ$* /9H&d ?   ) 0; Uc4vō2̍  *+Vs)M07 >H Q]c s}֏ #9N an Ȑې. DPl Ƒϑ# +2 :H `4  ŒВJ323f.ɓ)/@O V(w$""2&U|o)'Qq3   (2C S `k9z "ȗ  $'2 Zgl-q(Ș ͘ ٘//-E-s&&ș$$393m11Ӛ   +3IPX ^ j u  ɛ қݛ .6E JTY s~ "g2AמN>=D W,ȡ ѡ>ۡ#+1"$AB E .(WwĤ ڤ2.6Vip 3˥-"-P,j#.#*EL0fb$ 814" Wd|% ɩѩש 76R:ݪ  7%Ag@lR!"').*A$l10ìZ#O)sJĭ#&7'^  Ϯ&ݮ "$+/4 9GJNQTY9s ůʯү ('pP(@! ׺02/&b#ݼ( @KRp-5>FNTl~X; (y=}5(<e& " ,4C Wcs Y16=PEU";. = K!Vx:xG"]5;K05 '$<a)h##u87':%X~%0,<<X%$$  "0,4]c DQT`9 ,6!F*h@   ,6 EOj'*5< P[] ly  "0=nu | 5&8;$t0#~EZ"c #> #'/W9pA-DGB7 /Lf oy! &1Pk| ,"=Vq/&"%Io( *D&^(C5/5eT(=Ad1> @q" ,,-/*]*:u-d">6>%U.{#$ <5=#s  #<*K"v2&/,#.P+2)&(YO:6A;#},#5/('X "   # :YK-%&? N[/c P?-m @9F   "4E \f   %:Sj|$& 3 Q>@ 4 >=$Db2! #T- "J/_/&-#Fj ~(9,((D?m. ^(%RxNKQ7 8 -G-:u yK|foS+i  B&:a8j,    ( 6 DQap  %",:0g&<$@3Mt >;+ g s1  +EYsv! "o]5 Fg*y %,'3"[ ~       (4=0N3  )"1BUo)8L gZs&+Y! { 1   & / 1 'B  j   "   =  C  M  W d .        # / 8 $S x 0      1  F T ] #b #        3-acg z , 20 cmE|%   '2JZ8wB &0 I&V#}0Y1J|  )%=CI bp />Yq!% $#(L P[dm )!*"@%c0IG>E< ''"Or-# -Iew). y%2 '  2<=S  &=O7i  * *36j}90 8(8a771 1< /n / : : !8D!8}!!!! !"""0"7"F"U"^"p""" " " " " " """# # # #6#=#Q# X# d#n#######$&$%-&83&l&&o'e'U'>(M(P^((:r))))I)* &*3*;* *+0"+$S+Gx++ + +++D+A,%],<,0,, ,--- 0-Q-*k-;- -"-..-.L.U."q.7.1...#-/4Q/%/:/!/ 0&0,0B0K0h0"{0*00b1,!2N2Qd2M2U3Z3'p33313 3334 4!4:4K4 ^4=h4<4 4 44B5 E5Q5a555 5.55J5O=6*6666$616,76I737m7+"8*N8y88N889:*9.e999 999 99:2:Q:Z:a:c:i: p:{:}::: : ::: ::::I:@;H;Q;d; k;v;;; SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAcceptAccessAccess deniedAccount infoActionAction when encrypted RAR is downloadedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAudioAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatic FeedbackAutomatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)CancelCannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.CommentComplete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable OZnzb IntegrationEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enhanced functionality including ratings and extra status information is available when connected to OZnzb indexer.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you do not have an account it can be created at If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesIndexingInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOZnzbOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOtherOther MessagesOther SwitchesOther problemOut of retentionPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!Refer to https://www.oznzb.com/profileRefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.ReportReport-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSendSend GroupSend RSS notificationsSend automatically calculated validation results for downloads to indexer.Send email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...Site API KeySizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key provides identity to indexer. Refer to https://www.oznzb.com/profile.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVideoView Script LogView script outputVirus/spamWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2014-04-19 08:54+0000 Last-Translator: Matti Ylönen Language-Team: Finnish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:53+0000 X-Generator: Launchpad (build 17082) SABnzbd ei löydä sen web-käyttöliittymän tiedostoja polusta %s.
    Ole hyvä ja asenna ohjelma uudelleen.

    SABnzbd tunnisti Jonon ja Historian vanhemmasta (0.4.x) julkaisusta.

    Molemmat, jono ja historia ohitetaan ja ne saattavat hävitä!

    Haluat ehkä lopettaa SABnzbd-ohjelman ja ladata jonon loppuun vanhemmalla ohjelmalla.

    Klikkaa OK jatkaaksesi SABnzbd-ohjelmaan SABnzbd havaitsi tallennettua tietoa toisesta SABnzbd versiosta
    mutta ei voi uudelleenkäyttää tietoja toisesta ohjelmasta.

    Haluat ehkä ladata jonon loppuun toisella ohjelmallasi.

    Tämän jälkeen, käynnistä ohjelma "--clean" muuttujalla.
    Tämä tyhjentää nykyisen jonon ja historiasi!
    SABnzbd luki tiedostoa "%s". SABnzbd havaitsi, että tiedosto sqlite3.dll puuttuu.

    Jotkin huonosti suunnitellut viruksentorjunta ohjelmistot poistavat tämän tiedoston.
    Tarkista virustorjunta ohjelmistosi, yritä asentaa SABnzbd uudelleen ja valita virustorjunta ohjelmistosi valmistajalle.

    SABnzbd ei ole yhteensopiva kaikkien ohjelmistopalomuurien kanssa.
    %s
    Pahoittelumme, mutta emme voi ratkaista tätä yhteensopivuusongelmaa juuri nyt.
    Ole hyvä ja lähetä valitus palomuurin toimittajallesi.

    SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-palvelimelleen.
    Porttia %s kohteessa %s yritettiin käyttää , mutta se ei ollut vapaana.
    Jokin toinen ohjelmisto käyttää porttia tai SABnzbd on jo käynnissä.

    Ole hyvä ja uudelleenkäynnistä SABnzbd toisella porttinumerolla. SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-palvelimelleen.
    Porttia %s kohteessa %s yritettiin käyttää , mutta tilillä jolla SABnzbd käynnistettiin ei ollut oikeuksia käyttää sitä.
    OSX ja Linux järjestelmissä normaalien käyttäjien tulee käyttää portteja jotka ovat suurempia kuin 1023.

    Ole hyvä ja uudelleenkäynnistä SABnzbd toisella porttinumerolla. SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-palvelimelleen.
    Olet määritellyt epäkelvon osoitteen.
    Turvalliset arvot ovat localhost ja 0.0.0.0

    Ole hyvä ja uudelleenkäynnistä SABnzbd kunnollisella isäntäosoitteella. SABnzbd ohjelmalla EI OLE MINKÄÄNLAISTA TAKUUTA. Tämä on ilmainen ohjelma ja olet vapaa levittämään sitä tiettyjen ehtojen ollessa voimassa. Se on lisensoitu GNU GENERAL PUBLIC LICENSE Versio 2 alaiseksi ja (oman valinnan mukaan) myös myöhempien versioiden. %s -> Tuntematon koodaus%s => puuttuu kaikilta palvelimilta, hylätään%s artikkelissa oli ei-vastaavia kaksoiskappaleita%s artikkelia oli väärin muotoiltuja%s artikkelia puuttui%s artikkelia poistettiin%s kansio: %s virhe käytettäessä%s tiedostoa kohteessa %s%s ei ole oikea oktaalinen arvo%s ei ole kelvollinen sähköpostiosoite%s puuttuu  Selvitetään osoitetta tai Raportti ID 
    SABnzbd sammutus valmis.
    Odota noin 5 sekuntia ja paina sitten alapuolella olevaa nappia.

    Päivitä
    + Debug+ Tiedot+Poista+Korjaa+Pura.nzb varmuuskopiokansio1x05 Jakso kansio1x05 Tuotantokausi kansioHUOM: Kansiot luodaan automaattisesti tallennuksen yhteydessä. Voit käyttää täydellisiä polkuja jos haluat tallentaa oletuskansioiden ulkopuolelle.Tiedostoja ei tulla siirtämään. Vaatii SABnzbd uudelleenkäynnistyksen!Lue syöte hakee vain syötteen uuden sisällön. Pakota lataus hakee kaikki vastaavat NZB:t heti.IKÄAPI avainAPI avaimen QR-koodiAPI avain virheellinen, käytä Asetukset->Yleiset löytyvää api avainta käyttämääsi kolmannen osapuolen ohjelmaan:API avain puuttuu, ole hyvä ja syötä Asetukset->Yleiset löytyvä api avain käyttämääsi kolmannen osapuolen ohjelmaan:LopetaPeruuta työt jotka eivät voi valmistuaKeskeytetty, ei voi valmistuaKeskeytty, salattu arkisto tunnistettuHyväksyPääsyEi käyttöoikeuttaTilitiedotToimintoToiminto kun salattu RAR havaitaanToiminnotAktivoi toissijainen teema.LisääLisää syöteLisää tiedostostaLisää NZBLisää ajastusLisää palvelinLisää uusia latauksiaLisätty NZBHallinnollinen kansioKategoriat joita koskeeKun SABnzbd on käynnistynyt uudelleen, voit käyttää sitä seuraavasta osoitteesta: %sIkäKaikkiMyös testiversiotAinaKäytä uudelleenyritysten määrää vain valinnaisille palvelimilleKäytä valittuihinOletko varma, että haluat poistaaOletko varma, että haluat käynnistää SABnzbd uudelleen?Oletko varma, että haluat sammuttaa SABnzbdn?Oletko varma?ParametritVälimuistirajoitus artikkeleilleArtikkelin tunnisteÄäniVarmennus epäonnistui, tarkista käyttäjänimi/salasana.Authentikointi puuttuu, ole hyvä ja syötä käyttäjänimi/salasana Asetukset->Yleiset kolmannen osapuolen ohjelmaasi:Jatka automaattisestiNouda kirjanmerkit automaattisestiKeskeytä automaattisesti kun vapaan tilan määrä on vähemmän kuin tämä arvo.
    Tavuina, mutta voit laittaa perään K,M,G,T kirjaimen. Esimerkiksi: "800M" tai "8G"Automaattinen palauteLataa automaattisesti kirjanmerkkeihin lisätyt postaukset.Noutaa työt automaattisesti kirjanmerkeistäsi.Järjestelee kohteet (keskimääräisen) iän mukaan.BTakaisinVarmuuskopioiVarapalvelinVirheellinen ajastus %s kohteessa %s:%sHuonosti muotoiltu yEnc artikkeli %sKaistaEstä päivitykset kun hiiri on päälläKirjanmerkkien käsittelyAlinCRC virhe tiedostossa %s (%s -> %s)Välimuistita artikkelit muistissa levytapahtumien vähentämiseksi.
    Tavuina, vaihtoehtoisesti lisää pääte K,M,G. Esimerkiksi: "64M" tai "128M"%s artikkelia välimuistitettu (%s)PeruutaKäyttöoikeuksien muuttaminen epäonnistui kohteelle %sEi voida yhdistää rekisteripolkuun HKEY_CURRENT_USER.Palvelimeen %s ei voida yhdistää [%s]Ei voitu luoda %s kansiota %sEi voitu luoda varmuuskopiota %s :lleEi voi luoda kansiota %sEi voitu luoda lopullista kansiota %sVäliaikaistiedostoa ei voida luoda kohteelle %sSähköpostipohjia ei löydy hakemistosta %sWeb-mallia %s ei löydy, yritetään käyttää oletusmalliaSelainta ei voida käynnistää, todennäköisesti ei löydyEi voida avata rekisteriavainta "%s".Ei voida lukea %sVahdittua kansiota %s ei voida lukeaEi voitu kirjoittaa INI tiedostoa %sKategoriatKategoriaMuutoksia ei ole tallennettu ja ne menetetään.Muutokset vaativat SABnzbdn uudelleenkäynnistyksen!Tarkista ennen lataamistaTarkista uusi versioTarkista purkamisen lopputulosTarkistaa purkamisen lopputulokset (täytyy olla pois päältä joissain tiedostojärjestelmissä).TarkistetaanTarkistusväliTarkistusväli (minuutteina, vähintään 15). Ei aktiivinen kun käytät Ajastinta!Valitse teema.Puhdistuslista%s puhdistaminen epäonnistui.Puhdistaa par tiedostot (jos varmennus/korjaus onnistui).TyhjennäNollaa laskuritKlikkaa alapuolelta testataksesi.Klikkaa testataksesi syötettyjä tietoja.SuljeSelaimen tai sen välilehtien sulkeminen EI sammuta SABnzbd:tä.KommenttiValmistuneet-kansioValmistuneet-kansioValmistunutValmistuneet kansioAsetuksetAsetustiedostoAsetuksetVarmista historian poistotVarmista jonon poistotVirhe yhdistäessä %s@%s:%s, viesti=%sYhdistäminen onnistui!YhteydetSäiliön leveysNewzbin kirjanmerkkiä %s ei voitu poistaaYhteystestin lopputulosta ei voitu määrittää (%s)Nykyiset ajastuksetMukautettuDKAKSOISKAPPALEPäivittäinPäivittäiset kansiotPäivämäärän lajitteluKuukauden päiväVuosikymmen%s dekoodaus epäonnistuiOletusOletuskansioOletus jälkikäsittelyOletusprioriteettiKäyttäjän oletusskriptiMäärittää jälkikäsittelyn ja tallennuksen.PoistaPoistaPoista kaikkiPoista valmistuneetPoista epäonnistuneetPoista syötePoista lataamisen jälkeenPoistetaanko kaikki valmistuneet kohteet historiasta?Poistetaanko kaikki ladatut tiedostot?Poistetaanko kaikki epäonnistuneet kohteet historiasta?Poistetaanko kaikki kohteet jonosta?Poistetaanko kaikki epäonnistuneet historiasta?Kohteen %s poisto epäonnistui!Tunnista päällekkäiset latauksetTunnistaa identtisesti nimetyt NZB tiedostot (vaatii NZB varmuuskopio -valinnan) ja päällekkäiset otsikot RSS syötteissä.Poista käytöstä API avainEi käytössäHTTPS poistettu käytöstä puuttuvien CERT ja KEY tiedostojen vuoksiHylkääKatkaise yhteys Usenet palvelimeen/palvelimiin kun jono on tyhjä tai tila on keskeytetty.Katkaise yhteys kun jono on tyhjäLevy täynnä tiedotteetLevyvirhe luotaessa tiedostoa %sLevy täynnä! Pakotetaan keskeytysSuorittaa ylimääräisen varmennuksen SFV tiedostojen avulla.Älä lataaEi ole käyttöoikeutta syötteeseen %sÄlä vaadi API avainta.Resetoidaanko rajoitus joka päivä, viikko vai kuukausi?Eikö sinulla ole usenet tarjoajaa? Suosittelemme kokeilemaan %s.AlasLataaLataus valmistuiLataukset-kansioLataus epäonnistuiLataamisen nopeusrajoitusLataus epäonnistui - Työ on palvelimesi säilytyksen ulkopuolella?Lataaminen saattaa epäonnistua, vain %s osaa %s osasta saatavillaLatausnopeuden rajoitus (kt/s, kilotavuina sekunnissa).LatausnopeusLadattuLadattiin ajassa %s keskilatausnopeudella %sB/sLadattu tähän mennessäLadataanLatauksetKaksoisnäkymä1Kaksoisnäkymä2Esim.Esim. 119 tai 563 SSL yhteyksilleEsim. 8 tai 20SALATTUVIRHE:VIRHE: %sVIRHE: CRC epäonnistui kohteessa "%s"VIRHE: polku liian pitkä (%s)VIRHE: kohdetta "%s" ei löydyVIRHE: kirjoitusvirhe (%s)Aikaa jäljelläMuokkaaNZB tietojen muokkausSähköpostiSähköpostitilin asetuksetSähköposti-ilmoitus onnistuneesta työstäSähköpostiasetuksetSähköpostin vastaanottajaSähköpostin lähettäjäSähköposti lähetetty!Sähköpostipohjien kansioSähköpostitestin tuloksetSähköpostiosoite johon viestit lähetetään.Sähköpostitus onnistuiTyhjäTyhjä NZB tiedosto %sTyhjä RSS kohde löytyi (%s)Ota käyttöönPäivämäärän lajittelu käytössäTiedostojen yhdistäminen käytössäGrowl käytössäHTTPS käytössäAktivoi HTTPS pääsy SABnzbd-ohjelmaan.Elokuvien lajittelu käytössäMoniydin Par2 käytössäNotifyOSD käytössäOZnzb integraatio käytössäPar puhdistus käytössäPikatarkistus käytössäSFV-pohjaiset tarkistukset käytössäTS-tiedostojen yhdistäminen käytössäTV lajittelu käytössäUnrar käytössäUnzip käytössäOta käyttöön käyttöliittymän käyttäminen HTTPS-osoitteesta.Ottaa käyttöön sisäänrakennetun unrar toiminnon.Ottaa käyttöön sisäänrakennetun unzip toiminnon.Ottaa luokat käyttöön viesteille joita raportoidaan (ei mitään, yksi tai monta)Kansion uudelleennimeäminen käytössäLaita päälle jos haluat ohjelman käyttävän vähemmän muistia. Ota pois päältä jos haluat estää hitaiden töiden aiheuttavan ruuhkaa jonossa.Ottaa yleisen lajittelun ja uudelleennimeämisen käyttöön.Ota käyttöön jos latauksia ei ole laitettu omiin kansioihinsa.Ottaa päivämäärän mukaan nimettyjen tiedostojen lajittelun ja uudelleennimeämisen käyttöön.Ottaa jaksojen lajittelun ja uudelleennimeämisen käyttöön.KäytössäPolun päättäminen tähteen * estää työkansioiden luomisen.Lisää enemmän toimintoja, kuten arvostelut ja lisätiedot jotka saadaan kun yhdistetään OZnzb indeksointiin.Syötä osoiteJakson nimiJakson numeroJakson.nimiJakson_nimiVirhe "%s" ajettaessa file_join kohteelle %sVirhe "%s" ajettaessa par2_repair setille %sVirhe "%s" ajettaessa rar_unpack kohteelle %sVirhe "%s" ajettaessa unzip() kohteelle %sVirhe %s ajettaessa par2_repair setille %sVirhe %s: Syötä kelvollinen käyttäjänimi ja salasana.Virhe noudettaessa viesti-id %s osoitteesta www.newzbin2.es - Varmista, että käyttäjänimi ja salasana ovat oikeinVirhe luotaessa SSL avainta ja sertifikaattiaVirhe noudettaessa TV tietoja (%s)Virhe tuotaessa %sVirhe tuotaessa OpenSSL moduulia. Yhdistetään EI-SSL kautta.Virhe ladattaessa %s, korruptoitunut tiedosto havaittuVirhe poistettaessa %sVirhe poistettaessa työkansiota (%s)Virhe uudelleennimettäessä "%s" nimelle "%s"Virhe lisättäessä %s, poistetaanVirhe sammutettaessa järjestelmääVain virheetVirhe: Toissijaista käyttöliittymää ei ole määritelty.Virhe: Jono ei ole tyhjä, kansiota ei voida vaihtaa.Virhe: Istuntoavain on virheellinenVirhe: Istuntoavain vaaditaanVirheet/varoituksetKaikkiEsimerkkiPoistu SABnzbd:stäTunnisteYlimääräiset PAR2 parametritPuretaan...Huomioi yEnc CRC virheetEpäonnistunutKirjautuminen palvelimelle %s epäonnistuiKohteen (%s) luominen epäonnistuiKohteen %s siirtäminen kohteeseen %s epäonnistuiPostipalvelimen varmennus epäonnistuiTietokannan sulkeminen epäonnistui, katso lokiSähköpostiyhteyden sulkeminen epäonnistuiRegex käännös epäonnistui hakutermille: %sPostipalvelimeen yhdistäminen epäonnistuiJärjestelmän lepotilaan laittaminen epäonnistuiVirhe tuotaessa %s tiedostoa kohteesta %sVirhe initialisoidessa %s@%s:%sTLS yhteyden aloittaminen epäonnistuiJälkikäsittelyjonon lataaminen epäonnistui: Väärä versio (tarvitaan:%s, löytyi:%s)Tiedostojen siirto epäonnistuiErikoiskansioiden rekisteriavainten lukeminen epäonnistuiEi voitu poistaa nzo:ta jälkikäsittelyn jonosta (id)Samankaltaisen tiedoston uudelleennimeäminen epäonnistui: %s %sVirhe uudelleennimettäessä: %s %sRSS noutaminen epäonnistui kohteesta %s: %sSähköpostin lähetys epäonnistuiJärjestelmän valmiustilaan laittaminen epäonnistuiWeb-käyttöliittymän käynnistys epäonnistuiNewzbin työn %s päivitys epäonnistuiEpäonnistuiVirhe tiedostossa tempfile.mkstempVakava virheSyöteSyötteetNoudaNoudetaanNoudetaan %s lohkoa...Noudetaan ylimääräiset lohkot...Tiedosto %s on tyhjä, ohitetaanTiedostotunnisteTiedosto joka sisältää kaikki salasanat joita kokeillaan salattuihin RAR tiedostoihin.Tiedostoliitos %s epäonnistuiTiedostonimi tai polku HTTPS sertifikaattiin.Tiedostonimi tai polku HTTPS ketjuun.Tiedostonimi tai polku HTTPS avaimeen.TiedostojoukkoTiedostonimiSuodataOhittaa näytetiedostot (esim. videonäytteet).SuodattimetEnsimmäinenKansiota "%s" ei ole olemassaKansion asetuksetKansio jossa ovat käyttäjän skriptit joita käytetään jälkikäsittelyssä.Kansio joka sisältää käyttäjän luomat sähköpostipohjat.Kansio jota vahditaan .nzb tiedostojen varalta.
    Etsii .nzb tiedostoja myös .zip .rar ja .tar.gz arkistojen sisältä.Kansio/PolkuKansiotKirjautumisen vaativalle sähköpostille, tilin käyttäjänimi.Kirjautumisen vaativalle sähköpostille, tilin salasana.PakotaPakota yhteyden katkaisuPakota latausFoorumiVapaana (Temp)Vapaa tilaToistoPerjantaiLisää ohjeita löytyyGtYleisetYleisasetuksetLuo uusi avainYleinen lajitteluHae kirjanmerkitNouda kirjanmerkit nytNouda NZBNouda Newzbin kirjanmerkitSiirry SABnzbd:henMene velhoonRyhmien / Indeksoijan tunnisteetHTTPS sertifikaattiHTTPS ketjun sertifikaatitHTTPS avainHTTPS porttiHTTPS-tukiOhjeHorrostilaPiilota kirjanmerkitPiilota muokkausvalinnatPiilota yksityiskohdatPiilota tiedostotKorkeaHistoriaVie viimeiset 10 kohdetta historiaanHistorian kokoAlkuunKotisivuIsäntäOsoite jota SABnzbdn tulisi kuunnella.Tunti:MinKuinka paljon voidaan ladata tässä kuussa (K/M/G)Tahdon, että SABnzbd on käytettävissä jokaiselta verkossani olevalta PC:ltä.Tahdon, että SABnzbd on käytettävissä vain omalta PC:ltäni.EI TÖITÄKESKENERÄINENIONice muuttujatIRCToimetonJos tyhjä, oletusportti kuuntelee ainoastaan HTTPS.Mikäli olet newzbin tai nzbmatrix jäsen, voit syöttää käyttäjänimesi ja salasanasi tähän jotta ohjelma voi hakea nzb-tiedostot heiltä suoraan. Voit ohittaa tämän vaiheen jos et käytä kummankaan sivuston palveluita.Jos sinulla ei ole vielä tiliä, voit luoda sen osoitteessa Jos saat tämän virhesanoman uudestaan, kokeile toista numeroa.
    Jos sinulla on tili osoitteessa www.newzbin2.es, voit syöttää tilisi tiedot tähän.
    Tämä avaa lisätoimintoja.Jos sinulla on tili osoitteessa www.nzbmatrix.com, voit syöttää tilisi tiedot tähän.
    Nämä vaaditaan jos haluat käyttää RSS syötteitä kyseiseltä sivustolta.Ohita näytteetOhitetaan kaksoiskappale NZB "%s"KohteessaJos valitsit "Keskeytä", sinun täytyy asettaa salasana ja jatkaa työn lataamista.KansioissaMinuutteina (vähintään 15 min).Jotta voit ladata usenetistä tarvitset tarjoajan. Palveluntarjoajasi saattaa tarjota sinulle sellaisen, mutta on suositeltavaa hankkia premium-tarjoaja.Puutteellinen syöteEi-tuettu jonotiedosto löytyi, ei voida jatkaaLataukset-kansioKeskeneräinen NZB tiedosto %sPuutteellinen joukko yhdistettäviä tiedostojaVirheellinen RSS syötteen kuvaus "%s"Virheellinen parametriVirheellinen arvo %s: %sVirheellisesti koodattu salasana %sIndeksointisivustotIndeksoidaanAloitetaan uudelleenkäynnistys...
    Virheellinen NZB tiedosto %s, ohitetaan (syy=%s, rivi=%s)Virheellinen koodaus sähköpostipohjassa %sVirheelliset nzbmatrix käyttäjätiedotVirheellinen nzbmatrix raporttinumero %sVirheelliset par2 arkistot, varmennus ja korjaus ei mahdollistaVirheellinen palvelimen osoite.Virheelliset palvelimen tiedotVirheellinen tila lokihistoriassa kohteelle %sKäänteinenOn todennäköistä, että käytössäsi on ZoneAlarm ja käyttöjärjestelmäsi on Vista.
    On suositeltavaa, että painat linkistä hiiren oikealla ja lisäät sen kirjanmerkkeihin. Sitten voit käyttää kirjanmerkkiä kun haluat käyttää SABnzbd ohjelmaa sen ollessa käynnissä taustalla.Työ "%s" lisättiin uudelleen jonoonTyö valmistunutTöitä jotka ovat merkitty '*' merkillä ei ladata automaattisesti uudelleen.Yhdistä tiedostotYhdistää tiedostot jotka päättyvät .001,.002 jne. yhdeksi tiedostoksi.Yhdistää tiedostot jotka päättyvät .001.ts,.002.ts jne. yhdeksi tiedostoksi.Yhdistetäänkt/sPidä irralliset lataukset ylimääräisissä kansioissaKieliViimeinenViimeisimmät varoituksetKäynnistä selain käynnistyksen yhteydessäKäynnistä internet selaimeni SABnzbd-sivulle kun ohjelma käynnistyy.Käynnistää oletusselaimen kun SABnzbd käynnistetään.JäljelläNopeusrajoitusLinkitLista tiedostopäätteistä jotka tulisi poistaa lataamisen jälkeen.
    Esimerkiksi: .nfo tai .nfo, .sfv%s lataaminen epäonnistuiSijainti jonne tallennetaan jonon hallinnan ja historian tietokannat.
    Voidaan muuttaa vain jonon ollessa tyhjä.Sijainti jonne SABnzbd ohjelman lokitiedostot tallennetaan.
    Vaatii SABnzbd uudelleenkäynnistyksen!Sijainti jonne tallennetaan valmistuneet ja täysin käsitellyt ladatut kohteet.
    Käyttäjän asettamat kategoriat voivat kumota tämän.Sijainti jonne tallennetaan latauksessa olevat kohteet ennen käsittelyä.
    Voidaan muuttaa vain kun jono on tyhjä.Sijainti jonne .nzb tiedostot tallennetaan.LokikansioLokiinkirjausMatalaPienaakkosetMtPääpakettia ei löydy...VastaaEnimmäisnopeusEnimmäismäärä uudelleenyrityksiä yksittäiselle palvelimelle.Enimmäismäärä uudelleenyrityksilleMerkitysPienin vapaan tilan määrä väliaikaisille latauksilleMuutIstuntoavain puuttuuPuuttuvat artikkelitOdotettu tiedosto: %s puuttuu => purkuvirhe?MaanantaiKuukausiLisääElokuvan nimiElokuvan.nimiElokuvan_nimiSiirretäänSiirretään...MonioperaatiotMoniosainen seliteNZB avainNZB lisätty jonoonNimiNimeäminenEi koskaanUuden syötteen osoiteUusi versio %s saatavilla osoitteestaUusi versio saatavillaNewzbin salasanaNewzbin käyttäjänimiNewzbin antaa tuntemattoman virhekoodin (%s)Newzbin antaa tuntemattoman virhekoodin (%s, %s)Newzbin raporttia %s ei löydyNewzbin palvelin vaihto protokollaansaNewzbin palvelin ei onnistunut antamaan tietoja kohteesta %sSeuraavaNice muuttujatPAR2 ohjelmaa ei löydy, korjaukset eivät ole mahdollista
    UNRAR ohjelmaa ei löydy, RAR-tiedostojen purkaminen ei ole mahdollista
    Sähköpostipohjia ei löydyEi kansioitaJälkikäsittelyä ei suoritettu, koska varmennus epäonnistuiVastaanottajaa ei määritelty, sähköpostia ei lähetettyEi tuloksiaEi mitäänNormaaliEi vastaavuuttaEi tarpeeksi levytilaa latauksien valmistumiseen!Ei vastaaIlmoituskeskusIlmoitus lähetetty!Ilmoituksien luokatHuomautuksetSkannausväli sekunteina .nzb tiedostoille.NzbMatrix API avainNzbMatrix käyttäjänimiOKVALINNAINEN tilin salasanaVALINNAINEN tilin käyttäjänimiOZnzbEi käytössäValmistuessaKun jono on tyhjäMinä päivänä kuusta tai viikosta (1=Maanantai) palveluntarjoajasi resetoi rajoituksen? (Voit syöttää kellonajan perään hh:mm)Hae artikkelit vain jonon huipultaVain valinnaisille palvelimilleSuorittaa jälkikäsittelyn vain niille töille jotka läpäisevät kaikki PAR2 tarkistukset.Käytä vain Growl etäpalvelimelle (isäntä:portti)Avaa tietoja sisältävä osoiteAvaa lähdeosoiteAvaa pääte ja kirjoita rivi (esimerkki):Avaa valmistuneet-kansioValinnainenValinnainen täyte-NZBVaihtoehtoinen salasana todennukseen.Vaihtoehtoinen käyttäjänimi todennukseen.Valinnainen salasana Growl palvelimelleVaihtoehtoisesti anna tiedostonimiAsetuksetJärjestysAlkuperäinen tiedostonimiAlkuperäinen kansionimiMuuMuut viestitMuut valinnatMuu ongelmaSäilytyksen ulkopuolellaKESKEYTETTYSivuParametritOsan numeroSalasanaSalasanatiedostoSalasana on piilotettu ******, syötä uudelleenSuojaa SABnzbd käyttö salasanalla (suositeltavaa)SalasanasuojattuPolkuMalliMallin avainKeskeytäKeskeytä kaikkiKeskeytä lataus jälkikäsittelyn ajaksiKeskeytysväliKeskeytä ajaksiKeskeytä tunniksiKeskeytä 12:ksi tunniksiKeskeytä 15:ksi minuutiksiKeskeytä 24:ksi tunniksiKeskeytä 3:ksi tunniksiKeskeytä 30:ksi minuutiksiKeskeytä 5:ksi minuutiksiKeskeytä 6:ksi tunniksiKeskeytetään kuinka moneksi minuutiksi?Keskeytä ajaksi...Keskeytä jälkikäsittelyKeskeytettyKeskeyttää lataamisen kun jälkikäsittely alkaa ja jatkaa lataamista kun se lopetetaan.Keskeytetään kaksoiskappale NZB "%s"Käyttöoikeudet valmistuneille latauksilleHuomioithan, että 0.0.0.0 isäntänimi vaatii IPv6 osoitteen jotta pääset ulkoverkkoonSyötä kokonaisluku.Syötä pääasiallisen usenet tarjoajasi tiedot.Plush asetuksetPorttiPortti jota SABnzbdn tulisi kuunnella.Jälkikäsittely epäonnistui kohteelle %s (%s)JälkikäsittelyJälkikäsittele vain onnistuneet työtJälkikäsittelyskriptien kansioJälkikäsittelyJälkikäsittely aloitettuJälkikäsittely peruutettiin (%s)Esijonon käyttäjän skriptiEsiasetuksetPaina Windows-nappia+R ja kirjoita seuraava rivi (esimerkki):EdellinenEdellinenPrioriteettiMahdollinen tilin jakaminenOngelma nzbmatrix palvelimeen pääsyssä (%s)OngelmaKäsitellyt kirjanmerkitKäsitellyt tuloksetKäsitelläänKäsittelyparametritOhjelma ei käynnistynyt!EdistyminenPuhdistaPuhdista valmistuneet NZBtTyhjennä epäonnistuneiden historiaPuhdista epäonnistuneet NZBtPuhdista epäonnistuneet NZBt & poista tiedostotTyhjennä historiaPuhdista NZBtPuhdista NZBt & poista tiedostotTyhjennä jonoPuhdistetaanko historia?Puhdistetaanko jono?Python versioQR-koodiJonoVie ensimmäiset 10 kohdetta jonoonJonon automaattinen päivitysväli:Jonon korjausJonossaPikatarkistus...PikatarkistetaanLopetaLatausrajoitusLatausrajoitusta jäljelläLatausrajoituksen pituusLatausrajoitus saavutettu, keskeytetään latauksetRRSSRSS tarkistusväliRSS asetuksetRSS syöte %s oli tyhjäAjettiin %sVäliHarvoin käytetyt asetukset. Paina Ohje-painiketta Wiki-sivustolle päästäksesi, jotta saat tietää näiden tarkoituksen ja ohjeet käyttöön.
    Älä muuta ennen Wikin lukemista, koska näiden muuttamisella voi olla vakavia sivuvaikutuksia.
    Oletusarvot ovat kirjoitettuna sulkeiden sisään.Lue kaikki syötteet nytLue syöteLue RSS syötteetLue Wikin ohjeet tähän!Tarkista osoitteesta https://www.oznzb.com/profilePäivitäPäivitysväliJonon päivitysväli web-käyttöliittymässä(sek, 0= ei päivitä).PäivitysväliHylkääSuhteelliset kansiot jotka perustuvatJäljellä/YhteensäJäljelläPoistaPoista NZBPoista NZB ja tiedostotPoista palvelinPoista epäonnistuneet työtPoistaa kirjanmerkin listalta kun lataus on valmistunut.%s poistaminen epäonnistuiUudelleennimeäKorjaaKorjaaminen epäonnistui, ei tarpeeksi korjauslohkoja (%s puuttuu)KorjataanKorjaus epäonnistui, %sKorjataan...Korvaa kielletyt merkit kansionimissäKorvaa välilyönnit kansionimessäKorvaa pisteet kansionimessäKorvaa pisteet välilyönneillä kansionimissä.Korvaa kielletyt merkit kansionimissä vastaavalla merkillä (jos ei vastaavaa, poistaa).Korvaa välilyönnit alaviivoilla kansionimissä.IlmoitaRaportti-idVaatiiVaadittuCatNollaaResetoi latausrajoitus nytResetointipäiväKäynnistä uudelleenKäynnistä uudelleen ilman kirjautumistaKäynnistetään SABnzbd uudelleen...TulosJatkaJatka jälkikäsittelyäSäilytysaikaYritä uudelleenAjetaan skriptiAjetaan skripti...Ajetaan käyttäjän skripti %sS01E05 Jakso kansioS01E05 Tuotantokausi kansioSABnzbd %s käynnistettySABnzbd isäntäSABnzbd salasanaSABnzbd porttiSABnzbd pika-aloitus velhoSABnzbd käyttäjänimiSABnzbd versioSABnzbd web-palvelinSABnzbd havaitsi vakavan virheen:SABnzbd sammutus valmisSABnzbd on nyt käynnissä taustalla.SMTP-palvelinSQL komento epäonnistui, katso lokiSQL muutos epäonnistui, katso lokiSSLSSL tyyppiLauantaiTallennaTallenna muutoksetTallennettu%s tallentaminen epäonnistuiTallennetaan...Tarkista vahdittu kansioAjastettu tuntemattomalle palvelimelle %sAjastusAjastimen asetuksetSkriptiSkriptitTuotantokauden numeroToissijainen web-käyttöliittymäValitse web-käyttöliittymän kieli.Valitse vain jos tarjoajasi sallii SSL yhteydet.ValintaLähetäLähetä ryhmäLähetä RSS ilmoituksetLähetä automaattisesti laskettu latauksen vahvistustulos indeksoijalle.Lähetä sähköpostia kun RSS syötteestä lisätään töitä jonoon.Lähetä sähköposti kun levy on täynnä ja SABnzbd on keskeytetty.Lähettää ryhmäkomennon ennen artikkeleiden pyytämistä.Lähetä ilmoitukset GrowliinLähetä ilmoitukset ilmoituskeskukseenLähetä ilmoitukset NotifyOSD:henLähetettiin %s jonoonSarjojen lajitteluPalvelinPalvelin %s vaatii käyttäjänimen/salasananPalvelin %s ohitetaan %s minuutiksiPalvelimen tiedotPalvelimen osoitePalvelimen osoite "%s:%s" ei ole kelvollinen.Palvelimen osoite vaaditaanPalvelinasetuksetPalvelimen tyyppiPalvelimen salasanaPalvelin lopetettiin kesken kirjautumisenPalvelin vaatii käyttäjänimen ja salasanan.PalvelimetAseta keskeytysväliAseta käyttöoikeusmalli valmistuneille tiedostoille/kansioille.
    Oktaalilukuna. Esimerkiksi: "755" tai "777"Kirjoita NzbMatrix API avain tähän.Sähköpostin lähtevän postin palvelimen osoite.Kirjoita tilin salasana tähän.Syötä tilisi käyttäjänimi tähän.AsetuksetAsennus on nyt valmis!Pitäisikö latauksia jatkaa kun latausrajoitus on resetoitu?Näytä kaikkiNäytä kirjanmerkitNäytä muokkausvalinnatNäytä epäonnistuneetNäytä lokiOhjelman nimiOhjelman nimi kansioNäytä weblokiNäytä yksityiskohdatNäytä tiedostotNäytä käyttöliittymäNäyttää ajat AM/PM muodossa (ei vaikuta ajastuksiin)Ohjelman.nimiOhjelman_nimiNäytetään %s - %s tulosta %s tuloksestaNäytetään yksi tulosSammutaSammuta tietokoneSammuta SABnzbdSammutetaanSignaali %s kaapattu, tallennetaan ja lopetetaan...Sivuston API avainKokoOhitaOhita par2 tarkistus kun tiedostot ovat 100% kunnollisia.Jotkin tiedostot eivät varmentuneet "%s" kanssaLajitteleLajittelumerkkijonoJärjestä iän mukaanJärjestä iän mukaan(Uusin→Vanhin)Järjestä iän mukaan(Vanhin→Uusin)Järjestä iän mukaan Uusin→VanhinJärjestä iän mukaan Vanhin→UusinJärjestä nimen mukaan (A→Z)Järjestä nimen mukaan (Z→A)Järjestä nimen mukaan A→ZJärjestä nimen mukaan Z→AJärjestä koon mukaan (Suurin→Pienin)Järjestä koon mukaan (Pienin→Suurin)Järjestä koon mukaan Suurin→PieninJärjestä koon mukaan Pienin→SuurinLajittele iän mukaanLajittele nimen mukaanLajittele koon mukaanLajitteluLajittelun asetuksetLähdeErikoisasetuksetNopeusNopeusrajoitusNopeusrajoitusLepotilaKäynnistä velhoAloitetaan korjausKäynnistys/SammutusTilaVaihe viisiVaihe neljäVaihe yksiVaihe kolmeVaihe kaksiPysäytäPysäytetään...TallennusasemaOtsikkoSunnuntaiMuuttujatParametrien asetuksetKuormaJärjestelmäkansioTEKSTILIIAN SUURITehtäväVäliaikaiset lataukset kansioTestaa sähköpostiaTestaa huomautustaTestaa palvelintaTestataan pavelimen tietoja..."Korjaa" painike käynnistää SABnzbd uudelleen ja luo jonon
    sisällön täydellisesti uudelleen, säilyttäen jo ladatut tiedostot.
    Tämä muuttaa jonon järjestystä.Automaattinen usenet lataustyökaluValintaruutu syötteen nimen vieressä täytyy olla valittuna jotta syöte on päällä ja uusia kohteita tarkistetaan automaattisesti.
    Kun syöte lisätään, siitä lisätään vain uusia kohteita eikä niitä jotka ovat jo julkaistu syötteessä ellet paina "Pakota lataus" -painiketta.Isäntänimeä ei ole asetettu.Tarjoajasi sallimien yhteyksien lukumäärä.Yhteyksiä ei ole asetettu. Aktivoi ainakin yksi yhteys.Latauskansiossa on orpoja töitä.
    Voit valita niiden poistamisen (sisältäen tiedostot) tai voit lähettää ne takaisin jonoon.Tämä kenttä on pakollinen.Tämän avaimen avulla indeksoija tietää kuka olet. Tarkista avain osoitteesta https://www.oznzb.com/profile.Tämä avain antaa kolmannen osapuolen ohjelmille oikeudet lisätä NZB-tiedostoja SABnzbd-ohjelmaan.Tämä avain antaa kolmannen osapuolen ohjelmille täyden pääsyn SABnzbd-ohjelmaan.Tässä kuussaTällä viikollaTämä estää sisällön päivittämisen kun hiiren kursori on jonon päällä.Tämä uudelleenkäynnistää SABnzbdn.
    Käytä sitä kun luulet ohjelman toimivan epävakaasti.
    Lataaminen keskeytyy uudelleenkäynnistyksen ajaksi ja jatkuu ohjelman käynnistyttyä.Tämä lähettää testiviestin sähköpostiosoitteeseesi.KetjuTorstaiAikakatkaistiinAikakatkaistu: Yritä laittaa SSL päälle tai yhdistä toiseen porttiin.Aikaa jäljelläAikakatkaisuOtsikkoTo: %s From: %s Date: %s Subject: SABnzbd raportoi levy täynnä Hei, SABnzbd on lopettanut lataamasta, koska levy on lähes täynnä. Ole hyvä ja tee lisää tilaa ja jatka SABnzbd käsin. TänäänPäälle/Pois Lisää NZBLevytilaa ei ole tarpeeksi, pakotetaan KESKEYTYSLiikaa yhteyksiä palvelimelle %s:%sLiikaa yhteyksiä, keskeytä lataaminen tai yritä myöhemmin uudelleenYlinPäävalikkoYhteensäVianmääritysYritä uudelleenYritä ennustaa latauksen valmistuminen ennen lataamista (hitaampi!)Yritetään SFV tarkistustaYritetään noutaa NZB osoitteesta %sYritettiin asettaa tila ei olemassa olevalle palvelimelle %sYritetään purkaa rar arkistoa salasanalla "%s"TiistaiHienosäätöTyyppiUTUNT polku "%s" ei ole sallittuOsoitteen nouto epäonnistui; %sKÄYTÄ OMALLA VASTUULLA!Poista kirjanmerkki latauksen valmistuessaKäyttö estetty, tarkista newzbin käyttäjänimi/salasanaPoista estoTuntematon virhe dekoodattaessa %sTuntematon toiminto: %sPuraPurettiin %s tiedostoa/kansiota kohteeseen %sPuretaanPurkaminen epäonnistui, %sPurkaminen epäonnistui, CRC virhePurkaminen epäonnistui, odotettua tiedostoa ei purettuPurkaminen epäonnistui, arkisto vaatii salasananPurkaminen epäonnistui, polku on liian pitkäPurkaminen epäonnistui, katso lokiPurkaminen epäonnistui, nämä tiedostot puuttuvat:Purkaminen epäonnistui, %s ei löydyPurkaminen epäonnistui, kirjoitusvirhe tai levy täynnä?NZB tiedostoa ei voida käyttääKäyttökelvoton RAR arkistoYlösPäivitys saatavilla!LähetäLähetä: .nzb .rar .zip .gzKäynnissäoloaikaKäytä 12-tuntista kelloa (AM/PM)Käytä V23 ellei tarjoajasi vaadi toisin!Käyttää väliaikaisia nimiä kun jälkikäsittely on käynnissä. Poista käytöstä jos järjestelmäsi ei toimi oikein asetuksen ollessa päällä.Käytä "Ryhmien / Indeksoijan tunnisteet" -saraketta ryhmien ja tunnisteiden määrittämiseksi kategorioillesi.
    Jokerimerkkejä saa käyttää. Käytä pilkkuja termien erottelemiseen.Käytetään ennen NZB lisäämistä jonoon.Käytetty välimuistiKäytetään kun mitään jälkikäsittelyä ei ole määriteltynä kategorialle.Käytetään kun mitään prioriteettiä ei ole määritettynä kategorialle.Käytetään kun mitään käyttäjän skriptiä ei ole määritettynä kategorialle.KäyttäjähakemistotKäyttäjän määrittämät kategoriatKäyttäjänimiArvotTarkastus käyttäen SFV tapauksia oli onnistunutVarmennetaanVarmennetaan...VersioVideoNäytä skriptien lokiNäytä skriptin tulosteVirus/roskapostiOdota %s sekunttiaVAROITUS:VAROITUS: Keskeytettiin työ "%s" salatun RAR arkiston vuoksiVAROITUS: Keskeytetty työ "%s" salatun RAR tiedoston vuoksiVAROITUKSETOdotetaanVaroitusVaroitus: LOCALHOST on hämärä, käytä numeerista IP-osoitetta.VaroituksetVahdittu kansioVahditun kansion tarkistusväliWeb-käyttöliittymäWeb-palvelimen todennusKeskiviikkoTarkistaa viikottain uusimman SABnzbd version.MilloinJos artikkelissa on CRC virhe, yritetään hakea se toiselta palvelimelta.Keskeytetään työ, jos latauksen yhteydessä huomataan liikaa dataa puuttuvanKuka näytetään viestin lähettäjänä?WikiXVuosiVuosittaiset-Kuukausittaiset kansiotSinulla ei ole maksettua aikaa Newzbin tililläsiSinulla ei ole käyttöoikeuksia porttiin %sOta JavaScript käyttöön, jotta Plush toimii oikein!Tarvitset nzbmatrix VIP-tilin käyttääksesi API:aKäyttämäsi UNRAR versio ei ole suositeltu, nouda oikea osoitteesta http://www.rarlab.com/rar_add.htm
    [%s] Virhe "%s" yhdistettäessä tiedostoja[%s] Virhe "%s" purettaessa RAR tiedostoja[%s] Liitetty %s tiedostoa[%s] Ei par2 arkistoja[%s] PAR2 vastaanotti vääränlaiset asetukset, tarkista Asetukset->Muuttujat[%s] Pikatarkistus OK[%s] Korjattiin ajassa %s[%s] Varmennettiin ajassa %s, kaikki tiedostot kelvollisia[%s] Varmennetiin ajassa %s, vaatii korjauksen_yenc moduulia... EI löydy!kirjainkokoa säätävätyhjennäpvpäiväpäivääpoista palvelin käytöstäota palvelin käyttöönnoudetaan viesti-id %s osoitteesta www.newzbin2.estiedostokansiottuntituntiajäljellämkäsikäyttöinenminuuttimin.minuuttiaei asennettu/ei käytössäkäytössätaisivupar2 ohjelmaa... EI löydy!pyopenssl moduuli puuttuu, ole hyvä ja asenna se https käyttöä vartensekuntisekuntiakatso lokitiedostotekstituntematonunrar ohjelmaa... EI löydy!unzip ohjelmaa... EI löydy!viikkoSABnzbd-0.7.20/locale/fr/LC_MESSAGES/SABnzbd.mo0000644000000000000000000024231012433712600020500 0ustar00usergroup00000000000000, <@o=@@dA#CD D2E1G%HI*&I'QIyIII IIIJ 6JAJHJ`JsJKK!K)K1K9KLK`KsK?K8LLLLRL[*MM#MMM$MNN N +N8N:?N'zN'NNNNNNO O O&O 8OBOXOalOOOOO.OP1P)QP*{P P PPPP/PhQ QQQ)R(sGrssGtttuEu duouu&v,8vevwv%v#vvvw 'w3w kw /3MS Wacq"ՂA,T3܃!!6"X{̈́ӄ   '3 <*J0u  ʅ Ѕ(څ -@Uhz цކMI#dRۇ< 5CH"gو!7-?mr{' ʼn҉ -6<Qf x  ̊؊ . KX_n} ËNj݋  !0&Ls {? ȍՍ܍  # =K4^2  *>[)vM0 &0 9EK [em͐Ӑ !6 IV gtÑ. ,8Tos| #˒  "0 H4i  Jϓ33N.)͔(7 >(_$˕ "&=dlo)9Yy3͗֗  + ; HS9b "Ә  ' BOT-Y( /͙/---[&&$ך$3!3U11 18@ F R ] hu  ŜΜ Ӝߜ- 2<A [f x"Ors2AN>=, j uWס,| >â ͣӣ"$A*lpy  Eܤ.?_gnsu ˥2'GZa 3-"A,[#.ۧ(/JQ0kb$ 814' \i% Ϊ֪ܪ 7EW6ԫݫ:(1@ Zh %@R!Kmrty*$1ܭ0Z?#)JZn&'ѯ  &(OT[]bhmovz 9 7RWNk^u<t2M>+U-!ѽ +'=%e ̾ ӿ[hen4v&,'.=PHW*207?O bn% iaej?%/-@n A(T/m)3 ""Be$tn-9-"&3I"}",2V#@z--+' S _Bj= - &:da hYoS .+ZFa  $  *!8%Z. /;S lz |   $:+Y !8+97e49 *)zT G;PC/!3C6z9E=KM "?!RaB '!Iiz   !#* Nos{C  '=Mj=& (@ S a&o 1Lb t 5,,W x7EV43^ l , = J4W%504MN;32o"C; #E8i('#-*LX#  !(Je$#)/90+j@2" 5-#c.r$)FNL6)8b'/ %.3;S-qD+->6l*719A^@yB NO`g{ $ /?"Sv  -2Nb #6 @0JU{A  (=A4I~7SZ#Nr\ =+=6V'  '6A,x!(>/ K;l:k"X{N;@%fu5|&X1Y1GO&$Lq ,  ( /A=6  ";Ld m &#"'Fn*@Ueh531eu{? -];  m52'e6d   <     2; 7n ! 1     8 > N ] m       G F e      =    ) > T i }       U0^8l5>H !&+&FVp) <  !,<ix  '2At &1(AZ ,!NPTt %=.Q F  *8 @ J*X$H% .G:<. -8<ffI T ] ht"  #  #= Q\ q#  )I]p&$ )$"GKT [g - !7>FU,nH l%KT:3 n 3 %   !3!-K!y!!/!!!""32"6f"""~"$9#3^### # #P# M$[$p$$$ $$$$$%A+% m% x%"%%% %%%>%=&N&U&E\&4&&&&>&>;'<z'<''''(%D(%j(<(<(: ):E)) )))))))))**0*E*W*^*g*p*y************ + +&+ :+H+]+(o++.Y,<,!-@-Z(..8/]R/R/Q0U0 ]0[k00/u1 111L1 2"262<2 3&3"B3#e3_3334 4 &4Q144(4(4&45 5$5)5*+5 V5%d5%5,5B5 6'+6S6h6/w666'6K6AJ7,7,72758NO888888 99.9$F9@k999:8: ;6;:S;7;;;;<4 <B<Y<j<r<y<< <<<J<h(=G== = =I>K>Z>p> >>>N>?? ?{L?.????@(@C@@c@>@{@7_A;AAAY BgBB5B5BCC-C6C8C=CCCZC,mCCCCCCCCCCCC CCCCCCC:DQDUD^DvD|DDDD SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccessAccess deniedAccount infoActionAction when an unwanted extension is detected in RAR filesAction when encrypted RAR is downloadedAction when unwanted extension detectedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAudioAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatic FeedbackAutomatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)CancelCannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.CommentComplete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable OZnzb IntegrationEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enhanced functionality including ratings and extra status information is available when connected to OZnzb indexer.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you do not have an account it can be created at If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesIndexingInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOZnzbOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOtherOther MessagesOther SwitchesOther problemOut of retentionPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!Refer to https://www.oznzb.com/profileRefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.ReportReport-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSendSend GroupSend RSS notificationsSend automatically calculated validation results for downloads to indexer.Send email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...Site API KeySizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key provides identity to indexer. Refer to https://www.oznzb.com/profile.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereUNWANTEDURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUnwanted extensionsUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVideoView Script LogView script outputVirus/spamWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: In "%s" unwanted extension in RAR file. Unwanted file is %s WARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2014-06-10 17:11+0000 Last-Translator: Fox Ace Language-Team: French MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:53+0000 X-Generator: Launchpad (build 17082) SABnzbd ne peut pas trouver ses fichiers %s dans l'interface web .
    S'il vous plaît installer le programme.

    SABnzbd a détecté une file d'attente et un historique d'une version ancienne (0.4.x).

    La file d'attente et l'historique seront ignorés et peuvent aussi être perdus!

    Vous pouvez choisir d'arrêter SABnzbd et de finir la file d'attente avec l'ancien programme.

    Cliquez sur OK pour ouvrir SABnzbd SABnzbd a détecté des données sauvegardées avec une autre version de SABnzbd
    il ne peut pas réutiliser les données de l'autre programme.

    Vous devez terminer votre première file d'attente avec l'autre programme.

    Après cela, lancer ce programme avec l'option "--clean".
    Cette opération efface la file d'attente actuelle et l'historique!
    SABnzbd lis le fichier "%s". SABnzbd a détecté que le fichier sqlite3.dll est manquant.

    Certains antivirus mal conçu peuvent supprimer ce fichier.
    S'il vous plaît vérifier votre antivirus, essayez de ré-installer SABnzbd et plaignez vous à l'éditeur de l'antivirus.

    SABnzbd n'est pas compatible avec certains pare-feu logiciels.
    %s
    Désolé, mais nous ne pouvons pas résoudre cette incompatibilité pour le moment.
    S'il vous plaît faite une demande à l'éditeur de votre pare-feu.

    SABnzbd a besoin d'un port tcp/ip libre pour le serveur Web interne.
    Port %s à %s a été essayé, mais il n'est pas disponible.
    Un autres logiciels utilise ce port ou SABnzbd est déjà en cours d'exécution.

    S'il vous plaît redémarrer SABnzbd avec un numéro de port différent. SABnzbd a besoin d'un port tcp/ip libre pour le serveur Web interne.
    Port %s a %s a été essayé , mais le compte utilisé pour SABnzbd n'a pas la permission de l'utiliser.
    Sur les systèmes OSX et Linux, les utilisateurs normaux doivent utiliser des ports supérieurs à 1023.

    S'il vous plaît redémarrer SABnzbd avec un numéro de port différent. SABnzbd a besoin d'une adresse hôte valide pour son serveur Web interne.
    Vous avez spécifié une adresse non valide.
    sont des valeurs sûres localhost et 0.0.0.0

    S'il vous plaît redémarrer SABnzbd avec une adresse hôte approprié. SABnzbd est fourni sans AUCUNE GARANTIE. Ce logiciel est gratuit, et vous êtes invité à le redistribuer sous certaines conditions. Il est distribué sous licence GNU GENERAL PUBLIC LICENSE Version 2 ou toute autre version ultérieure. %s -> Encodage inconnu%s => absents de tous les serveurs, rejeté%s articles ne correspondaient pas a la copie%s articles ont été mal formés%s articles sont manquants%s articles ont été retirés%s dossier : %s Erreur d'accès%s fichiers en %s%s n'est pas une valeur octale correcte%s n'est pas une adresse email valide%s manquants  Résoudre l'adresse ou Report ID 
    Extinction de SABnzbd terminée.
    Veuillez attendre plus de 5 secondes et cliquer sur le bouton ci-dessous.

    Rafraîchir
    + Debug+ Info+Supprimer+Réparer+DécompresserDossier de sauvegarde NZB1x05 Dossier Épisode1x05 Dossier SaisonNOTE: Les dossiers seront créés automatiquement lors de l'enregistrement. Il est possible d'utiliser des chemins absolus.Les données ne seront pas déplacées. Requiert un redémarrage de SABnzbd !Lire RSS obtient le contenu du flux en cours. Forcer téléchargements pour télécharger de suite tous les NZB correspondants.ÂGEClé APIClé API code QRClé API incorrecte, utilisez la clé API de la configuration générale dans votre application tierce :Clé API manquante, entrez la clé API de la configuration générale dans votre application tierce :AnnulerInterrompre les tâches qui ne peuvent être remplisInterrompu, ne peut pas être achevéeInterrompu, cryptage détectéAbandonné, extension indésirable détectéAccepterAccèsAccès refuséinformation compteActionAction si une extension indésirable est détecté dans les fichiers RARAction quand RAR crypté est téléchargéAction si une extension indésirable est détectéActionsChoisissez un thème pour la 2nde interface web.AjouterAjouter un fluxAjouter un fichierAjouter NZBAjouter planificationAjouter un serveurAjouter de nouveaux téléchargementsNZB ajoutéDossier administrateurCatégories affectéesAprès que SABnzbd a terminé de redémarrer, vous serez en mesure d'y accéder à l'adresse suivante: %sAgeTousVersions de test égalementToujoursApplique tentatives maximums uniquement aux serveurs optionnelsAppliquer à la sélectionEtes-vous sûr de vouloir supprimer ?Êtes-vous sûr de vouloir redémarrer SABnzbd?Etes-vous sûrs de vouloir arrêter SABnzbd ?Êtes-vous sûr ?ArgumentsLimite d'article en cacheIdentifiant de l'articleAudioEchec d'authentification, vérifiez les identifiant/mot de passe.Authentification manquante, entrez vos identifiant/mot de passe dans la configuration générale dans votre application tierce :Continuation autoTéléchargement automatique des favorisAuto-pause lorsque l'espace libre est en-dessous de cette valeur.
    En octets, peut être suivi de O,M,G,T. Par exemple : "800M" ou "8G"Commentaires automatiqueTélécharger automatiquement les marque-pages.Télécharge automatiquement les favoris.Trie automatiquement les fichiers par âge (moyen).BRetourSecoursServeur de soutienMauvaise planification %s à %s:%sArticle yEnc mal construit dans %sBande passanteBloquer Rafraîchissements Au SurvolTraitement des favorisDernierErreur CRC dans %s (%s -> %s)Permet de mettre en cache les articles pour réduire les accès disques.
    En Octets, peut être suivi de K,M,G.Par exemple : "64M" ou "128M"%s Articles en cache (%s)AnnulerImpossible de changer les permissions pour %sImpossible de se connecter au registre HKEY_CURRENT_USER.Impossible de se connecter au serveur %s [%s]Impossible de créer %s dossier %sImpossible de créer le fichier de sauvegarde de %sImpossible de créer le dossier %sImpossible de créer le dossier %sNe peut créer le fichier temporaire pour %sImpossible de trouver les modèles d'email dans %sImpossible de trouver le template de l'interface web: %s, essayer le template standardImpossible de lancer le navigateur web, probablement pas trouvéImpossible d'ouvrir la clé de registre "%s".Ne peut lire %sImpossible de lire le dossier a surveillé %sImpossible d'écrire dans le fichier INI %sCatégoriesCatégorieLes modifications n'ont pas été enregistrées et seront perdues.Les modifications nécessiteront un redémarrage de SABnzbd !Vérifiez avant de téléchargerVérifier la présence d'une nouvelle versionVérifier le résultat de l'extractionVérifie le résultat de l'extraction (doit être désactivée pour certains systèmes de fichiers).VérificationIntervalle de vérificationIntervalle de vérification (en minutes, au moins 15). Non actif lorsque vous utilisez le Planificateur!Choisissez un thème.Liste de nettoyageÉchec du nettoyage de %s.Supprime les fichiers Par2 (uniquement si la vérification/réparation a réussie).EffacerEffacer compteursCliquer ci-dessous pour tester.Cliquez pour tester les informations entrées.FermerFermer la fenêtre/onglet de votre navigateur NE QUITTERA PAS SABnzbd.CommentaireDossier CompletDossier completTerminésDossier de téléchargement terminéConfigurationFichier de configurationConfigurationConfirmer Suppressions HistoriqueConfirmer Suppressions File d'attenteÉchec de la connexion à %s@%s:%s, message=%sConnexion réussie !ConnectionsLargeur de L'affichageImpossible de retirer le marque-page newzbin %sImpossible de déterminer le résultat de la connexion (%s)Planifications actuellesPersonnaliséSDUPLIQUÉEQuotidienDossiers QuotidiensTri par dateJour du moisDécadeÉchec du décodage de %sPar défautDossier racine par défautPost-traitement par défautPriorité par défautScript utilisateur par défautDéfinit le post-traitement et le stockage.Suppr.SupprimerSupprimer ToutSupprimer TerminéSupprimer échouésSupprimer le fluxSupprimer après téléchargementSupprimer tous les éléments terminés de l'historique?Supprimer tous les fichiers téléchargés?Supprimer tous les éléments erronés de l'historique?Supprimer tous les éléments de la file d'attente ?Supprimer tous les éléments échoués de l'historique ?Impossible de supprimer %s !Détecter les téléchargements dupliquésDétection des NZB portant le même nom (nécessite l'option de sauvegarde NZB) et des titres en double dans les flux RSS.Désactiver la clé APIDésactivéHTTPS désactivé car le certificat et la clé n'ont pas été trouvésRejeterDéconnecte du serveur(s) Usenet lorsque la file d'attente est vide ou en pause.Déconnexion lorsque la file d'attente est videNotifications de disque dur pleinErreur de disque lors de la création du fichier %sDisque plein! Pause ForcéeFait une vérification supplémentaire basée sur les fichiers SFV.Ne pas téléchargerVous n'avez pas d'authentification valide pour ce flux %sLa clé API ne sera plus nécessaire pour l'interaction avec SABnzbd.Le quota doit se réinitialiser chaque jour, semaine ou mois?Vous n'avez pas de fournisseur usenet? Nous vous recommendons d'essayer %s.DescendreTéléchargerTéléchargement terminéDossier TéléchargementTéléchargement échouéVitesse limite de téléchargementÉchec de téléchargement - Rétention du serveur dépassée ?Le téléchargement pourrait échouer, seulement %s des requis %s sont disponiblesVitesse limite de téléchargement en kilobytes par seconde (kB/s)Vitesse de téléchargementTéléchargéTéléchargé en %s à %sB/s de moyenneTéléchargé jusqu'à présentTéléchargementTéléchargementsVueDuoVVueDuoHPar ex. :Ex: 119 ou 563 pour le SSLEx: 8 ou 20CRYPTÉEERREUR:ERREUR : %sERREUR : échec CRC pour "%s"ERREUR: le chemin trop long (%s)ERREUR : impossible de trouver "%s"ERREUR : erreur d'écriture (%s)TREÉditerÉditer les détails du NZBEmailParamètres du compte emailNotification par email lorsque des téléchargements sont terminésOptions emailAdresse email de réceptionAdresse email d'envoiEmail Envoyé !Dossier des modèles d'emailRésultat de l'Email de testAdresse email à laquelle seront envoyées les notifications.Succès de l'envoi du mailVideFichier NZB %s videEntrée vide de flux RSS trouvée (%s)ActiverActiver le tri par dateActiver assemblageActiver GrowlActiver HTTPSActiver l'accès à SABnzbd via HTTPS.Activer le tri des FilmsUtilisé 'Par2 Multi-processeur'Activer NotifyOSDActiver l'intégration de OZnzbActiver nettoyage ParActiver contrôle rapideActiver les contrôles SFVActiver assemblage TSActiver le tri TVActiver UnrarActiver UnzipActive l'accès à l'interface via une adresse HTTPS.Activer la fonctionnalité unrar intégrée.Activer la fonctionnalité unzip intégrée.Activer les classes de messages qui doivent être communiqués (aucun, un ou plusieurs)Activer le renommage du dossierActiver pour dimininuer l'utilisation de la RAM. Désactiver pour éviter que les téléchargements lents bloquent la file d'attente.Active le tri et le renommage générique des fichiers.Activer si les téléchargement ne sont pas dans leur propre dossier.Active le tri et le renommage des fichiers par date.Active le classement et le renommage des épisodes.ActivéEn terminant le chemin avec une étoile *, ceci évite la création des dossiers de la tâche.Cette fonctionnalité améliorée qui comprend des notes et des informations d'état supplémentaire est disponible lorsque vous êtes connecté à OZnzb indexeur.Saisir une URLNom ÉpisodeNuméro ÉpisodeNom.ÉpisodeNom_ÉpisodeErreur "%s" lors de l'exécution de file_join sur %sErreur "%s" lors la réparation de %sErreur "%s" lors de l'exécution de rar_unpack sur %sErreur "%s" lors de l'exécution de unzip sur %sErreur %s lors de l'exécution de par2_repair sur %sErreur %s: Vous devez fournir un nom d'utilisateur et un mot de passe valide.Erreur d'obtention msgid %s à partir de www.newzbin2.es - S'il vous plaît assurez-vous que votre nom d'utilisateur et mot de passe soient définitErreur lors de la création de la clé et du certificat SSLErreur lors de l'obtention des information TV (%s)Erreur lors de l'importation de %sErreur lors de l'importation du module OpenSSL. Connection sans SSLErreur lors du chargement de %s, fichier corrompu détectéErreur lors de la suppression de %sErreur lors de la suppression du dossier de travail (%s)Erreur lors du renommage de "%s" en "%s"Erreur lors de l'ajout de %s, suppriméErreur lors de l'arrêt du systèmeErreurs-uniquementErreur : Pas d'interface secondaire définie.Erreur : La file d'attente n'est pas vide, impossible de changer le dossier.Erreur : Clé de session incorrecteErreur : Clé de session requiseErreurs/AvertissementsToutExempleQuitter SABnzbdExtensionParamètres PAR2 supplémentairesDécompression en cours...Échec lors d'erreurs CRC yEncÉchouéÉchec de la connexion au serveur %sÉchec lors de la création de (%s)Échec lors du déplacement de %s vers %sÉchec de l'authentification au serveur de mailImpossible de fermer la base de données, voir le journalÉchec de la fermeture de la connexion mailEchec de la compilation de regex pour la recherche du terme : %sÉchec lors de la connexion au serveur de courrielÉchec de la mise en hibernatationEchec lors de l'importation des fichiers %s depuis %sÉchec de l'initialisation %s@%s:%sÉchec de l'initialisation de la connexion TLSÉchec lors du chargement de la file d'attente de post-traitement : Mauvaise version (nécessaire:%s, trouvée:%s)Impossible de déplacer les fichiersÉchec de la lecture des clés de registre pour les dossiers spéciauxÉchec de la suppression du nzo de la file d'attente de post-traitement (id)Impossible de renommer le fichier similaire : %s en %sÉchec du renommage : %s en %sÉchec de la récupération RSS de %s: %sÉchec de l'envoi de l'emailÉchec de la mise en veilleImpossible de démarrer l'interface webÉchec de la mise à jour du travail newzbin %sÉchecÉchec dans tempfile.mkstempErreur fataleFlux RSSFluxChargerRécupération en coursRécupération de %s blocs...Récupération des blocs supplémentaires ...Fichier %s vide, rejetéExtension de fichierFichiers contenant tous les mots de passe des fichiers RAR cryptés.La concaténation du fichiers %s a échouéNom du fichier ou chemin du certificat HTTPS.Nom du fichier ou chemin d'accès de la chaîne HTTPS.Nom du fichier ou chemin de la clé HTTPS.Ensemble de fichiersNom de fichierFiltreFiltre les fichiers échantillons de la file d'attente.FiltresPremierLe dossier "%s" n'existe pasConfiguration des dossiersDossier contenant les scripts utilisés lors du post-traitement.Dossier contenant les modèles d'email définis par l'utilisateur.Dossier à surveiller pour vérifier s'il contient des fichiers .nzb.
    Prends en compte également les nzb contenus dans les fichiers .zip, .rar et .tar.gz.Dossier/CheminRépertoiresSi une authentification pour l'envoi est requise, saisissez votre identifiant.Si une authentification pour l'envoi est requise, saisissez votre mot de passe.ForcerForcer DéconnexionForcer téléchargementsForumLibre (Temp)Espace LibreFréquenceVendrediDe l'aide peut être trouvée sur leGoGénéralConfiguration généraleGénérer une nouvelle cléTri génériqueRécupérer FavorisRécupérer les favoris maintenantRécupérer NZBRécupérer favoris NewzbinAller à SABnzbdAller à l'assistantGroupes/Tags indexeurCertificat HTTPSCertificats Chaîne HTTPSClé HTTPSPort HTTPSSupport HTTPSAideMettre le PC en hibernationMasquer les favorisCacher les options d'éditionMasquer détailsCacher les fichiersHauteHistoriqueHistorique les 10 derniers articlesTaille HistoriqueAccueilPage d'accueilHôteHôte sur lequel SABnzbd doit attendre les connexions.Heure:MinCombien peut-être télécharger ce mois (K/M/G)Je veux que SABnzbd soit accessible à partir de tous les ordinateurs de mon réseau.Je veux que SABnzbd ne soit accessible que depuis mon ordinateur.EN ATTENTEINCOMPLETParamètres 'IONice'IRCInactifSi vide, le port standard écoutera seulement HTTPS.Si vous être membres de newzbin ou nzbmatrix, vous pouvez entrer vos identifiants et mot de passe pour pouvoir utiliser ces services. Si vous n'utilisez pas ces services, vous pouvez passer à l'étape suivante.Si vous n'avez pas un compte, il peut être créé sur Si vous obtenez ce message d'erreur à nouveau, veuillez essayer un nombre différent.
    Si vous avez un compte www.newzbin2.es, vous pouvez entrer vos informations de compte ici.
    Cela débloquera des fonctionnalités supplémentaires.Si vous avez un compte sur www.nzbmatrix.com, vous pouvez entrer vos informations de compte ici.
    Ceci est obligatoire si vous désirez utilisez les flux RSS de ce site.Gestion des échantillons (Samples)Ignorer NZB dupliqué "%s"DansEn cas de «Pause», vous aurez besoin de mettre un mot de passe et de reprendre le travail.Dans DossiersEn minutes (minimum 15 min).Pour pouvoir télécharger sur les newsgroups, il est nécessaire d'avoir un fournisseur usenet. Votre FAI peut vous fournir un accès, cependant un fournisseur usenet premium est recommandé.Flux incompatibleFichier de file d'attente incompatible, impossible à traiterDossier incompletFichier NZB %s incompletSéquence incomplète de fichiers pouvant être jointsDescription du flux RSS incorrecte "%s"Paramètre incorrectValeur incorrecte pour %s: %sMot de passe incorrect %sSites IndexIndexationInitialisation du redémarrage...
    Fichier NZB invalide %s, rejeté (raison=%s, ligne=%s)Codage non valide pour le modèle d'email %sIdentification NZBMatrix invalideNuméro de rapport nzbmatrix invalide %sFichiers par2 non valides, impossible de vérifier ou réparerAdresse du serveur erronéeDétails sur le serveur invalideÉtape de journalisation invalide dans l'historique pour %sInverserIl est probable que vous utilisez ZoneAlarm sur Vista.
    Il est recommandé de mettre un marque-page sur cette adresse pour la retrouver facilement ultérieurement.%s a été remis en file d'attenteTâche terminéLes éléments marqués avec '*' ne seront pas automatiquement téléchargés.ConcaténationAssemble les fichiers .001, .002, etc. en un seul fichier.Assemble les fichiers .001.ts, .002.ts, etc. en un seul fichier.Concaténationkbit/sGarder les téléchargements perdus dans des dossiersLangueDernierAvertissements RécentsLancer le navigateur web au démarrageLancer mon navigateur internet avec l'adresse de SABnzbd au démarrage de l'application.Lance le navigateur web au démarrage de SABnzbd.RestantVitesse limiteLiensListe des extensions de fichiers qui doivent être supprimés après téléchargement
    Par exemple: .nfo ou .nfo, .sfvChargement %s echouéSituation de la file d'attente et de la base de données historique.
    Ne peut être changé que lorsque la file d'attente est vide.Emplacement des fichiers journaux de SABnzbd.
    Redémarrage requis !Pour le stockage des téléchargements terminés et post-traités.
    Peut être outrepassé par les catégories définies par l'utilisateur.Pour le stockage des téléchargements en cours, non post-traités.
    Ne peut être modifié que lorsque la file d'attente est vide.Pour la sauvegarde des fichier .nzb.Dossier du fichier journalJournalisationBasseMinusculeMoLe paquet principal n'a pas été trouvé...CorrespondVitesse MaxiNombre maximal de tentatives par serveurTentatives maximumSignificationEspace disque minimum pour le Dossier téléchargement temporaireDiversClé de session manquanteArticles manquantsLe fichier attendu est manquant : %s => erreur unrar ?LundiMoisPlusNom FilmNom.FilmNom_FilmDéplacementDéplacement en cours...Multi-OperationsÉtiquette Multi-partieClé NZBNZB ajouté à la file d'attenteNomAppellationJamaisURL Nouveau FluxUne nouvelle version %s est disponibleNouvelle version disponibleMot de passe NewzbinIdentifiant NewzbinErreur Newzbin non documentée (%s)Erreur Newzbin non documentée (%s, %s)Rapport Newzbin %s non trouvéLe serveur Newzbin a changé son protocoleImpossible d'obtenir les informations pour %s du serveur NewzbinSuiv.Paramètres 'Nice'Le binaire PAR2 n'a pas été trouvé, les réparations ne seront pas possibles
    Le binaire UNRAR n'a pas été trouvé, la décompression des fichiers RAR ne sera pas possible
    Aucun modèle email trouvésPas De DossiersPas de post-traitement car la vérification a echouéAucun destinataire déterminé, aucun email envoyéAucun résultatAucunNormaleNe correspond pasEspace disque insuffisant pour terminer les téléchargements !Ne correspond pasCentre de notificationNotification envoyée!Classes de notificationNotificationsNombre de secondes entre chaque scan du dossier pour vérifier la présence de fichiers .nzb.NzbMatrix clé APIIdentifiant NzbMatrixOKMot de passe (facultatif)Identifiant (facultatif)OZnzbDésactivéUne fois terminéEn fin de file d'attenteQuel jour du mois ou de la semaine (1=lundi) votre fournisseur réinitialise le quota? (Optionnel avec hh:mm)Uniquement les articles en tête de file d'attenteUniquement pour les serveurs optionnelsLimite le post-traitement aux téléchargements qui ont passés avec succès les vérifications par2.Utiliser seulement pour Growl à distance (hôte:port)Ouvrir URL Info.Ouvrir URL SourceOuvrez une fenêtre de Terminal et tapez la ligne (exemple):Ouvrir le dossier terminéOptionnelOption supplémentaire NZBMot de passe pour l'authentification (facultatif).Nom d'utilisateur pour l'authentification (facultatif).Mot de passe optionnel pour GrowlVous pouvez également indiquer un nom de fichierOptionsOrdreNom De Fichier OriginalNom du dossier OriginalAutreAutres messagesAutres optionsAutre problèmeEn dehors de la rétentionEN PAUSEPageParamètresNuméro PartieMot de passeFichier de mot de passeMot de passe masqués en ******, s'il vous plaît veuillez le ressaisirProtection de l'interface de SABnzbd par un mot de passe (recommandé)Protégé par un mot de passeChemin d'accèsModèleModel de cléPauseSuspendre toutMettre en pause les téléchargements lors du post-traitementIntervalle pausePause dePause pour 1 heurePause pour 12 heuresPause pour 15 minutesPause pour 24 heuresPause pour 3 heuresPause pour 30 minutesPause pour 5 minutesPause pour 6 heuresPause pour combien de minutes?Pause pour...Pause post-traitementEn pauseMet en pause les téléchargements lors des post-traitements et les reprends ensuite.Mise en pause de "%s" en raison de NZB dupliquéPermissions pour le dossier de téléchargement terminéS'il vous plaît soyez conscient que l'Hôte 0.0.0.0 aura besoin d'une adresse IPv6 pour les accès externesEntrez un numéro.Entrez les informations de votre fournisseur principal usenet.Options PlushPortPort que SABnzbd doit surveiller.Échec du post-traitement pour %s (%s)Post-traitementNe post-traiter que les fichiers vérifiésDossier des scripts de post-traitementPost-traitementPost-traitement démarréPost-traitement interrompu (%s)Script utilisateur de pré-file d'attentePrédéfinisAppuyez sur la touche Drapeau+R et tapez la ligne (exemple):Préc.PrécédentPrioritéPartage de compte probableProblème d'accès au serveur nzbmatrix (%s)Problème avecFavoris traitésRésultat traitéTraitement en coursOptions de traitementLe Programme ne démarre pas!AvancementViderVider les NZB terminésPurger Historique erronésVider les NZB avec erreurVider les NZB avec erreur & Supprimer les fichiersVider l'historiqueVider les NZBVider les NZB & Supprimer les fichiersVider file d'attenteVider l'Historique ?Vider la file d'attente?Version de PythonCode QRFile d'attenteMettre en file d'attente les 10 premiers articlesIntervalle de rafraîchissement automatique de la file d'attente:Réparation File D'AttenteMis en file d'attenteVérification rapide...Contrôle RapideQuitterQuotaQuota restantQuota périodeQuota atteint, téléchargement mis en pauseRRSSInvervalle de vérification RSSConfiguration RSSLe Flux RSS %s était vide%s exécutéPlageOptions rarement utilisé. Pour leur sens et leur explication, cliquez sur le bouton Aide pour accéder à la page Wiki.
    Ne pas modifier celles-ci sans vérifier en premier le wiki, certaines ont de graves effets secondaires.
    Les valeurs par défaut sont indiquées entre parenthèses.Lire tous les Flux MaintenantLire RSSLire les flux RSSConsultez le Wiki pour plus d'info à ce sujet (en anglais) !Reportez-vous à https://www.oznzb.com/profileRafraîchirFréquence de rafraîchissementIntervalle de rafraichissement dans l'interface web (en sec, 0=aucun).Taux de rafraîchissementRejeterDossiers relatifs àRestant/TotalRestantSupprimerSupprimer NZBSupprimer les NZB & Supprimer les fichiersSupprimer le ServeurRetirer les tâches qui ont échouéRetire de la liste des favoris lorsque le téléchargement est terminé.Échec de la suppression de %sRenommerRéparationÉchec de la réparation, blocs de réparation insuffisants (manque %s)Réparation en coursÉchec de la réparation, %sRéparation en cours...Remplacer les caractères illégaux dans les noms de dossierRemplacer les espaces dans les noms de dossierRemplacer les points dans les noms de dossierRemplace les points par des espaces dans les noms de dossierRemplace les caractères illégaux dans les noms de dossier par des équivalents (sinon les supprime).Remplace les espaces par des underscores ( _ ) dans les noms de dossiers.SignalerRapport-idObligatoireObligatoireCatRéinitialiserRéinitialisation Quota maintenantJour de RAZRedémarrerRedémarrer sans se connecterRedémarrage de SABnzbd en cours...RésultatReprendreReprendre post-traitementTemps de rétentionRéessayerExécution de scriptExécution de script en cours...Exécution du script utilisateur %sS01E05 Dossier ÉpisodeS01E05 Dossier SaisonSABnzbd %s démarréHôte SABnzbdMot de passe SABnzbdPort SABnzbdSABnzbd Assistant ConfigurationIdentifiant SABnzbdVersion de SABnzbdServeur web SABnzbdSABnzbd a détecté une erreur fatale:Arrêt terminé de SABnzbdSABnzbd s'exécute en arrière plan.Serveur SMTPEchec de la commande SQL, voir le journalEchec du commit SQL, voir le journalSSLType SSLSamediEnregistrerEnregistrer les modificationsEnregistréEnregistrement %s echouéEnregistrement..Analyser le dossier des NzbsPlanification pour un serveur non existant %sPlanificationConfiguration de la planificationScriptScriptsNuméro SaisonInterface Web secondaireSéléction de la langue de l'interface web.Cochez uniquement si votre fournisseur usenet permet les connexions SSL.SélectionEnvoyéEnvoyer 'Group'Envoyer les notifications RSSEnvoyer les résultats de la validation calculées automatiquement pour les téléchargements à l'indexeur.Envoie un email quand un flux RSS ajoute un fichier dans la file d'attente.Envoie un email lorsque le disque dur est plein et que SABnzbd a été mis en pause.Envoyer la commande 'group' avant la demande des articles.Envoie une notification GrowlEnvoyer des notifications au centre de notificationEnvoie les notifications à NotifyOSD%s mis en file d'attenteTri des sériesServeurLe serveur %s requiert des identifiant/mot de passeLe serveur %s sera ignoré pendant %s minutesDétails du serveurAdresse du serveurL' adresse du serveur "%s:%s" n'est pas valide.Adresse du serveur requisConfiguration du ServeurDéfinition du ServeurMot de passe du serveurServeur arrêté pendant la séquence de connexion.Le serveur requiert un identifiant et un mot de passe.ServeursIntervalle de pauseAffecter les permissions au dossier de téléchargement terminé.
    En notation octale. Par exemple : "755" ou "777"Entrez ici votre clé API NzbMatrix.Entrez le serveur de courrier sortant de votre FAI.Entrez votre mot de passe ici.Entrez votre identifiant ici.ParamètresLa configuration est terminée !Le téléchargement peut t-il reprendre après que le quota soit réinitialisé?Afficher ToutAfficher les favorisAfficher les options d'éditionAfficher les ErreursAfficher le journalNom SérieDossier Nom SérieAfficher les weblogsAfficher détailsAfficher les fichiersAfficher l’interfaceAffiche l'heure au format AM/PM (n'affecte pas la planification).Nom.SérieNom_SérieAffiche %s de %s sur %s résultatsAffichage d'un seul résultatArrêterÉteindre PCArrêter SABnzbdArrêt en cours...Signal %s intercepté, enregistrement et fermeture en cours...Clé API du siteTaillePasserNe pas vérifier avec par2 si tous les fichiers sont valides à 100%.Certains fichiers n'ont pas pu être vérifiés "%s"TrierChaîne de trieTrier par âgeTrier par Age (Plus récent→Moins récent)Trier par Age (Moins récent→Plus récent)Trier par Age Plus récent→Moins récentTrier par Age Moins récent→Plus récentTrier par Nom (A→Z)Trier par Nom (Z→A)Trier par Nom A→ZTrier par Nom Z→ATrier par Taille (Plus grand→Plus petit)Trier par Taille (Plus petit→Plus grand)Trier par Taille Plus grand→Plus petitTrier par Taille Plus petit→Plus grandTrier par âgeTrier par nomTrier par tailleTriageConfiguration du triSourceSpécialVitesseVitesse limiteLimite de vitesseMettre le PC en veilleDémarrer l'AssistantRéparation en coursDémarrage/ArrêtStatutÉtape 5Étape 4Étape 1Étape 3Étape 2ArrêtArrêt en cours...StockageSujetDimancheSwitchesConfiguration des optionsSysloadDossiers systèmeTEXTETROP GRANDETâcheDossier de téléchargement temporaireEmail de TestTest de NotificationTester le ServeurTest des détails du serveur en cours...Ceci redémarre SABnzbd et fait une complète reconstruction
    de la file d'attente, tout en conservant les fichiers déjà téléchargés.
    Ceci modifiera l'ordre de la file d'attente.L'outil de téléchargement usenet tout inclusLa case à cocher à coté du nom du flux doit être cochée pour que le flux soit activé et qu'il soit pris en compte dans la vérification des nouveaux téléchargements.
    Quant un flux est ajouté, seuls les nouveaux téléchargements seront pris en compte à moins de cliquer sur "Forcer téléchargements".Le nom d'hôte n'est pas défini.Le nombre de connexions autorisées par votre fournisseur usenetPas de connexions configurées. Veuillez s'il vous plaît définir au moins une connexion.Il y a des dossiers orphelins dans le répertoire de téléchargement.
    Vous pouvez choisir de les supprimer (y compris les fichiers) ou de les renvoyer dans la file d'attente.Ce champ est obligatoire.Cette clé fournit l'identité de l'indexeur. Reportez-vous à https://www.oznzb.com/profile.Cette clé permettra aux programmes tierces de pouvoir ajouter des NZB à SABnzbd.Cette clé permettra aux programmes tierces d'avoir un accès complet à SABnzbd.Ce moisCette semainePermet d'éviter le rafraîchisssment du contenu quand la souris survole la file d'attente.Ceci redémarrera SABnzbd.
    Utilisez cette fonction si vous pensez avoir un problème de stabilité.
    Les téléchargements en cours seront mis en pause puis repris.Ceci enverra un email de test sur votre compte.TraitementJeudiDélai dépasséDélai dépassé : Essayez d'activer la connexion SSL ou un port différent.Temps RestantDélai d'expirationTitrePour: %s De: %s Date: %s Sujet: SABnzbd rapporte Disque Plein Salut, SABnzbd a arrêté le téléchargement, car le disque est presque plein. S'il vous plaît faite de la place avant de reprendre SABnzbd manuellement. Aujourd'huiAfficher / Cacher Ajout NZBEspace disque faible PAUSE forcéeTrop de connexions au serveur %s:%sTrop de connexions, s'il vous plaît mettez en pause les téléchargements ou essayez plus tardPremierAfficher/Masquer menuTotalRésoudre les problèmesRéessayerTente de prédire l’achèvement complet avant le téléchargement réel (lent!)Essai vérification SFVEssai de récupération du NZB depuis %sEssaie de définir l'état du serveur %sEssaie unrar avec le mot de passe "%s"MardiRéglagesTypeDLe chemin UNC "%s" n'est pas autorisé iciINDÉSIRABLESÉchec de récupération de l'URL; %sA utiliser à vos risques et périls!Retirer le favori s'il a été téléchargéNon autorisé, vérifiez vos identifiant/mot de passe pour newzbinDébloquerErreur inconnue lors du décodage de %sAction inconnue : %sDécompression%s fichier(s)/dossier(s) décompressé(s) en %sDécompressionÉchec de la décompression, %sÉchec de la décompression, erreur CRCÉchec de la décompression, un fichier attendu n'a pas été décompresséÉchec de la décompression, l'archive nécessite un mot de passeExtraction échoué, le chemin est trop longÉchec de la décompression, voir le journalExtraction échoué, ces fichiers sont manquants :Échec de la décompression, %s n'a pas été trouvéÉchec de la décompression, erreur d'écriture ou espace disque insuffisant ?Fichier NZB inutilisableFichier RAR inutilisableExtensions indésirablesMonterMise à Jour Disponible!EnvoyerEnvoyer : .nzb .rar .zip .gzTemps de fonctionnementUtiliser l'horloge 12 heures (AM/PM)Utiliser V23 à moins que votre fournisseur exige un autre type!Utilise des noms de répertoires temporaires au cours du post-traitement. Désactiver lorsque votre système ne gère pas cela correctement.Utilisez les colonnes "Groupes/Tags indexeur" pour classer les groupes et les tags de vos catégories.
    Utilisez des virgules pour séparer les termes.Employé avant qu'un NZB n'entre dans la file d'attente.Cache utiliséUtilisé quand la catégorie ne précise pas de choix.Utilisé quand la catégorie ne précise pas de priorité.Utilisé quand la catégorie ne précise pas de script.Dossiers utilisateurCatégories utilisateurNom d'utilisateurValeursVérifié avec succès en utilisant des fichiers SFVVérification en coursVérification...VersionVidéoAfficher journal des ScriptsVoir le résultat du scriptVirus/spamPATIENTER %s secAVERTISSEMENT:AVERTISSEMENT: Tâches "%s" interrompus en raison de fichiers RAR cryptésAVERTISSEMENT : Le fichier RAR"%s" contient une extension indésirables. Le fichier indésirable est %s AVERTISSEMENT: Mise en pause de "%s" en raison de fichiers RAR cryptésAVERTISSEMENTSEn attenteAvertissementAvertissement: LOCALHOST est ambigü, utilisez une adresse IP numérique.AvertissementsDossier à surveillerIntervalle de scanInterface WebAuthentification Serveur WebMercrediVérifie hebdomadairement la disponibilité d'une nouvelle version de SABnzbd.QuandUtilise les serveurs de soutien si il y a des erreurs CRC yEnc.Lorsque pendant le téléchargement il apparaît clairement que les données trop grande fasse défaut, annuler le travail.Adresse email de provenance des notifications.WikiXAnnéeDossiers Année-MoisPas de crédits sur votre compte NewzbinLe port %s n'est pas accessibleVous devez activer JavaScript pour que Plush puisse fonctionner!Vous avez besoin d'un compte VIP NZBMatrix pour utiliser l'APILa version de votre binaire UNRAR n'est pas recommandée, Vous pouvez l'obtenir ici http://www.rarlab.com/rar_add.htm
    [%s] Erreur "%s" lors de la concaténation des fichiers[%s] Erreur "%s" lors de la décompression des fichiers RAR[%s] Concaténation %s fichiers[%s] Pas de fichiers par2[%s] PAR2 a des options incorrectes, vérifiez votre configuration-> Paramètres Switches[%s] Contrôle Rapide OK[%s] Réparé en %s[%s] Vérifié en %s, tous les fichiers sont corrects[%s] Vérifié en %s, une réparation est nécessairemodule _yenc... Introuvable!Lettre Capitaleéffacerjjourjoursdésactiver le serveuractiver le serveurRécupération msgid %s from www.newzbin2.esfichierdossierhheureheuresrestantmmanuelminmin.minsnon installédenonouioupagebinaire par2... Introuvable!module pyopenssl manquant, nécessaire pour l'accès HTTPSsecsecondesvoir le fichier journaltexteinconnubinaire unrar... Introuvable!binaire unzip... Introuvable!semaineSABnzbd-0.7.20/locale/nb/LC_MESSAGES/SABnzbd.mo0000644000000000000000000022004312433712600020467 0ustar00usergroup00000000000000l=om==d>S@MA !B2.CaDUE?F*VF'FFFF FG&GFG fGqGxGGGBHJHQHYHaHiH|HHH?(IhIIIIRJ[ZJJ#JJJK!K (K 6KCK'JKrKzKKKKK K KK KKLaLvLzL~LL.LLL)L*#M NM \MfMzM/MhM &N2NGN(N0N*%OPOROWO ^OlOO OOOOOOPP2P P Q &QGQbQQ!Q6Q-Q&RERTRrR RR.R'RRS%SB?SSSSSS T T5#TYT_TnT"TT8T TT U U&U -U 9UGUaU&yUU UU$U*U#V5VVHV NV \V iVvV}VVVVVV$VWW W$W 5W CWOW(eWW%W W-W X4XfOXX4XX?YCY]YuYY,YY,YZ13Z5eZZZZ ZZZ1Z5 [5V[[ ['[[ [ [ [\\ \ *\4\ ;\E\_\y\\\\\\\$\ ]] &] 3]?]V]#h]]]]]]]] ] ^^4^I^_^p^^^^^ ^ ^4^$!_$F_Ak__S_-`5D`0z`(``H` %a /alTlfl ~l l ll lll l llll mm !m+m0mOm-Xm6m.m mm n n6nIn3nG1oyoppppEp #q.qLqq,q$r6r%Mr#srrrr rr2s%Asgs"s+sss't+t72tjt"t u<%u bu3mu9uuu%uvvv,vIFv5vv vvqvOwHawow]x)xx xxx xxxx x$xy'y0/y`yeyyy)yyyy y y yy yy zz"z5z:zAz GzTzpzzz*z.z{#{(B{k{p{1{A{{ |1|"J|m|r| y|,| |||| |/}8}J}]}`}z}} }}c}"~9~AS~,~~3~!$!F"h   '*50`  (   5HZo ԁMہ)#DRh<؂ #("GjzɃ-MR[d'} Ƅ ׄ 1F X y  ˅܅ +8?N]b h s φއ  & .?; { Ĉ ˈֈ 4FY`2g  *Ɖ))MS0 Ҋ܊   )?FMdsyNj܋  5FVi. Ҍތ"+ 0=CT]#q  ȍ֍ 4 D NY3p3.؎)#Mm~ (ޏ$!9N`"p&oՐE)eϑؑ3#,; M Y fp 9 ")< EQ b'p-(Г //F-v-&Ҕ&$ $E3j31ҕ1 6 B O\dz Ζߖ   (08?H_gv {  ͗"2ՙAJ>b= ߚ WL,% .>8wBH"W$zA E Qi.Ԟܞ ! 72XƟ͟  3(-\",Ǡ#.GY\n0bۡ>$ˢ 8144f %ɣ  1=7F6~Ƥ:Τ ! ;I c%m@R٥!,NSUZ*m$10Z #{)ɧާJ;O&c' ͨۨ & 057<BDKOT Ygjnqt9ȩ̩ ԩ"'xҫ/KW{Ӯ%I'" "6Nm!}% ŵе׵  ɶն @ \c q%x ֹ ) ;Ecl { պO^bg|/!û,( ;IR p8|e0sK'&%46>M\&u *Ӿ}#/!!1Sn$ .;$:_'p *$1D=] R *AC+S? Wdk - -%>d~ 8K&a  06-d+y_;<O9$&/@p).?/ 3?Qn%6:Mi ~8 )28A\w )-=M\s# *80Gx!% / F T;b)(K=^X*6=+WO ,.A-p*,6g--?'9a#y'!! ..Fu   "B`(|$#)8$J o J15J,$%&"7$Z  N `,!) 0BJRj,}2gv/}, &"-PS\s) B O Zh n|     5.AKp< 3"V2D;KDLg,CV&n$ 7U.u(8)< f0pm,D;?E+$0U\bt</ m&Pq_o */"?bz2( * 4> FQb t&*>)i%)BC< ;)  1#U [ h v* g3'?6S6g !$"( E R\l  +119B] o&z   (6 S^th{$F"i;z % *Gdt - ,3 `l   $"GWg #( & 2=Obkq +   #1 JT3i  )8B{ M  "'Jh)J- '2 9CWhx   5I\o !+' S_!& 3Cah p$}#8 ?#:c,/>#E2i & '3$[a*0)Zx : 1@ EOb j w/   /)O y 6(22N//** )7 )a 9 9 9 99 s             - @ U \  e o w                 )  9 D a . A  R7sDSEY E- <  *6= -('VJ~  PIb9  /E7e( 66T+#"(5Dz2k&$/T8g33  0(; d p~   48 .8?:H )'D#Hh )(5C5ye%-;iL)+=i#)  !(-6HKNRXBw    SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAcceptAccessAccess deniedAccount infoActionAction when encrypted RAR is downloadedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)Cannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.Complete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)FrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.INCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you do not have an account it can be created at If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOther MessagesOther SwitchesPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!RefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.Report-idRequiresRequiresCatReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSend GroupSend RSS notificationsSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.This field is required.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUpUpdate Available!Upload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogView script outputWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilehhourhoursmmanualminmin.minsnot installedofoffonorpar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2014-07-02 18:02+0000 Last-Translator: einar Language-Team: Norwegian Bokmal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:54+0000 X-Generator: Launchpad (build 17082) SABnzbd kan ikke finne filene for webgrensesnittet i %s.
    Vennligst installer programmet på nytt.

    SABnzbd oppdaget nedlastingskø og historie fra en eldre (0.4.x)-utgave.

    Både nedlastingskø og historie vil bli slettet!

    Du kan velge å avslutte SABnzbd og fullføre nedlastingskøen i det eldre programmet.

    Klikk OK hvis du vil starte den nye versjonen av SABnzbd SABnzbd oppdaget instillinger fra en annen SABnzbd-versjon
    men kan ikke bruke disse.

    Kanskje vil du fullføre nedlastingskøen i det gamle programmet først?

    Etter det kan du starte dette programmet med "--clean"-parameteren.
    Dette vil slette nedlastingskø og historie!
    SABnzbd leste filen "%s". SABnzbd oppdaget at filen sqlite3.dll is mangler.

    Enkelte antivirus-programmer fjerner denne filen.
    Vennligst sjekk ditt antivirusprogram og forsøk å installer SABnzbd på nytt.

    SABnzbd har problemer med visse programvare-baserte brannmurer.
    %s
    Uheldigvis kan ikke dette problemet løses akkurat nå.
    Forhør deg med leverandøren av brannmuren din for støtte.

    SABnzbd trenger en ledig TCP/IP-port for sin interne webserver.
    Port %s på %s ble forsøkt brukt, men er utilgjengelig.
    Enten er porten allerede i bruk av et annet program, eller så kjører SABnzbd fra før av.

    Start SABnzbd på nytt med et annet portnummer. SABnzbd trenger en ledig TCP/IP-port for sin interne webserver.
    Port %s på %s ble forsøkt brukt, men kontoen brukt av SABnzbd har ikke tilgang til å bruke den.
    På OSX og Linux-systemer må standardbrukere benytte seg av port 1023 eller høyere.

    Start SABnzbd på nytt med et annet portnummer. SABnzbd krever en gyldig adresse for sin interne webserver.
    Du har spesifisert en ugyldig adresse.
    Korrekte verdier er localhost og 0.0.0.0

    Vennligst start SABnzbd på ny med en gyldig adresse. SABnzbd kommer HELT UTEN GARANTI. Dette er fri programvare, og du kan redistribuere det under visse vilkår. Det er lisensier under GNU GENERAL PUBLIC LICENSE Versjon 2 eller senere versjoner. %s -> Ukjent koding%s => mangler på alle servere, fjerner%s artikler hadde ulike duplikater%s artikler var korrupte%s artikler manglet%s artikler ble slettet%s mappe: %s tilgang mislyktes%s filer på %s%s er ikke en korrekt oktal verdi%s er ikke en godkjent e-post-adresse%s mangler  Løs adresse eller Rapport ID 
    SABnzbd er avsluttet.
    Vent rundt 5 sekunder og klikk deretter på knappen under.

    Last på nytt
    + Feilsøking+ Info+Fjern+Reparere+Pakker opp.nzb Reservemappe1x05 Episodemappe1x05 SesongmappeOBS: Mapper kommer til å bli opprettet automatiskt når du Lagrer. Du må angi korrekte søkestier til din mapper for å kunne lagre utenfor standardmappene.Data vil ikke bli flyttet. Krever SABnzbd restart!Les kildestrøm vil hente gjeldende kildestrømsinnhold. Tving Nedlasting Vil laste ned alle samsvarende NZB'er nå.AlderAPI-nøkkelAPI-nøkkel QR-kodeAPI-nøkkel er feil, bruk API-nøkkel fra Konfigurasjon->Generelt i ditt tredjepartsprogram:API-nøkkel mangler, skriv inn API-nøkkelen fra Konfigurasjon->Generelt i ditt tredjepartsprogram:AvbrytAvbryt jobber som ikke kan fullføresAvbrutt, kan ikke fullføresAvbrutt, kryptering funnetAkseptereTilgangIngen tilgangBrukerinformasjonHandlingReaksjon når kryptert RAR fil lastes nedHendelserAktiver ett alternativt skin.Legg-tilLegg til kildeLegg til filLegg til NZBLegg til nedlastingsplanLegg til serverLegg til ny nedlastingLa til NZB-filAdministrativ MappePåvirkede kategorierEtter at SABnzbd har startet på nytt får du tilgang på følgende adresse: %sTidAlleOgså nye utgivelserAlltidBruke maksimum forsøk kun på valgfrie servereBruk på ValgteEr du sikker på at du vil fjerneEr du sikker på at du vil omstarte SABnzbd?Er sikker på at du vil slå av SABnzbd?Er du sikker?ArgumentCachestørrelse for artikklerArtikkel-idGodkjenning mislyktes, kontroller brukernavn og passord.Autentisering mangler, angi brukernavn/passord fra Konfigurasjon->Generelt i ditt tredjepartsprogram:Gjenoppta automatiskHent bokmerkene automatiskAuto-pause når fri plass er nærme grensen.
    I bytes, fulgt av K,M,G,T. For eksempel: "800M" eller "8G"Last automatiskt ned bokmerkede poster.Henter jobb fra bokmerkene automatisk.Sortere automatisk etter(midt) alder.BTilbakeSikkerhetskopiReserve serverFeil skjema %s ved %s:%sFeilaktigt utformet yEnc artikkel i %sBåndbreddeBlokker oppfrisking når musen svever overBearbeider bokmerkeneBunnCRC-feil i %s (%s -> %s)Lagrer artikler i minnet for å redusere diskaktivitet.
    I bytes, fulgt av K,M,G. For eksempel: "64M" eller "128M"Lagret %s artikler (%s)Kunne ikke endre rettigheter på %sKan ikke koble til registret HKEY_CURRENT_USER.Kan ikke koble til server %s [%s]Kan ikke opprette %s mappe %sKan ikke sikkerhetskopiere fil %sKan ikke opprette mappe %sKan ikke opprette mappe %sKan ikke lage midlertidig fil for %sKan ikke finne e-post-maler i %sKan ikke finne webmal: %s, prøver standardmalKan ikke starte webserveren, ble sannsynlig vis ikke funnetKan ikke åpne registernøkkel "%s".Kan ikke lese %sKan ikke lese den overvåkede mappen %sKan ikke skrive til INI-fil %sKategorierKategoriEndringer som ikke er lagret vil gå tapt.Endringer krever omstart av SABnzbd!Sjekk før nedlastingSe etter ny utgaveSjekk utpakkingsresultatSjekk utpakkingsresultat (må være av for noen filsystemer).UndersøkerOppdateringsintervallSjekk intervall (i minutter, minst 15). Ikke aktiv når du bruker nedlastingsplan!Velg et skall.Rens listeRensning av %s mislyktesRenser bort par filer (om verifisering/reperasjon var vellykket).RensNullstill TellereKlikk nedenfor for å teste.Klikk her for å teste serverinstillingene.StengSABnzbd kommer ikke til å avsluttes om du lukker vinduet eller fanen i webleseren.Ferdig nedlastingsmappeFerdig mappeFerdigFerdig nedlastingsmappeKonfigurasjonKonfig filKonfigurasjonBekreft Sletting av HistorieBekreft Sletting av KøTilkobling mot %s@%s:%s mislyktes, melding=%sTilkobling lyktes!TilkoblingerKontainer breddeKunne ikke fjerne newzbin bokmerke %sKunne ikke koble til (%s)Aktuelle nedlastingsplanerTilpasseTDUPLIKATDagligDaglige mapperDato sorteringDag i månedenTitallDekoding av %s mislyktesStandardStandard base filstiStandard etterbehandlingStandard prioritetStandard brukerskriptDefinierer etterbehandling og lagring.FjernFjernTa bort alleSlett FerdigeSlett MislykkedeFjern feedFjern etter nedlastingSlett alle fullførte nedlastinger fra historie?Slett alle nedlastninger?Vil du slette alle feilete nedlastinger fra historien?Slett alt fra køen?Ta bort alle feilmeldinger fra historikken?Fjerning av %s mislyktes!Oppdag duplikatnedlastingerOppdag NZB filer med identisk navn (krever NZB backup opsjon) og duplikat-titler i RSS feed'eneSlå av API-nøkkelDeaktiverte HTTPS på grunn av manglende CERT- og KEY-filer.ForkastKople fra usenet serverne når køen er tom eller pauset.Koble fra når køen er tomFull harddisk varslingDiskfeil under opprettelse av fil %sDisken er full! Pauser...Utfør ekstra verifisering basert på SFV filerLast ikke ned.Ugyldig autentisering for nyhetsstrøm %sIkke krev API-nøkkel.Blirkvoten resatt hver dag, uke, eller måned?Har du ikke noen usenet leverandør? Vi anbefaler å prøve %s.NedNedlastningNedlasting ferdigMidlertidig nedlastingsmappeNedlasting mislyktesHastighetsbegrensning for NedlastningHenting mislyktes - Overskrevet din servers retensjon?Nedlasting kan feile, kun %s av kravet på %s tilgjengeligMiddelhastighetsbegrensning for Nedladlasting (i KB/s - kilobyte per sekund).NedlastingshastighetNedlastetHentet filer på %s med gjenomsnitts hastighet på %sB/sNedlastet en så lengeLaster nedVisning 1Visning 2Eks.F.eks 199 eller 563 for SSLF.eks 8 eller 20KRYPTERTFEIL:FEIL: %sFEIL: CRC mislyktes i "%s"FEIL: sti er for lang (%s)FEIL: kunne ikke finne "%s"FEIL: skrive feil (%s)Tid igjenEndreEndre NZB detaljerE-PostE-post konto innstillingerE-Post varsling når nedlasting er ferdigE-Post alternativerE-post mottakerE-post avsenderSendte E-post!Mappe for E-post malerE-post testresultatE-post adresse til mottaker.E-post sendning lykkesTomTom NZB-fil %sTom RSS post funnet (%s)AktivereAktiver datosorteringAktiver Filsammenslåing (Filejoin)Aktiver GrowlHTTPS AktivereAktiver HTTPS protokoll for tilgang til SABnzbd.Aktiver filmsorteringAktiver MultiCore Par2Aktiver NotifyOSDAktiver Par rensing (Par Cleanup)Aktiver HurtigsjekkAktiver SFV-baserte sjekkerAktiver TS Sammenslåing (TS Joining)Aktiverer TV sorteringAktiver UnrarAktiver UnzipAktiverer tilgangen til webgrensesnittet med HTTPS adresse.Aktiverer den innbyggde Unrar funksjonen.Aktiverer den inbyggde Unzip funktionen.Aktiver hvilke meldingsklasser som skal rapporteres (ingen, en eller flere)Aktiver omdøping av mappeAktiveres for mindre minneforbruk. Deaktiver for å forhindre langsom jobb da køen blokkeres.Aktiverer sortering og endring av filnavn.Aktiver om nedlastning ikke er flyttet til egen mappe.Aktiverer sortering og endring av navn på datomerkede filer.Aktiverer sortering endring av episodenavn.AktivertVed å avslutte filstien med en asterisk * vil arbeidsmapper ikke bli opprettetURLEpisodenavnEpisodenummerEpisode.NavnEpisode_NavnFeil "%s" under kjøring av file_join på %sFeil "%s" under kjøring av par2_repair på %sFeil "%s" under kjøring av rar_unpack på %sFeil "%s" under kjøring av unzip() på %sFeil %s under kjøring av par2_repair på %sFeil %s: Du må oppgi et gyldig brukernavn og passord.Feil under henting av meldings-id %s fra www.newzbin2.es - Kontrollér at brukernavn og passord er sattKunne ikke lage SSL-nøkkel eller sertifikat.Kunne ikke hente TV info (%s)Kunne ikke importere %sMislyktes med importering av OpenSSL modul. Kobler til uten SSLLastingsfeil %s, feilaktig fil oppdagetFeil ved fjerning av %sKunne ikke fjerne arbeidsmappe (%s)Kunne ikke endre navn fra "%s" til "%s"Kunne ikke legge til %s, tar bortFeil under avslutting av systemetBara ved feilFeil: Sekundært grensesnitt er ikke definert.Feil: Køen er ikke tom, kan ikke bytte mappe.Feil: Feil sesjonsnøkkelFeil: Krever sesjonsnøkkelFeil/AdvarselEksempelAvslutt SABnzbdendelseEkstra PAR2 parametereTrekker ut...Ved feil på yEnc CRCMislyktesKunne ikke logge inn på server %sOpprettelse av (%s) mislyktesKunne ikke flytte %s til %sAutentisering mot mailserveren mislyktesKunne ikke stenge databasen, se loggKunne ikke stenge e-post-tilkoblingKunne ikke lage regex for søkestreng: %sKunne ikke koble til mailserverDvalemodus feiletKunne ikke importere %s filer fra %sKunne ikke initialisere %s@%s:%sKunne ikke starte TLS-tilkoblingKunne ikke laste etterbehandlings køen: Feil versjon (krever:%s, fant:%s)Klarte ikke å flytte filerKunne ikke lese registernøkkel for spesialmapperKunne ikke fjerne nzo fra etterbehandlings køen (id)Kunne ikke endre navn på lik fil: %s til %sKunne ikke endre navn fra: %s til %sKunne ikke hente RSS-kilde fra %s: %sKunne ikke sende e-postKunne ikke sette systemet i ventemodusKunne ikke starte webgrensesnittetKunne ikke oppdatere newzbin jobb %sFeilFeil i tempfil.mkstempKritisk feilRSS-kildeKilderHenterHenter %s blokker...Henter ektra blokk...Fil %s er tom, hopper overFilendelseFil som inneholder alle passordene som skal forsøkes på krypterte RAR filer.Filsammenslåing av %s mislyktesFilnavn eller søkesti til HTTPS Sertifikat.Filnavn eller sti til HTTPS-lenkeFilnavn eller søkesti til HTTPS Nøkkel.FilsettFilnavnFilterFiltrere ut sample-filer (ex. video samplinger).FiltereFørsteMappen "%s" finnes ikkeMappekonfigurasjonMappe inneholder skript for etterbehandling.Mappe som inneholder brukerdefinerte e-post maler.Mappe som automatiskt søkes igjennom etter .nzb filer.
    Skanner også igjennom .zip .rar og .tar.gz arkiver etter .nzb filer.Mappe/SøkestiMapperBrukernavn for e-post som krever autentisering.Passord for e-post som krever autentisering.TvingTving frakoblingTving nedlastingForumLedig (midlertidig)HyppighetFredagØvrig hjelp kan du finne på vårGBGenereltGenerell konfigurasjonGenerer Ny NøkkelGenerell sorteringHente bokmerkerHente bokmerker nåHent NZBHente Newzbin bokmerkerGå til SABnzbdGå til guidenGrupper / Indeks etiketterHTTPS SertifikatHTTPS-lenke sertificaterHTTPS NyckelHTTPS-portHTTPS StøtteHjelpDvalemodus PCGjem bokmerkerSkjul redigeringsalternativerSkjul detaljerSkjul filerHøyHistorikkHistorikk (10 siste)Historikk størrelseHjemStartsideAdresseAdressen som SABnzbd skal bruke.Time:MinuttHvor mye can lastes ned denne måneden (K/M/G)Jeg vil at SABnzbd skal kunne brukes fra alle datamaskiner i mitt nettverk.Jeg vil at SABnzbd kun skal kunne brukes fra min datamaskin.UFULLSTENDIGIONice parametereIRCLedigOm tom, så vil standardporten bare lytte til HTTPSOm du er medlem på newzbin eller nzbmatrix kan du bruke ditt brukernavn og passord her så kan vi hente dine nzb filer. Dette kan hoppes over om du ikke bruker deres tjenester.Hvis du ikke har en bruker, kan det opprettes på Prøv et annet nummer hvis du får denne feilmeldingen på nytt.
    Hvis du har konto ved www.newszbin2.es, så ka du skrive inn kontoinformasjon her.
    Dette vil låse opp ekstra funksjonalitet.Om du har en konto på www.nzbmatrix.com, så kan du skrive inn brukerinformasjonen her.
    Det kreves for at du skal kunnr bruke RSS-feeden fra nzbmatrix.Ignorer Sample-filerIgnorerer duplikatfil "%s"Hvor:I tilfelle "Pause", så trenger du å sette et passord og gjenoppta jobben.I mappeI minutter (minst 15 min).For å laste ned fra usenet trenger du tilgang til en leverandør. Din internettleverandør kan gi deg tilgang, men en "proff" leverandør anbefales.Ukompatibel nyhetsstrømFeilaktig kø-fil funnet, kan ikke fortsetteUfullstendig mappeUfullstendig NZB-fil %sUfullstendig sekvens av oppdelte filerFeilaktig RSS-kilde beskrivelse "%s"Feil parameterFeil verdi for %s: %sFeil kodet passord %sIndex-siderForbereder omstart...
    Feilaktig NZB fil %s, hopper over (årsak=%s, linje=%s)Ugyldig koding av e-post mal %sUgyldige nzbmatrix brukernavn og/eller passordUgyldig nzbmatrix rapporteringsnummer %sUgyldige par2-filer, kan ikke kontrollere eller reparereUgyldig server-adresse.Ugyldige server-innstillingerUgyldig scenen logging i historien for %sInvertereDu bruker mest sannsynlig ZoneAlarm under Vista.Det er anbefalt at du lagrer denne siden som et bokmerke for å treffe SABnzbd når det kjøres i bakgrunnen."%s" jobber er igjen i køenJobb fullførtNedlasting markert med '*' kommer ikke å bli lastet ned automatisk.Slå sammen filerSlår sammen filer med filendelsene .001, .002 etc. til en fil.Slår sammen filer med filendelsene .001.ts, .002.ts etc. til en fil.Slår sammen filerKB/sLa nedlastningen i ekstramappe væreSpråkSisteSeneste AdvarslerStarter webleseren ved oppstartStart webleseren med SABnzbd's side når programmet startes.Starter standard webleser når SABnzbd starter.VenstreHastighetsbegrensningLenkerListe med filendelser som skal slettes etter nedlastning.
    For eksempel: .nfo or .nfo, .sfvLasting av %s mislyktesPlass for lagrede loggfiler fran SABnzbd.
    Krever omstart av SABnzbd!Plass for å lagre bearbeidede og ferdige nedlastinger.
    Kan overstyres av brukerdefinerte kategorier.Plass for å lagre ikke bearbeidede nedlastinger.
    Kan kun endres når køen er tom.Plass der .nzb filer lagres.LoggmappeLoggingLavSmå bokstaverMBHovedarkiv mangler...LikeMaks. hastighetMaksimum antall forsøk per serverMaksimum antall forsøkBetyrMinimal fri plass for midlertidig nedlastingsmappeDiverseMangler sesjonsnøkkelManglende artiklerMangler forventet fil: %s => unrar feil?MandagMånedMerFilm NavnFilm.NavnFilm_NavnFlytterFlytter...MultioperasjonerMulti-del etikettNZB-nøkkelNZB er lagt til i køenNavnFilnavnAldriNy RSS-kilde adresseNy utgave %s tilgjengeligNy utgave er tilgjengeligNewzbin PassordNewzbin BrukernavnNewzbin gir udokumentert feilkode (%s)Newzbin gir udokumentert feilkode (%s, %s)Newzbin rapporterte at %s ble ikke funnetNewzbin serveren endret sin protokollNewzbin serveren mislyktes gi info for %sNesteNice parametereKunne ikke finne noen PAR2 program, reparasjon er ikke mulig
    Kunne ikke finne noen UNRAR program, utpakking er ikke mulig
    Ingen e-post-mal funnetIngen mappeIngen etterbehandling, på grunn av misslykket verifiseringIngen mottaker oppgitt, e-post ikke sendtIngenNormalIngen treffIkke nok diskplass for å fullføre nedlastingen.UlikeVarselsenterVarsel sendt!VarselklasserVarslerSekunder mellom skanninger for .nzb filer.NzbMatrix API-nøkkelNzbMatrix BrukernavnOKVALGFRITT PassordVALGFRITT BrukernavnAvVed avslutningNår køen er ferdigPå hvilken dag i måneden eller uken (1=mandag) resetter til nettilbyder kvoten? (Valgfritt med tt:mm)Bara artiklene fra begynnelsen av køenKun for valgfrie servereEtterbehandle kun nedlastinger som har passert PAR2 kontrollen.Brukes kun for fjerntliggende Growl tjener (vert:port)Åpen kildekode URLÅpne et terminalvindu og skriv inn linjen (eksempel):Åpne fullført mappeValgfrittKan velge autentiserings passord.Kan velge autentiserings brukernavn.Valgfritt passord for Growl tjenerValgfritt spesifiser filnavnAlternativerSorteringOriginalfilnavnOriginalt mappenavnAndre meldingerAndre parametrePauseSideParametereDelnummerPassordPassordfilPassordet er skjult med ******, prøv igjenPassordbeskytte tilgangen til SABnzbd (anbefales)SnarveiMønsterHjelp til SorteringsstrengStans midlertidigPause AlltPause nedlasting under etterbehandlingPauseintervallPause forPause 1 timePause 12 timmePause 15 minutterPause 24 timerPause 3 timerPause 30 minutterPause 5 minutterPause 6 timerPause i hvor mange minutter?Pause i...Pause etterbehandlingPausetPauser nedlasting når etterbehandling begynner og gjenopptar nedlasting når etterbehandling er ferdig.Stanser duplikatfil "%s"Rettigheter for ferdige nedlastingerHusk at vertsnavnet 0.0.0.0 krever en IPv6-adresse for ekstern tilgangBruk et heltall.Skriv inn opplysningene om din primære usenet leverandør.Plush ValgPortPorten som SABnzbd skal bruke.Etterbehandling mislyktes for %s (%s)PostprosesseringEtterbehandle kun verifiserte nedlastingerEtterbehandlings skriptmappeEtterbehandlingEtterbehandling startetEtterbehandling ble avbrutt (%s)Før-kø bruker skriptFor innstillingerTrykk Start+R og skriv inn linjen (eksempel):ForrigeForrigePrioritetMistenkt kontodelingOppkoblingsproblem til nzbmatrix server (%s)Problem medBearbeider bokmerkerProsesser resultatBearbeidingerBearbeider parameterProgrammet startet ikke!JobbSlett og ryddFjern Ferdige NZBerSlett feil-historieFjern Mislykkede NZBerFjern Mislykkede NZBer & Slett FilerSlett historikkSlett NZB-filerSlett NZB & tilhørende filerSlett køVil du virkelig slette historikken?Vil du virkelig slette køen?Python-versjonQR-kodeKøKø (10 første)Automatisk oppdateringsintervall av kø:Reparer KøSatt i køHurtigkontroll...HurtigkontrollererAvslutteKvoteGjenværende kvoteKvoteperiodeKvote oppbrukt, setter nedlasting på pauseRRSSRSS OppdateringsintervallRSS-konfigurasjonRSS-kilde %s var tomKjørte i %sSjeldent brukte valg. for å finne forklaring og betydning, klikk på hjelpknappen for å gå til Wiki siden.
    Ikke endre på disse uten å sjekke Wiki først, siden noen av dem har alvorlige bieffekter.
    Standardverdiene står i parantes.Les alle kilder nåLes kildeLes RSS-kildeLes Wiki Help fer dette!OppdatereOppdateringsfrekvensOppdateringsintervall av kø-siden (sek, 0= ingen).OppdateringsfrekvensAvviseRelative mapper er basert påGjenstår/TotaltGjenstårFjernFjern NZBFjern NZB & slett filerTa bort serverFjerne mislykkede jobberTa bort fra bokmerkeslisten når nedlastingen er ferdig.Fjerning av %s mislyktesEndre navnReparererMislykket reparasjon, finner ikke nødvendige reparasjonsblokker (%s mangler)ReparererReparasjon mislyktes, %sReparerer...Erstatt ulovlige tegn i mappenavn.Erstatt mellomrom i mappenavnErstatt punktum i mappenavnErstatt punktum med mellomrom i mappenavnErstatt ulovlige tegn i mappenavn med tilsvarende tegn(ellers fjernes de).Erstatt mellomrom med understrek i mappenavn.Rapport-idKreverKreverKatNullstill kvote nåNullstillingsdagStarte på nyttRestart uten å logge innStarter SABnzbd på nytt...ResultatGjenopptaGjenoppta etterbehandlingTidsrom for liggefristPrøv igjenKjører skriptKjører skript...Kjør brukerskript %sS01E05 EpisodemappeS01E05 SesongmappeSABnzbd %s startetSABnzbd AdresseSABnzbd PassordSABnzbd-portSABnzbd Hurtigstart GuideSABnzbd BrukernavnSABnzbd VersjonSABnzbd WebbserverSABnzbd oppdaget en kritisk feil:SABnzbd er nå avsluttetSABnzbd kommer nå å kjøres i bakgrunnen.SMTP-tjenerSQL-kommando mislyktes, se loggSQL Innsetting mislyktes, se loggSSLSSL typeLørdagLagreLagre endringerLagretLagring av %s mislyktesLagrer..Sjekk overvåkingsmappeSkjema for ikke eksisterende server %sNedlastingsplanNedlastingsplan konfigurationSkriptSkriptsSesongnummerEndre utseende til Webgrensesnittet.Velg språket til Webgrensesnittet.Velges kun om din leverandør tillater SSL-tilkoblinger.UtvalgSend gruppeSend RSS varslerSend e-post nå en RSS feed legger til en nedlasting til køen.Send e-post når harddisken er full og SABnzbd har pauset.Send gruppekommando før du ber om artikler.Send varsler til GrowlSend varsler til VarselsenterSend varsler til NotifyOSDSendte %s til køenSeriesorteringServerServer %s krever brukernavn/passordServer %s vil bli ignorert i løpet av %s minutterServerinstillingerTjeneradresseServeradressen "%s:%s" er ikke gyldig.Krever server-adresseServerkonfigurasjonServer definisjonPassord for tjenerServer avbrøt undet innloggingssekvensServer krever brukernavn og passord.ServereSett pauseintervallSett rettigheter for ferdige filer og mapper.
    Bruk tall. For eksempel: "755" or "777"Skriv inn API-nøkkelen for NzbMatrix her.Still inn din ISP's server for utgående e-post.Skriv inn passordet ditt her.Skriv inn ditt brukernavn her.InnstillingerInstallasjonen er nå ferdig!Skal nedlasting starte på nytt etter at kvoten er resatt?Vis alleVis bokmerkerVis redigeringsalternativerVis MislykkedeLoggShow NavnVis Navn på mappeWebloggVis detaljerVis filerVis grensesnittVis tider i AM/PM (påvirker ikke kjøreplanen)Show.NavnShow_NavnViser %s til %s av %s resultatViser et resultatAvsluttSlå av PCAvslutning av SABnzbdStarter avslutning av SABnzbd..Signal %s mottatt, lagrer og avslutter...StørrelseHopp overIkke kjør par2 kontroll når filene er 100% korrekte.Some files failed to verify against "%s"SortereSorteringsstrengSortere etter alderSorter på Alder (Yngst%rarr;Eldst)Sorter på Alder (Eldst%rarr;Yngst)Sorter etter alder Ny→EldstSorter etter alder Eldst→NySorter på Navn (A%rarr;Å)Sorter på Navn (Å%rarr;A)Sorter etter navn A→ZSorter etter navn Z→ASorter på Størrelse (Størst→Minst)Sorter på Størrelse (Minst→Størst)Sorter etter størrelse Størst→MinstSorter etter størrelse Minst→StørstSortere etter alderSortere etter navnSortere etter størrelseSorteringSorteringskonfigurasjonKildeSpesiellHastighetHastighetsgrenseHastighetsgrenseVentemodus PCStart VeiviserStarter reparasjonOppstart/avsluttningStatusSteg femSteg fireSteg enSteg treSteg toStoppAvslutter...LagringEmvneSøndagSvitsjerParameterkonfigurasjonSystemlastSystemmapperTEKSTFOR STOROppgaveMidlertidig nedlastingsmappeTest E-postTest varslingenTestserverTester serverinstillinger...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.Det automatiske usenet nedlastnings verktøyetAvkrysningsboksen ved kildenavnet må aktiveres for at kilden automatiskt skal kontrolleres for nye objekt.
    Når en kilde legges til, legges det kun til nye objekt(ikke objekt som allerede finnes). Alle objekter i kilden vises når du klikker på "Tving nedlastning".Du har ikke stilt inn vertsnavn.Antallet tilkoblinger som er tillatt av din leverandørIngen tilkoblinger er aktivert. Du må aktivere minst en tilkobling.Detta feltet kreves.Denne nøkkelen vil gi tredjepartsprogrammer lov til å legge til NZBer til SABnzbdDenne nøkkelen vil gi tredjepartsprogrammer full tilgang til SABnzbdDenne månedenDenne ukenDette vil hindre oppfrisking av innhold når muspekeren er over køenDette vil starte om SABnzbd.
    Brukes når du tror programmet er ustabilt.
    Nedlastning vil bli satt på pause før omstarten og gjenoppta etterpå.Dette vil sende en test e-post til din konto.TrådTorsdagTidsavbruddTidsavbrudd: Prøv å aktivere SSL eller bruk en annen port.GjenstårTidsavbruddTittelTo: %s From: %s Date: %s Subject: SABnzbd rapporterer at disken er full Hei, SABnzbd har stoppet all nedlasting da lagringsdisken nesten er full. Frigjør mer diskplass og gjenoppta nedlasting manuelt. I dagVis/Skjul Legg til NZBFor lite diskplass, nedlasting satt på pauseFor mange oppkoblinger til server %s:%sFor mange tilkoblinger, sett nedlasting på pause eller prøv igjen senereToppToppmenyTotaltFeilsøkingForsøk igjenPrøve å beregne om ferdigstillelse er mulig før selve nedlastingen (tregere!)Prøver SFV-verifiseringForsøker å hente NZB fra %sForsøker å sette status på ikke-eksisterende server %sPrøver unrar med passord "%s"TirsdagJusteringerTypePUNC-sti "%s" er ikke tillatt herURL henting mislyktes; %sBRUK PÅ EGET ANSVAR!Fjern bokmerke etter nedlastingUautorisert, kontroller ditt newzbin brukernavn/passordFjern blokkeringUkjent feil oppstod under dekoding av %sUkjent handling: %sUtpakkingUtpakket %s filer/mapper på %sUtpakkerUtpakking mislyktes, %sUtpakking mislyktes, CRC-feilUtpakking mislyktes, en forventet fil er ikke utpakketUtpakking mislyktes, arkivet krever passordUtpakking feilet, stien er for langUtpakking mislyktes, se loggUtpakking feilet, fil(er) mangler:Utpakking mislyktes, kunne ikke finne %sUtpakking mislyktes, skrivefeil eller er disken full?Feil, Ubrukelig akrivfilOppOppdatering tilgjengeligLast opp: .nzb .rar .zip .gzOppetidBruk 12 timers klokke (AM/PM)Bruk V23 om ikke din leverandør krever noe annet!Bruk midlertidige navn under postprosessering. Deaktiver når systemet ditt ikke håndtere dette skikkelig.Bruke "Grupper / Indeksetiketter" kolonnen for å koble grupper og etiketter til kategorier.
    Jokertegn er støttet. Bruk komma for å skille vilkårene.Brukes før en NZB blir lagt til køBrukt hurtigbufferBrukes når etterbehandlingen er bestemt etter kategori.Brukes når ingen prioritet er bestemt av kategori.Brukes når brukerskript er bestemt etter kategori.BrukermapperBrukerdefinerte kategorierBrukernavnVerifisering med SFV-filer var vellykketVerifisererVerifserer...VersjonSe skriptloggVis skript kjøringenVENT %s sekADVARSEL:ADVARSEL: Avbrutt jobb "%s" grunnet kryptert RAR filADVARSEL: Jobb "%s" satt på pause pga. kryptert RAR-filADVARSLERVenterAdvarselAdvarsel: LOCALHOST er tvetydig, bruk numerisk IP-adresse.AdvarslerOvervåket MappeSkanningsintervall for Overvåkede mapparWebgrensesnittWebserver autentiseringOnsdagSe etter ny utgave av SABnzbd hver uke.NårHvis artikkelen har CRC feil, prøv å hent den fra en annen server.Avbryt jobben om det blir klart under nedlasting at for mye data manglerHvem skal vi sende e-posten fra?WikiXÅrÅr-Måneds mapperDu har ikke kreditt på din Newzbin kontoDu har ikke tilgang for å bruke port %sDu må aktivere Javaskript for at Plush skal fungere!Du trenger en nzbmatrix VIP konto for å bruke API'enDin versjon av UNRAR er ikke anbefalt, hent en ny versjon fra http://www.rarlab.com/rar_add.htm
    [%s] Feil "%s" under filsammenslåing[%s] Feil "%s" under utpakking av RAR fil(er)[%s] Slår sammen %s filer[%s] Ingen par2 deler[%s] PAR2 mottok feil kommandoer, undersøk brytere i Konfigurasjon->Brytere[%s] Hurtigkontroll OK[%s] Reparert på %s[%s] Verifiseing tok %s, alle filer er ok[%s] Verifisering tok %s, krever reparasjon_yenc-modul... IKKE funnet!justert for store og små bokstaversletteddagdøgnDeaktiver serverAktiver serverhenter meldings-id %s fra www.newzbin2.esfilhtimetimermmanueltminuttmin.minutter(ikke installert)avavpåellerpar2-binærfil... IKKE funnet!pyopenssl modul mangler, vennligst installer den for https tilgangsekundsekunderse loggfiltekstukjentunrar-binærfil... IKKE funnet!unzip-binær... IKKE funnet!ukeSABnzbd-0.7.20/locale/nl/LC_MESSAGES/SABnzbd.mo0000644000000000000000000022767412433712600020522 0ustar00usergroup00000000000000D l@om@@dASCMD !E2.FaGUH?I*VI'IIII IJ&JFJ fJqJxJJJBKJKQKYKaKiK|KKK?(LhLLLLRM[ZMM#MMM$N?NFN MN [NhN:oN'N'NNO O$O-O6O >O KOVO hOrOOaOOPPP. POPaP)P*P P PPQQ/QhKQ QQQYR(lR0R*RRRR R S&S FSPSiS}SSS T8T?T2_T TT TT U(U!GU6iU-UUUUV 6VAV.JV'yVVVVBV*W3WSEWW WW5WXXX"+XNX8TXX XX XXX X XXY&)YPY gYsY$Y*YYYY YY Y Z Z&Z-Z@ZHZ\ZtZZ$ZZZ ZZ Z ZZ([>[%[[ [-[[[f[f\v\4\\?\\].]M],f]],]]1]5^T^Y^b^ u^^^1^5^5_E_ T_'___ _ _ _ ___ _ __ _`"`<`W`o`s`x```$` `` ` `aa#+aOa_aeawaaaa a aaa b"b3bLb_brbbb b b4b$b$"cAGccSc-c5 d0Vd(ddHdse ue ee e e(e.e) f&7f,^f<fbf&+gRgmg7g'gggh*h Jh kh&vh-hhhi ii &i 3i=i Siaiyiiii%i!i j+-j Yjzj!jj!jFj>k0Sk-k'kk"kl.lGlelll llllllllmA(mjm'm!mmmmm-n2n:n@n[n3pn/ngn ~N~0V~~~~)~~~~ ~ ~  0AI\ah n{*.)#E(i1Aـ 41?"q  ,  ,/:j|Ƃ̂ Ђڂc"NqA,̓3!Ujs!!"ф 2FL[ jx  *Å0 */ 7C I(S| Ά. JWmMt‡#݇RT<q "3Rbz-' >K_ p{ʊߊ  + EQdu ċы؋  :<@Vh~} &ō ? ANU s   Ď4׎ &2- `j *ԏ)M0g  Đ Ԑސ 7FL[m ‘ϑ )<\.v ͒ '0#D hs  4 ! &1JH33ǔ.*)Fp (ؕ$D\q"&:ݖ o3)× -63M ĘΘߘ 9 P Z"d  'Ι - (;d i u//--&=&d$$3՛3 1=1o ǜϜ   )9J Q [e ny ʝҝ   ,8R"&'2@As:NR>=  )W3,0]d m>wǣͣ"$Aޤ $- 3 @EJ.ĥ"')HQi 2Ӧۦ 5?T3p-"ҧ,#<.`$ب#*0Dbuة$e 81Ϊ4 5BZc%j ū ث 7E06v:Ƭ  3A [%e@Rѭ!$FKMR*e$10Z#s)֯J3G&[' ŰӰٰ۰߰ &(-46;AFHOSX ]knrux}9ѱձ ݱ+0j+rM8I]L*e)ռ %8X vU\ b m x&@ξM] \_x$!&'H p{M6+4`<g  *UCB#-=,k :o9* 276j"  "$GMDg %>,8e% (% B1.t$+ % 24<*q"T M YVg1=V]l B  $ AK `%j!' -*< g u   &$7\ ` jw 0'/*I2thIdAh I1)0'Z.4*2>4q /K19}/ & .8 P \hnw! ) HUfu($+"Dgw(&!?%a%%Fc5/5Ae/Pl/  $,)G:qCt0e719#U$y0&*83 l  '0 8Y"m#8$2*E&p*"Q!U5w44*7b'%  %+3;Un\'."1Q* #  >1,pA/+JSiz  .EMiy  (7GY ^k $/E5U <1A*!oX /6 -6 d 6'9a$~C-C+Kkw$ : PB\H %9-Y- Mb$qO,bk,(9@ETW t # 2),?ltz    5U oz$* &,!NW8iN -1I{ 1H^mp ^75mUJ,@>P )"2U\e| 1#0U ( * 9GZ lz )(b$6  <.Hw  9,3 :E`   ";-Y  +3<#Uy  '.B Vbig~&%> ? I%Sy    ;. I  N :X    $   0 QO A         2  > I a  x           *  / : @ W f  u &    % , C G P Y a  i t   "        )>7v  DOE@%)+:/A.q $ !/8Q4K%&1L~ N ,7 I U c q | C   A P Zg y- B:Xaq3311)Q){''33)1]1    # 4?N ^i p z     + 8 E%Qw!><1UK[ZjJH Y dKn   J !-3 ( %H Jn      P A!Y!9x!!!! !!!! ""1" J"Dk" "+"" "## *#4#J#8f#1#)##1$%I$.o$$$&$$ %%$%,%G%N%Dn%l% &0& '='<Z'8''''(*( A(M(\(c(i(( ( ( (@(M(BJ) )) )C) ) )**0*I*2R**D*\*(/+X+]+_+d+$v+1+.+E+bB,,,2,-$-@;-|--0-*-.&!.H.O.Q.U. [. g.,s........ ...........1/N/R/[/j/p/y/// SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAborted, unwanted extension detectedAcceptAccessAccess deniedAccount infoActionAction when an unwanted extension is detected in RAR filesAction when encrypted RAR is downloadedAction when unwanted extension detectedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAudioAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatic FeedbackAutomatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)CancelCannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.CommentComplete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable OZnzb IntegrationEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enhanced functionality including ratings and extra status information is available when connected to OZnzb indexer.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you do not have an account it can be created at If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesIndexingInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList all unwanted extensions. For example: exe or exe, comList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOZnzbOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOtherOther MessagesOther SwitchesOther problemOut of retentionPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PasswordedPathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!Refer to https://www.oznzb.com/profileRefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.ReportReport-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSendSend GroupSend RSS notificationsSend automatically calculated validation results for downloads to indexer.Send email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.Server side error (server code %s); could not get %s on %sServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...Site API KeySizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key provides identity to indexer. Refer to https://www.oznzb.com/profile.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereUNWANTEDURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUnwanted extension is in rar file %sUnwanted extensionsUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionVideoView Script LogView script outputVirus/spamWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: In "%s" unwanted extension in RAR file. Unwanted file is %s WARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2014-07-02 18:08+0000 Last-Translator: shypike Language-Team: Dutch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:53+0000 X-Generator: Launchpad (build 17082) SABnzbd kan de web interface bestanden niet vinden in %s.
    Installeer het programma opnieuw.

    SABnzbd heeft een Wachtrij en Geschiedenis van een oudere (0.4.x) versie ontdekt.

    Beide kunnen verloren gaan!

    Je kunt nu SABnzbd stoppen en de wachtrij afmaken met de oude versie.

    Klik op OK om door te gaan. SABnzbd heeft opgeslagen data van een andere SABnzbd versie gevonden
    maar kan de data van dit andere programma niet opnieuw gebruiken.

    Rond zo nodig eerst je werk met het andere programma af.

    Herstart daarna dit programma met de optie "--clean".
    Dit zal de huidige taak en geschiedenis wissen!
    SABnzbd las het bestand "%s". SABnzbd heeft ontdekt dat het bestand sqlite3.dll ontbreekt.

    Sommige slecht ontworpen virus scanner verwijderen dit bestand.
    Controleer je virus scaner, probeer SABnzbd opnieuw te installeren en klaag bij je leverancier.

    SABnzbd werkt niet in combinatie met sommige firewall programma's.
    %s
    Het spijt ons, maar we kunnen dit probleem niet oplossen.
    Graag een klacht indienen bij je firewall leverancier.

    SABnzbd heeft een vrije TCP/IP poort nodig voor de interne web server.
    Poort %s op %s is geprobeerd, maar is niet beschikbaar.
    Een ander programma gebruikt de poort al of SABnzbd is al aktief.

    Start SABnzbd met een ander poort nummer. SABnzbd heeft een vrije TCP/IP poort nodig voor de interne web server.
    Poort %s op %s is geprobeerd, maar het gebruikers account van SABnzbd heeft geen toestemming.
    Op OSX en Linux systemen mogen standaard gebruikers alleen poorten boven 1023 gebruiken.

    Start SABnzbd met een ander poort nummer. SABnzbd heeft een geldig host adres voor de interne web server.
    Je hebt een onbruikbaar adres opgegeven.
    Veilige waarden zijn localhost en 0.0.0.0

    Start SABnzbd met een geldig host adres. SABnzbd wordt aangeboden ZONDER ENIGE VORM VAN GARANTIE. Het is vrije software en je mag het, onder bepaalde voorwaarden, verder verspreiden. De licentie is de GNU GENERAL PUBLIC LICENSE Versie 2 of (naar eigen keuze) een latere versie. %s -> Onbekende codering%s => ontbreekt op alle servers, overslaan%s artikelen hadden afwijkende duplicaten%s artikelen zijn misvormd%s artikelen ontbreken%s artikelen zijn verwijderd%s map: fout %s bij toegang%s bestanden in %s%s is geen correct octaal getal%s is geen geldig email adres%s ontbreekt  Adres opzoeken of Report ID 
    SABnzbd is nu afgesloten.
    Wacht ongeveer 5 seconden en klik dan op onderstaande knop.

    Verversen
    +Debug+Info+Opschonen+Repareren+UitpakkenMap voor het bewaren van nzb bestanden1x05 Episodemap1x05 SeizoensmappenLet op: mappen worden vanzelf aangemaakt bij "Opslaan".De bestanden worden niet verplaatst. SABnzbd herstart is nodig!Uitlezen leest/ververst de huidige feed inhoud. Forceer download zal alle geselecteerde NZBs nu downloaden.LeeftijdAPI SleutelQR code van de API sleutelAPI Sleutel is fout Vul de API Sleutel van "Algememe instellingen" in bij je hulp programma:API Sleutel ontbreekt: Vul de API Sleutel van "Algememe instellingen" in bij je hulp programma:AfbrekenAfbreken als voltooien niet kanAfgebroken, kan niet voltooid wordenAfgebroken, versleuteling ontdektAfgebroken: ongewenste extensie ontdektAccepterenToegangToegang geweigerdAbonnementsgegevensAktieAktie uit te voeren bij ontdekking van ongewenste extensie in een RAR bestandAktie wanneer versleuteld RAR bestand wordt gedownloadAktie bij ontdekken van ongewenste extensieAktiesAktiveer een tweede bedieningsstijl (herstart nodig).ToevoegenFeed toevoegenBestandNZB toevoegenTaak toevoegenVoeg server toeOpdrachten toevoegenNZB toegevoegdAdministratieve mapBeïnvloede categorieënAls de SABnzbd herstart klaar is, kun je de bediening via deze koppeling bereiken: %sLeeftijdallesOok test versiesAltijdStel alleen een maximaal aantal pogingen in voor optionele serversOp selectie toepassenWeet u zeker dat u wilt verwijderenWeet je zeker dat je SABnzbd wilt herstarten?Weet je zeker dat je SABnzbd wilt afsluiten?Weet je het zeker?ParametersArtikel buffer grootteArtikel nummerAudioInloggen mislukt, controleer gebruikersnaam en wachtwoord.Authenticatie ontbreekt: Vul gebruikersnaam en wachtwoord van "Algememe instellingen" in bij je hulp programma:Automatisch doorgaanBladwijzers ophalenDownload wordt gepauzeerd als er te weinig ruimte vrij isAutomatische terugkoppelingAutomatisch ophalen van newzbin bookmarks.Automatisch NZB bestanden van bladwijzers ophalen.Automatisch sorteren op basis van gemiddelde leeftijd.BTerugReserveReserve serverFoutieve taak %s om %s:%sFoutief gevormd yEnc artikel in %sBandbreedteGeen verversing bij popupsAutomatische bladwijzer verwerkingOnderCRC fout in %s (%s -> %s)Bewaar de artikelen in het werkgeheugen (verminderd schijf gebruik).%s artikelen (%s) gebufferedAnnulerenKan beveiliging van %s niet aanpassenKan geen verbinding maken met register deel HKEY_CURRENT_USER.Kan geen verbinding maken met server %s [%s]Kan %s map %s niet aanmakenKan geen backup bestand voor %s makenKan map %s niet aanmakenKan bestemmingsmap %s niet makenKan geen tijdelijk bestand maken voor %sKan geen email sjablonen vinden in %sKan web sjabloon %s niet vinden, standaard sjabloon wordt gebruiktKan de web-browser niet starten, geen gevondenKan register sleutel "%s" niet lezenKan %s niet lezenKan Bewaakte Map %s niet lezenSchrijven naar het INI bestand %s lukt nietCategorieënCategorieWijzigingen niet opgeslagen en zullen verloren gaan.Wijzigingen worden pas aktief na herstart!Controle vóór downloadenInformeer naar nieuwe versiesControleer resultaat van uitpakkenControleer resultaat van uitpakken (moet "uit" staan voor sommige bestandssystemen).ControlerenLees intervalMinuten tussen het uitlezen (minimaal 15). Niet aktief bij gebruik van de Taakplanner!Kies een bedieningsstijl (herstart nodig).Opschoon lijstOpschonen van %s misluktRuim PAR bestanden op (na succesvolle verificatie/reparatie).WissenTellers op nulKlik hier onder om te testen.Klik om de verbinding te testen.SluitenAfsluiten van de browser vensters zal SABnzbd niet stoppen.CommentaarMap voltooidMap voltooidVoltooidMap voor verwerkte downloadsInstellenInstellingen bestandInstellenBevestig verwijderen uit geschiedenisBevestig verwijderen uit wachtrijVerbinding %s@%s:%s mislukt, bericht=%sSuccesvol verbonden!VerbindingenBreedte van kaderVerwijderen van newzbin bladwijzer %s misluktKan verbindingsresultaat niet bepalen (%s)Huidige takenAangepastODUBBELdagelijksDagelijkse MappenDatum sorterendagnummerDecadeDecoderen van %s misluktStandaardStandaard basis mapStandaard nabewerkingStandaard prioriteitStandaard scriptBepalend voor nabewerking en opslag.WisVerwijderAlles wissenVerwijder geslaagdeVerwijder mislukteVerwijderVerwijderen na downloadVerwijder alle geslaagde items uit Geschiedenis?Alle gedownloade bestanden verwijderen?Verwijder alle mislukte items uit Geschiedenis?Verwijder alle opdrachten uit de wachtrij?Verwijder alle mislukte items uit de Geschiedenis?Verwijderen van %s mislukt!Detecteer dubbele opdrachtenHerken identieke NZB namen (hiervoor is de NZB backup optie nodig) en identieke titels binnen RSS feeds.API-sleutel niet gebruikenUitHTTPS is uitgeschakeld vanwege ontbrekende CERT en KEY bestanden.VerwerpenVerbreek verbindingen wanneer de wachtrij leeg is of er gepauzeerd wordt.Verbreek verbindingen wanneer er niets te doen isZend email wanneer de harde schijf vol isSchrijf fout bij opslaan van bestand %sSchijf is vol! Forceer PauzeDoe een extra verificatie m.b.v. SFV bestandenNiet downloadenGeen geldige inlog gegevens beschikbaar voor feed %sGebruik van de API sleutel niet afdwingen.Wordt het quotum elke dag, week of maand hersteld?Heb je nog geen Usenet provider? Wij bevelen %s aan.LagerDownloadDownload voltooidMap downloadDownload misluktDownload snelheidsbeperkingDownload mislukt - Buiten de server bewaartijd?Download mislukt waarschijnlijk, slechts %s van de benodigde %s beschikbaarDownload snelheidsbeperking kilobytes per seconde (kB/s).SnelheidGedaanGedownload in %s met een gemiddelde van %sB/secTot nu toe gedaanDownloadenDownloadsDubbel1Dubbel2VoorbeeldBv. 119 of 563 voor SSLBv. 8 of 20VERSLEUTELDFOUT:FOUT: %sFOUT: Foutieve CRC "%s"FOUT: bestandspad is te lang (%s)FOUT" kan "%s" niet vindenERROR: schrijf fout (%s)Klaar omBewerkBewerk NZB DetailsEmailEmail gegevensZend email na voltooien van elke downloadEmail OptiesEmail bestemmingEmail afzenderEmail verzonden!Map met email sjablonenTest resultaat emailAdres waarnaar de email verstuurd wordt.Email verzondenLeegNZB bestand %s is leegLege RSS-feed gevonden (%s)AktiefDatum sorteren aanzettenSamenvoegen van bestanden toestaanGrowl aanzettenMaak HTTPS mogelijkMaak HTTPS (beveiligd) verkeer mogelijk.Film sorteren aanMultiCore Par2 toestaanNotifyOSD aanzettenOZnzb integratie inschakelenPAR bestanden opruimenSnelle controle toestaanVoer SFV-gebaseerde controles uitSamenvoegen van TS bestanden toestaanTV sorteren aanUnrar toestaanUnzip toestaanSta gebruik van HTTPS toe.Uitpakken van RAR archieven toestaan.Uitpakken van ZIP archieven toestaan.Kies welke bericht types verstuurd moeten worden (geen, één of meer)Gebruik tijdelijke mapnamenAanzetten zal leiden tot minder geheugen gebruik.
    Uitzetten om te voorkomen dat langzame opdrachten de wachtrij blokkeren.Sta algemeen sorteren en hernoemen van bestanden toe.Sta opslaan van downloads in een eigen map toe.Sta sorteren en hernoemen van datum-gebaseerde bestandsnamen toe.Sta sorteren en hernoemen van afleveringen toe.ActiefAls het pad eindigt met een ster *, dan worden geen aparte taak folders gemaakt.Uitgebreide functionaliteit met waarderingen en extra status informatie wanneer gekoppeld aan OZnzb indexer.URLEpisode NaamEpisode NummerEpisode.NaamEpisode_NaamFout %s bij samenvoegen van %sFout "%s" bij reparatie van groep %sFout "%s" bij uitvoeren van rar_unpack op %sFout "%s" bij uitvoeren van unzip() op %sFout %s bij uitvoeren van par2 reparatie op verzameling %sFout %s: Je moet een geldige gebruikersnaam en wachtwoord invullen.Fout tijdens ophalen van msgid %s van www.newzbin2.es - Zorg dat je gebruikersnaam en wachtwoord goed zijn ingesteldFout bij aanmaken van SSL sleutel en certificaatFout bij ophalen TV info (%s)Fout bij importeren van %sFout bij importeren van module OpenSSL, probeer NON-SSLFout bij inladen van %s, corrupt bestand gevondenFout bij verwijderen van %sFout bij verwijderen van werkmap %sFout bij hernoemen van "%s" tot "%s"Fout bij toevoegen van %s, wordt weer verwijderdFout bij het afsluiten van het systeemAlleen bij foutenFout: geen secundaire interface ingesteld.Fout: Wachtrij is niet leeg, kan geen andere map kiezen.Fout: Sessie sleutel niet geldigFout: Sessie sleutel nodigFouten/WaarschuwingenAllesVoorbeeldStop SABnzbdExtensieExtra PAR2 parameters:Uitpakken...Verwijder artikelen met yEnc crc foutenMisluktKan niet aanmelden bij server %sAanmaken %s misluktVerplaatsen van %s naar %s misluktKan niet aanmelden bij email serverHet lukt niet om de database te sluiten, zie log bestandAfsluiten email verbinding lukt nietSamenstellen van reguliere expressie lukt niet: %sKan geen verbinding maken met email serverKan systeem niet in slaapstand krijgenImporteren van %s bestanden van %s misluktKan geen verbinding maken %s@%s:%sKan geen TLS verbinding makenFout bij laden van nabewerkingswachtrij: verkeerde versie (nodig:%s, gevonden:%s)Verplaatsen van bestanden misluktKan register sleutels voor speciale mappen niet lezenVerwijderen van nzo van nabewerkingswachtrij misluktHernoemen van gelijkaardig bestand %s tot %s misluktHernoemen van %s tot %s misluktKan RSS-feed "%s" niet lezen vanwege: "%s"Verzenden van email is misluktKan het systeem niet in standby krijgenKan web interface niet startenBijwerken newzbin opdracht %s misluktMisluktProbleem met tempfile.mkstempFatale foutFeedFeedsOphalenOphalenOphalen van %s blokken...Extra blokken ophalen...Bestand %s is leeg, overslaanBestandsextensieBestand met alle wachtwoorden die uitgeprobeerd moeten worden op versleutelde RAR bestanden.Samenvoegen van Bestanden %s is misluktNaam of pad van het HTTPS Certificaat bestand.Bestandsnaam of padnaam van "HTTPS chain" bestandNaam of pad van het HTTPS Sleutel bestand.BestandsverzamelingBestandsnaamFilterWat te doen met "sample" bestanden?FiltersEersteMap "%s" bestaat niet.Map instellingenMap waarin zich de script bestanden voor nabewerking bevinden.Map waarin zich de email sjablonen bevinden..nzb en .zip bestanden in deze map worden automatisch gedownload.Map/PadMappenWanneer authenticatie nodig is, gebruikersnaam.Wanneer authenticatie nodig is, wachtwoord.ForcerenVerbreek verbindingenForceer downloadForumVrij (tijdelijk)Vrije ruimteFrequentievrijdagVoor meer informatie: zie onzeGBAlgemeenAlgemene instellingenMaak een nieuwe sleutelAlgemeen sorterenBookmarks ophalenBladwijzers nu ophalenOphalenHaal Newzbin Bladwijzers opGa naar SABnzbdGa naar WizardGroepen / Indexer markeringenHTTPS Certificaat"HTTPS Chain" bestandHTTPS SleutelbestandHTTPS PoortHTTPS ondersteuningHulpPC slapenBladwijzers verbergenVerberg OptiesVerberg detailsVerberg bestandenHoogGeschiedenisGeschiedenis Laaste 10 ItemsTotaalOpdrachtenStartpaginaServer naamHost adres waar op SABnzbd luistert.Uur:MinHoeval mag deze maand worden gedownload (K/M/G)Ik wil SABnzbd kunnen gebruiken vanaf iedere PC in mijn thuisnetwerk.Ik wil SABnzbd alleen vanaf deze PC kunnen gebruiken.RUSTONVOLLEDIG"IONice" parametersIRCRustIndien leeg, werkt de standaard poort uitsluitend met HTTPS.Wanneer je een Newzbin of een nzbmatrix abonnement hebt, kun je hier je gegevens invullen, zodat SABnzbd de NZB bestanden kan ophalen. Je kunt dit overslaan als je deze diensten niet gebruikt.Als je geen account hebt, kun je dat aanmaken op Als je dit bericht weer krijgt, probeer dan een ander nummer.
    Als je een account bij www.newzbin2.es hebt dan kun je hier je gebruikersnaam en wachtwoord invullen. Je krijgt dan extra newzbin functies.Wanneer je een account bij www.nzbmatrix.com hebt, kun je hier je gegevens invullen.
    Dit is nodig om RSS feeds van deze site te kunnen verwerken.Verwerking van "sample" bestandenDubbele NZB "%s" overgeslagenInAls je "Pause" kiest, dan dien een wachtwoord in te stellen en de download vrij te gevenIn mappenIn minuten (minimaal 15).Om te kunnen downloaden van Usenet, heb je een provider nodig. Je Internet bedrijf heeft misschien een server, maar we bevelen een betaalde server aan.Ongeschikte feedOnbruikbaar wachtrij bestand gevonden, kan niet verderMap downloadOnvolledig NZB bestand %sOnvolledige reeks van samenvoegbare bestandenFoutieve RSS-feed definitie "%s"Foute instellingFoute waarde voor %s: %sFoutief gecodeerd wachtwoord %sIndex sitesIndexeringBegin met herstart...
    Foutief NZB bestand %s, overslaan (reden=%s, regel=%s)Foutieve codering van email sjabloon %sOngeldige nzbmatrix gegevensOngeldig nzbmatrix rapport nummer %sOngeldige par2 bestanden, verificatie en reparatie is niet mogelijkOngeldige servernaamOngeldige servergegevensFoutieve fase logging in geschiedenis voor %somkerenMogelijk gebruik je ZoneAlarm op Vista.
    Tip: maak een "Bladwijzer" of "Favoriet" voor deze lokatie, zodat je SABnzbd gemakkelijk terug kunt vinden.Opdracht "%s" terug naar de wachtrijNZB voltooidItems met een ster '*' worden niet automatisch gedownload.SamenvoegenVoeg bestanden eindigend met .001, .002 enz. samen tot één file.Voeg bestanden eindigend met .001.ts, .002.ts enz. samen tot één file.SamenvoegenKB/sZet downloads in aparte mappenTaalLaatsteRecentste meldingenStart web browser bij opstartenStart de web browser wanneer SABnzbd opstart.Start de web browser wanneer SABnzbd opstart.OverBeperk snelheidKoppelingenLijst van alle ongewenste extensies. Voorbeeld: exe or exe, comLijst van bestand extensies die verwijderd worden
    Voorbeeld: .nfo of .nfo, .sfvInlezen van %s lukt nietMap voor wachtrij administratie en geschiedenis bestand.
    Kan alleen wijzigen als de wachtrij leeg is.Map waarin de log bestanden worden opgeslagen
    Vereist een herstart.(kan aangepast worden door de categorieën).Plaats om onbewerkte downloads op te slaan
    Kan alleen gewijzigd worden als de wachtrij leeg is.Map waar reserve kopieën opgeslagen worden.Map voor loggingLoggenLaagKleine lettersMBHoofdpakket niet gevonden...GeselecteerdMax SnelheidMaximaal aantal pogingen per serverMaximum aantal pogingenBetekenisMinimale vrije ruimte voor tijdelijke download mapDiversenSessie sleutel ontbreektOntbrekende artikelenVerwacht bestand %s ontbreekt => unrar fout?maandagmaandMeerFilm NaamFilm.NaamFilm_NaamVerplaatsenVerplaatsen...Meervoudige bewerkingMeervoudig labelNZB SleutelNZB aan wachtrij toegevoegdNaamNaamgevingNooitURL van nieuwe RSS-feedNieuwe versie %s beschikbaar opNieuwe versie beschikbaarWachtwoordGebruikersnaamNewzbin meldt onbekende fout code %sNewzbin meldt onbekende fout code (%s, %s)Newzbin rapport %s niet gevondenNewzbin server gebruikt ander protocolNewzbin server geeft geen informatie over %sVolgende"Nice" parametersGeen PAR2 programma, kan geen reparaties uitvoeren
    Geen UNRAR programma gevonden, uitpakken van RAR bestanden niet mogelijk
    Geen email sjablonen gevondenGeen mappenGeen nabewerking vanwege mislukte verificatieGeen geadresseerden gegeven, geen e-mail gestuurdGeen resultatenGeenNormaalNiet geselecteerdOnvoldoende schijfruimte over!Niet geselecteerdBerichtencentrumMelding verzondenBericht typesMeldingenAantal seconden tussen lezen van de bewaakte map.NzbMatrix API sleutelGebruikersnaamOKOPTIE: Account wachtwoordOPTIE: Account gebruikersnaamOZnzbBehoudenBij lege wachtrijBij lege rijOp welke dag van de maand of week (1=maandag) wordt het quotum hersteld? (Eventueel met hh:mm)Download alleen artikelen van het begin van de wachtrijAlleen voor optionele serversVoer de nabewerking alleen uit op downloads die alle PAR2 controles hebben doorlopen.Alleen gebruiken voor een Growl server op een ander systeem (server:poort)Open Informatie URLOpen Source URLOpen een "Terminal" venster en type deze regel in (voorbeeld):Open map met voltooide downloadsOptioneelEventuele extra NZBWachtwoord voor web login.Gebruikersnaam voor web login.Optioneel wachtwoord voor de Growl serverGeef eventueel een bestandsnaam opOptiesVolgordeOriginele BestandsnaamOorspronkelijke mapnaamOverigeAndere berichtenDiverse instellingenAnder probleemBuiten retentiePAUZEPaginaParametersVolgnummerWachtwoordWachtwoordenbestandWachtwoord gemaskeerd met ******, voer opnieuw inWachtwoord beveiliging voor SABnzbd (aanbevolen)VersleuteldPadPatroonUitlegPauzeAlles pauzerenOnderbreek downloaden tijdens nabewerkenPauze IntervalPauzeerPauzeer 1 uurPauzeer 12 uurPauzeer 15 minutenPauzeer 24 uurPauzeer 3 uurPauzeer 30 minutenPauzeer 5 minutenPauzeer 6 uurHoeveel minuten pauzeren?Pauzeer...Pauzeer nabewerkenPauzeOnderbreek downloaden tijdens nabewerken.Pauzeer dubbele NZB "%s"Toegangsrechten voor verwerkte downloadsLet op, wanneer je 0.0.0.0 als hostnaam gebruikt, heb je voor externe toegang een IPv6 adres nodigVul hier een geheel getal in.Vul hier de gegevens van je primaire Usenet server in.Plush instellingenPoort nummerPoort waar op SABnzbd luistert.Nabewerking van %s mislukt (%s)NabewerkingVerwerk alleen correct geverifieerde downloadsMap met gebruikers scriptsNabewerkingNabewerken gestartNabewerking is afgebroken (%s)Wachtrij filter scriptVoorkeuzesGebruik Windowstoets-R en type deze regel in (voorbeeld):VorigeVorigePrioriteitMogelijk delen van accountGeen toegang tot nzbmatrix (%s)Probleem metVerwerkte bookmarksBewerkt resultaatModusNabewerking instellingenProgramma is niet opgestart!VoortgangOpschonenVerwijder geslaagde opdrachtenVerwijder mislukte itemsVerwijder mislukte opdrachtenVerwijder mislukte opdrachten incl. bestandenWis de volledige geschiedenisVerwijder opdrachtenVerwijderen incl. bestandenWis wachtrijWis de volledige geschiedenis?Verwijder uit de Wachtrij?Python versieQR CodeWachtrijWachtrij Eerste 10 ItemsVerversingsinterval van de WachtrijWachtrij reparatieWachtSnelle Controle...Snelle Controle uitvoerenAfsluitenQuotumQuotum overQuotum periodeQuotum verbruikt, downloaded is gestoptRRSSRSS uitlees intervalRSS-feed DefinitiesRSS-feed %s is leeg%s is klaarBereikZelden gebruikte opties. Voor betekenis en uitleg, klik op de Help knop om naar de Wiki te gaan.
    Wijzig hier niet zonder eerst de uitleg op de Wiki te lezen. Er kunnen nadelige bijwerkingen optreden.
    De standaard instellingen staan tussen haakjes.Alle feeds nu uitlezenUitlezenUitlezen RSS feedsLees de Wiki pagina over dit onderwerpKijk op https://www.oznzb.com/profileVerversVerversingstempoVerversingsinterval van het de Wachtrij pagina (sec, 0= geen).VerversenVerwerpenDe relatieve mappen zijn gebaseerd opTe doen/TotaalNog te doenVerwijderVerwijder NZBVerwijder NZB incl. bestandenVerwijderVerwijder mislukte opdrachtenBladwijzer automatisch verwijderen na succesvolle download.Verwijderen van %s misluktNaamReparerenReparatie mislukt, te weinig herstelblokken (%s te weinig)ReparerenReparatie mislukt, %sRepareren...Vervang verboden tekens in map namenVervang spaties in map namenVervang punten in map namenVervang punten door spaties in namen van mappen.Vervang verboden tekens in map namen door gelijkende tekens (anders verwijderen).Vervang spaties door onderliggende streepjes in namen van mappen.OverzichtNewzbin rapportVerplichtVerplichteCatHerstelQuotum nu herstellenHerstel dagHerstartenHerstarten zonder loginSABnzbd herstart nu...ResultaatDoorgaanHervat nabewerkenBewaartijdOpnieuwScript uitvoerenScript uitvoeren...Gebruiker script %s looptS01E05 EpisodemapS01E05 SeizoensmapSABnzbd %s is gestartHostWachtwoordPoortSABnzbd Snelstart HulpGebruikersnaamSABnzbd versieWeb serverSABnzbd heeft een fatale fout ontdekt:SABnzbd is afgeslotenSABnzbd werkt op de achtergrond.SMTP email serverSQL opdracht mislukt, zie log bestandSQL opslag opdracht mislukt, zie log bestandSSLSSL typezaterdagOpslaanOpslaanOpgeslagenOpslaan van %s lukt nietOpslaan..Bewaakte map uitlezenTaak voor niet bestaande server %sTaakplannerAgenda instellenScriptScriptsSeizoen NummerSecundair GebruikersinterfaceKies een taalVink dit alleen aan als je provider SSL verbindingen toestaat.SelectieVerzendenVerzend groepZend email voor RSSVerzend berekende validatie gegevens over downloads naar de indexer.Zend email wanneer een RSS bron opdrachten
    aan de wachtrij heeft toevoegd.Zend email wanneer SABnzbd gestopt is vanwege een volle harde schijf.Verzend de groepsnaam naar de server.Zend meldingen naar GrowlStuur berichten naar het BerichtencentrumZend meldingen naar NotifyOSD%s naar de wachtrij gestuurdSerie sorterenServerServer %s heeft gebruikersnaam/wachtwoord nodigServer %s wordt gedurende %s minuten genegeerdServer instellingenServer adresServer adres "%s:%s" is niet geldig.Server adres verplichtUsenet serversServer definitieServer wachtwoordDe server stopte tijdens de loginServer heeft een gebruikersnaam en een wachtwoord nodig.Server fout (code is %s); kon geen %s van %s krijgenServersSet Pauze IntervalZet toegangsrechten voor verwerkte bestanden/mappen, alleen octale notatie!Vul hier de NzbMatrix API sleutel in.Het adres van je Internet providers email server.Vul hier je wachtwoord in.Vul hier je gebruikersnaam in.InstellingenHet instellen is klaar!Moet het downloaden automatisch doorgaan bij het ingaan van het nieuwe quotum?Toon AllesBladwijzers tonenToon OptiesToon mislukteToon log infoSerie NaamToon Naam mapToon weblog infoToon detailsToon bestandenToon InterfaceToon tijden in AM/PM notatie (heeft geen invloed op de taakplanner)Serie.NaamSerie_NaamToon %s t/m %s van %s resultatenEén resultaatAfsluitenPC afsluitenSABnzbd afsluitenAfsluitenSignaal %s ontvangen, opslaan en afsluiten...API sleutel van indexerOmvangOverslaanGeen uitgebreide PAR2 controle als de bestanden 100% in orde zijn.Sommige bestanden konden niet geverifieerd worden met "%s"SorterenSorteer formuleSorteer op leeftijdSorteer op Leeftijd (Nieuw→Oud)Sorteer op Leeftijd (Oud→Nieuw)Sorteer op Leeftijd Nieuw→OudSorteer op Leeftijd Oud→NieuwSorteer op Naam (A→Z)Sorteer op Naam (Z→A)Sorteer op Naam A→ZSorteer op Naam Z→ASorteer op Omvang (Groot→Klein)Sorteer op Omvang (Klein→Groot)Sorteer op Omvang Groot→KleinSorteer op Omvang Klein→GrootOp leeftijdOp naamOp grootteSorterenSorteer instellingenBronSpeciaalSnelheidMax. snelheidMaximum snelheidPC standbyWizard startenStart reparatieStart/StopStatusStap VijfStap VierStap EenStap DrieStap TweeStopAfsluiten...OpslagOnderwerpzondagOptiesDiverse instellingenSysloadSysteem foldersTEKSTTE GROOTTaakTijdelijke download mapEmail testenTest MeldingTest ServerServer instellingen aan het testen...De "Repareren" knop herstart SABnzbd met een complete
    reconstructie van de wachtrij, met behoud van al gedownloade bestanden.
    Dit beïnvloedt wel de volgorde.De automatische Usenet downloaderOm de RSS-feed automatisch te verwerken, vink het selectievlakje bij de definitie naam aan.
    Wanneer een nieuwe feed wordt gedefinieerd, zullen alleen nieuwe items gevonden worden en geen bestaande, behalve wanneer je de op "Forceer download" klikt.Geen hostnaam opgegeven.Het aantal verbindingen dat je provider toestaat.Er zijn geen verbindingen opgegeven. Er is minimaal één verbinding nodig.Er staan verweesde opdrachten in de download map.
    Je kunt ze verwijderen (inclusief bestanden) of ze terug naar de wachtrij sturen.Verplicht veldDeze sleutel is het toegangsbewijs voor de indexer. Kijk op https://www.oznzb.com/profile.Met deze sleutel kan een hulp programma NZB bestanden naar SABnzbd sturen.Met deze sleutel heeft een hulp programma volledige toegang tot SABnzbd.Deze MaandDeze WeekDit voorkomt pagina verversing wanneer de muis aanwijzer in de wachtrij is.Deze knop zal SABnzbd herstarten.
    Dit kan nuttig zijn wanneer je vermoedt dat het programma niet stabiel is.
    Het downloaden zal vóór de herstart gestopt worden en daarna weer doorgaan.Hiermee stuur je een test email.VerbindingdonderdagTijdslimiet overschredenTijdslimiet overschreden. Probeer met SSL aan of gebruik een andere poort.Te gaanTijdslimietTitelTo: %s From: %s Date: %s Subject: SABnzbd meldt een volle harde schijf Hallo, SABnzbd is gestopt met downloaden omdat de harde schrijf bijna vol is. Maak ruimte vrij en laat SABnzbd weer doorgaan. Vandaag"NZB toevoegen" uitklappenTe weinig schijfruimte, pauze geforceerdTe veel verbindingen met server %s:%sTe veel verbindingen, onderbreek het downloaden of probeer later nog eens.BovenTop menu aan/uitTotaalProbleemoplosserOpnieuwProbeer de succes kans van een download van te voren in te schatten (langzamer!)Probeer SFV verificatieProbeer NZB op te halen van %sPoging om status van niet bestaande server %s te wijzigenProbeer unrar met wachtwoord "%s"dinsdagAfstellingSoortUHet UNC pad "%s" mag hier niet.ONGEWENSTURL ophalen mislukt; %sGEBRUIK OP EIGEN RISICO!Bladwijzers achteraf verwijderenNiet geauthoriseerd, controleer je newzbin gebruikersnaam/wachtwoordDeblokkerenOnbekende fout tijdens het decoderen van %sOnbekende aktie: %sUitpakken%s bestanden/mappen uitgepakt in %sUitpakkenUitpakken mislukt, %sUitpakken mislukt, CRC foutUitpakken mislukt, er zijn te weinig bestanden uitgepaktUitpakken mislukt, archief heeft wachtwoord nodigUitpakken mislukt, bestandspad is te langUitpakken mislukt, zie logUitpakken is mislukt, deze bestand(en) ontbreken:Uitpakken mislukt, kan %s niet vindenUitpakken mislukt, schrijffout of schijf vol?Onbruikbaar NZB bestandOnbruikbaar RAR bestandOngewenste extensie zit in RAR file %sOngewenste extensiesHogerUpdate beschikbaar!OphalenUpload: .nzb .rar .zip .gzAktiefGebruik de 12-uren klok (AM/PM)Gebruik V23, behalve wanneer persé nodig voor je Internet provider!Gebruik tijdelijke mapnamen tijdens de nabewerking. Zet dit uit wanneer je systeem daar problemen mee heeft.Gebruik de "Groepen / Indexer markeringen" kolom om groepen en markeringenop je categorieën af te beelden.
    Joker karakters zijn toegestaan.Gebruik komma's om elementen te scheiden.Wordt uitgevoerd vóór een NZB de queue in gaatGebruikte bufferWordt gebruikt wanneer de categorie geen nabewerking opgeeft.Wordt gebruikt wanneer de categorie geen prioriteit opgeeft.Wordt gebruikt wanneer de categorie geen script opgeeft.GebruikersmappenCategorieën voor nabewerkingGebruikersnaamWaardenVerificatie m.b.v. SFV bestanden is geluktVerifiërenVerificatie...VersieVideoToon Script resultaatToon script resultaatVirus/spamWACHT %s secWAARSCHUWING:Waarschuwing: "%s" is afgebroken vanwege versleuteld RAR bestandWAARSCHUWING: Ongewenste extensie ontdekt in "%s". Ongewenst bestand is "%s" WAARSCHUWING: Item "%s" gepauzeerd vanwege versleuteld RAR bestandMELDINGENWachtWaarschuwingLet op: LOCALHOST is niet eenduidig, gebruik een numeriek IP-adres.MeldingenBewaakte mapLeestempo bewaakte mapGebruikersinterfaceWeb server authenticatiewoensdagInformeer iedere week naar nieuwe SABnzbd versies.WanneerProbeer deze artikelen opnieuw te downloaden van een reserve server.Als tijdens de download duidelijk wordt dat te veel data ontbreekt, breek dan de download afWie zou de email gestuurd moeten hebben?WikiXjaarJaar-Maand MappenJe hebt geen betaald Newzbin accountJe hebt geen toestemming om poort %s te gebruikenJavaScript is nodig voor de werking van Plush!Je hebt een nzbmatrix VIP account nodig om de API te kunnen gebruikenVersie van UNRAR wordt niet aanbevolen, download UNRAR van http://www.rarlab.com/rar_add.htm
    [%s] Fout "%s" bij samenvoegen van bestanden[%s] Fout "%s" bij het uitpakken van RAR bestanden[%s] %s bestanden samengevoegd[%s] Geen par2 groepen[%s] De PAR2 opties zijn niet goed, controleer Instellen->Opties[%s] Snelle Controle OK[%s] Reparatie in %s[%s] Verificatie in %s, alle bestanden zijn goed[%s] Verificatie in %s, reparatie is nodig_yenc module niet gevonden!Aanpassen van hoofd- en kleine lettersWissenddagdagenServer uit:Server aan:msgid %s aan het ophalen van www.newzbin2.esbestandmaphuururenovermhandmatigminmin.minniet geinstalleerdvanuitaanofPaginapar2 programma niet gevonden!Module "pyopenssl" ontbreekt, geen HTTPS mogelijksecsecondenzie logbestandtekstonbekendunrar programma niet gevonden!unzip programma niet gevonden!weekSABnzbd-0.7.20/locale/pl/LC_MESSAGES/SABnzbd.mo0000644000000000000000000022261512433712601020513 0ustar00usergroup00000000000000=o=>d.?@A aB2nCDEF*F'FFGG 6GWGfGG GGGGGHHHHHHHHH?hII+J/J7JRGJ[JJK0K7K >K LKYK`KhKKKKK K KK KKKaLdLhLlL.sLLL)L*L )M 7MAMUM/hMhM N N"N(N0N*O+O0O 7OEO^O ~OOOOOOXPpP2P PP P Q;QYQ!xQ6Q-QQR-RKR gRrR.{R'RRRRBS[SdSSvSS SS5S2T8TGT"\TT8T TT TTT U U U:U&RUyU UU$U*UUVV V!V 'V 5V BVOVVViVqVVVV$VVV VV W W(W(>WgW%W W-WW Xf(XXX4XX?X%Y?YWYvY,YY,YY1Z5GZ}ZZZ ZZZ1Z5[58[n[ }['[[ [ [ [ [[[ \ \ \ '\1\K\e\\\\\\\$\ \] ] ]+]B]#T]x]]]]]]] ] ]^ ^5^K^\^o^^^^ ^ ^4^$ _$2_W_Sl_-_5_0$`(U`~`H` ` `` ` a(a.8a)ga&a,a<ab"b&bbb7b'c:cLchcc c c&c-c%dBd^d mdxd d dd ddddde%e!Eege+e ee!ef!/fFQff0f-f' g4g"Ogrgggggg hhhh h)h?hXhshAhh'hi#i,i5i-(Hq Àր# ?LbMi#ҁRI<f "Ղ(GWo-ۃ' 3@T epԄ   :FYjy ƅͅ܅  /15K]szr  ‡?χ # A NX _j 4ڈ2 .8 M*Z)M05 fp y Êي "4Ka v ͋݋.* Ye Čʌی# '@G O] u4 ˍ Ս33+._ʎێ (;J$Y~"͏&o2) ,53L Ñ͑ޑ 9 O Y"c  '͒-(-V [ g/s/-ӓ-&/&V$}$3ǔ31/1a וޕ  +< C MW `kt yĖӖ ؖ  *D"22Ae,>D= ̚W֚.,ӛ >Ybjp$*"9$\AÝǝН ֝ E3K.gŞʞ̞ 2:mu ϟٟ3 ->"l,#֠.);MPbi0b֡9$Ƣ 81/4a ģ%ˣ  3?7H6Ȥ:Ф # =K e%o@!ۥ *$G1l0ZϦ#*)NxJ&'9a | &ߨ  "%),/49N ǩrxG3%/$ &9?+yŴݴ5!$W | T bou }ǶE^3 8B_TX +JS Zg{ ʹ ܹ K1}@Ӻ!# > L#Vz3{ŻA[{/ 1=5oƽ (7NVo-<L)$ӿ(,@m1G(+.Ap ) T< `$67V#*:9L `j  4* <G)[,  "6?Wv1  (-9g)#%j5 4A9U%r!7 ..=E5 J$9o9 0 ; F PZ^ v -!(>D([  +&+=\b %!?as ,$%F53|?-(GRP .8/P,6;Z '{"-*/%Hn## +8 Ff  1 M%n(5:#.#R*v^.AN55%!"D$Y&~.   )!BdxQ!,',T co-u3>iW)#(.@O U b p~$+FUf  "8IO_*d*=: B LYj n<xAt@ 1>  *9#d!8)2/\(=5)_:gx/K>] 7<&:+flu<: ", CqMrHKhk#i   !" 9AC )    +;P hr  14A'v -<IB;' .3</K{ (! 8BQth'R%.x0# +6O`"}  !, 3=M S2^3 41 HUl !1 QU\!#<55O +26 )Bl!$ 2 , 7 BL,h  4M!b   +-Y is ,!2IX_h 'U?Y `  0 *6U> 1""!,D`q2  " ( 6CTj#.D X f#s! & 2*S~ * !-IP Xe}3  33..b"5*6a t#$ /00aiy -!O a  A ! 0  @ N b v   7   "  / 7 G  V 9a   5 >  % 8 :L : 8 8 *4 *_ ( ( @ @ >^ >     4 <FO_o~      $ * 4A ]h{  -"3T,{@3U  74S U_v|NV)k$Q  !'7RI4#% ,8<>#Z~?$&9&Bi#x9F>1\9<5?;{&*G(|*)*<Ndv- ! ? @`  9  *  G U r 9x  :  !!!! 4!(U!)~!(!d!%6"1\"""W"#5#3J#)~####### # $*$;$@$H$J$R$ Z$d$f$n$u$z$$$ $$$$ $B$%%%3%8%!A%!c%% SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:Aborted, cannot be completedAborted, encryption detectedAcceptAccessAccess deniedAccount infoActionActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)Cannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.Complete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification Sent!NotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOther MessagesOther SwitchesPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!RefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.Report-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSend GroupSend RSS notificationsSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUnusable RAR fileUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogView script outputWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.Who should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2014-07-02 18:04+0000 Last-Translator: shypike Language-Team: Polish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:54+0000 X-Generator: Launchpad (build 17082) SABnzbd nie moze znalezc plików interfejsu WWW w %s.
    Nalezy zainstalowac program ponownie.

    SABnzbd wykryl kolejke i hostorie ze starszej (0.4.x) wersji.

    Zostana one zignorowane i moga zostac utracone!

    Mozesz zatrzymac SABnzbd i dokonczyc kolejke ze starsza wersja programu.

    Kliknij OK aby konynuowac z SABnzbd SABnzbd wykryl dane zapisane w innej wersji SABnzbd
    lecz nie moze ponownie uzyc tych danych.

    Powinienes najpierw zakonczyc kolejke w innym programie.

    Nastepnie nalezy uruchomic program z opcja "--clean".
    SPowoduje to wymazanie aktualnej kolejki i histori!
    SABnzbd czyta plik "%s". SABnzbd wykryl brak pliku sqlite3.dll.

    Niektóre zle dzialajace programy antywirusowe usuwaja ten plik.
    Sprawdz swój skaner antywirusowy, spróbuj przeinstalowac SABnzbd i zglos problem dostawcy antywirusa.

    SABnzbd nie jest zgodny z niektórymi programai typu firewall.
    %s
    Przepraszamy, ale nie mozemy obecnie rozwiazac tego problemu.
    Zglos problem u dostawcy swojego programu.

    SABnzbd wymaga wolnego portu tcp/ip dla wewnetrznego serwera www.
    Próbowano portu %s na %s, ale nie jest dostepny.
    Inny program uzywa tego portu lub SABnzbd jest juz uruchomiony.

    Uruchom ponownie SABnzbd na innym porcie. SABnzbd wymaga wolnego portu tcp/ip dla wewnetrznego serwera WWW.
    Próbowano portu %s na %s, lecz uzytkownik dla SABnzbd nie ma uprawnien do jego uzycia.
    W systemach OSX oraz Linux normalny uzytkownik musi uzywac portów ponizej 1023.

    Zrestartuj SABnzbd na innym porcie. SABnzbd wymaga prawidlowego adresu hosta dla wewnetrznego serwera WWW.
    Podano nieprawidlowy adres.
    Bezpieczne wartosci to localhost i 0.0.0.0

    Zrestartuje SABnzbd z prawidlowym adresem. SABnzbd nie posiada ABSOLUTNIE ZADNEJ GWARANCJI. Program jest wolnym oprogramowaniem i zachecamy do jego rozpowszechniania z zachowaniem odpowiednich warunków. Program jest wydany na licencji GNU GENERAL PUBLIC LICENSE wersja 2 lub (dla twojego wyboru) kazda pózniejsza wersja. %s -> Nieznane kodowanie%s => nie znaleziono na zadnym serwerze, porzucam zadanie%s artykulów posiada niepasujace duplikaty%s artykulów bylo uszkodzonychBrakowalo %s artykulówUsunieto %s artykulów%s katalog: %s: blad dostepu%s plików w %s%s jest nieprawidlowa wartoscia w systemie ósemkowym%s nie jest prawidlowym adresem mailbrakuje %s  Rozwiazywanie odresu lub ID raportu 
    SABnzbd zostal wylaczony.
    Zaczekaj okolo 5 sekund i kliknij guzik ponizej.

    Odswiez
    + Debugowanie+ Informacje+Usun+Napraw+RozpakujKatalog backupów .nzbKatalog odcinka 1x05Katalog sezonu 1x05UWAGA: Katalogi zostana automatycznie utworzone po zapisaniu. Mozna uzywac sciezek absolutnych aby wskazac katalogi poza domyslnym katalogim.Dane nie zostana przeniesione. Wymaga restartu SABnzbd!Czytaj kanal pobierze aktualna zawartosc kanalu. Wymus pobranie pobierze teraz wszystkie pasujace pliki NZB.WIEKKlucz APIKod QR klucza APIKlucz API jest nieprawidlowy, uzyj klucza API z Konfiguracja->Ogólne w twoim drugim programie:Brak klucza API, nalezy wprowadzic klucz API z Konfiguracja->Ogólne do innego programu:Przerwano, nie mozna ukonczycPrzerwano, wykryto szyfrowanieAkceptujDostepBrak dostepuInformacje o koncieAkcjaAkcjeWlacz alternatywna skórke.DodajDodaj kanalDodaj plikDodaj NZBDodaj harmonogramDodaj serwerDodaj nowe plikiDodano NZBKatalog administracyjnyDotkniete kategoriePo zakonczeniu ponownego uruchamiania bedziesz mial dostep do niego pod: %sWiekWszystkoZawszeZastosuj maksymalna ilosc prób tylko dla serwerów dodatkowych.Zastosuj do zaznaczonychCzy na pewno usunac?Czy na pewno zrestartowac SABnzbdNa pewno wylaczyc SABnzbd?Czy na pewno?ArgumentyLimit pamieci podrecznej artykulówIdentyfikator artykuluBlad polaczenia, sprawdz nazwe uzytkownika i haslo.Brak danych uwierzytelniajacych, wprowadz nazwe uzytkownika/haslo z Konfiguracja->Ogólne do twojego zewnetrznego programu:Automatyczne przywracanieAutomatycznei pobieraj zakladkiZatrzymaj automatycznie jesli pozostanie mniej miejsca niz ta wartosc.
    w bajtach, opcjonalnie z K,M,G,T. Na przyklad: "800M" lub "8G"Automatycznie pobieraj posty dodane do zakladekAutomatycznei pobieraj zadania z twoich zakladek.Automatycznie sortuj pozycje wedlug (sredniego) wiekuPowrótZapasowySerwer zapasowyZly harmonogram %s w %s:%sZle zbudowny artykul yEnc w %sPrzepustowoscZablokuj odswiezanie podczas wskazywaniaPrzetwarzanie zakladekNa dólBlad CRC w %s (%s -> %s)Umieszcza artykuly w pamieci podreczne aby ograniczyc korzystanie z dysku.
    w bajtach, opcjonalnie z dodatkiem K,M,G. Na przyklad: "64M" lub "128M"Przechowano %s artykulów (%s)Nie mozna zmienic uprawnien %sNie mozna sie polaczyc do galezi rejestru HKEY_CURRENT_USER.Nie mozna polaczyc sie z serwerem %s [%s]Nie moge utworzyc %s katalog %sNie moge utworzyc kopii zapasowej %sNie mozna stworzyc katalogu %sNie mozna utworzyc koncowego katalogu %sNie mozna utworzyc tymczasowego pliku dla %sBrak szablonów maili w %sNie ma szablonu: %s, uzyto standardowego szablonuNie mozna uruchomic przegladarki, prawdopodobnie nie zostala znalezionaNie mozna otworzyc klucza rejestru "%s".Nie mozna odczytac %sNie mozna przeczytac Obserwowanego Katalogu %sNie moge zapisac pliki INI %sKategorieKategoriaNiezachowano zmian, zostana one utracone.Zmiany wymagaja restartu SABnzbdSprawdz przed pobraniemSprawdzaj aktualizacjeSprawdzaj wyniki rozpakowywaniaSprawdzaj wyniki rozpakowywania (nalezy wylaczyc dla niektórych systemów plików).SprawdzanieInterwal sprawdzaniaInterwal sprawdzania (w minutach, co najmniej 15). Nieuzywany podczas korzystania z harmonogramuWybierz skórke.Lista czyszczeniaCzyszczenie %s nie powiodlo sieCzysc pliki par (jesli weryfikacja/naprawa byla udana).WyczyscWyczysc licznikiNacisnij ponizej, aby przetestowac.Kliknij aby przetestowac wprowadzone dane.ZamknijZamkniecie okna przegladarki lub karty NIE zamknie SABnzbdKatalog na pobraneFolder zakonczonychUkonczoneKatalog dla ukonczonych plikówKonfiguracjaPlik konfiguracyjnyKonfiguracjaPotwierdzaj usuwanie historiiPotwierdzaj usuwanie z kolejkiPolaczenie z %s@%s:%s nieudane, odpowiedz serwera=%sPolaczenie udane!PolaczeniaSzerokosc konteneraNie mozna usunac zzakladki Newzbin dla %sNie mozna okreslic rezultatu polaczenia (%s)Obecne harmonogramyWlasnyUZDUPLIKOWANYCodziennieKatalogi dzienneSortowanie po dacieDzien miesiacaDekadaBlad dekodowania %sDomyslnyDomyslny katalog bazowyDomyslne przetwarzanie koncoweDomyslny priorytetDomyslny skrypt uzytkownikaDefiniuje przetwarzanie koncowe i przechowywanie.UsunUsunUsun wszystkoUsuwanie zakonczoneUsuwanie nie powiodlo sieUsun kanalUsun po pobraniuUsunac z historii wszystkie ukonczone pliki?Usunac wszystkie pobrane pliki?Usunac z historii wszystkie bledne pliki?Usunac wszystkie obiekty z kolejki?Usunac wszystkie nieudane z hostorii?Usuwanie %s nie powiodlo sie!Wykrywaj zduplikowane plikiWykrywaj identycznie nazwane pliki NZB (wymaga opcji backupu NZB) oraz zduplikowane tytuly w kanalach RSS.Wylacz klucz APIWylaczoneWylaczono HTTPS z powodu braku plików CERT oraz KEYPorzucRozlacz serwer(y) Usenet kiedy kolejka jest pusta lub zatrzymana.Rozlacz przy pustej kolejcePowiadomienie o pelnym dyskuBlad dysku podczas tworzenia pliku %sDysk pelny! wstrzymuje pobieranieWykonuj dodatkowa weryfikacje na podstawie plików SFV.Nie pobierajBrak poprawnego uwierzytelnienia dla kanalu %sNie wymagaj klucza APICzy limit jest kasowany dziennie, tygodniowo czy miesiecznie?Nie posiadasz dostawcy usenet? Polecamy spróbowac %sNizejPobierzZakonczono pobieranieKatalog pobieraniaPobieranie nie powiodlo sieLimit pobierania danychPobieranie nie powiodlo sie - Poza okresem przechowywania twojego serwera?Pobieranie moze sie nie udac, dostepne %s z wymaganych %sLimit pobierania danych (w KB/s - kilobajtach na sekunde)Szybkosc pobieraniaPobranePobrano w %s ze srednia %sB/sDotychczas pobranoPobieraniePobieranieDualView1DualView2Np.Np. 119 lub 563 dla SSLNp. 8 lub 20ZASZYFROWANYBLAD:BLAD: %sBLAD: nieprawidlowa suma kontrolna CRC w "%s"BLAD: za dluga sciezka (%s)BLAD: nie mozna znalezc "%s"BLAD: blad zapisu (%s)ETAEdytujEdytuj szczególy NZBEmailUstawienia konta emailPowiadomienia email po zakonczeniu zadanOpcje emailOdbiorca emailiNadawca emailWyslano email!Katalog szablonów emailWynik testu emailAdres email na który wysylac powiadomieniaWiadomosc wyslanaBrakPusty plik NZB %sZnaleziono pusty wpis RSS (%s)WlaczWlacz sortowanie wedlug datyWlacz laczenie plikówWlacz GrowlWlacz HTTPSWlacz dostep HTTPS do SABnzbdWlacz sortowanie filmówWlacz wielordzeniowy Par2Wlacz NotifyOSDWlacz czyszczenie parWlacz szybkie sprawdzanieWlacz sprawdzania bazujace na SFVWlacz laczenie TSWlacz sortowanie TVWlacz unranWlacz unzipWlacz dostep do interfejsu przez adres HTTPSWlacz wbudowana funkcjonalnosc unrarWlacz wbudowana funkcjonalnosc unzip.Wlacz zmiane nazwy katalogówOszczedza pamiec. Nalezy wylaczyc jesli wolne zadania blokuja kolejke.Wlacz standardowe sortowanie i zmiane nazw plików.Wlacz, jesli zadania nie sa umieszczane we wlasnych katalogach.Wlacz sortowanie i zmiane nazwy wedlug dacie.Wlacz sortowanie i zmiane nazw odcinkówWlaczoneZakonczenie sciezki znakiem asterisk * zapobiegnie tworzeniu katalogów dla zadan.Wprowadz URLNazwa OdcinkaNumer OdcinkaNazwa.OdcinkaNazwa_OdcinkaBlad "%s" podczas uruchamiania file_join na %sBlad "%s" podczas wykonywania par2_rapair na zestawie %sBlad "%s" podczas uruchamiania rar_unpack na %sBlad "%s" podczas uruchamiania unzip() na %sBlad %s podczas uruchamiania par2_repair na zbiorze %sBlad %s: nalezy podac prawidlowa nazwe uzytkownika i haslo.Blad pobierania %s z www.newzbin2.es - Upewnij sie, ze ustawiles nazwe uzytkownika i hasloBlad tworzenie certyfikatu i klucza SSLBlad pobieranie informacji TV (%s)Blad importu %sBlad importu modulu OpenSSL. Laczenie bez SSLBlad ladowania %s, wykryto uszkodzony plikBlad podczas usuwania %sBlad usuwania katalogu roboczego (%s)Blad zmiany nazwy "%s" na "%s"Blad podczas dodawania %s, usuwanieWylaczenie systemu nie powiodlo sieTylko bledyBlad: nie zdefiniowano drugiego interfejsu.Blad: Kolejka nie jest pusta, nie mozna zmienic kataloguBlad: nieparwidlowy klucz sesjiBlad: wymagany klucz sesjiBledy/OstrzezeniaWszystkoPrzykladWyjscie SABnzbdRozszerzenieDodatkowe parametry PAR2Rozpakowywanie...Przerywaj po bledach CRC yEncNieudaneBlad logowania do serwera %sNie udalo sie utworzyc (%s)Nie udalo sie przeniesc %s do %sBlad autoryzacji z serwerem pocztowymBlad zamykania bazy danych, sprawdz logiNie udalo sie zamknac polaczenia z serwerem pocztowymBlad kompilacji wyrazenia regularnego dla wyszukiwania: %sBlad polacenia z serwerem pocztowymHibernacja systemu nie powiodla sieNie udalo sie zaimportowac %s plików z %sBlad inicjowania %s@%s:%sBlad polaczenia TLSNie udalo sie wczytac kolejki przetwarzania koncowego: Zla wersja (wymagana:%s, znaleziona:%s)Nie udalo sie przeniesc plikówNie udalo sie odczytac kluczy rejestru dla katalogów specjalnychNie udalo sie usunac nzo z kolejki przetwarzania (id)Nie udalo sie zmienic nazwy podobnego pliku: %s na %sNie udalo sie zmienic nazwy: %s na %sNie udalo sie pobrac RSS z %s: %sBlad wysylania mailaWstrzymanie systemu nie powiodlo sieNie udalo sie uruchomic interfejsu wwwNie udalo sie zaktualizowac zadania newzbin %sNiepowodzenieBlad w tempfile.mkstempBlad krytycznyKanalKanalyPobierzPobieraniePobieranie %s bloków...Pobieranie dodatkowych bloków...Plik %s jest pusty,Rozszerzenie plikuPlik zawierajace wszystkie hasla do wykorzystania dla zaszyfrowanych plików RAR.Laczeni pliku %s nie powiodlo sieNazwa pliku lub sciezka do certyfikatu HTTPSNazwa pliku lub sciezka do klucza HTTPSZestaw plikówNazwa plikuFiltrOdfiltrowuj pliki próbek (np. próbki wideo)FiltryPierwszaFolder "%s" nie istniejeKonfiguracja katalogówKatalog zawierajacy skrypty przetwarzania koncowegoKatalog zawierajacy szablony uzytkownika dla powiadomien emailKatalog monitorowany na obecnosc plików .nzb.
    Skanuje równiez pliki .zip, .rar oraz .ta.gz.Katalog/SciezkaKatalogiNazwa konta dla kont z uwierzytelnieniem.Haslo dla kont z uwierzytelnieniem.WymusWymus rozlaczenieWymus pobranieForumWolne (Temp)Wolne miejsceCzestotliwoscPiatekDalsza pomoc mozna uzyskac na naszejGBOgólneOgólna konfiguracjaUtwórz nowy kluczSortowanie standardowePobierz zakladkiPobierz teraz zakladkiPobieranie NZBPobierz zakladki z NewzbinIdz do SABnzbdUruchom kreatoraGrupy / Etykiety indekseraCertyfikat HTTPSKlucz HTTPSPort HTTPSWsparcie dla HTTPSPomocHibernuj komputerUkryj zakladkiUsun opcje edycjiUkryj szczególyUkryj plikiWysokiHistoriaHistoria ostatnich 10Rozmiar historiiStartStrona projektuHostHost na którym SABnzbd bedzie uruchomionyGodziny:MinutyIle danych mozna pobrac w miesiacu (K/M/G)Chce, aby kazdy komputer w mojej sieci mial dostep do SABnzbdChce, abym mial dostep do SABnzbd tylko z mojego komputeraBEZCZYNNYNIEKOMPLETNYParametry IONiceIRCBezczynnyJesli nie podano obsluga HTTPS bedzie na standardowym porcieJesli jestes czlonkiem newzbin lub nzbmatrix, mozesz tutaj podac swoja nazwe uzytkownik i haslo aby umozliwic pobieranie NZB stamtad. Ten etam mozna pominac jesli nie uzywasz tych serwisów.Jesli ponownie otrzymasz ten sam blad, spróbuj zmienic port.
    Jesli posiadasz konto na www.newzbin2.es, mozesz tutaj podac jego dane.
    Spowoduje to wlaczenie dodatkowych funkcji.Jesli posiadasz konto w www.nzbmatrix.com, mozesz tutaj podac jego dane.
    Jest to wymagane do uzywania kanalów RSS z tej strony.Ignoruj próbkiIgnoruje zduplikowany NZB "%s"wW katalogachW minutach (co najmniej 15).Pobieranie z usenet wymaga dostepu do dostawcy. Twój ISP moze umozliwiac dostep, aczkolwiek zalecany jest dostawca klasy premium.Niekompatybilny kanalZnaleziono niekompatybilny plik kolejki, nie mozna kontynuowacFolder niezakonczonychNiekompletny plik NZB %sNiekompletna sekwencja plików do laczeniaNieprawiodlowy opis kanalu RSS "%s"Bledny parametrNieprawidlowa wartosc %s: %sNieprawidlowo zakodowane haslo %sIndeksyInicjuje restart...
    Nieprawidlowy plik NZB %s, pomijam (powód=%s, linia=%s)Nieprawidlowe kodowanie szablonu maila %sNieprawidlowe dane uwierzytelniajace nzbmatrix.Nieprawidlowy numer raportu nzbmatrix %sNieprawidlowe pliki par2, nie mozna zweryfikowac lub naprawicNieprawidlowy adres serwera.Niewlasciwe dane serweraNieprawidlowy zapis dziennika etapu w historii dla %sOdwrócWyglada na to, ze uzywasz ZoneAlarm na systemie Vista.
    Zalecamy dodanie tej strony do zakladek i uzywanie tej zakladki do pózniejszego dostepu do SABnzbd uruchomionego w tle.Zadanie "%s" zostalo dodane ponownie do kolejkiZadanie ukonczoneZadanie oznaczone jako '*' nie zostanie automatycznie pobrane.Zlacz plikiLacz pliki konczace sie na .001, .002 itd. w jeden plikLacz pliki konczace sie na .001.ts, 002.ts itd. w jeden plikLaczenieKB/sTrzymaj niesklasyfikowane zadania w dodatkowych katalogachJezykOstatniaOstatnie ostrzezeniaUruchom przegladarke na starcieUruchom strone SABnzbd w przegladarce kiedy program startujeUruchom domyslna przegladarka podczas startowania SABnzbd.PozostaloOgraniczenie predkosciOdnosnikiLista rozszerzen które powinny zostac usuniete po sciagnieciu.
    Na przyklad:.nfo lub .nfo,.sfvNie udalo sie wczytac %sPolozenie admina kolejki oraz bazy danych historycznych.
    Mozna zmienic tylko kiedy kolejka jest pusta.Polozenieplików dziennika SABnzbd.
    Wymaga restartu SABnzbd!Miejsce przechowywania ukonczoncyh, przetworzonych plików.
    Mozna nadpisac przez kategorie.Miejsce przechowywania nieprzetworzonych plików.
    Mozna zmienic tylko kiedy kolejka jest pusta.Miejsce przechowywania plików .nzbKatalog dzienników zdarzenLogowanieNiskiMale literyMBGlówna paczka nieznaleziona...DopasowanoMax szybkoscMaksymalna ilosc prób per serwerMaksymalna ilosc próbZnaczenieMinimalna ilosc wolnego miejsca w tymczasowym katalogu pobieraniaPozostaleBrak klucza sesjiBrakujace artykulyBrak oczekiwanego pliku: %s =>blad unrar?PoniedzialekMiesiacWiecejNazwa filmuNazwa.FilmuNazwa_FilmuPrzenoszeniePrzenoszenie...Wielokrotne operacjeWIeloczesciowa etykietaKlucz NZBNZB dodany do kolejkiNazwaNazewnictwoNigdyNowy URL kanaluDostepne nowe wydanie %s naDostepne jest nowe wydanieHaslo NewzbinNazwa uzytkownika NewzbinNewzbin zwrócil nieudokumentowany kod bledu (%s)Newzbin zwrócil nieudokumentowany kod bledu (%s,%s)Raport Newzbin %s nie zostal znalezionySerwer Newzbin zmienil protokólSerwer Newzbin nie zwrócil informacji dla %sNastepnaParametry niceNie znaleziono programu PAR2, naprawa nie jest mozliwa
    Nie znaleziono programu UNRAR, wypakowanie flików nie jest mozliwe
    Nie znaleziono szablonów mailiBrak katalogówBrak przetwarzania koncowego z powodu nieudanej weryfikacjiBrak odbiorców, nie wyslano wiadomosciBrak wynikówBrakNormalnyNie dopasowanoBrak miejsca na dysku na dokonczenie pobieraniaNie dopasowanoWyslano powiadomienie!PowiadomieniaIlosc sekund miedzy skanami plików .nzbKlucz NzbMatrixNazwa uzytkownika NzbMatrixOKOPCJONALNE haslo do kontaOPCJONALNA nazwa kontaWylaczonePo zakonczeniuPo zakonczeniu kolejkiW którym dniu miesiaca lub tygodnia (1=poniedzialek) twój dostawca resetuje limit pobierania (opcjonalnie z gg:mm)Pobieraj artykuly tylko z góry kolejkiTylko dla dodatkowych serwerówUruchamiaj przetwarzanie koncowe tylko dla zadan, które przeszly sprawdzanie PAR2Tylko dla zdalnych serwerów Growl (host:port)Otwórz URL informacyjnyOtwórz URL zródlowyOtwórz okno terminala i wpisz linie (przyklad):Otwórz katalog z pobranymi plikamiOpcjonalnyOpcjonalne dodatkowe NZBOpcjonanle hasloOpcjonalna nazwa uzytkownikaOpcjonalne haslo dla serwera GrowlOpcjonalnie podaj nazwe plikuOpcjeKolejnoscOryginalna nazwa plikuOryginalna nazwa kataloguInne komunikatyInne przelacznikiZATRZYMANEStronaParametryNumer fragmentuHasloPlik haselHaslo ukryte za ******, prosze wprowadzic ponownieZabezpiecz dostep do SABnzbd haslem (rekomendowane)SciezkaWzorzecKlucz wzorcaPauzaZatrzymaj wszystkieZatrzymaj pobieranie podczas przetwarzania koncowegoInterwal wstrzymywaniaZatrzymaj naWstrzymaj na 1 godzineWstrzymaj na 12 godzinWstrzymaj na 15 minutWstrzymaj na 24 godzinyWstrzymaj na 2 godzinyWstrzymaj na 30 minutWstrzymaj na 5 minutWstrzymaj na 6 godzinNa ile minut wstrzymac?Wstrzymaj na...Zatrzymaj przetwarzanie koncoweWstrzymanoZatrzymuje pobieranie na poczatku przetwarzania koncowego i przywraca po zakonczeniu.Zatrzymuje zduplikowany NZB "%s"Uprawnienia dla ukonczonych plikówNazwa hosta 0.0.0.0 wymaga adresu IPv6 do dostepu z zewnatrzWprowadz liczbe calkowitaPodaj szczególy twojego podstawowego dostawcy usenetOpcje PlushPortPosrt na którym SABnzbd bedzie uruchomionyPrzetwarzanie koncowe nie powiodlo sie dla %s (%s)Przetwarzanie koncowePrzetwarzanie koncowe tylko dla zweryfikowanych zadan.Katalog skryptów przetwarzania koncowegoPrzetwarzanie koncoweUruchomiono przetwarzanie koncowePrzetwarzanie zostalo przerwane (%s)Skrypt uzytkownika przed kolejkaPredefiniowaneNacisnij Klawisz start+R i wpisz linie (przyklad):PoprzedniaPoprzedniaPriorytetPrawdopodobny sharing kontaProblem z dostepem do serwera nzbmatrix (%s)Problem zPrzetworzone zakladkiPrzetworzone wynikiPrzetwarzaniePrzetwarzanie przelacznikówProgram sie nie uruchomil!PostepWyczyscWyczysc ukonczone NZBWyczysc historie bledówWyczysc nieudane NZBWyczysc nieudane NZB i usun plikiusuniecie historiiWyczysc NZBWyczysc NZB i usun plikiCzyszczenie kolejkiWyczyscic historie?Wyczyscic kolejke?wersja PythonKod QRKolejkaZakolejkuj 10 pierwszychInterwal automatycznego odswiezania kolejkiNaprawa kolejkiW kolejceSzybkie sprawdzanie...Szybkie sprawdzanieZakonczLimit pobieraniaPozostalo limituOkres limituPrzekroczono limit, zatrzymywanie pobieraniaNRSSInterwal sprawdzania RSSKonfiguracja RSSKanal RSS %s byl pustyUruchomiono %sZakresRzadko uzywane opcje. Jesli chcesz sie dowiedzic co oznaczaja, klikniej przycisk Pomoc i przeczytaj strony Wiki.
    Nie zmieniaj tych opcji bez uprzedniego przeczytania Wiki, poniewaz niektóre maja skutki uboczne.
    Domyslne wartosci sa umieszczone w nawiasach.Czytaj teraz wszystkie kanalyPobierz kanalCzytaj kanaly RSSPrzeczytaj na ten temat w Wikii Pomocy!OdswiezCzest. odswiezaniaInterwal autmatycznego odswiezania strony kolejki w interfejsie WWW (sekundy, 0=brak)Czestotliwosc odswiezaniaOdrzucWzgledne katalogi sa bazowane naPozostalo/RazemPozostaloUsunUsun NZBUsun NZB i plikiUsun serwerUsun nieudane zadaniaUsun z listy zakladek po zakonczeniu pobierania.Usuwanie %s nie powiodlo sieZmien nazweNaprawaNaprawa nie powiodla sie, brak wystarczajacej ilosci bloków naprawczych (brakuje %s)NaprawianieNaprawa nie powiodla sie, %sNaprawianie...Zastap niedopuszczalne znaki w nazwach katalogówZastap spacje w nazwach katalogówZastap kropki w nazwach katalogówZastap kropki w nazwach katalogów spacjami.Zastap niedopuszczalne znaki w nazwach katalogów ich odpowiednikami (w przeciwnym wypadku usun)Zastap spacje w nazwach katalogów podkresleniami.Kod raportuWymagaWymagaKatResetResetuj limitDzien resetuUruchom ponownieRestart bez logowaniaREstarowanie SABnzbd...WynikWznówWznów przetwarzanie koncoweCzas przechowywaniePonówUruchamianie skryptuWykonywanie skryptu...Uruchamianie skryptu uzytkownika %sKatalog odcinka S01E05Katalog sezonu S01E05Adres hosta SABnzbdHaslo SABnzbdPort SABnzbdSzybki kreator konfiguracji SABnzbdUzywkownik SABnzbdWersja SABnzbdSerwer www SABnzbdSABnzbd wykryl krytyczny blad:SABnabd zostal wylaczonySABnzbd bedzie uruchomiony w tle.Serwer SMTPBlad polecenia SQL, sprawdz logiBlad wykonania polecenia SQL, sprawdz logiSSLTyp SSLSobotaZapiszZapisz zmianyZapisanoNie udalo sie zapisac %sZapisywanie...Przeszukaj obserwowany katalogHarmonogram dla nieistniejacego serwera %sHarmonogramKonfiguracja harmonogramówSkryptSkryptyNumer SezonuDodatkowy interfejs WWWWybierz jezyk interfejsu WWW.Zaznaczy tylko jesli twój dostawca zezwala na SSL.ZaznaczenieWyslij groupPowiadomienia RSSPowiadom, kiedy kanal RSS dodaje zadanie do kolejkiPowiadom kiedy dysk jest pelen a SABnzbd zatrzymanyWyslij polecenie group przed zadaniem artykuluWysylaj powiadomienia GrowlWysylaj powiadomienia do NotifyOSDWyslano %s do kolejkiSortowanie seryjneSerwerSerwer %s wymagania podania nazwy uzytkownika i haslaSerwer %s bedzie ignorowany przez %s minutSzczególy serweraAdres serweraNieprawidlowy adres serwera "%s:%s"Wymagane jest podanie adresu serweraKonfiguracja serweraDefinicja serweraHaslo serweraSerwer przerwal komunikacje w trakcie logowaniaSerwer wymaga podania nazwy uzytkownika i hasla.SerweryUstaw interwal wstrzymywaniaUstawienia wzorca uprawnien dla pobranych plików/katalogów.
    notacja ósemkowa. Na przyklad: "775" lub "777"Tutaj ustaw klucz API NzbMatrix.Ustaw serwer twojego dostawcy dla powiadomienPodaj swoje hasloPodaj nazwe twojego uzytkownika.UstawieniaKonfiguracja zostala zakonczona!Czy pobieranie powinno sie automtycznie przywrócic w dniu resetuPokaz wszystkoPokaz zakladkiPokaz opcje edycjiPokaz nieudanePokaz logowanieNazwa serialuPokaz katalog nazwyPokaz logowanie webPokaz szczególyPokaz plikiPokaz interfejsPokazuj czas w notacji AM/PM (nie dotyczy harmonogramu)Nazwa.SerialuNazwa_SerialuPokazywanie %s do %s z %s wynikówPokazuje jeden wynikZakonczWylacz komputerWYlacz SABnzbdWylaczanieOdebrano sygnal %s. Zapisywanie i i zamykanie programu...RozmiarPominPomin sprawdzanie par2 dla 100% prawidlowych plików.Weryfikacja niektórych plików wzgledem "%s" nie powiodla sieSortujLancuch sortowaniaSortuj wedlug wiekuSortuj po wieku (Najnowsze→Najstarsze)Sortuj po wieku (Najstarsze→Najnowsze)Sortuj po wieku Najnowsze→NajstarszeSortuj po wieku Najstarsze→NajnowszeSortuj po nazwie (A→Z)Sortuj po nazwie (Z→A)Sortuj po nazwie A→ZSortuj po nazwie Z→ASortuj po rozmiarze (Najwieksze→Najmniejsze)Sortuj po rozmiarze (Najmniejsze→Najwieksze)Sortuj po rozmiarze Najwieksze→NajmniejszeSortuj po rozmiarze Najmniejsze→NajwiekszeSortuj po wiekuSortuj po nazwieSortuj po rozmiarzeSortowanieKonfiguracja sortowaniaZródloSpecjalneSzybkoscLimit predkosciLimit predkosciUspij komputerUruchom AsystentaRozpoczynanie naprawianiaUruchomienie/WylaczenieStatusKrok piatyKrok czwartyKrok pierwszyKrok trzeciKrok drugiStopZatrzymywanie...MiejsceTematNiedzielaPrzelacznikiKonfiguracja przelacznikówObciazenieKatalogi systemoweTEKSTZA DUZYZadanieTymczasowy katalog pobieraniaTestuj EmailPowiadomienie testoweTestuj serwerTestuje szczególy serwera...Przycisk "Napraw" ponownie uruchomi SABnzbd i spowoduje kompletne
    odtworzenie zawartosci kolejki, zachowujac juz pobrane pliki
    ZMieni to kolejnosc kolejki.Automatyczne narzedzie pobieranie dla usenetuPole wyboru obok nazwy kanalu musi byc zaznaczone, aby kanal byl wlaczony do automatycznego sprawdzania nowych wpisów.
    Dla nowych kanalów pobrane zostana tylko nowe wpisy, bez wpisów juz istniejacych, chyba ze zostanie wybrane "Wymuszenie pobrania".Nazwa hosta nie zostala ustawiona.Ilosc polaczen dopuszczanych przez twojego dostawceNie ma polaczenia z zadnym serwerem. Nalezy ustanowic przynajmniej jedno polaczenie.W katalogu pobieranie istnieja opuszczone zadania.
    Mozesz je usunac (razem z plikami) lub wyslac spowrotem do kolejki.To pole jest wymagane.Klucz umozliwi innym programom dodawanie plików NZB do SABnzbd.Klucz umozliwi dostep innych programów do SABnzbd.Ten miesiacTen tydzienZablokuje odswiezanie zawartosci po najechaniu kursoremSPowoduje to restart SABnzbd.
    Uzyj tego jesli wydaje ci sie, ze program ma problemy ze stabilnoscia.
    Pobieranie zostanie zatrzymane przez restartem i wznowione po ponownym uruchomieniu.NastaLi wyslanie testowej wiadomosci na twoje konto.WatekCzwartekUplynal limit czasu odpowiedziUplynal limit czasu odpowiedzi: Spróbuj wlaczyc SSL lub polacz sie z innym portem.PozostaloLimit czasu odpowiedziTytulTo: %s From: %s Date: %s Subject: SABnzbd raportuje przekroczenie zajetosci dysku Czesc, SABnzbd przestal pobierac pliki, poniewaz dysk jest prawie pelen. Opróznij troche miejsca i wznów SABnzbd recznie. DzisiajPrzelacz dodanie NZBZbyt malo miejsca, wymuszanie WSTRZYMANIAZbyt wiele polaczen z serwerem %s:%sZbyt wiele polaczen, prosze wstrzymac pobieranie lub spróbowac ponownie pózniejNa góreGórne menuRazemRozwiaz problemSpróbuj ponownieSpróbuj przewidziec, czy pobieranie bedzie udane przed jego rozpoczeciem (wolne!)Próba weryfikacji SFVPróba pobrania NZB z %sPróba ustawienia statusu nieistniejacego serwera %sPróba rozpakowania rar z haslem %sWtorekDostrajanieTypRSciezka UNC %s niedozwolonaPobieranie URL nie powiodlo sie; %sUZYWAJ NA SWOJA ODPOWIEDZIALNOSUsun zakladke po pobraniuNie uwierzytelniono, sprawdz nazwe uzytkownika/haslo do NewzbinOdblokujNieznany blad podczas dekodowania %sNieznana akcja: %sRozpakujRozpakowano %s plików/katalogów w %sRozpakowywanieRozpakowywanie nie powiodlo sie, %sRozpakowywanie nie powiodlo sie, blad sumy kontrolnej CRCRozpakowywanie nie powiodlo sie, oczekiwany plik nie zostal wypakowanyRozpakowywanie nie powiodlo sie, archiwum wymaga podania haslaRozpakowywanie nie powiodlo sie, za dluga sciezkaRozpakowywanie nie powiodlo sie, srpawdz dziennik zdarzenRozpakowywanie nie powiodlo sie, brak nastepujacych plików:Rozpakowywanie nie powiodlo sie, nie mozna znalezc %sRozpakowywanie nie powiodlo sie, byc moze dysk jest zapelniony.Nieprzydatny plik NZBNieuzywalny plik RARWyzejDostepna aktualizacjaWczytajWczytaj: .nzb .rar .zip .gzCzas dzialaniaUzywaj 12sto godzinnego zegara (AM/PM)Uzyj V23 chyba, ze dostawca wymaga innego!Uzywaj tymczasowych nazw plików podczas przetwarzania koncowego. Nalezy wylaczyc, jesli system nie obsluguje tej opcji prawidlowo.Uzyj kolumny "Grupy / Etykiety indeksera" to zmapowania grup i etykiet do twoich kategorii.
    Znaki wieloznaczne sa dopuszczalne. Uzyj przecinków do rozdzielenia terminów.Uzywany, zanim plik NZB trafi do kolejkiUzyta pamiec podrecznaUzywane, kiedy brak definicji w kategorii.Uzywane, kiedy brak definicji w kategoriiUzywane, kiedy brak definicji w kategorii.Uzywaj katalogówKategorie uzytkownikaNazwa uzytkownikaWartosciPoprawnie zweryfikowano z uzyciem plików SFVSprawdzanieWeryfikowanie...WersjaZobacz dziennik skryptuZobacz komunikaty wyjscia skryptuCZEKAM %s sekUWAGA:UWAGA: Przerwano zadanie "%s" z powodu zaszyfrowanego pliku RARUWAGA: wstrzymane zadanie "%s" z powodu zaszyfrowanego pliku RAROSTRZEZENIAOczekujeOstrzezenieOstrzezenie: LOCALHOST jest wieloznaczny, uzyj adresu IP.OstrzezeniaObserwowany katalogSzybkosc skanowania katalogu obserwowanegoInterfejs WWWUwierzytelnienie serwera wwwSrodaSprawdzaj co tydzien w poszukiwaniu nowych wydan SABnzbd.KiedyPróbuj pobierac artykuly z bledami CRC z innych serwerówKto powinien byc nadawca emaila?WikiXRokKatalogi Rok-MiesiacBrak kredytów na koncie NewzbinNie masz uprawnien do uzywania portu %s.Plush wymaga wlaczenia oblsugi JavaScriptDostep do API wymaga konta VIP nzbmatrixTwoja wersja programu UNRAR jest niezalecana, pobierz nowa z http://www.rarlab.com/rar_add.htm
    [%s] Blad %s podczas laczenia plików[%s] Blad "%s" podczas rozpakowywania plików RAR[%s] Polaczono %s plików[%s} Brak zestawów par2[%s} PAR2 otrzymal nieprawidlowe opcje, sprawdz ustawienia w Konfiguracja->Przelaczniki[%s} Szybkie sprawdzenie OK[%s] Naprawiono w %s[%s] Zweryfikowano w %s, wszystkie pliki prawidlowe[%s] Zweryfikowano w %s, wymagana naprawamodul _yens... NIE znaleziono!z dostosowaniem wielkosciwyczyscddziendniwylacz serwerwlacz serwerpobieranie wiadomosci %s z www.newzbin2.esplikkatalogggodzinagodzinypozostalomrecznieminutamin.minutnie zainstalowanezwylaczoneWl.lubstronaprogram par2 ... NIE znaleziono!brak modulu pyopenssl, nalezy go zainstalowac w celu dostepu httpsseksekundsprawdz plik dziennikatextnieznanyprogram unrar ... NIE znaleziono!program unzip ... NIE znaleziono!tydzienSABnzbd-0.7.20/locale/pt_BR/LC_MESSAGES/SABnzbd.mo0000644000000000000000000023046612433712601021111 0ustar00usergroup00000000000000L|>o}>>d?cA]B 1C2>DqEeFOG*fG'GGGG H'H6HVH vHHHHHRIZIaIiIqIyIIII?8JxJJJKRK[jKK#KK L*L1L 8L FLSL'ZLLLLLLL L LL LLMa$MMMMM.MMM) N*3N ^N lNvNN/NhN 6OBOWO(O0P*5P`PbPgP nP|PP PPPPPQQQ2Q QR 6RWRrRR!R6R-S6SUSdSS SS.S'S TT5TBOTTTSTU UU53UiUoU~U"UU8U UV VV6V =V IVWVqV&VV VV$V*W3WEWLW NWXW ^W lW yWWWWWWWW$WX"X )X4X EX SX_X(uXX%X X-Y0YDYf_YYY4YZ?Z\ZvZZZ,ZZ,[0[1L[5~[[[[ [[[1\59\5o\\ \'\\ \ ] ] ]#](] @] M]W] ^]h]]]]]]]]]$^ +^9^ I^ V^b^y^#^^^^^^^ _ _ *_7_W_l_______ _ `4`$D`$i`A``S`-9a5ga0a(aaHa Hb Rb_b nb {b(b.b)b& c,1c<^cbc&c%d@d7Sd'ddddd e >e&Ie-peeee ee e ff &f4fLfSfnff%f!ff+g ,gMg!hgg!gFgh0&h-Wh'hh"hhii8iXi`i |iiiiiiiiiAi=j'Tj!|jjjjj-jk kk.k3Ck/wkgk ll&#l"Jlmlslll l l ll llllmm $m2mDmLm bm pm}mmm m m mm mmn n n+n0n8n Nn[n `njnonn-n6n.n+o 0o;oMoQo6VooGAppqqqqEq 3r>r\rr,s4sFs%]s#ssss st2t%Qtwt"t+ttt'u;u7Buzu"v (v<5v rv3}v9vvv%vw'w,wE c pz  4NJ2 PZ o*|ċ)ߋM 0W   njό  /5DVm  ɍ֍%E._ юՎގ #- Q\u|  4ˏ 3,3`.Ð)ߐ ):I P(q$ݑ ",&Ov~o)!Kk3ߓ  ",= M Ze9t "”  ',TY-^( ƕ/ҕ/-2-`&&$ܖ$3&3Z11  6=E K W b mz  ʘӘ ؘ#2 7AF `k }"Twx2Aě>= +W5,2_f o>yɞϞ"$A"&/ 5 BEL.Ơ$)+Jb x2̡ԡ .8M3i-"ˢ,#5.Yѣأ0b#$ 88C1|4 % > HU]m 76ͦ :Xap  %@R(!{*$1 0>Zo#ʩ)-J?&'٪ *026; J&X «ūɫ̫ϫԫ9(, 4@EMg(*^ԯ3:$.WS 2ȷ1-Lh!)Ӹ  +> !9QiOAӻ ٻamUü.̼%!!CK R`w*~ νؽ 0JYnT׾ݾ@F"_++ڿ 4,oa$6#;CELS!c+D.($W4|"(644LiH11.J*y 4,5)Ody !\ i{A*EBL  ";)X 0:$ 8F H R^n <SZ cq 2#/ D/ewE [4f M(.W6t .444 it} 7I>X#   2 >LR[ t'",)Vi, $-!B dn".G(g2&&9M`^:-DhE1%[+ %0&0#W.{En%_&9/*(=f-C F#g   "6,P0}#:' 5#Qu] 5%7[-$ :&[ T)!~4+.0EU8\:8sK /',4HY`z '$ AKcu   =N_ d o(*G >h ?Q:G 9E>X,r&"/7L0 *@ Bc1>.D ;AR.X /c >SX2o/1 ans y# + ;T]w/    *4KPY_p 48#5&Y5IZ$r :3 '.A><(?RU"m {(5 ^Z8)7=u!$$-LU[t +4#X`gy /)<Rgz O&4a[$A$3#9(].''Gg4w #- #9 N\v ' $0 O[p#).4C#Uy{!   (, U_Yu!' /;ZkCC 7 A  X 3e $ " 0 d 6w            5  ? I h |        $ 5 (F o    " /  ! $/ &T {         +  #BIQf)9  ;EQ34%E]t!}+.!%Gc|-! |%(!  9: t  '98 r "  )%-@31t==;S;**(!(J5s533GYk !   1 N Y fs    (/ N\s .Y#!2HJKB?  `3 I Q  `  m w 8!=!-V!&!N!! ! "","G<"""4"&" # !#/#4#)6#`#z#3#A# $#$;$ S$'`$$$&$E$4"%3W%%%>%:%:+&f& &&&& &&&6&s1'')g((G(?(B)) l)x))),) ))))**/*G6*F~** **=*+$+.8+ g+u+ +0++J+X$,'},,,,,-,.,7-8U-\-$-..?.W.Lq...1.-"/!P/r///////#////// 0 0 0000 0/0 20<0C0F0#N0<r00000 0$0$ 1/1 SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:AbortAbort jobs that cannot be completedAborted, cannot be completedAborted, encryption detectedAcceptAccessAccess deniedAccount infoActionAction when encrypted RAR is downloadedActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BBackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)Cannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.Complete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn case of "Pause", you'll need to set a password and resume the job.In foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOther MessagesOther SwitchesPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!RefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.Report-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSend GroupSend RSS notificationsSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogView script outputWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.When during download it becomes clear that too much data is missing, abort the jobWho should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2013-02-11 19:34+0000 Last-Translator: lrrosa Language-Team: Brazilian Portuguese MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:55+0000 X-Generator: Launchpad (build 17082) SABnzbd não pode encontrar seus arquivos da interface web em %s.
    Por favor instale o programa novamente.

    SABnzbd detectou uma Fila e Histórico de uma versão antiga (0.4.x).

    Tanto a fila quanto o histórico serão ignorados e podem se perder!

    Você pode optar por parar o SABnzbd e terminar a fila com o programa mais antigo.

    Clique em OK para prosseguir ao SABnzbd SABnzbd detectou dados salvos de outra versão do SABnzbd
    mas não pode reutilizar os dados do outro programa.

    Você pode querer terminar sua fila antes com o outro programa.

    Após isso inicie este programa com a opção "--clean".
    Isto irá apagar a fila atual e histórico!
    SABnzbd leu o arquivo "%s". SABnzbd detectou que o arquivo sqlite3.dll está faltando.

    Alguns anti-vírus mal projetados removem este arquivo.
    Por favor, verifique o seu anti-vírus, tente reinstalar o SABnzbd e reclame com o seu fornecedor de anti-vírus.

    SABnzbd não é compatível com alguns softwares de firewall.
    %s
    Lamentamos, mas não podemos resolver esta incompatibilidade no momento.
    Por favor, registre uma reclamação com seu fornecedor de firewall.

    SABnzbd precisa de uma porta tcp/ip livre para seu servidor web interno.
    A porta %s em %s foi tentada, mas não está disponível.
    Algum outro software usa a porta ou o SABnzbd já está rodando.

    Por favor reinicie o SABnzbd com um número de porta diferente. SABnzbd precisa de uma porta tcp/ip livre para seu servidor web interno.
    A porta %s em %s foi tentada, mas a conta usada para o SABnzbd não tem permissão para usá-la.
    Nos sistemas OSX e Linux, usuários normais devem usar portas acima de 1023.

    Por favor reinicie o SABnzbd com um número de porta diferente. SABnzbd precisa de um endereço de host válido para seu servidor web interno.
    Você especificou um endereço inválido.
    Valores seguros são localhost e 0.0.0.0

    Por favor reinicie o SABnzbd com um endereço de host correto. SABnzbd não possui QUALQUER GARANTIA. É software livre, e você está convidado a redistribuí-lo sob certas condições. Está licenciado sob a LICENÇA PÚBLICA GERAL GNU Versão 2 ou (a seu critério) qualquer versão posterior. %s -> Codificação desconhecida%s => faltando em todos os servidores. Descartando%s artigos tinham duplicatas não-correspondentes%s artigos estavam malformados%s artigos estavam faltando%s artigos foram removidospasta %s: %s erro de acesso%s arquivos em %s%s não é um valor octal correto%s não é um endereço de e-mail válidofaltando %s  Resolvendo endereço ou Report ID 
    Encerramento do SABnzbd concluído.
    Espere cerca de 5 segundos e, em seguida, clique no botão abaixo.

    Atualizar
    + Debug+ Info+Excluir+Reparar+DescompactarPasta de Backup de .nzb1x05 Pasta Do Episódio1x05 Pasta Da TemporadaNOTA: Pastas serão criadas automaticamente ao salvar. Você pode usar caminhos absolutos para salvar fora das pastas padrão.Dados não serão movidos. Será necessário reiniciar o SABnzbd!Ler Feed vai pegar o conteúdo do feed atual. Forçar Download irá baixar todos os NZBs correspondentes agora.IDADEChave APIAPI Key QR CodeChave de API incorreta. Use a chave de API de Configuração->Geral em seu programa de terceiros:Chave de API faltando. Por favor insira a chave de API de Configuração->Geral em seu programa de terceiros:CancelarCancela tarefas que não podem ser concluídasCancelado, não é possível concluirCancelado, criptografia detectadaAceitarAcessoAcesso negadoInformações da contaAçãoAção quando RAR criptografado é baixadoAçõesAtivar uma skin alternativa.AdicionarAdicionar FeedAdicionar ArquivoAdicionar NZBAdicionar AgendamentoAdicionar ServidorAdicionar novos downloadsNZB AdicionadoPasta AdministrativaCategorias AfetadasApós o SABnzbd ter reiniciado você será capaz de acessá-lo no seguinte local: %sIdadeTodosTambém versões de testesSempreAplicar o máximo de tentativas somente com servidores opcionaisAplicar aos SelecionadosVocê tem certeza que quer apagar?Tem certeza que deseja reiniciar o SABnzbd?Tem certeza de que quer encerrar o SABnzbd?Você tem certeza?ParâmetrosLimite de Cache de ArtigosIdentificador de artigoFalha de autenticação, verifique usuário / senha.Autenticação faltando. Por favor insira usuário/senha de Configuração->Geral em seu programa de terceiros:Retomar automaticamenteObtenção automática dos favoritosPausar automaticamente quando o espaço livre estiver abaixo deste valor.
    Em bytes, opcionalmente seguido de K,M,G,T. Por exemplo: "800M" ou "8G"Fazer download automaticamente de mensagens favoritas.Download automático dos favoritos.Classificar automaticamente os itens por (média de) idade.BVoltarBackupServidor backupAgendamento %s incorreto em %s:%sArtigo yEnc mal formado em %sLargura de bandaImpedir Atualizações no FocoProcessamento dos favoritosBaseErro de CRC em %s (%s -> %s)Manter artigos em memória para reduzir o acesso a disco.
    Em bytes, opcionalmente seguido de K,M,G. Por exemplo: "64M" ou "128M"%s artigos em cache (%s)Não é possível alterar permissões de %sNão é possível conectar à seção de registro HKEY_CURRENT_USER.Não é possível conectar ao servidor %s [%s]Não foi possível criar %s pasta %sNão é possível criar um arquivo de backup para %sNão é possível criar a pasta %sNão é possível criar a pasta final %sNão é possível criar um arquivo temporário para %sNão é possível encontrar templates de email em %sNão foi possível encontrar o template web: %s. Tentando o template padrãoNão é possível iniciar o navegador. Provavelmente não foi encontradoNão é possível abrir a chave de registro "%s".Não é possível ler %sNão é possível ler a Pasta de Assistidos %sNão é possível gravar no arquivo INI %sCategoriasCategoriaAs alterações não foram salvas e serão perdidas.Mudanças exigirão um reinício do SABnzbd!Verifique antes de baixarProcurar por nova versãoVerificar o resultado da descompactaçãoVerificar o resultado da descompactação (precisa ficar desativado em alguns sistemas de arquivos).VerificandoIntervalo entre as verificaçõesIntervalo de verificação (em minutos, ao menos 15). Inativo quando você usar o Agendador!Escolha uma skin.Lista de LimpezaA limpeza de %s falhou.Limpar arquivos par (se a verificação/reparo for bem sucedida).LimparLimpar ContadoresClique abaixo para testar.Clique para testar os detalhes informados.FecharFechar qualquer janela/aba do navegador NÃO vai fechar o SABnzbd.Pasta CompletadosPasta de FinalizadosConcluídoPasta de Downloads ConcluídosConfiguraçãoArquivo de ConfiguraçãoConfiguraçãoConfirmar Exclusões do HistóricoConfirmar Exclusões da FilaA conexão a %s@%s:%s falhou. Mensagem=%sConexão com Sucesso!ConexõesLargura do ContêinerNão foi possível excluir o favorito newzbin %sNão foi possível determinar o resultado da conexão (%s)Agendamentos AtuaisPersonalizadoDDUPLICADODiariamentePastas DiáriasOrdenação por dataDia do mêsDécadaFalha ao decodificar %sPadrãoPasta Inicial PadrãoPós-processamento PadrãoPrioridade PadrãoScript de usuário padrãoDefine os métodos de pós-processamento e de armazenamento.ApagarEliminarExcluir TodosExclusão ConcluídaFalha na ExclusãoRemover FeedExcluir após downloadEliminar do histórico todos os itens concluídos?Excluir todos os arquivos baixados?Eliminar do histórico todos os itens falhados?Eliminar todos os itens da fila?Excluir do histórico todos os itens com falha?A exclusão de %s falhou!Detectar Downloads DuplicadosDetectar arquivos NZB com nomes idênticos (requer opção de backup de NZB) e duplicar títulos através de feeds RSS.Desabilitar Chave APIDesativadoHTTPS desabilitado pela falta de arquivos CERT e KEYDescartarDesconecte do(s) servidor(es) Usenet quando a fila estiver vazia ou pausada.Desconecte quando fila vaziaNotificações de Disco CheioErro de disco na criação do arquivo %sDisco cheio! Forçando PausaFazer uma verificação extra baseada em arquivos SFV.Não baixarNão há autenticação válida para o feed %sNão requer a chave API.A quota é restabelecida a cada dia, semana ou mês?Não tem um provedor usenet? Recomendamos testar %s.Para baixoDownloadDownload concluídoPasta de DownloadO download falhouLimite de Velocidade de DownloadO download falhou - Fora da retenção do seu servidor?O download pode falhar. Somente %s de %s necessários estão disponíveisLimite da taxa de download (em KB/s - quilobytes por segundo).Velocidade de downloadBaixadosBaixado em %s a uma média de %sB/sBaixados até agoraBaixandoDownloadsDualView1DualView2Ex.Ex. 119 ou 563 para SSLEx: 8 ou 20CRIPTOGRAFADOERRO:ERRO: %sERRO: CRC falhou em "%s"ERRO: caminho muito extenso (%s)ERRO: Não foi possível encontrar "%s"ERRO: erro de escrita (%s)EstimadoEditarEditar Detalhes do NZBE-mailConfigurações da Conta de E-mailNotificar por e-mail na conclusão da tarefaOpções de e-mailDestinatário do E-mailE-mail do RemetenteEmail Enviado!Pasta de Modelos de E-mailResultado do Teste de E-mailEndereço de e-mail para receber os e-mails.E-mail enviado com sucessoEsvaziarArquivo NZB %s vazioEntrada RSS vazia encontrada (%s)HabilitarAtivar a ordenação por dataHabilitar FilejoinHabilitar GrowlHabilitar HTTPSHabilitar acesso HTTPS ao SABnzbd.Ativar a ordenação de filmesHabilitar MultiCore Par2Habilitar NotifyOSDHabilitar Limpeza de ParHabilitar Verificação RápidaHabilitar verificações baseadas em SFVHabilitar União TSAtivar a ordenação de TVHabilitar UnrarHabilitar UnzipAtivar acesso à interface por um endereço HTTPS.Habilitar funcionalidade unrar internaHabilitar funcionalidade unzip internaHabilita classes de mensagens a serem relatadas (nenhuma, uma, ou múltiplas)Habilitar renomeação de pastaAtive para menor uso de memória. Desative para impedir que trabalhos lentos bloqueiem a fila.Ativar a ordenação e a renomeação genérica dos FilmesAtivar se os downloads não são colocados em suas próprias pastas.Ativar classificação e renomeação de arquivos nomeados com datas.Ativa a ordenação e renomeação de episódios.AtivoPara evitar a criação de pastas de trabalho, adicione um asterisco (*) depois do caminho.Digite a URLNome do EpisódioNúmero do EpisódioNome.EpisódioNome_EpisódioErro "%s" ao executar file_join em %sErro "%s" ao executar par2_repair no conjunto %sErro "%s" ao executar rar_unpack em %sErro "%s" ao executar unzip() em %sErro %s ao executar par2_repair no conjunto %sErro %s: Você precisa fornecer um nome de usuário e senha válidos.Erro ao obter msgid %s de www.newzbin2.es - Por favor, tenha certeza que seu usuário e senha estão corretos.Erro ao criar chave SSL e certificadoErro ao obter informações de TV (%s)Erro ao importar %sErro ao importar o módulo OpenSSL. Conectando-se sem SSLErro ao carregar %s. Arquivo corrupto detectadoErro ao remover %sErro ao remover a pasta de trabalho (%s)Erro ao renomear "%s" para "%s"Erro ao adicionar %s. RemovendoErro ao desligar o sistemaSomente para errosErro: Nenhuma interface secundária definida.Erro: A fila não está vazia. Não será possível mudar de pasta.Erro: chave de sessão incorretaErro: chave de sessão obrigatóriaErros/AvisosTudoExemploSair do SABnzbdExtensãoParâmetros Extras PAR2Extraindo...Falhar em erros CRC yEncFalhouFalha de logon ao servidor %sFalha ao criar (%s)Falha ao mover %s para %sFalha ao autenticar com o servidor de e-mailFalha ao fechar o banco de dados. Consulte o logFalha ao fechar a conexão de emailFalha ao compilar a expressão para o termo pesquisado: %sFalha ao conectar ao servidor de e-mailFalha ao hibernar o sistemaFalha ao importar %s arquivos de %sFalha ao iniciar %s@%s:%sFalha ao iniciar a conexão TLSFalha ao carregar fila de pós-processamento: Versão incorreta (requerido:%s, encontrado:%s)Falha ao mover arquivosFalha ao ler chaves de registro para pastas especiaisFalha ao remover nzb da fila de pós-processamento (id)Falha ao renomear arquivo similar: %s para %sFalha ao renomear: %s para %sFalha ao obter RSS de %s: %sFalha ao enviar o e-mailFalha ao colocar o sistema em esperaFalha ao iniciar a interface webFalha ao atualizar a tarefa newzbin %sFalhaFalha em tempfile.mkstempErro fatalFeedFeedsObterObtendoObtendo %s blocos...Obtendo blocos extras...Arquivo %s está vazio. PulandoExtensão do arquivoArquivo contendo todas as senhas que serão testadas em arquivos RAR criptografados.A união de arquivos de %s falhouNome do arquivo ou caminho para o certificado HTTPS.Nome de arquivo ou caminho da Cadeia HTTPS.Nome do arquivo ou caminho para a chave HTTPS.Conjunto de arquivosNome do arquivoFiltroExclui arquivos de amostra. Exemplo: amostras de vídeo.FiltrosPrimeiraA pasta "%s" não existeConfiguração de pastaPasta contendo scripts de usuário para pós-processamentoPasta contendo modelos de e-mail definidos pelo usuárioPasta para monitorar por arquivos .nzb.
    Também procura arquivos .nzb em arquivos .zip, .rar e .tar.gz.Pasta/CaminhoPastasNome da conta, para e-mails com autenticação.Senha, para e-mails com autenticação.ForçarForçar DesconexãoForçar DownloadFórumDisponível (Temporário)Espaço DisponívelFrequênciasexta-feiraMais ajuda pode ser encontrada em nossoGBGeraisConfiguração geralGerar Nova ChaveOrdenação genéricaObter FavoritosRecuperar os favoritos agoraObter NZBObter Favoritos NewzbinIr para o SABnzbdIr para o assistenteIndexador Grupos/EtiquetasCertificado HTTPSCadeia de Certificados HTTPSChave HTTPSPorta HTTPSSuporte HTTPSAjudaHibernar o PCOcultar FavoritosOcultar Opções de EdiçãoOcultar detalhesOcultar arquivosAltaHistóricoHistórico dos últimos 10 itemsTamanho do históricoInícioPágina inicialHostComputador onde o SABnzbd ficará ativo.Hora:MinQuanto pode ser baixado neste mês (K/M/G)Quero que o SABnzbd seja acessado de qualquer computador em minha rede.Quero que o SABnzbd seja acessado somente pelo meu computador.OCIOSOINCOMPLETOParâmetros IONiceIRCInativoSe estiver vazio, a porta padrão só irá funcionar com HTTPS.Se você é um membro de newzbin ou nzbmatrix, você pode digitar seu nome de usuário e senha aqui para que possamos buscar nzbs deles. Esta etapa pode ser pulada se você não usar nenhum desses serviços.Se você receber esta mensagem de erro outra vez, tente um número diferente.
    Se você já possui uma conta em www.newzbin2.es, introduza as informações necessárias.
    Isto permitirá o uso de funcionalidades adicionais.Se você já possui uma conta em www.nzbmatrix.com, introduza as informações necessárias.
    Isso é necessário se você quiser usar os feeds RSS deste site.Ignorar amostrasIgnorando NZB duplicado "%s"EmEm caso de "Pausa", você precisa definir uma senha e retomar a tarefa.Em pastasEm minutos (pelo menos 15 min).Para baixar a partir da usenet você precisa ter acesso a um provedor. Seu provedor de Internet pode fornecer-lhe acesso, no entanto, um provedor exclusivo é recomendado.Feed incompatívelEncontrado arquivo de fila incompatível. Não é possível continuarPasta de Não-FinalizadosArquivo NZB incompleto %sSequência de arquivos multiparte incompletaDescrição de feed RSS incorreta "%s"Parâmetro incorretoValor incorreto para %s: %sSenha %s codificada incorretamenteSites de IndexaçãoFazendo o reinício...
    Arquivo NZB %s inválido. Pulando (razão=%s, linha=%s)Codificação inválida do template de e-mail %sCredenciais nzbmatrix inválidasNúmero de registro nzbmatrix %s inválidoArquivos PAR2 inválidos. Não é possível verificar ou repararEndereço do servidor inválido.Detalhes inválidos do servidorRegistro inválido de etapa no histórico para %sInverterÉ provável que você esteja usando o ZoneAlarm no Vista.
    Recomenda-se que você adicione este local como favorito para acessar o SABnzbd quando ele estiver sendo executado em segundo plano.A tarefa "%s" foi adicionada novamente à filaTarefa concluídaAs tarefas marcadas com um '*' não serão baixadas automaticamente.Unir arquivosUnir arquivos terminando em .001, .002, etc. em um arquivo.Unir arquivos terminando em .001.ts, .002.ts, etc. em um arquivo.UnindoKB/sManter em pastas separadas os downloads soltosIdiomaÚltimaÚltimos AlertasAbrir navegador ao iniciarAbrir meu navegador de internet com a página do SABnzbd quando o programa for iniciado.Abrir o navegador padrão ao iniciar o SABnzbd.RestantesLimitar VelocidadeAtalhosLista de extensões dos arquivos que devem ser excluídos após o download.
    Por exemplo: .nfo ou então .nfo, .sfvFalha ao carregar %sLocalização do banco de dados de histórico e administrador de fila.
    Só pode ser alterado quando a fila estiver vazia.Local dos arquivos de log do SABnzbd.
    Será necessário reiniciar o SABnzbd!Local para armazenar downloads concluídos, totalmente processados​​.
    Pode ser anulado por categorias definidas pelo usuário.Local para armazenar downloads não processados.
    Só pode ser alterado quando a fila estiver vazia.Local onde os arquivos .nzb serão armazenados.Pasta de LogLogsBaixaMinúsculasMBPacote principal não encontrado...CorrespondidoVelocidade MáxNúmero máximo de tentativas por servidor.Máximo de tentativasSignificadoEspaço livre mínimo para a pasta temporária de downloadsDiversosFaltando chave de sessãoArtigos faltandoFaltando arquivo esperado: %s => erro no unrar?segunda-feiraMêsMaisNome FilmeNome.FilmeNome_FilmeMovendoMovendo...Multi-OperaçõesRótulo multi-parteChave NZBNZB adicionado à filaNomeNomeandoNuncaNova URL de FeedNova versão %s disponível emNova versão disponívelSenha NewzbinUsuário NewzbinNewzbin enviou código de erro não documentado (%s)Newzbin enviou código de erro não documentado (%s, %s)Newzbin informou %s não encontradoO servidor Newzbin mudou seu protocoloServidor Newzbin falhou ao enviar informações de %sPróxParâmetros NiceNenhum programa PAR2 foi encontrado. Reparos não serão possíveis
    Nenhum programa UNRAR foi encontrado. Não será possível descompactar arquivos RAR
    Nenhum template de e-mail encontradoSem pastasSem pós-processamento por causa de falha na verificaçãoNenhum destinatário fornecido. E-mail não enviadoSem resultadosNenhumNormalNão EncontradoNão há espaço em disco suficiente para completar os downloads!Não correspondidoCentro de NotificaçõesNotificação Enviada!Classes de notificaçãoNotificaçõesQuantidade de segundos entre as varreduras de arquivos .nzb.Chave API do NzbMatrixUsuário NzbMatrixOKSenha OPCIONAL da contaNome de usuário OPCIONAL da contaDesligadoAo ConcluirAo terminar a filaEm que dia do mês ou da semana (1 = segunda-feira) seu provedor de Internet redefine sua quota? (Opcionalmente com hh: mm)Apenas Obter Artigos para o Topo da FilaApenas para servidores opcionaisRealizar pós-processamento apenas em trabalhos que passaram todas as verificações PAR2.Utilize apenas para servidor remoto Growl (host: porta)Abrir URL InformativaAbrir URL de OrigemAbra uma janela de terminal e digite a linha (exemplo):Abrir pasta de finalizadosOpcionalNZB Suplementar OpcionalSenha de autenticação opcional.Usuário de autenticação opcional.Senha opcional para o servidor GrowlOpcionalmente, especifique um nome de arquivoOpçõesOrdemNome do arquivo originalNome da pasta originalOutras MensagensOutras OpçõesEM PAUSAPáginaParâmetros:Número do EpisódioSenhaArquivo de senhasSenha mascarada em ******, digite novamenteProteger o acesso ao SABnzbd com senha (recomendado)CaminhoModeloModelo do padrãoPausarPausar TodosPausar o download durante o pós-processamento.Intervalo de PausaPausa dePausar por 1 horaPausar por 12 horasPausar por 15 minutosPausar por 24 horasPausar por 3 horasPausar por 30 minutosPausar por 5 minutosPausar por 6 horasPausar por quantos minutos?Pausar por...Pausar o pós-processamentoPausadoPausar o download no início do pós-processamento e retomar quando concluído.Pausando NZB duplicado "%s"Permissões para downloads concluídosEsteja ciente de que o nome de host 0.0.0.0 vai precisar de um endereço IPv6 para acesso externoPor favor insira um número inteiro.Por favor insira os detalhes de seu provedor de usenet primário.Opções PlushPortaPorta onde o SABnzbd será ativado.O pós-processamento falhou para %s (%s)Pós-processamentoPós-processar apenas os trabalhos verificadosPasta de Arquivos de Pós-ProcessamentoPós-processamentoPós-processamento iniciadoO pós-processamento foi cancelado (%s)Script de usuário de pré-filaPredefiniçõesAperte a tecla Windows+R e digite a linha (exemplo):AntAnteriorPrioridadeProvável compartilhamento de contaProblema ao acessar o servidor nzbmatrix (%s)Problema comFavoritos processadosResultado ProcessadoProcessamentoOpções de ProcessamentoO programa não iniciou!ProgressoEliminarLimpar NZBs TerminadosLimpar Histórico de FalhasLimpar NZBs FalhadosLimpar NZBs Falhados & Excluir ArquivosLimpar HistóricoLimpar NZBsLimpar NZBs & Excluir ArquivosLimpar FilaLimpar o Histórico?Limpar a fila?Versão do PythonQR CodeFilaFila dos primeiros 10 itemsIntervalo de atualização da fila:Reparação da filaNa filaVerificação Rápida...Verificação RápidaSairQuotaQuota restantePeríodo da quotaQuota esgotada, pausando o downloadRRSSIntervalo de verificação de RSSConfiguração de RSSO feed RSS %s estava vazio%s executadoIntervaloOpções raramente utilizadas. Para seu significado e explicação, clique no botão Ajuda para ir para a página Wiki.
    Não altere estas sem checar o Wiki em primeiro lugar, já que algumas têm sérios efeitos colaterais.
    Os valores padrão estão entre parênteses.Ler Todos os Feeds AgoraLer FeedLer feeds RSSLeia a sessão ajuda no Wiki sobre isso!AtualizarTaxa de AtualizaçãoIntervalo de atualização da página da interface web da fila (em segundos, 0 = nenhum).Taxa de atualizaçãoRecusarCaminho base das pastas relativasRestante/TotalRestanteRemoverRemover NZBRemover NZB & Excluir ArquivosRemover servidorRemover tarefas com falhaEliminar da lista de favoritos quando o download estiver concluido.A remoção de %s falhouRenomearRepararReparação falhou. Blocos de reparação insuficientes (faltam %s)ReparandoReparação falhou, %sReparando...Substituir caracteres inválidos em nomes de pastasSubstituir espaços no nome da pastaSubstituir pontos no nome da pastaSubstituir pontos por espaços no nome da pasta.Substituir caracteres inválidos em nomes de pastas por equivalentes (caso contrário, removê-los).Substituir espaços por sublinhado no nome das pastas.Report-idRequerRequiresCatReiniciarRedefinir Quota agoraPrimeiro dia do cicloReiniciarReinicie sem loginReiniciando SABnzbd...ResultadoContinuarContinuar o pós-processamentoTempo de retençãoRepetirExecutando scriptExecutando script...Executando script de usuário %sS01E05 Pasta Do EpisódioS01E05 Pasta Da TemporadaSABnzbd %s iniciadoHost do SABnzbdSenha do SABnzbdPorta do SABnzbdAssistente de Início Rápido do SABnzbdUsuário do SABnzbdVersão do SABnzbdServidor Web do SABnzbdSABnzbd detectou um erro fatal:Encerramento do SABnzbd concluídoSABnzbd agora será executado em segundo plano.Servidor SMTPO comando SQL falhou. Consulte o logO commit do SQL falhou. Consulte o logSSLTipo SSLsábadoGravarSalvar AlteraçõesSalvoFalha ao salvar %sSalvando...Varrer pasta de assistidosAgendamento para um servidor inexistente %sAgendamentoConfiguração de agendamentosScriptScriptsNúmero da TemporadaInterface Web SecundáriaSelecione um idioma para a interface web.Selecione somente se seu provedor permitir conexões SSL.SeleçãoEnviar GrupoEnviar notificações RSSEnviar e-mail quando um feed RSS adicionar tarefas à fila.Enviar e-mail quando o disco estiver cheio e SABnzbd estiver pausado.Enviar comando do grupo antes de solicitar artigos.Enviar notificações ao GrowlEnvia notificações para o Centro de NotificaçõesEnviar as notificações a NotifyOSD.Enviados %s para a filaOrdenação de SériesServidorServidor %s requer usuário/senhaO servidor %s será ignorado por %s minutosDetalhes do ServidorEndereço do servidorEndereço de servidor "%s:%s" não é válido.Endereço do servidor necessárioConfigurações do servidorDefinições do servidorSenha do servidorServidor parou durante a sequência de login.Servidor requer usuário e senha.ServidoresDefinir Intervalo de PausaDefinir padrão de permissões para arquivos/pastas concluídos.
    Em notação octal. Por exemplo: "755" ou "777"Digite a chave API do NzbMatrix aqui.Define o servidor para envio de e-mails.Digite sua senha aqui.Digite seu nome de usuário aqui.ConfiguraçõesA configuração está completa!O download deve retomar quando a quota for restabelecida?Mostrar TodosMostrar favoritosMostrar Opções de EdiçãoMostrar FalhadosMostrar LogsNome do ShowPasta do Nome do ShowMostrar Logs da WebMostrar detalhesExibir arquivosExibir interfaceExibir horas na notação AM/PM (não afeta o agendador).Nome.do.ShowNome_do_ShowMostrando %s a %s de %s resultadosMostrando um resultadoEncerrarDesligar o PCEncerrar o SABnzbdEncerrandoSinal %s encontrado. Salvando e saindo...TamanhoPularPular verificação par2 quando os arquivos forem 100% válidos.Alguns arquivos falharam na verificação de "%s"OrdenarString de ordenaçãoOrdernar por IdadeOrdenar por Idade (Mais novo→Mais antigo)Ordenar por Idade (Mais antigo→Mais novo)Ordenar por Idade Mais novo→Mais antigoOrdenar por Idade Mais antigo→Mais novoOrdenar por Nome (A→Z)Ordenar por Nome (Z→A)Ordenar por Nome A→ZOrdenar por Nome Z→AOrdenar por Tamanho (Maior→Menor)Ordenar por Tamanho (Menor→Maior)Ordenar por Tamanho Maior→MenorOrdenar por Tamanho Menor→MaiorOrdenar por idadeOrdenar pelo nomeOrdenar por tamanhoOrdenaçãoConfiguração de classificaçãoCódigo fonteEspecialVelocidadeLimite de velocidadeLimite de velocidadePC em esperaIniciar o AssistenteIniciando reparaçãoInicialização/EncerramentoSituaçãoQuinto PassoQuarto PassoPrimeiro PassoTerceiro PassoSegundo PassoPararParando...ArmazenamentoAssuntodomingoOpçõesConfiguração de opçõesCarga do sistemaPastas de SistemaTEXTOMUITO GRANDETarefaPasta Temporária de DownloadsTestar E-mailNotificação de testeTestar ServidorTestando detalhes do servidor...O botão "Reparar" irá reiniciar o SABnzbd e fazer uma reconstrução
    completa do conteúdo da fila, preservando arquivos já baixados.
    Isto modificará a ordem da fila.A ferramenta de download automático da usenetA caixa de seleção ao lado do nome do feed deve ser assinalada para que o feed seja ativado e automaticamente verificado por novos itens.
    Quando um feed é adicionado, ele só vai pegar novos itens e não algo que já esteja no feed RSS a menos que você pressione "Forçar Download".O nome do host não foi definido.O número de conexões permitidas por seu provedorNão há conexões definidas. Por favor, defina pelo menos uma conexão.Existem tarefas órfãs na pasta de downloads.
    Você pode optar por excluí-las (incluindo arquivos) ou enviá-las de volta para a fila.Este campo é necessário.Esta chave permitirá que programas de terceiros adicionem NZBs ao SABnzbd.Esta chave dará a programas de terceiros pleno acesso ao SABnzbd.Este mêsEsta semanaIsso irá impedir que o conteúdo seja atualizado quando o cursor do mouse estiver sobre a fila.Isto irá reiniciar o SABnzbd.
    Use-o quando você achar que o programa tem um problema de estabilidade.
    Os downloads serão pausados antes de reiniciar e retomados depois.Isto irá enviar um e-mail de teste para sua conta.Tópicoquinta-feiraTempo esgotadoTempo esgotado: Tente habilitar o SSL ou conectar em uma porta diferente.Tempo restanteTempo limiteTí­tuloTo: %s From: %s Date: %s Subject: SABnzbd informa Disco Cheio Olá, SABnzbd parou de baixar, porque o disco está quase cheio. Por favor, arranje mais espaço e retome SABnzbd manualmente. HojeAlternar Adição de NZBMuito pouco espaço em disco. Forçando PAUSEExcesso de conexões ao servidor %s:%sExcesso de conexões, por favor pause o download ou tente novamente mais tardeTopoMenu SuperiorTotalResolução de problemasTente novamenteTentar prever a conclusão bem sucedida de um futuro download? (lento!)Tentando verificação SFVTentando obter NZB de %sTentando definir o status do servidor inexistente %sTentando descompactar com a senha "%s"terça-feiraAjustes finosTipoUO caminho UNC "%s" não é permitido aquiA busca da URL falhou; %sUSE POR SUA CONTA E RISCO!Eliminar o favorito se o download estiver concluidoNão autorizado. Verifique o seu nome de usuário e senha NewzbinDesbloquearErro desconhecido ao decodificar %sAção desconhecida: %sDescompactarDescompactados %s arquivos/pastas em %sDescompactandoA descompactação falhou. %sA descompactação falhou. Erro de CRCA descompactação falhou. Um arquivo esperado não foi descompactadoA descompactação falhou. O arquivo exige uma senhaDescompactação falhou, o caminho é muito extensoA descompactação falhou. Veja o logA descompactação falhou. Este(s) arquivo(s) estão faltando:A descompactação falhou. Não foi possível encontrar %sA descompactação falhou. Erro de escrita ou disco cheio?Arquivo NZB inutilizávelPara cimaAtualização Disponível!EnviarEnviar: .nzb .rar .zip .gzTempo ativoUtilizar relógio com 12 horas (AM/PM)Utilize V23 a não ser que o seu provedor exija outro!Usar nomes temporários durante o pós-processamento. Desative quando seu sistema não lidar com isso corretamente.Use a coluna “Indexador Grupos/Etiquetas” para classificar os grupos e as etiquetas em funçao de suas categorias
    Os caracteres curinga são permitidos. Separe os termos por vírgulas.Utilizado antes de um NZB entrar na fila.Cache utilizadoUsado quando nenhum pós-processamento estiver definido pela categoria.Utilizado quando nenhuma prioridade é definida pela categoria.Usado quando nenhum script de usuário é definido pela categoria.Usar PastasCategorias do usuárioUsuárioValoresVerificado com sucesso. Usando arquivos SFV.VerificandoVerificando...VersãoExibir Log do ScriptVer saída do scriptEspere %s segundo(s)AVISO:ATENÇÃO: Tarefa "%s" cancelada por causa de arquivo RAR criptografadoATENÇÃO: Tarefa "%s" em pausa por causa de arquivo RAR criptografadoAVISOSAguardandoAlertaAtenção: LOCALHOST é ambíguo, use endereço IP numérico.AlertasPasta de AssistidosVelocidade de Varredura na Pasta de AssistidosInterface WebAutenticação do servidor webquarta-feiraChecar semanalmente por nova versão do SABnzbd.QuandoQuando o artigo possuir um erro de CRC, tentar obtê-lo de outro servidor.Quando durante o download ficar claro que muitos dados estão faltando, cancela a tarefaQuem devemos dizer que enviou o e-mail?WikiXAnoPastas Ano-MêsVocê não tem créditos na sua conta NewzbinVocê não tem permissão para usar a porta %sVocê deve habilitar o JavaScript para Plush funcionar!Você precisa de uma conta VIP nzbmatrix para usar a APISua versão do UNRAR não é recomendada. Pegue-a de http://www.rarlab.com/rar_add.htm
    [%s] Erro "%s" na união de arquivos[%s] Erro "%s" ao descompactar os arquivos RAR[%s] Unidos %s arquivos[%s] Nenhum conjunto par2[%s] PAR2 recebeu opções incorretas. Verifique em Configuração->Opções[%s] Verificação Rápida OK[%s] Reparado em %s[%s] Verificado em %s. Todos os arquivos corretos[%s] Verificado em %s. É necessário repararmódulo _yenc... NÃO encontrado!ajuste de maiúsculaslimparddiadiasdesativar o servidorativar o servidorobtendo msgid %s de www.newzbin2.esarquivopastahhorahorasrestantesmmanualminmin.minnão instaladodedesligadoligadooupáginaaplicativo par2... NÃO encontrado!Módulo pyOpenSSL ausente. Instale-o para obter acesso httpssegsegundosveja o arquivo de logtextodesconhecidoaplicativo unrar... NÃO encontrado!aplicativo unzip... NÃO encontrado!semanaSABnzbd-0.7.20/locale/ro/LC_MESSAGES/SABnzbd.mo0000644000000000000000000022514412433712601020520 0ustar00usergroup00000000000000=o=M>d^?@A B2CDEF*F'FG4G MGnG}GG GGGGGHHHHHHHHH?IIBJFJNJR^J[J K*K1K 8K FKSKZKbKKKKK K KK KKKaK^LbLfLyL.LLL)L* M 6M DMNMbM/uMhM NN/N(N0N* O8O=O DOROkO OOOOOOeP}P2P PP Q-QHQfQ!Q6Q-Q R+R:RXR tRR.R'RRR SB%ShSqSSSS SS5 T?TETTT"iTT8T TT TT U U U-UGU&_UU UU$U*U VV"V $V.V 4V BV OV\VcVvV~VVVV$VVV V W W )W5W(KWtW%W W-WXXf5XXX4XX?X2YLYdYY,YY,YZ1"Z5TZZZZ ZZZ1Z5[5E[{[ ['[[ [ [ [ [[[ \ #\-\ 4\>\X\s\\\\\\$\ \\ ] ]]5]#G]k]{]]]]]] ] ]]^(^>^O^b^u^^^ ^ ^4^$_$%_AJ__S_-_5#`0Y`(``H` a aa *a 7a(Da.ma)a&a,a<bbWb&bbb7c'Gcocccc c c&d-,dZdwdd dd d dd ddee*e=e%Te!zee+e e f!$fFf!dfFff0f-g'Agig"ggggghh 8hDhIhOhUh^hthhhAhh'i!8iZiziii-iiiii3i/3jgcj jj&j"k)k/k@kOk Uk ak lkvk }kkkkkk kkll l ,l9lOlal yl l ll lll l llll mm m&m+mJm-Sm6m.mm mm n n6nInGnEoo{ppp pppkq,}qqq%q#qr1rLr lrxr2r%rr" s+.sZsrs'ss7ss"{t t<t t3t9'uauiu%nuuuuuIu5vLv Qv]vqcvvcvHKwow]x)bx xxx xxxx x$xyy0yJyOycy)tyyyy y y yy yyyz zz$z+z 1z>zZzpzz*z.zz#{(,{U{Z{1j{A{{ {1|"4| W|b|g| n|,z| |||| |/|-}?}R}U}o}} }}c}" ~.~AH~,~~~3~'0!J!l"!( - 8D M*[0 ĀЀ ր( "3F[n ׁMO#jR< ;IN"m߃'=-Esx' ˄؄ 3<BWl ~  ҅ޅ4 Q^et džɆ͆  '6R Z?g  و   *4=r2 ƉЉ *:)UM0͊  # 3=E[qx̋ !. ?Lgx.Ռ ,GKT] bou# Ǎҍ  4A v 33֎. 9)U Ə($.Sk"&Őow) 3!U^m   Ò Вے9 $ ."8[n w 'ʓϓ-ԓ(+ 0 </H/x--֔&&+$R$w33Е116 h t  ͖ ؖ   ", 5@I NZbjqz  ֗ "ʘ2A:|>=X W,՜ܜ >.7?E"$1AV Ež .<k؟ 2BJj} à3ߠ-A,[#.ۡ $+0Ebv٢$f 81ϣ4 6C[d%k  Ӥߤ76 W`h:på ݥ %5@:!{*$1 0>Zo#ʧ)-J?&'٨ *026; J&X ©ũɩ̩ϩԩ9(, 4@EMg}L? $jE,յ(+Kh%"     8J[M6׹ dsdغ  ( 0Q Yf uϻH?G"M p>}м//J Ycz<ͽX$g)'D2lǿ "1JQn"1:&l'%!+>M7$  8 B5L.!"a o|Z A)kr(F - ;E co *  -*Lw  0F&a  .%/A$q/"y{ ;M"0S$i- % <"?_ 5 5@Bv %  $ 1 ?MTr     &%9 _m~ . & >Ib{9Sg}2+,L+xv: >FC,K J V b p |%7&/ 5=Ds{-4b@-!7Wt /3 !ATX`qz$' $'2L$. &- I%j]96?2v%& "0"Sv $74l&"! /JQXp.+x W b%m"  5RU]t !:K c o z  ,>Q$X}:I6 A ISdh7pZw>Ni mx%2;n~&"  3@3`*"/1J'b 2,Y5MS/8!3 <@} $h?Qw+ # 0 < FRU r|$ 7.->lqw    !"D`p*.*)1: lw8L %63*j F '< N4Z #d##N@Zq5$ &#J%j    :,.g  1)?Xn Wp)l-%JS &(*";^m' (  +7 cp&,)Eo !+JZi) .9BZ w#O8J S t  G' ?KAS  4**$4OU0   2= R ^i   &9KZ j!w$  9&E(l   * ;G` g r =   ;& @b 2  ) $ ? T d (k *   %   / @ (O -x   z  B 2c ! )   +  6 C ^ u        ?  9 E0Q   "=28 kuHHF6F}..,",OF|FD DO   4>Qbu {        $ )3< Wb s,s(L9KB/ rY2Y ^ jx~>B$V*{e  "+V> 1 ".2#4Xw/F ,C \'j "?2#O7s'5 ! %  ? I g | C u V!0! ."A<"=~";"" #+#>#$E# j# w######L#F$ d$ p$ }$?$ $$!$ %%2%0;%l%Mr%-%%%%%'&-/&@]&=&`&-='8k'''R'#(=(3Q()(((((((()%)>)E)K)M)R)V)])_)f)j)o) v)) )))))7)))** *$*=* V* SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address. SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. %s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!Read Feed will get the current feed content. Force Download will download all matching NZBs now.AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:Aborted, encryption detectedAcceptAccessAccess deniedAccount infoActionActionsActivate an alternative skin.AddAdd FeedAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAfter SABnzbd has finished restarting you will be able to access it at the following location: %sAgeAllAlso test releasesAlwaysApply maximum retries only to optional serversApply to SelectedAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto resumeAuto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBandwidthBlock Refreshes on HoverBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)Cannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check before downloadCheck for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClear CountersClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.Complete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsContainer WidthCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete CompletedDelete FailedDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Does the quota get reset each day, week or month?Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDownloadsDualView1DualView2E.g.E.g. 119 or 563 for SSLE.g. 8 or 20ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable GrowlEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable NotifyOSDEnable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable classes of messages to be reported (none, one or multiple)Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnding the path with an asterisk * will prevent creation of job folders.Enter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExit SABnzbdExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFeedsFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Chain.File name or path to HTTPS Key.File setFilenameFilterFilter out sample files (e.g. video samples).FiltersFirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardGroups / Indexer tagsHTTPS CertificateHTTPS Chain CertifcatesHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide BookmarksHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinHow much can be downloaded this month (K/M/G)I want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you get this error message again, please try a different number.
    If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix credentialsInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMaximum number of retries per serverMaximum retriesMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-OperationsMulti-part labelNZB KeyNZB added to queueNameNamingNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNo resultsNoneNormalNot MatchedNot enough disk space to complete downloads!Not matchedNotification CenterNotification Sent!Notification classesNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOffOn FinishOn queue finishOn which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)Only Get Articles for Top of QueueOnly for optional serversOnly perform post-processing on jobs that passed all PAR2 checks.Only use for remote Growl server (host:port)Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.Optional password for Growl serverOptionally specify a filenameOptionsOrderOriginal FilenameOriginal FoldernameOther MessagesOther SwitchesPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPortPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post processingPost-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessed ResultProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:Queue repairQueuedQuick Check...Quick CheckingQuitQuotaQuota leftQuota periodQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses.Read All Feeds NowRead FeedRead RSS feedsRead the Wiki Help on this!RefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRenameRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.Report-idRequiresRequiresCatResetReset Quota nowReset dayRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetention timeRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd %s startedSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd VersionSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SMTP ServerSQL Command Failed, see logSQL Commit Failed, see logSSLSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSend GroupSend RSS notificationsSend email when an RSS feed adds jobs to the queue.Send email when disk is full and SABnzbd is paused.Send group command before requesting articles.Send notifications to GrowlSend notifications to Notification CenterSend notifications to NotifyOSDSent %s to queueSeries SortingServerServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer addressServer address "%s:%s" is not valid.Server address requiredServer configurationServer definitionServer passwordServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.SettingsSetup is now complete!Should downloading resume after the quota is reset?Show AllShow BookmarksShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow times in AM/PM notation (does not affect scheduler).Show.NameShow_NameShowing %s to %s out of %s resultsShowing one resultShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSkipSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStart WizardStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTEXTTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will prevent refreshing content when your mouse cursor is hovering over the queue.This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTimeoutTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTop MenuTotalTroubleshootTry againTry to predict successful completion before actual download (slower!)Trying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUpUpdate Available!UploadUpload: .nzb .rar .zip .gzUptimeUse 12 hour clock (AM/PM)Use V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameValuesVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogView script outputWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.Who should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou must enable JavaScript for Plush to function!You need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!case-adjustedclearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilefolderhhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfiletextunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2012-10-13 17:23+0000 Last-Translator: nicusor Language-Team: Romanian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:54+0000 X-Generator: Launchpad (build 17082) SABnzbd nu poate gãsi fisierele de la interfata-web %s.
    Vã rugãm sã reinstalati programul din nou.

    SABnzbd a detectat o Coadã si Istoric de la o versiune veche (0.4.x).

    Atât coada si istoricul vor fi ignorate si s-ar putea pierde!

    Puteti sã opriti SABnzbd si sã terminati coada cu cealaltã versiune de program.

    Clic OK pentru a porni SABnzbd SABnzbd a detectat informatii salvate de la o altã versiune SABnzbd
    dar nu poate sã refoloseascã informatiile de la cealaltã versiune de program.

    Ar fi bine sã terminati coada mai întâi cu cealaltã versiune de program.

    Dupã aceia , porniti programul cu optiunea "--clean".
    Aceasta va sterge coada curentã si istoricul!
    SABnzbd citeste fisierul "%s". SABnzbd a detectat cã fisierul sqlite3.dll lipseste.

    Unele antivirusuri sterg acest fisier.
    Vã rugãm sã verificati antivirusul , încercati sã reinstalati SABnzbd si plângetivã autorului antivirusului.

    SABnzbd nu este compatibil cu unele programe firewall
    %s
    Ne pare rãu, dar noi nu putem rezolva aceastã incompatibilitate acum.
    Vã rugãm sã vã plângeti producãtorului dvs. de firewall.

    SABnzbd are nevoie de un tcp/ip port liber pentru serverul sãu intern.
    Portul %s de pe %s a fost încercat , dar nu este disponibil.
    Alt program foloseste portul sau SABnzbd este deja pornit.

    Vã rugãm sã reporniti SABnzbd cu un numãr de port diferit. SABnzbd are nevoie de un port tcp/ip liber pentru serverul sãu intern.
    Portul %s de pe %s a fost încercat , dar contul folosit de SABnzbd nu are permisiunea de a-l folosi.
    În sisteme OSX si Linux , utilizatori normali trebuie sã foloseascã porturi peste 1023.

    Vã rugãm sã reporniti SABnzbd cu un numãr de port diferit. SABnzbd are nevoie de o adresã gazdã validã pentru serverul sãu intern.
    Dvs. a-ti specificat o adresã invalidã.
    Valori sigure sunt localhost si 0.0.0.0

    Vã rugãm sã reporniti SABnzbd cu o adresã gazdã bunã. SABnzbd vine cu ABSOLUT NICI O GARANTIE. Acesta este software gratis, si sunteti binevenit sã-l redistribuiti în anumite conditii. Este licentiat sub GNU General Public License versiunea 2 sau (la optiunea dumneavoastrã) orice versiune ulterioarã. %s -> Codificare Necunoscutã%s => lipsã de pe toate serverele, ignorare%s articolele au avut duplicate diferite%s articolele au fost incorecte%s articolele au fost lipsãdosarul %s: eroare accesare %s%s fisiere în %s%s nu este o valoare octalã corectã%s nu este o adresã email validã%s lipsã  Reolvare adresã sau Report ID 
    Închidere SABnzbd terminatã.
    Asteptati timp de aproximativ 5 secunde si apoi faceti clic pe butonul de mai jos.

    Reîmprospãteazã
    + Depanare+ Info+Stergere+Reparare+DezarhivareDosar Copie de Sigurantã .nzb1x05 Dosar Episod1x05 Dosar SezonNOTÃ:Dosarele vor fi create automat când se Salveazã. Puteti utiliza cãi absolute pentru a salva în afara dosarelor implicite.Informatiile vor nu vor fi mutate. Necesitã repornire SABnzbd!Citeste Flux va descãrca continutul fluxului curent. Descãrcare Fortatã va descãrca toate NZB-urile corespunzãtoare acum.VârstãCheie APICheie API sau Cod QRCheie API incorectã, Folositi cheia api din Configurare->General în programul dumneavoastrã tert:Cheie API lipsã, vã rugãm sã introduceti cheia api de la Configurare->General în programul dumneavoastrã tertTerminat, encriptare detectatãAcceptãAccesAcces interzisInfo ContActiuneActiuniActiveazã o temã alternativã.AdaugãAdaugã fluxAdaugã fisierAdaugã NZBAdaugã PlanificareAdaugã ServerAdaugã descãrcãri noiNZB-uri AdãugateDosar AdministrativCategorii AfectateDupã repornire SABnzbd ,îl veti putea acesa la urmãtoarea locatie: %sVârstaToateTesteaza si versiuni de încercareÎntotdeaunaAplicã numãrul maxim de reîncercãri la serverele optionaleAplicã la SelectieSigur doriti sã stergetiSunteti sigur cã doriti sã reporniti SABnzbd?Sunteti sigur cã doriti sã inchideti SABnzbd?Sunteti sigur?ArgumenteLimitã Cache ArticoleIdentificator ArticolAutentificare nereusitã, verificã nume utilizator/parolã.Autentificare lipsã, vã rugãm sã introduceti numele de utilizator/parola de la Configurare->General în programul dumneavoastrã tert:Auto repornireDescãrcare-Automatã Semne de CarteAuto-pauzã când spatiul liber este sub aceastã valoare.
    În octeti, urmati optional de K, M, G, T. De exemplu: "800M" sau "8G"Descãrcare automatã a semnelor de carteDescarcã automat semnele dvs. de carteSorteazã automat obiectele dupa vârstã (medie).ÎnapoiServer SecundarServer SecundarProgramator Gresit %s la %s:%sArticoul yEnc invalid în %sDescãrcatBlocheazã Reîmprospãtarea HoverProcesare Semne de CarteCoadãEroare CRC în %s (%s -> %s)Stocheazã articolele în memorie pentru a reduce acesul disc.
    În octeti, optional urmati de K,M,G. De exemplu : "64M" sau"128M"Articole %s în cache (%s)Nu pot schimba permisiunile lui %sNu mã pot conecta la registru HKEY_CURRENT_USER.Nu mã pot conecta la serverul %s [%s]Nu pot crea %s dosar %sNu pot crea copie de rezervã pentru %sNu pot crea dosarul %sNu pot crea dosar final %sNu pot crea fisier temporar pentru %sNu pot gasi sabloane email în %sNu se poate gãsi sablon web:%s, se încearcã sablon standardNu pot porni navigatorul web, probabil nu a fost gãsitNu pot deschide cheie registru "%s".Nu pot citi %sNu pot citi Dosar Urnãrire %sNu pot scrie în fisierul INI %sCategoriiCategorieModificãrile nu au fost salvate, si vor fi pierdute.Modificãrile vor necesita repornirea SABnzbd!Verificã înainte de descãrcareVerificã Versiuni NoiVerificã rezultatul dezarhivãriiVerificã rezultatul dezarhivãrii ( trebuie sã fie dezactivat pentru unele sisteme de fisiere )Se verificãInterval VerificareInterval verificare (în minute, cel putin 15). Inactiv când se foloseste Planificatorul!Alege o temã.Listã CurãtenieStergerea lui %s nereusitã.Sterge fisierele par (dacã verificarea/repararea este cu succes)StergeReseteazã StatisticiClic mai jos pentru a testa.Clic pentru a testa detaliile introduse.ÎnchideÎnchidere a oricãrei ferestrele browser/file NU va închide SABnzbd.Dosar CompleteDosar CompletFinalizatDosar Descãrcãri FinalizateConfigurareFisier ConfigurareConfigurareConfirmã Stergere IstoricConfirmã Stergere CoadãConectarea %s@%s:%s nereusitã, mesajul=%sConexiune Reusitã!ConexiuniLãtime ContainerNu am putut sterge semnul de carte newzbin %sNu pot determina reultatul conexiunii (%s)Planificãri CurentePersonalizatDDUPLICATZilnicDosare ZilniceSortare DatãZi din lunãDeceniuDecodarea %s nereusitãImplicitDosar de Bazã ImplicitPost-Procesare ImplicitãPrioritate ImplicitãScript Utilizator ImplicitDefineste post-procesarea si stocarea.StergeStergeSterge totStergere FinalizatãSterge NereusiteSterge fluxSterge dupã descãrcareStergeti toate obiectele complete din Istoric?Stergeti toate fisierele descãrcate?Stergeti toate obiectele nereusite din Istoric?Stergeti toate obiectele din coadã?Stergeti toate fisierele nereusite din istoric?Stergere %s nereusitã!Detecteazã Descãrcãri DuplicateDetecteazã fisierele NZB denumite la fel (necesitã optiunea copie de rezervã NZB) si titluri duplicat în fluxuri RSS.Dezactiveazã cheie-APIDezactivatDezactiveazã HTTPS din cauza lipsei fisierelor CERT si KEYIgnorãDeconecteazã de la serverul(ele) Usenet când coada e goalã sau în pauzã.Deconecteazã când Coada e GoalãNotificãri Disc PlinEroare disc la crearea fisierului %sDisc plin! Pauzã FortatãFã o verificare extra bazatã pe fisiere SFVNu descãrcaAutentificare invalida pentru flux %sNu necesitã cheie API.Cota se reseteazã în fiecare zi, sãptãmânã sau lunã ?Nu aveti un furnizor usenet? Vã recomandãm sã încercati %s.JosDescarcãDescãrcare terminatãDosar DescãrcareDescãrcarea a esuatLimitã de Vitezã DescãrcareDescãrcare nereusitã - Retentie server depãsitã ?Descãrcarea ar putea esua, doar %s din %s disponibilLimitã Ratã de Descãrcare ( în KB/s - kilo-octeti pe secundã)Vitezã de descãrcareDescãrcateDescãrcat în %s cu o medie de %sB/sDecãrcat pânã acumDescãrcareDescãrcãriVedereDualã1VedereDualã2De ex.De ex. 119 sau 563 pentru SSLDe ex. 8 sau 20ENCRIPTATEROARE:EROARE: %sEROARE: CRC nereusit în "%s"EROARE: nu pot gãsi "%s"EROARE: eroare scriere (%s)Timp EstimatEditeazãEditeazã Detalii NZBEmailSetãri Cont EmailNotificãri Email Sarcinã TerminatãOptiuni EmailDestinatar EmailExpeditor EmailEmail Trimis!Dosar Sabloane EmailRezultat Test EmailAdresã de email cãtre care se trimite email.Email reusitGolFisier NZB gol %sValoare RSS gasitã a fost goalã (%s)ActiveazãActiveazã Sortare DatãActiveazã Unire FisiereActiveazã GrowlActiveazã HTTPSPermite acces HTTPS la SABnzbd.Activeazã Sortare FilmeActiveazã Par2 MultiCoreActiveazã NotifyOSDActiveazã Sterge ParActiveazã Verificare RapidãActiveazã verficãri SFVActiveazã Unire TSActiveazã Sortare TVActiveazã UnrarActiveazã UnzipPermite acesarea interfetei de la o adresã HTTPS.Activeazã functionalitatea inclusã unrar.Activeazã functionalitatea inclusã unzip .Activeazã clasã mesaje ce vor fi raportate (niciunul, unul sau mai multe)Activeazã redenumire dosarActiveazã pentru folosire de memorie mai putinã. Dezactivati pentru a preveni ca sarcinile lente sã blocheze coada.Activeazã sortarea si redenumirea genericã a fisierelor.Activeazã dacã descãrcãrile nu sunt puse în dosarele lor.Activeazã sortarea si redenumirea fisierelor denumite dupã datã.Permite sortarea si redenumirea de episoade.ActivatFinalizarea unei cãi cu un asterix * va preveni crearea de dosare sarcini.Introdu URLNume EpisodNumãr EpisodNume.EpisodNume_EpisodEroare "%s" în timpul file_join a %sEroare "%s" în timpul rulãrii par2_repair pe setul %sEroare "%s" în timpul rar_unpack a %sEroare "%s" în timpul rulãrii unzip() pe %sEroare %s în timpul rulãrii par2_repair pe setul %sEroare %s: Trebuie sã furnizati un nume utilizator si parolã validEroare descãrcare msgid %s de la www.newzbin2.es - Vã rugãm asigurati-vã cã Nume de Utilizator si Parolã sunt setateEroare la crearea cheiei si certificatlui SSLEroare obtinere info TV (%s)Eroare importare %sEroare importare modul OpenSSL . Se conecteazã folosind NON-SSLEroare încãrcare %s, fisier corupt detectatEroare stergere %sEroare stergere dosar curent (%s)Eroare redenumire "%s" în "%s"Eroare adãugare %s, stergemEroare la oprirea sistemuluiDoar-eroriEroare: Nici o interfatã secundarã definitã.Eroare: Coada nu este goalã, nu pot schimba dosar.Eroare: Cheie Sesiune IncorectãEroare: Cheie Sesiune NecesarãErori/AvertismenteTotExempluÎnchide SABnzbdExtensieParametri Extra PAR2Dezarhivare...Nereusit din cauza Erorilor CRC yEncNereusitAutentificare nereusitã la serverul %sFacere nereusitã (%s)Mutare %s în %s nereusitãAutentificare server mail nereusitãÎnchidere bazã de date nereusitã, vedeti jurnalÎnchidere conexiune mail nereusitãCompilarea unei cãutãri regex nereusitã: %sConectare server mail nereusitãPunere sistem în hibernare nereusitãImportare %s a fisierelor de la %s nereusitãInitializare nereusitã %s@%s:%sInitializare conexiune TLS nereusitãÎncãrcare coadã post-procesare nereusitã : Versiune gresitã (am nevoie de:%s, gãsit:%s)Nu am putu muta fisierCitire valoare registru pentru dosare speciale nereusitãStergere nzo din coadã post-procesare nereusitã (id)Redenumire fisiere similare : %s în %s nereusitãRedenumire:%s în %s nereusitãDescãrcare %s: %s din RSS nereusitãTrimitere email nereusiãPunere sistem în asteptare nereusitãPornirea interfetei-web nereusitãActualizare sarcinã %s nereusitãNereusitEroare în tempfile.mkstempEroare fatalãFluxFluxuriDescarcãDescãrcareDescãrcare %s blocuri...Descãrcare blocuri extra...Fisierul %s este gol , ignorãmExtensie fisierFisier ce contine parole pentru fisiere RAR encriptate.Unirea fisierului %s nereusitãNume fisier sau cale Certificat HTTPS.Nume fisier sau cale cheie HTTPS.Nume fisier sau cale Cheie HTTPS.Set fisiereNume de fisierFiltruIgnorã fisiere monstrã (de ex. monstre video)FiltrePrimulDosarul "%s" nu existãConfigurare DosareDosar ce contine script-uri de post-procesare.Dosar ce contine sabloane email utilizator.Dosar pentru supraveghere fisiere .nzb.
    Scaneazã de asemenea si arhivele .zip .rar .tar.gz de fisiere .nzb.Dosar/CaleDirectoarePentru email autentificat, nume cont.Pentru email autentificat, parola.ForteazãForteazã DeconectareaDescãrcare FortatãForumGol (Temp)Spatiu liberFrecventãVineriAjutor suplimentar poate fi gãsit pe pagina noastrãGBGeneralConfiguratie GeneralãGenereazã o Cheie NouãSortare GenericãDescarcã Semne de CarteIa Semne de Carte AcumDescarcã NZBDescarcã Semne de Carte NewzbinDu-te la SABnzbdDute la vrãjitorGrupuri / Taguri IndexerCertificat HTTPSCertificate Cheie HTTPSCheie HTTPSPort HTTPSSuport HTTPSAjutorHibernare PCAscunde Semnele de CarteAscunde Optiuni EditareAscunde detaliileAscunde fisiereRidicatãIstoricIstoric Ultimele 10 ObiecteMãrime IstoricPagina de pornirePaginã de pornireGazdãNume Gazdã unde SABnzbd va asculta.Ore:MinCât de mult poate fi descãrcat în acestã lunã (K/M/G)Vreau SABnzbd sã fie vizibil de cãtre orice calculator din reteaua mea.Vreau SABnzbd sã fie vizibilã numai de pe PC-ul meu.INACTIVINCOMPLETParametri IONiceIRCInactivDacã e gol, portul standard va asculta doar în HTTPS.Dacã sunteti un membru al newzbin sau nzbmatrix, puteti introduce numele de utilizator si parola aici, astfel încât sã putem descãrca nzb-uri de la ei. Aceastã etapã poate fi omisã dacã nu folositi serviciile lor.Dacã primiti acest mesaj de eroare din nou, vã rugãm sã încercati un alt numãr.
    Dacã aveti un cont la www.newzbin2.es, puteti introduce informatiile contului aici.
    Aceasta va debloca functionalitate extra.Dacã aveti un cont la www.nzbmatrix.com, puteti introduce informatiile contului dvs. aici .
    Acest lucru este necesar dacã doriti sã utilizati fluxurile RSS de pe acest site.Ignorã MonstreIgnorãm duplicat NZB "%s"ÎnÎn dosareÎn minute (cel putin 15 min).Pentru a descãrca de pe usenet veti avea nevoie de un furnizor. ISP-ul dvs. vã poate oferi acces, totusi un furnizor premium e recomandat.Fulx RSS incompatibilFisier coadã gãsit incompatibil, nu pot înaintaDosar IncompletFisier NZB incomplet %sSecventã incompletã de unire fisiereDescriere flux RSS incorectã "%s"Parametru IncorectValoare incorectã pentru %s: %sParolã %s codificatã gresitSituri IndexInitializare repornire...
    Fisier NZB invalid %s, ignorãm (motiv=%s, line=%s)Codificare invalidã a sablonului email %sCredentiale invalide nzbmatrixNumãr report invalid nzbmatrix %sFisier par2 invalid, nu pot verifica sau reparaAdresã server invalidãDetalii server invalideJurnal istoric stagii invalid pentru %sInverseazãEste posibil cã folositi ZoneAlarm în Vista.
    Este recomandat sã faceti clic dreapta si sã faceti o scurtaturã , pe care sã o folositi pentru a accesa SABnzbd când ruleazã în fundal.Sarcina "%s" a fost re-adãugatã în coadãSarcinã terminatãSarcinile selectate cu '*' vor fi descãrcate automatUneste fisiereleUneste fisierele care se terminã în .001, .002 etc. într-un singur fisier.Uneste fisierele care se terminã în .001.ts, .002.ts etc. într-un singur fisier.UnimKB/sPãstreazã descãrcãrile suplimentare în dosare extraLimbãUltimulUltimele AvertizãriPorneste Navigator Web la PornireLanseazã navigatorul meu web la pornirea SABnzbd .Porneste navigatorul web implicit când se porneste SABnzbd.StângaLimitare de VitezãLegãturiLista de extensii de fisiere care ar trebui sã fie sterse dupã descãrcare.
    De exemplu: .nfo sau .nfo, .sfvÎncãrcarea %s nereusitãLocatia coadei admin si istoricul bazei de date.
    Poate fi folosit doar când coada e goalã.Locatie a fisierelor jurnal ale SABnzbd.
    Necesitã repornire SABnzbd!Locatie pentru stocare , a descãrcãrilor procesate complet.
    Poate fi suprascris de categoriile definite de utilizator.Locatie de stocare a descãrcãrilor neprelucrate.
    Poate fi schimbatã doar atunci când coada este goalã.Locatie unde fisierele .nzb vor fi stocate.Dosar JurnalJurnalizareScãzutãLitere MiciMBPachet principal negãsit...PotriviteVitezã MaximãNumãr Maxim reîncercãri pe serverNumãr Maxim reîncercãriSemnificatieMinim de Spatiu Liber pentru Dosar Descãrcare TemporarDiverseCheie Sesiune lipsãArticole lipsãFisiere asteptate lipsã: %s => eroare unrar?LuniLunãMai multNume FilmNume.FilmNume_FilmMutareMutare...Operatii-MultipleEtichetã Multi-pãrtiCheie NZBNZB adãugat în coadãNumeRedenumireNiciodatãFlux URL NouVersiune nouã %s disponibilã laVersiune nouã disponibilãParolã NewzbinNume de Utilizator NewzbinNewzbin a dat o eroare nedocumentatã (%s)Newzbin a dat o eroare nedocumentatã (%s, %s)Newzbin raporteazã ca nu a fost gãsit %sServerul Newzbin si-a schimbat protocolulServerul Newzbin nu poate da informatii pentru %sUrmãtorulParametri NiceNici un program PAR2 gãsit, repararea imposibilã
    Nici un program UNRAR gãsit, dezarhivarea fisierelor RAR imposibilã
    Sabloane email negãsiteFãrã dosareNici o post-procesare din cauza verificãrii nereusiteDestinatar necunoscut, niciun email trimisFãrã rezultateNiciunulNormalNepotrivitSpatiul liber insuficient pe disc pentru finalizarea descãrcãrilor !NepotriviteCentru NotificãriNotificare Trimisã!Clase notificãriNotificãriNumãrul de secunde între scanarea de fisiere .nzb.Cheia API NzbMatrixNume de Utilizator NzbMatrixOKParolã Cont OPTIONALNume Cont OPTIONALOpritLa TerminareLa terminarea coadei de descãrcareÎn ce zi a lunii sau sãptãmânã (1=Luni) ISP dumneavoastrã reseteazã cota? (Optional cu hh:mm)Ia Articole doar din Vârful CoadeiDoar pentru servere optionaleExecutã post-procesarea doar dacã sarcina a trecut toate verificãrile PAR2.Foloseste doar pentru server Growl de la distantã (gazdã:port)Dechide URL InformatiiDeschide URL SursãDeschide fereastra Terminal si scrie linia (exemplu):Deschide dosar descãrcãri completeOptionalNZB Suplimentar OptionalParolã autentificare optionalãNume Utilizator autentificare optionalParolã optionalã server GrowlOptional specificã un nume de fisierOptiuniOrdineNume de Fisier OriginalNume de Dosar OriginalAlte MesajeAlte ComutatoareÎNTRERUPTPaginãParametriiNumãr ParteParolãFisier paroleParolã ascunsã în ******, Vã rugãm sã re-introducetiAcces SABnzbd protejat cu parolã (recomandat)CaleSablonModel CheiePauzãPauzã ToateÎntrerupe Descãrcarea în Timpul Post-ProcesareInterval PauzãPauzã timp dePauzã timp de o orãPauzã timp de 12 orePauzã timp de 15 minutePauzã timp de 24 orePauzã timp de 3 orePauzã timp de 30 minutePauzã timp de 5 minutePauzã timp de 6 orePauzã pentru câte minute?Pauzã timp de...Pauzã post-procesareÎntreruptÎntrerupe descãrcare la începerea post procesãrii si reporneste când e terminatã.Întrerupem duplicat NZB "%s"Permisiuni pentru descãrcãri finalizateVã rugãm sã fiti constienti cã numele gazdei 0.0.0.0 va avea nevoie de o adresa IPv6 pentru acces externVã rugãm sã introduceti un numãr întreg.Vã rugãm sã introduceti detaliile furnizorului dvs principal de usenet.Optiuni PlushPortPortul pe care SABnzbd îl va asculta.Post Procesare Nereusitã pentru %s (%s)Post procesarePost-Proceseazã Doar Sarcinile VerificateDirector Script-uri Post-ProcesarePost-procesarePost-procesare pornitãPost-Procesarea a fost abandonatã (%s)Script utilizator Pre-CoadãPresetãriApasã Start+R si scrie linia (exemplu):PrecedentPrecedentPrioritatePartajare cont probabilãProbleme la accesarea server nzbmatrix (%s)Problemã cuSemne de Carte ProcesateRezultat ProcesatÎn curs de procesareComutatoare ProcesareAplicatia nu a pornit!ProgresStergeSterge NZB-uri CompleteGoleste Istoric Descãrcãri NereusiteSterge NZB-uri nereusiteSterge NZB-uri Nereusite & Fisiere SterseSterge IstoriculSterge NZB-uriSterge NZB-uri & Fisiere SterseGoleste CoadãGoliti Istoricul?Goliti Coada?Versiune PythonCod QRCoadãPune la Coadã Primele 10 ObiecteInterval reîmprospãtare automatã coadã:Coadã repararePus în coadãVerificare Rapidã...Verificare RapidãIesireCotãCotã rãmasãPerioadã CotãCotã epuizatã, întrerupem descãrcareaRRSSInterval Verficare RSSConfigurare RSSFluxul RSS %s a fost golDuratã %sIntervalOptiuni folosite rar. Pentru explicatiile si semnificatia lor, click pe meniul Ajutor si viziteazã pagina Wiki.
    Nu modificati aceste setãri fãrã a verifica mai întâi pagina Wiki , pentru cã unele pot cauza probleme serioase .
    Valorile originale sunt în paranteze .Citeste Toate Fluxurile AcumCiteste FluxCiteste fluxuri RSSCiteste Ajutorul Wiki despre asta !ReîmprospãteazãRata de ReîmprospãtareInterval reîmprospãtare a coadei din pagina interfetei web(sec, 0= niciunul).Ratã actualizareRespingeDosarele relative se bazeazã peRãmas/TotalRãmasStergeSterge NZBSterge NZB & Fisiere SterseSterge ServerEliminã sarcini nereusiteSterge din lista dvs. de semne de carte dupã o descãrcare finalizatãStergerea %s nereusitãRedenumesteReparãReparare nereusitã, blocuri reparare insuficiente (%s mai putin)Se reparãReparare nereusitã, %sReparare...Înlocuieste Caracterle Ilegale din Numele DosarelorÎnlocuieste Spatiile din Numele DosarelorÎnlocuieste punctele din Numele DosarelorÎnlocuieste puntele cu spatii în numele dosarelor.Înlocuieste caracterele ilegale din numele dosarelor cu echivalente (altfel sterge).Înlocuieste spatiile cu _ în numele dosarelor.Report-idNecesitãNecesitãCategoriaReseteazãReseteazã Cota acumZi resetareRepornesteReporneste fãrã autorizareRepornim SABnzbd...RezultatReiaReia post-procesareTimp RetentieReîncearcãRulare scriptRulare script...Rulare script utilizator %sS01E05 Dosar EpisodS01E05 Dosar SezonSABnzbd %s pornitGazdã SABnzbdParolã SABnzbdPort SABnzbdVrãjitor Pornire-Rapidã SABnzbdNume Utilizator SABnzbdVersiune SABnzbdServer Web SABnzbdSABnzbd a detectat o eroare fatalã:Închidere SABnzbd terminatãSABnzbd va rula acum în fundal.Server SMTPComandã SQL Nereusitã, vedeti jurnalModificare SQL Nereusitã, vedeti jurnalSSLTip SSLSâmbãtãSalveazãSalveazã ModificãrileSalvatSalvarea %s nereusitãSalvãm..Scaneazã dosar urmãrirePlanificare pentru un server inexistent %sPlanificareConfigurare PlanificatorScriptScript-uriNumãr SezonInterfatã Web SecundarãAlegeti o limbã interfatã web.Selecteazã doar dacã furnizorul dvs. permite conexiuni SSL.SelectieTrimite GrupTrimite notificãri RSSTrimite email când un flux RSS adaugã sarcini în coadã.Trimite email când discul este plin si SABnzbd este întrerupt.Trimite comanda group înainte de a cere articole.Trimite notificãri GrowlTrimite notificãri la Centru NotificãriTrimite notificãri cãtre NotifyOSDTrimis %s în coadãSortare SerialeServerServerul %s necesitã utilizator/parolãServerul %s va fi ignorat pentru %s minuteDetalii ServerAdresã serverAdresa server "%s:%s" nu este validãAdresã server necesarãConfigurare ServerDefinitie ServerParolã serverServerul a renuntat în timpul logãrii.Serverul necesitã nume utilizator si parolãServereSeteazã Interval PauzãSeteazã permisiunile pentru fisierele/directoarele finalizate.
    În valori octale. De exemplu: "755" sau "777"Setati cheia API NzbMatrix aici.Seteazã serverul dvs. ISP pentru trimitere email.Setati parola contului dvs. aici.Setati numele de utilizator de cont aici.SetãriInstalarea este acum completã!Se reia descãrcarea dupã resetarea cotei?Aratã toateAfiseazã Semnele de CarteAratã Optiuni EditareAratã NereusiteAratã JurnalizareaNume SerialAratã Nume dosarAratã Jurnal WebAratã detaliiAratã fisiereAratã interfataAfisati timpii în notatia AM/PM (nu afecteazã planificatorul)Nume.SerialNume_SerialAfisare %s pânã la %s din totalul %s rezultateAfisãm un rezultatÎnchidereÎnchide PCÎnchide SABnzbdÎnchidereSemnal %s prins, salvez si ies...MãrimeOmiteIgnorã verificarea par2 când fisierele sunt complete 100%%.Unele fisiere nu au fost verificate corect cu "%s"SorteazãSir Caractere SortareSorteazã dupã VârstãSorteazã dupã Vârstã (Cel mai Nou→Cel mai Vechi)Sorteazã dupã Vârstã (Cel mai Vechi→Cel mai Nou)Sorteazã dupã Vârstã Cel mai Nou→Cel mai VechiSorteazã dupã Vârstã Cel mai Vechi→Cel mai NouSorteazã dupã Nume (A→Z)Sorteazã dupã Nume (Z→A)Sorteazã dupã Nume A→ZSorteazã dupã Nume Z→ASorteazã dupã Mãrime (Cel mai Mare→Cel mai Mic)Sorteazã dupã Mãrime (Cel mai Mic→Cel mai Mare)Sorteazã dupã Mãrime Cel mai Mare→Cel mai MicSorteazã dupã Mãrime Cel mai Mic→Cel mai MareSorteazã dupã vârstãSorteazã dupã numeSorteazã dupã mãrimeSortareConfigurare SortareSursãSpecialVitezãLimitã de VitezãLimitare de VitezãRepaus PCPorneste VrãjitorPornire RepararePornire/ÎnchidereStarePasul CinciPasul PatruPasul UnuPasul TreiPasul DoiStopSe opreste...StocareSubiectDuminicãComutatoareConfigurare ComutatoareÎncãrcare sistemDosare SistemTEXTPREA MARESarcinãDosar Descãrcare TemporarEmail TestNotificãri TestTest ServerTestez detalii server...Butonul "Reparare" va reporni SABnzbd si face o reconstructie completã
    a continutului coadei de descãrcare , mentinând fisierele deja descãrcate.
    Acest lucru va modifica ordinea în coada de descãrcare.Instrumentul de descãrcare automatã usenetCaseta de lângã numele fluxului trebuie sã fie selectatã pentru ca fluxul sã fie verificat de obiecte noi automat.
    Când un flux este adãugat , el va lua doar obiectele noi si nu cele deja existente, cu exceptia când apãsati "Descãrcare Fortatã".Numele gazdei nu este setat.Numãrul de conexiuni permis de furnizorNu sunt conexiuni stabilite. Vã rugãm sã stabiliti cel putin o conexiune.Sunt sarcini orfane în dosarul de descãrcare.
    Puteti alege în a le sterge (inclusiv fisierele) sau a le trimite înapoi în coadã.Acest câmp este obligatoriu.Aceastã cheie va permite programelor terte sã adauge NZB-uri în SABnzbd.Aceastã cheie va oferi programelor terte acces deplin la SABnzbd.Luna aceastaSãptãmâna aceastaAcest lucru va preveni reîmprospãtarea când cursorul mouse-ului este deasupra coadei.Acest lucru va reporni SABnzbd.
    Folositi-l atunci când credeti cã programul are o problemã de stabilitate.
    Descãrcarea va fi opritã înainte de repornire si reluatã ulterior.Acesta va trimite un email test cãtre contul dvs.ProcesJoiA depãsit timpul alocatA depãsit timpul alocat : Încercati sã activati SSL sau conectarea pe un port diferit.Timp rãmasTimp ExpirareTitluFrom: %s To: %s Date: %s Subject: SABnzbd raporteaza Disc Plin Salut, SABnzbd sa oprit din descarcare, deoarece discul este aproape plin. Va rugam sa faceti loc si reluati SABnzbd manual. AziComutã Adaugã NZBPrea putin spatiu disc fortez PAUZÃPrea multe conexiuni cãtre serverul %s:%sPrea multe conexiuni, vã rugãm sã întrerupeti descãrcarea sau sã încercati din nou mai târziuVârfMeniu TopTotalDepanareÎncercati din nouÎncearcã sã prezici decãrcarea cu succes înaintea descãrcãrii reale (mai lent!)Încerc verificare SFVÎncerc sã descarc NZB de la %sÎncerc sã setez starea unui server nexistent %sÎncerc unrar cu parola "%s"MartiOptimizãriTipUcale UNC "%s" nu este premisã aiciDescãrcare URL nereusitã; %sUTILIZATI PE RISCUL DVS. !Sterge Semn Carte dupã Descãrcare FinalizatãNeautorizat, verificati numele de utilizator/parola dvs. de la newzbinDeblocheazãEroare Necunoscutã în timpul decodãrii %sActiune necunoscutã: %sDezarhiveazãDezarhivat %s fisierele/dosarele în %sDezarhivareDezarhivare nereusitã, %sDezarhivare nereusitã, eroare CRCDezarhivare nereusitã, un fisier asteptat nu a fost dezarhivatDezarhivare nereusitã, arhiva necesitã o parolãDezarhivare nereusitã, vezi jurnalDezarhivare nereusitã, acest(e) fisier(e) sunt lipsã:Dezarhivare nereusitã, nu pot gãsi %sDezarhivare nereusitã, eroare scriere sau disc plin?Fisier NZB InutilizabilSusActualizare Disponibilã!ÎncarcãÎncarcã: .nzb .rar .zip .gzDurata FunctionãriiFolositi sitemul 12 ore (AM/PM)Folositi V23 doar dacã furnizorul dumneavoastrã necesitã altfel!Foloseste nume temporare în timpul post procesãrii. Dezactivati când sistemul dvs. nu gestioneazã aceasta corect.Utilizati coloana "Grupuri /Taguri Indexer" pentru a desemna taguri categoriilor dvs. .
    Metacaracterele sunt acceptate. Utilizati virgule pentru a separa termeni.Folosit înainte ca un NZB sã intre în coadã.Cache FolositFolosit când nu este definit nici o post-procesare de categorie.Folosit când nu este definit nici o prioritate de categorie.Folosit când nu este definit nici un script de categorie.Dosare UtilizatorCategorii definite de utilizatorNume de UtilizatorValoriVerificare reusitã cu fisierele SFVSe verificãVerificare...VersiuneVezi Jurnal ScriptVezi rezultat scriptASTEAPTÃ %s secATENTIE:ATENTIE: Sarcinã "%s" abandonatã deoarce contine un fisier RAR ecriptatATENTIE: Sarcina "%s" întreruptã din cauza fisierelor RAR encriptateAVERTIZÃRISe asteaptãAvertismentAtentie:LOCALHOST este ambiguu, folositi o adresã IP numericãAtentionãriDosar MonitorizatVitezã Scanare Dosar MonitorizatInterfatã WebAutentificare server webMiercuriVerificare sãptãmânalã versiuni noi SABnzbd.CândCând un articol are o eroare CRC , încearcã sã-l iei de pe un alt server.Cine ar trebui sã spunem cã a trimis email?WikiXAnDosar An-LunãNu aveti credit în contul dvs. NewzbinNu ai permisiunea sã folosesti acest port %sTrebuie sã activati JavaScript pentru ca Plush sã functioneze!Aveti nevoie de un cont VIP la nzbmatrix pentru a utiliza APIVersiunea dvs. UNRAR nu este recomandatã, luati-o de la http://www.rarlab.com/rar_add.htm
    [%s] Eroare "%s" în timpul unirii fisierelor[%s] Eroare "%s" în timpul dezarhivãrii fisierelor RAR[%s] Unit %s fisierele[%s] Niciun set par2[%s] PAR2 a primit optiuni incorecte, verificã setãrile Configurare->Comutatoare[%s] Verficare Rapidã OK[%s] Reparat în %s[%s] Verificat în %s, toate fisierele sunt corecte[%s] Verificat în %s, reparare necesarãmodulul _yenc ... Negãsit!ajustare nume fisierStergedziziledezactiveazã serveractiveazã serverdescarc msgid %s from www.newzbin2.esfisierdosarhorãorerãmasmmanualminmin.minuteneinstalatdindezactivatactivatsaupaginãbinar par2 ... Negãsit!modul pyopenssl lipsã, instalati-l pentru acces httpssecsecundevezi fisier jurnaltextnecunoscutbinar unrar... Negãsit!binar unzip... Negãsit!sãptãmânãSABnzbd-0.7.20/locale/sv/LC_MESSAGES/SABnzbd.mo0000644000000000000000000020400412433712601020520 0ustar00usergroup000000000000008o88d9;; <2=?@*@'G@o@@@ @@@ A ,A7A>AVAiABBBB'B/BBBVBiB?B.C2C:CRJC[CCDD $D 2D?DFDNDlDpDyD D DD DDDDDDD)E*8E cE qE{EE/EhE;FPF(F0F*.GYG^G eGsGGGGGGcH{H2H HH I+IFIdI!I6I-I J)J8JVJ rJ}J.J'JJJB KPKYKSkKK KK5K'L-L"BLeL8kL LL LLL L LM M&8M_M vM$M*MMMM MM M N N%N,N?NGN[NsNN$NNN N NN(NO%;O aO-OOOfOFPVP4_PP?PPPQ-Q,FQsQ,QQ5QRRR #R0R@R1UR5R5RR S' S5S GS SS ]SgS lSvS }SSSSSSSSTT$%T JTXT hT uTTT#TTTTTUU,U o DoQomooo*o.oo#p(?phpmp1}pApp q1q"Gqjqoq,vq q q/qqqrr/rIr MrWr"grArrr3r's~ S~`~ q~~~~~~~.~&B]fo t#   24S 3.р (Aj$y"ˁ&o0) *AJ \ h u  ǃ у"ۃ  $'2Z-_( DŽ/ӄ/-3-a&&$݅$3'3[11 !7>F L X cn~  LJ ̇؇ &05 OZ lx"Cfg2Az>=ы  $,Ɍ >OX^"'$JAo ȎҎ.5U]dik 2ُ 4GN nx3-ݐ" .,H#u.ȑڑݑ 0bB$ ʒ8Ւ14@ u% ɓ ӓ 7 6X: # =%Gm@r!Օڕܕ*$0DZu#Ж)3JE&'ߗ"(*.3 B&Pw|~ Ř9ߘ %19Snsr"3ɜ amWbtע٣')@Zo %Ҥ  2ݥ  +=Dܦ! %0bBa %/8 IW `k Ũר &-2%90_1©ѩک DnEtҪ(G*p)ū̫ ޫ$)>E]ݬ,0""Sv!!ǭ  5*6`"ʮ! 8 &Y"I R'z ;8K\R ȱձݱ   >2Z .޲ )8 HSZw'ֳ *.Ds/´.$0xUε 1 !>+jĶ$߶,AEY Ƿ'8 GYL *9 S ^ jv z#ҹ,3*NyԺ'*.C^g%%ۻ# .A'a7$$?iN,89/X  &ƾ*'$@&eAmο4<%q@( ):)d+( %+BZ v  ( ")*L,w+7)(2-['-S!39U>3&1)[-{*+  $3:AI]t L$-)=gw0/9K 40HOdw} %"4IXr   =M Q["b R<! )4F J6URSb x_)q/% #1H eq6$)6K`$x 9y [|<@F bm!r>3FOfnnaS[~c. 1@H^)o    *E]o%)!&,KR6a7 90-^dGk +&)Eadm$77 EY`#z'    # - 7.E6t '  ! ,:J[kz jU(sN41 F)g%:3M -  +EMSi*  $ 1<KRV(o )/ GQYj 3  (3 ;G]l? N =G c%p)M.G v    $3K]q &*'"R u&.BIP_!{9 ?.*Ym)|+%#1,Ul) 15'g"    . < JU f pz %*6(S|7755Q,,** 979q770C Yc{      !-5;CLc t   ,4K6P#@t 8>%+ %:*`I ";3)o )#;6r    9*2d2 ,/4H}2Z$a <6:CS s$  C6L ? *"8P.WX!  *$2O9`%-Cq\'&)Nx&"369=CHCb  SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s". SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number. SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number. SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address.%s -> Unknown encoding%s => missing from all servers, discarding%s articles had non-matching duplicates%s articles were malformed%s articles were missing%s articles were removed%s directory: %s error accessing%s files in %s%s is not a correct octal value%s is not a valid email address%s missing  Resolving address or Report ID 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    + Debug+ Info+Delete+Repair+Unpack.nzb Backup Folder1x05 Episode Folder1x05 Season FolderNOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.Data will not be moved. Requires SABnzbd restart!AGEAPI KeyAPI Key QR CodeAPI Key incorrect, Use the api key from Config->General in your 3rd party program:API Key missing, please enter the api key from Config->General into your 3rd party program:Aborted, cannot be completedAcceptAccessAccess deniedAccount infoActionActionsActivate an alternative skin.AddAdd FileAdd NZBAdd ScheduleAdd ServerAdd new downloadsAdded NZBAdministrative FolderAffected CategoriesAgeAllAlwaysAre you sure you want to deleteAre you sure you want to restart SABnzbd?Are you sure you want to shutdown SABnzbd?Are you sure?ArgumentsArticle Cache LimitArticle identifierAuthentication failed, check username/password.Authentication missing, please enter username/password from Config->General into your 3rd party program:Auto-Fetch BookmarksAuto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"Automatically download bookmarked posts.Automatically retrieve jobs from your bookmarks.Automatically sort items by (average) age.BackBackupBackup serverBad schedule %s at %s:%sBadly formed yEnc article in %sBookmark ProcessingBottomCRC Error in %s (%s -> %s)Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"Cached %s articles (%s)Cannot change permissions of %sCannot connect to registry hive HKEY_CURRENT_USER.Cannot connect to server %s [%s]Cannot create %s folder %sCannot create backup file for %sCannot create directory %sCannot create final folder %sCannot create temp file for %sCannot find email templates in %sCannot find web template: %s, trying standard templateCannot launch the browser, probably not foundCannot open registry key "%s".Cannot read %sCannot read Watched Folder %sCannot write to INI file %sCategoriesCategoryChanges have not been saved, and will be lost.Changes will require a SABnzbd restart!Check for New ReleaseCheck result of unpackingCheck result of unpacking (needs to be off for some file systems).CheckingChecking IntervalChecking interval (in minutes, at least 15). Not active when you use the Scheduler!Choose a skin.Cleanup ListCleanup of %s failed.Cleanup par files (if verifiying/repairing succeded).ClearClick below to test.Click to test the entered details.CloseClosing any browser windows/tabs will NOT close SABnzbd.Complete DirComplete FolderCompletedCompleted Download FolderConfigConfig FileConfigurationConfirm History DeletionsConfirm Queue DeletionsConnecting %s@%s:%s failed, message=%sConnection Successful!ConnectionsCould not delete newzbin bookmark %sCould not determine connection result (%s)Current SchedulesCustomDDUPLICATEDailyDaily FoldersDate SortingDay of monthDecadeDecoding %s failedDefaultDefault Base FolderDefault Post-ProcessingDefault PriorityDefault User ScriptDefines post-processing and storage.DelDeleteDelete AllDelete FeedDelete after downloadDelete all completed items from History?Delete all downloaded files?Delete all failed items from History?Delete all items from the queue?Delete the all failed items from the history?Deleting %s failed!Detect Duplicate DownloadsDetect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.Disable API-keyDisabledDisabled HTTPS because of missing CERT and KEY filesDiscardDisconnect from Usenet server(s) when queue is empty or paused.Disconnect on Empty QueueDisk Full NotificationsDisk error on creating file %sDisk full! Forcing PauseDo an extra verification based on SFV files.Do not downloadDo not have valid authentication for feed %sDo not require the API key.Don't have a usenet provider? We recommend trying %s.DownDownloadDownload CompletedDownload DirDownload FailedDownload Speed LimitDownload failed - Out of your server's retention?Download might fail, only %s of required %s availableDownload rate limit (in KB/s - kilobytes per second).Download speedDownloadedDownloaded in %s at an average of %sB/sDownloaded so farDownloadingDualView1DualView2E.g.ENCRYPTEDERROR:ERROR: %sERROR: CRC failed in "%s"ERROR: path too long (%s)ERROR: unable to find "%s"ERROR: write error (%s)ETAEditEdit NZB DetailsEmailEmail Account SettingsEmail Notification On Job CompletionEmail OptionsEmail RecipientEmail SenderEmail Sent!Email Templates FolderEmail Test ResultEmail address to send the email to.Email succeededEmptyEmpty NZB file %sEmpty RSS entry found (%s)EnableEnable Date SortingEnable FilejoinEnable HTTPSEnable HTTPS access to SABnzbd.Enable Movie SortingEnable MultiCore Par2Enable Par CleanupEnable Quick CheckEnable SFV-based checksEnable TS JoiningEnable TV SortingEnable UnrarEnable UnzipEnable accessing the interface from a HTTPS address.Enable built-in unrar functionality.Enable built-in unzip functionality.Enable folder renameEnable for less memory usage. Disable to prevent slow jobs from blocking the queue.Enable generic sorting and renaming of files.Enable if downloads are not put in their own folders.Enable sorting and renaming of date named files.Enable sorting and renaming of episodes.EnabledEnter URLEpisode NameEpisode NumberEpisode.NameEpisode_NameError "%s" while running file_join on %sError "%s" while running par2_repair on set %sError "%s" while running rar_unpack on %sError "%s" while running unzip() on %sError %s while running par2_repair on set %sError %s: You need to provide a valid username and password.Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are setError creating SSL key and certificateError getting TV info (%s)Error importing %sError importing OpenSSL module. Connecting with NON-SSLError loading %s, corrupt file detectedError removing %sError removing workdir (%s)Error renaming "%s" to "%s"Error while adding %s, removingError while shutting down systemError-onlyError: No secondary interface defined.Error: Queue not empty, cannot change folder.Error: Session Key IncorrectError: Session Key RequiredErrors/WarningEverythingExampleExtensionExtra PAR2 ParametersExtracting...Fail on yEnc CRC ErrorsFailedFailed login for server %sFailed making (%s)Failed moving %s to %sFailed to authenticate to mail serverFailed to close database, see logFailed to close mail connectionFailed to compile regex for search term: %sFailed to connect to mail serverFailed to hibernate systemFailed to import %s files from %sFailed to initialize %s@%s:%sFailed to initiate TLS connectionFailed to load postprocessing queue: Wrong version (need:%s, found:%s)Failed to move filesFailed to read registry keys for special foldersFailed to remove nzo from postproc queue (id)Failed to rename similar file: %s to %sFailed to rename: %s to %sFailed to retrieve RSS from %s: %sFailed to send e-mailFailed to standby systemFailed to start web-interfaceFailed to update newzbin job %sFailureFailure in tempfile.mkstempFatal errorFeedFetchFetchingFetching %s blocks...Fetching extra blocks...File %s is empty, skippingFile ExtensionFile containing all passwords to be tried on encrypted RAR files.File join of %s failedFile name or path to HTTPS Certificate.File name or path to HTTPS Key.File setFilenameFilter out sample files (e.g. video samples).FirstFolder "%s" does not existFolder configurationFolder containing user scripts for post-processing.Folder containing user-defined email templates.Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.Folder/PathFoldersFor authenticated email, account name.For authenticated email, password.ForceForce DisconnectForce DownloadForumFree (Temp)Free SpaceFrequencyFridayFurther help can be found on ourGBGeneralGeneral configurationGenerate New KeyGeneric SortingGet BookmarksGet Bookmarks NowGet NZBGet Newzbin BookmarksGo to SABnzbdGo to wizardHTTPS CertificateHTTPS KeyHTTPS PortHTTPS SupportHelpHibernate PCHide Edit OptionsHide detailsHide filesHighHistoryHistory Last 10 ItemsHistory SizeHomeHome pageHostHost SABnzbd should listen on.Hour:MinI want SABnzbd to be viewable by any pc on my network.I want SABnzbd to be viewable from my pc only.IDLEINCOMPLETEIONice ParametersIRCIdleIf empty, the standard port will only listen to HTTPS.If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services.If you get this error message again, please try a different number.
    If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.Ignore SamplesIgnoring duplicate NZB "%s"InIn foldersIn minutes (at least 15 min).In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.Incompatible feedIncompatible queuefile found, cannot proceedIncomplete FolderIncomplete NZB file %sIncomplete sequence of joinable filesIncorrect RSS feed description "%s"Incorrect parameterIncorrect value for %s: %sIncorrectly encoded password %sIndex SitesInitiating restart...
    Invalid NZB file %s, skipping (reason=%s, line=%s)Invalid encoding of email template %sInvalid nzbmatrix report number %sInvalid par2 files, cannot verify or repairInvalid server address.Invalid server detailsInvalid stage logging in history for %sInvertIt is likely that you are using ZoneAlarm on Vista.
    It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.Job "%s" was re-added to the queueJob finishedJobs marked with a '*' will not be automatically downloaded.Join filesJoin files ending in .001, .002 etc. into one file.Join files ending in .001.ts, .002.ts etc. into one file.JoiningKB/sKeep loose downloads in extra foldersLanguageLastLatest WarningsLaunch Browser on StartupLaunch my internet browser with the SABnzbd page when the program starts.Launch the default web browser when starting SABnzbd.LeftLimit SpeedLinksList of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfvLoading %s failedLocation for queue admin and history database.
    Can only be changed when queue is empty.Location of log files for SABnzbd.
    Requires SABnzbd restart!Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.Location to store unprocessed downloads.
    Can only be changed when queue is empty.Location where .nzb files will be stored.Log FolderLoggingLowLower CaseMBMain packet not found...MatchedMax SpeedMeaningMinimum Free Space for Temporary Download FolderMiscMissing Session keyMissing articlesMissing expected file: %s => unrar error?MondayMonthMoreMovie NameMovie.NameMovie_NameMovingMoving...Multi-part labelNZB KeyNZB added to queueNameNeverNew Feed URLNew release %s available atNew release availableNewzbin PasswordNewzbin UsernameNewzbin gives undocumented error code (%s)Newzbin gives undocumented error code (%s, %s)Newzbin report %s not foundNewzbin server changed its protocolNewzbin server fails to give info for %sNextNice ParametersNo PAR2 program found, repairs not possible
    No UNRAR program found, unpacking RAR files is not possible
    No email templates foundNo foldersNo post-processing because of failed verificationNo recipients given, no email sentNoneNormalNot enough disk space to complete downloads!Not matchedNotificationsNumber of seconds between scans for .nzb files.NzbMatrix API keyNzbMatrix UsernameOKOPTIONAL Account PasswordOPTIONAL Account UsernameOffOn FinishOn queue finishOnly Get Articles for Top of QueueOnly perform post-processing on jobs that passed all PAR2 checks.Open Informational URLOpen Source URLOpen a Terminal window and type the line (example):Open complete folderOptionalOptional Supplemental NZBOptional authentication password.Optional authentication username.OptionsOrderOriginal FilenameOther MessagesOther SwitchesPAUSEDPageParametersPart NumberPasswordPassword filePassword masked in ******, please re-enterPassword protect access to SABnzbd (recommended)PathPatternPattern KeyPausePause AllPause Downloading During Post-ProcessingPause IntervalPause forPause for 1 hourPause for 12 hoursPause for 15 minutesPause for 24 hoursPause for 3 hoursPause for 30 minutesPause for 5 minutesPause for 6 hoursPause for how many minutes?Pause for...Pause post-processingPausedPauses downloading at the start of post processing and resumes when finished.Pausing duplicate NZB "%s"Permissions for completed downloadsPlease be aware the 0.0.0.0 hostname will need an IPv6 address for external accessPlease enter a whole number.Please enter in the details of your primary usenet provider.Plush OptionsPort SABnzbd should listen on.Post Processing Failed for %s (%s)Post-Process Only Verified JobsPost-Processing Scripts FolderPost-processingPost-processing startedPostProcessing was aborted (%s)Pre-queue user scriptPresetsPress Startkey+R and type the line (example):PrevPreviousPriorityProbable account sharingProblem accessing nzbmatrix server (%s)Problem withProcessed BookmarksProcessingProcessing SwitchesProgram did not start!ProgressPurgePurge Completed NZBsPurge Failed HistoryPurge Failed NZBsPurge Failed NZBs & Delete FilesPurge HistoryPurge NZBsPurge NZBs & Delete FilesPurge QueuePurge the History?Purge the Queue?Python VersionQR CodeQueueQueue First 10 ItemsQueue auto refresh interval:QueuedQuick Check...Quick CheckingQuitQuota leftQuota spent, pausing downloadingRRSSRSS Checking IntervalRSS ConfigurationRSS Feed %s was emptyRan %sRangeRead RSS feedsRead the Wiki Help on this!RefreshRefresh RateRefresh interval of the queue web-interface page(sec, 0= none).Refresh rateRejectRelative folders are based onRemain/TotalRemainingRemoveRemove NZBRemove NZB & Delete FilesRemove ServerRemove failed jobsRemove from bookmark list when download is complete.Removing %s failedRepairRepair failed, not enough repair blocks (%s short)RepairingRepairing failed, %sRepairing...Replace Illegal Characters in Folder NamesReplace Spaces in FoldernameReplace dots in FoldernameReplace dots with spaces in folder names.Replace illegal characters in folder names by equivalents (otherwise remove).Replace spaces with underscores in folder names.Report-idRequiresRequiresCatReset Quota nowRestartRestart without loginRestarting SABnzbd...ResultResumeResume post-processingRetryRunning scriptRunning script...Running user script %sS01E05 Episode FolderS01E05 Season FolderSABnzbd HostSABnzbd PasswordSABnzbd PortSABnzbd Quick-Start WizardSABnzbd UsernameSABnzbd Web ServerSABnzbd detected a fatal error:SABnzbd shutdown finishedSABnzbd will now be running in the background.SQL Command Failed, see logSQL Commit Failed, see logSSL typeSaturdaySaveSave ChangesSavedSaving %s failedSaving..Scan watched folderSchedule for non-existing server %sSchedulingScheduling configurationScriptScriptsSeason NumberSecondary Web InterfaceSelect a web interface language.Select only if your provider allows SSL connections.SelectionSend GroupSend email when disk is full and SABnzbd is paused.Send group command before requesting articles.Sent %s to queueSeries SortingServer %s requires user/passwordServer %s will be ignored for %s minutesServer DetailsServer address "%s:%s" is not valid.Server address requiredServer configurationServer quit during login sequence.Server requires username and password.ServersSet Pause IntervalSet permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"Set the NzbMatrix API key here.Set your ISP's server for outgoing email.Set your account password here.Set your account username here.Setup is now complete!Show AllShow Edit OptionsShow FailedShow LoggingShow NameShow Name folderShow WebloggingShow detailsShow filesShow interfaceShow.NameShow_NameShowing %s to %s out of %s resultsShutdownShutdown PCShutdown SABnzbdShutting downSignal %s caught, saving and exiting...SizeSkip par2 checking when files are 100% valid.Some files failed to verify against "%s"SortSort StringSort by AgeSort by Age (Newest→Oldest)Sort by Age (Oldest→Newest)Sort by Age Newest→OldestSort by Age Oldest→NewestSort by Name (A→Z)Sort by Name (Z→A)Sort by Name A→ZSort by Name Z→ASort by Size (Largest→Smallest)Sort by Size (Smallest→Largest)Sort by Size Largest→SmallestSort by Size Smallest→LargestSort by ageSort by nameSort by sizeSortingSorting configurationSourceSpecialSpeedSpeed LimitSpeedlimitStandby PCStarting RepairStartup/ShutdownStatusStep FiveStep FourStep OneStep ThreeStep TwoStopStopping...StorageSubjectSundaySwitchesSwitches configurationSysloadSystem FoldersTOO LARGETaskTemporary Download FolderTest EmailTest NotificationTest ServerTesting server details...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.The automatic usenet download toolThe checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".The hostname is not set.The number of connections allowed by your providerThere are no connections set. Please set at least one connection.There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.This field is required.This key will allow 3rd party programs to add NZBs to SABnzbd.This key will give 3rd party programs full access to SABnzbd.This monthThis weekThis will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.This will send a test email to your account.ThreadThursdayTimed outTimed out: Try enabling SSL or connecting on a different port.TimeleftTitleTo: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. TodayToggle Add NZBToo little diskspace forcing PAUSEToo many connections to server %s:%sToo many connections, please pause downloading or try again laterTopTotalTroubleshootTry againTrying SFV verificationTrying to fetch NZB from %sTrying to set status of non-existing server %sTrying unrar with password "%s"TuesdayTuningTypeUUNC path "%s" not allowed hereURL Fetching failed; %sUSE AT YOUR OWN RISK!Un-Bookmark If Download CompleteUnauthorised, check your newzbin username/passwordUnblockUnknown Error while decoding %sUnknown action: %sUnpackUnpacked %s files/folders in %sUnpackingUnpacking failed, %sUnpacking failed, CRC errorUnpacking failed, an expected file was not unpackedUnpacking failed, archive requires a passwordUnpacking failed, path is too longUnpacking failed, see logUnpacking failed, these file(s) are missing:Unpacking failed, unable to find %sUnpacking failed, write error or disk is full?Unusable NZB fileUpUpdate Available!Upload: .nzb .rar .zip .gzUptimeUse V23 unless your provider requires otherwise!Use temporary names during post processing. Disable when your system doesn't handle that properly.Used before an NZB enters the queue.Used cacheUsed when no post-processing is defined by the category.Used when no priority is defined by the category.Used when no user script is defined by the category.User FoldersUser-defined categoriesUsernameVerified successfully using SFV filesVerifyingVerifying...VersionView Script LogView script outputWAIT %s secWARNING:WARNING: Aborted job "%s" because of encrypted RAR fileWARNING: Paused job "%s" because of encrypted RAR fileWARNINGSWaitingWarningWarning: LOCALHOST is ambiguous, use numerical IP-address.WarningsWatched FolderWatched Folder Scan SpeedWeb InterfaceWeb server authenticationWednesdayWeekly check for new SABnzbd release.WhenWhen article has a CRC error, try to get it from another server.Who should we say sent the email?WikiXYearYear-Month FoldersYou have no credit on your Newzbin accountYou have no permisson to use port %sYou need an nzbmatrix VIP account to use the APIYour UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    [%s] Error "%s" while joining files[%s] Error "%s" while unpacking RAR files[%s] Joined %s files[%s] No par2 sets[%s] PAR2 received incorrect options, check your Config->Switches settings[%s] Quick Check OK[%s] Repaired in %s[%s] Verified in %s, all files correct[%s] Verified in %s, repair is required_yenc module... NOT found!clearddaydaysdisable serverenable serverfetching msgid %s from www.newzbin2.esfilehhourhoursleftmmanualminmin.minsnot installedofoffonorpagepar2 binary... NOT found!pyopenssl module missing, please install for https accesssecsecondssee logfileunknownunrar binary... NOT foundunzip binary... NOT found!weekProject-Id-Version: sabnzbd Report-Msgid-Bugs-To: FULL NAME POT-Creation-Date: 2014-07-02 18:06+0000 PO-Revision-Date: 2013-03-17 20:50+0000 Last-Translator: Kristofer Norén Language-Team: Swedish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Launchpad-Export-Date: 2014-07-03 05:55+0000 X-Generator: Launchpad (build 17082) SABnzbd kan inte hitta webbgränssnittets filer i %s.
    Var vänlig installera om programmet.

    SABnzbd upptäckte Kö and Historik från en äldre (0.4.x) version.

    Både kö och historik kommer att ignoreras och kan försvinna!

    Du kan välja att stoppa SABnzbd och färdigställa nedladdningskön med den äldre versionen.

    Klicka OK för att gå vidare till SABnzbd SABnzbd har upptäckt sparad data från en annan version av SABnzbd
    men kan inte återanvända datan från det andra programmet.

    Färdigställ dina nedladdningar med det andra programmet först.

    Därefter kan du starta det här programmet med alternativet "--clean".
    Detta kommando kommer att ta bort din nuvarande kö och historik!
    SABnzbd read the file "%s". SABnzbd upptäckte att filen sqlite3.dll saknas.

    Det händer att bristfälligt designade virusprogram tar bort denna fil.
    Var vänlig kontrollera ditt virusprogram, försök installera om SABnzbd och klaga till din återförsäljare.

    SABnzbd är inte kompatibelt med vissa mjukvarubaserade brandväggar.
    %s
    Tyvärr kan vi inte lösa denna inkompatibilitet just nu.
    Vänligen registrera ett klagomål hos brandväggens tillverkare.

    SABnzbd behöver en ledig tcp/ip -port för sin interna webbserver.
    Port %s på %s testades , men den är inte tillgänglig.
    Någon annan applikation använder porten eller så körs redan SABnzbd.

    Vänligen starta om SABnzbd med ett annat portnummer. SABnzbd behöver en tillgänglig tcp/ip port för dess interna web server.
    Port %s på %s testades, men kontot som används för SABnzbd har inte tillåtelse att använda den.
    På OSX och Linux-system måste normala användare använda portnummer 1023 eller högre.

    Var vänlig starta om SABnzbd med ett annat portnummer. SABnzbd behöver en giltig värdadress för dess interna webbserver.
    Du har specifierat en ogiltig adress.
    Säkra värdadresser är localhost och 0.0.0.0

    Var vänlig starta om SABnzbd med en giltig värdadress.%s -> Okänd kodning%s => saknas från alla servrar, kastar%s artiklar hade icke-matchande dubletter%s artiklar var felaktiga%s artiklar saknades%s artiklar borttagna%s mapp: %s åtkomst misslyckad%s filer i %s%s är inte rätt siffervärde%s är inte en godkänd e-mail adress%s saknas  Lösa adress eller Report ID 
    SABnzbd nedstängning färdig.
    Vänta ungefär 5 sekunder och klicka sedan på knappen under..

    Ladda om
    + Debug+ Info+Ta bort+Reparera+Packar upp.nzb Reservmapp1x05 Episodmapp1x05 SäsongsmappOBS: Mappar kommer att skapas automatiskt när du Sparar. Du måste ange exakta sökvägar till dina mappar för att spara utanför standardmapparna.Data kommer inte tas bort. Kräver omstart av SABnzbd!ÅrAPI-nyckelAPI- eller QR-kodAPI-nyckel felaktig, använd api-nyckeln från Konfiguration-> Allmänt i ditt tredjepartsprogram:API-nyckel saknas, skriv in api-nyckeln från Konfiguration-> Allmänt i ditt tredjepartsprogram:Avbrutet, kan inte slutförasAccepteraÅtkomstÅtkomst nekadesAnvändarinfoÅtgärdÅtgärderAktivera ett alternativt skin.Lägg tillLägg till filLägg till NZBLägg till schemaLägg till serverLägg till ny nedladdningNZB tillagdAdministrativ mappPåverkade kategorierÅlderAllaAlltidÄr du säker på att du vill ta bortÄr du säker på att du vill starta om SABnzbd?Är du säker på att du vill stänga av SABnzbd?Är du säker?ArgumentCachestorlek för artiklarArtikel-IDAutentisering misslyckades, kontrollera användarnamn och lösenord.Autentisering saknas, ange användarnamn / lösenord från Konfiguration-> Allmänt i ditt tredjepartsprogram:Hämta bokmärken automatisktAuto-pausa när fri plats är nära sin gräns.
    I bytes, följt av K,M,G,T. Till exempel: "800M" or "8G"Ladda automatiskt ned bokmärkta poster.Hämtar jobb från bokmärken automatiskt.Sortera automatiskt efter (medel) ålder.BakåtSäkerhetskopieraReserv serverFel schema %s vid %s:%sFelaktigt utformad yEnc artikel i %sBearbetar bokmärkenBottenCRC Fel i %s (%s -> %s)Sparar artiklar i minnet för att reducera diskåtkomst.
    I bytes, följt av K,M,G. Till exempel: "64M" eller "128M"Sparat %s artiklar (%s)Det gick inte att ändra rättigheter på %sKan ej ansluta till registret HKEY_CURRENT_USER.Kan ej ansluta till server %s [%s]Kan inte skapa %s mapp %sKan inte skapa backup-fil för %sKan ej skapa mapp %sKan inte skapa slutgiltig mapp %sKan inte skapa temp -fil för %sKan ej finna e-mail mallar i %sHittar inte webbmall: %s, försöker med standardmallKan inte starta webbläsaren, hittades troligtvis inteKan ej öppna registernyckel "%s".Kan ej läsa %sKan ej läsa övervakad mapp %sKan inte skriva till INI filen %sKategorierKategoriÄndringarna har inte sparats och kommer att försvinna.Ändringar kräver omstart av SABnzbd!Kolla efter ny utgåvaKontrollera resultat av uppackningKontrollera resultat av uppackning (måste slås av på vissa filsystem).KontrollerarUppdateringsintervallKontrollintervall (i minuter, minst 15). Ej aktiv om du använder Schemaläggaren!Välj ett skin.Rensa listaRensning av %s misslyckades.Rensar bort par filer (om verifiering/reparation lyckades).RensaKlicka nedan för att testa.Klicka här för att testa dina angivna serveruppgifter.StängSABnzbd kommer inte att stängas av om du stänger ett fönster eller en tab i webbläsaren.Färdig nedladdningsmappFärdig mappFärdigFärdig nedladdningsmappKonfigurationKonfig filKonfigurationBekräfta Historik-borttagningarBekräfta Kö-borttagningarAnslutning av %s@%s:%s misslyckades, meddelande=%sAnslutning lyckades!AnslutningarDet gick inte att ta bort newzbin bokmärke %sDet gick inte att ansluta (%s)Aktuella schemanAnpassaTDUBLETTDagligenDagliga mapparDatum sorteringMånadsdagTiotalAvkodning av %s misslyckadesStandardStandard basmappStandard efterbehandlingStandard prioritetStandard användarskriptDefinierar efterbehandling och lagring.Ta bortTa bortTa bort allaTa bort flödeTa bort efter nedladdningTa bort alla slutförda objekt från Historik?Ta bort alla nedladdade filer?Ta bort alla misslyckade objekt från Historik?Ta bort alla saker från kön?Ta bort alla felaktiga saker från historiken?Borttagning av %s misslyckades!Upptäck dubbletter av nedladdningarUpptäck NZB:er med samma namn (kräver att NZB säkerhetskopiering är på) och dubbletter av titlar över RSS-flöden.Stäng av API-nyckelAvaktiveradAvaktiverade HTTPS då CERT och KEY -filer saknasFörkastaKoppla ifrån usenet servrarna när kön är tom eller pausad.Koppla ifrån när kön är tomFull hårddisk notifieringDiskfel vid skapande av fil %sDisken är full! Pausar...Gör en extra kontroll med SFV filerLadda inte ned.Har inte giltig autentisering för flöde %sKräv ingen API-nyckel.Har du inte någon usenet leverantör? Vi rekommenderar att prova %s.NerNedladdningHämtningen slutfördesTemporär nedladdningmappHämtning misslyckadesHastighetsbegränsning för NedladdningHämtning misslyclades - Out of your server's retention?Nerladdningen kan misslyckas, bara %s av krävda %s finns tillgängligtMedelhastighetsbegränsning för Nedladdning (i KB/s - kilobyte per sekund).NedladdningshastighetNedladdaeHämtade i %s vid ett genomsnitt på %sB/sNedladdade än så längeLaddar nerFlerskärm1Flerskärm2Ex.KRYPTERATFEL:FEL: %sFEL: CRC misslyckades i "%s"FEL: sökvägen är för lång (%s)FEL: gick inte att hitta "%s"FEL: skrivningsfel (%s)Tid kvarÄndraÄndra NZB detaljerE-mailE-mail kontoinställningarE-mail notifiering när jobb är slutförtE-mail alternativE-mail mottagareE-mail sändareSkickat E-mail!Mapp för E-mail mallarE-mail testresultatE-mail adress att skicka e-mailen till.E-mail sändning lyckadesTomNZB filen %s är tomTom RSS post hittades (%s)AktiveraAktivera datumssorteringAktivera Filsammanslagning (Filejoin)HTTPS AktiveraAktivera HTTPS åtkomst till SABnzbd.Aktivera filmsorteringAktivera MultiCore Par2Aktivera Par rensning (Par Cleanup)Aktivera SnabbkollAnvänd SFV-baserade kontrollerAktivera TS Sammanslagning (TS Joining)Aktivera TV sorteringAktivera UnrarAktivera UnzipAktivera åtkomst till webbkontrollen med HTTPS adress.Aktiverar inbyggda Unrar funktionen.Aktiverar inbyggda Unzip funktionen.Döp om mapparAktivera för lägre minnesanvändning. Avaktivera för att förhindra långsamma jobb att blockera kön.Aktiverar sortering och omdöpning av filer.Aktivera om nedladdning inte är flyttad till egen mapp.Aktiverar sortering och omdöpning av datummärkta filer.Aktiverar sortering och omdöpning av episoder.AktiveradURLEpisodnamnEpisodnummerEpisod.NamnEpisod_NamnFel "%s" när du kör file_join på %sFel "%s" medans par2_repair kördes på %sFel "%s" när du kör rar_unpack på %sFel "%s" när du kör unzip() på %sFel %s när du kör par2_repair på %sError %s: Du måste ange ett giltigt användarnamn och lösenord.Fel vid hämtning av msgid %s från www.newzbin2.es - Kontrollera att användarnamn och lösenord är angivnaDet gick inte att skapa SSL-nyckel eller certifikat.Det gick inte att hämta TV info (%s)Det gick inte att importera %sMisslyckades med importering av OpenSSL modul. Ansluter utan SSLLaddningsfel %s, felaktig fil detekteradFel vid borttagning av %sDet gick inte att ta bort arbetsmapp (%s)Det gick inte att döpa om "%s" till "%s"Det gick inte att lägga till %s, tar bortFel uppstod då systemet skulle stängasBara vid felFel: Inget andrainterface definierat.Fel: Kön är inte tom, kan inte byta mapp.Fel: Fel sessionsnyckelFel: Kräver sessionsnyckelFel/VarningAlltExempeländelseExtra PAR2 parametrarExtraherar...Vid fel på på yEnc CRCMisslyckadesDet gick inte att logga in på server %sSkapande av (%s) misslyckadesDet gick inte att flyta %s till %sAutentisering till mailserver misslyckadesDet gick inte att stänga databasen, se loggDet gick inte att stänga e-mail anslutningDet gick inte att kompilera regex för sök-sträng: %sDet gick inte att ansluta till mailserverKunde inte sätta systemet i väntelägeDet gick inte att importera %s filer från %sDet gick inte att initialisera %s@%s:%sDet gick inte att initialisera TLS anslutningDet gick inte att ladda efterbehandlings kön: Fel version (kräver:%s, hittade:%s)Misslyckades med att flytta filerDet gick inte att läsa registernyckel för specialmapparDet gick inte att ta bort nzo från efterbehandlings kön (id)Det gick inte att döpa om liknande fil: %s till %sDet gick inte att döpa om: %s till %sDet gick inte att hämta RSS flödet från %s: %sDet gick inte att skicka e-mailDet gick inte att sätta systemet i vilolägeDet gick inte att starta webbgränssnittetDet gick inte att uppdatera newzbin jobb %sMisslyckadesFel i tempfile.mkstempAllvarligt felFlödeHämtaHämtarHämtar %s block...Hämtar extra block...Fil %s är tom, hoppar överFiländelseFil som innehåller alla lösenord som ska prövas på krypterade RAR-filer.Filsammanslagning av %s misslyckadesFilnamn eller sökväg till HTTPS Certifikat.Filnamn eller sökväg till HTTPS Nyckel.FiluppsättningFilnamnFiltrera ut sample-filer (ex. video samplingar).FörstaMappen "%s" finns inteMappkonfigurationMapp innehållande skript för efterbehandling.Mapp som innehåller användar-definierade e-mail mallar.Mapp som igenomsöks automatiskt efter .nzb filer.
    Skannar även igenom .zip .rar och .tar.gz arkiv efter .nzb filer.Mapp/SökvägMapparAnvändarnamn för e-mail som kräver autentisering.Lösenord för e-mail som kräver autentisering.TvingaTvinga frånkopplingTvinga nedladdningForumLedigt temputrymmeLedigt diskutrymmeFörekomstFredagÖvrig hjälp kan du hitta på våranGBAllmäntAllmän konfigurationGenerera Ny NyckelAllmän sorteringHämta bokmärkenHämta bokmärken nuLägg till NZBHämta Newzbin bokmärkenGå till SABnzbdGå till guidenHTTPS CertifikatHTTPS NyckelHTTPS-portHTTPS StödHjälpViloläge PCDölj RedigeringsalternativGöm detaljerGöm filerHögHistorikHistorik (10 senaste sakerna)HistorikstorlekHemWebbplatsAdressAdress som SABnzbd ska lyssna på.Timme:MinutJag vill att SABnzbd ska bli nåbart från vilken dator som helst i mitt nätverk.Jag vill att SABnzbd ska bli nåbart enbart från min dator.VäntarINKOMPLETTIONice parametrarIRCSysslolösOm tom kommer standardporten endast lyssna till HTTPS.Om du är medlem på newzbin eller nzbmatrix kan du ange ditt användarnamn och lösenord här så kan vi hämta deras nzb filer. Detta stadium kan hoppas över om du inte använder deras tjänster.Om du får detta felmeddelande igen, var vänlig försök med en annan siffra.
    Om du har ett konto på www.nzbmatrix.com, så kan du skriva in din användarinformation här.
    Det krävs för att du ska kunna använda RSS-flödet från nzbmatrix.Ignorera Sample-filerIgnorerar dubblett för NZB "%s"IIn mappI minuter (minst 15 min).För att ladda ner från usenet du behöver tillgång till en leverantör. Din internetleverantör kan ge dig tillgång, men en premie leverantör rekommenderas.Inkompatibel feedFelaktig köfil funnen, kan ej fortsättaOfullständig mappNZB filen %s är inte komplettEj komplett sekvens av filer för ihopläggningFelaktigt RSS-flödesbeskrivning "%s"Fel parameterFel värde för %s: %sFelaktigt kodat lösenord %sIndex-sidorFörbereder omstart...
    Felaktig NZB fil %s, hoppar över (orsak=%s, linje=%s)Ogiltig avkodning av email mallen %sOgiltigt nzbmatrix rapporteringsnummer %sKorrupta par2 filer, kan inte verifiera eller repareraOgiltig serveradressOgiltiga serverdetaljerFelaktig loggning i historiken av %sInverteraDet är troligt att du använder ZoneAlarm på Vista.
    Det är rekommenderat att du sparar denna plats som ett bokmärke för att komma åt SABnzbd när det körs i bakgrunden.Jobb "%s" är återinlagt i könArbetet utfördJobb markerade med '*' kommer ej att laddas ned automatiskt.Slår ihop filerSlår ihop filer med filändelserna .001, .002 etc. till en fil.Slår ihop filer med filändelserna .001.ts, .002.ts etc. till en fil.Slår ihopKB/sLåt nedladdning i extramapp varaSpråkSistaSenaste VarningarStarta webbläsare vid uppstartStarta webbläsaren med SABnzbd's sida när programet startas.Startar standard webbläsaren när SABnzbd startar.VänsterHastighetsbegränsningLänkarLista med filändelser som ska tas bort efter nedladdning.
    Till exempel: .nfo or .nfo, .sfvLaddning av %s misslyckadesPlats för köadministration och historiedatabas.
    Kan bara ändras när kön är tom.Plats för sparade loggfiler från SABnzbd.
    Kräver omstart av SABnzbd!Plats för att lagra bearbetade och färdiga nedladdningar.
    Kan åsidosättas av användar-definierade kategorier.Plats för att lagra ej bearbetade nedladdningar.
    Kan endast ändras när kön är tom.Plats där .nzb filer sparas.LoggmappLoggningLågSmå bokstäverMBHuvudarkiv saknas...MatchadeMax hastighetBetyderMinimal fri plats för temporär nedladdningsmappDiverseSaknar sessionsnyckelSaknade artiklarSaknade förväntad fil: %s => unrar fel?MåndagMånadMerFilm NamnFilm.NamnFilm_NamnFlyttarFlyttar...Multi-del etikettNZB-nyckelNZB tillagd i könNamnAldrigNy flödesadressNy utgåva %s tillgängligNy utgåva tillgängligNewzbin LösenordNewzbin AnvändarnamnNewzbin ger odokumenterad felkod (%s)Newzbin ger odokumenterad felkod (%s, %s)Newzbin rapporterade %s ej funnenNewzbin server ändrade sitt protokollNewzbin servern misslyckades ge info för %sNästaBra parametrarInget PAR2 program funnet, reparation ej möjlig
    Inget UNRAR program funnet, uppackning ej möjlig
    Inga email mallar funnaIngen mappIngen efterbehandling på grund av misslyckad verifieringIngen mottager angiven, ingen email har skickatsIngenNormalInte tillräckligt med diskutrymme för att kunna fortsätta ladda ned.Matchade inteMeddelandenSekunder mellan skanningar för .nzb filer.NzbMatrix API-nyckelNzbMatrix AnvändarnamnOKVALFRITT AnvändarlösenordVALFRITT KontoanvändarnamnAvVid slutNär kön är färdigBara artiklarna för början av könEfterbehandla enbart jobb som passerat PAR2 kontrollen.Öppen informations URLÖppen källdkod URLÖppna ett Terminal-fönster och skriv raden (exempel):Öppna färdig mappValfriValfri Kompletterande NZBVäljbart autentiserings lösenord.Väljbart autentiserings användarnamn.AlternativOrdningOriginalfilnamnAndra meddelandenAndra parametrarPAUSADSidaParametrarDelnummerLösenordLösenordsfilLösenordet är dolt med ******, försök igenLösenordsskydda åtkomst till SABnzbd (rekommenderas)GenvägMönsterHjälp till SorteringssträngPausaPausa AlltPausa nedladdning under efterbehandlingPausintervallPausa förPausa 1 timmePausa 12 timmarPause 15 minuterPausa 24 timmarPausa 3 timmarPausa 30 minuterPausa 5 minuterPausa 6 timmarPausa hur många minuter?Pausa i...Pausa efterbehandlaPausadPausas nedladdning när efterbehandling börjar och återupptar nedladdning när efterbehandling är klar.Pausar dubblett för NZB "%s"Rättigheter för färdiga nedladdningarTänk på att värdnamnet 0.0.0.0 behöver en IPv6-adress för extern åtkomstAnge ett heltal.Fyll i uppgifter om din primära usenet leverantör.Plush InställningarPort som SABnzbd ska lyssna på.Efterbehandling misslyckades för %s (%s)Efterbehandla endast verifierade jobbEfterbehandlings skriptmappEfterbehandlingEfterbehandling påbörjadEfterbehandling avbröts (%s)Kö-specifika användarskriptFörinställningarTryck på Startknappen+R och skriv raden (exempel):FöregåendeFöregåendePrioritetMisstänkt kontodelningAnslutningsproblem till nzbmatrix server (%s)Problem medBearbetar bokmärkenBearbetarBearbetar parametrarProgrammet startade inte!ArbetarRensaRensa färdiga NZB:erRensa Misslyckad HistorikRensa Misslyckade NZB:er.Rensa Misslyckade NZB:er och ta bort filerTöm historikRensa NZB:erRensa NZB:er och ta bort filerRensa köVill du verkligen tömma historiken?Töm kön?Python-versionQR-kodKöKö (10 första sakerna)Automatisk uppdateringsintervall av kö:KöadSnabbkontroll...SnabbkontrollerarAvslutaKvot kvarDin kvot är uppnådd, pausar nerladdningRRSSRSS UppdateringsintervallRSS-konfigurationRSS-flödet %s var tomtKörde %sOmfångLäs RSS-flödenLäs Wiki Help för detta!UppdateraUppdateringsintervallUppdateringsintervall av kö-sidan (sek, 0= ingen).UppdateringsfrekvensAvvisaRelativa mappar är baserade påÅterstår/TotaltÅterstårTa bortTa bort NZBTa bort NZB och filerTa bort serverTa bort misslyckade jobbTa bort från bokmärkeslistan när nedladdning är genomförd.Borttagning av %s misslyckadesReparerarMisslyckad reparation, finns ej tillräckligt med reparationsblock (%s saknas)ReparerarReparation misslyckades, %sReparerar...Ersätt otillåtna tecken i mappnamn.Ersätt mellanslag i mappnamnErsätt punkter i mappnamnErsätt punkter med mellanslag i mappnamnErsätt otillåtna tecken i mappnamn med motsvarande tecken (annars ta bort).Ersätt mellanslag med understreck i mappnamn.Rapport-idKräverKräverKatÅterställ Kvot nuStarta omStarta om utan loginStartar om SABnzbd...ResultatÅterupptaÅteruppta efterbehandlaFörsök igenKör skriptKör skript...Kör användarskript %sS01E05 EpisodmappS01E05 SäsongsmappSABnzbd AdressSABnzbd LösenordSABnzbd-portSABnzbd Snabbstart GuideSABnzbd AnvändarnamnSABnzbd WebbserverSABnzbd upptäckte ett allvarligt fel:SABnzbd nedstängning utförd.SABnzbd kommer nu att köras i bakgrunden.SQL Kommando misslyckades, se loggSQL Commit misslyckades, se loggSSL typLördagSparaSpara ändringarSparadSparar %s misslyckadesSparar..Scanna bevakad mappSchema för icke existerande server %sSchemaläggareSchemakonfigurationSkriptSkriptSäsongsnummerAndra WebbkontrollsutseendeVälj språk till webbkontrollen.Välj bara om din leverantör tillåter SSL-anslutningar.UrvalSkicka gruppSkicka e-mail när hårddisken är full och SABnzbd har pausat.Skicka gruppkommando innan du begär artiklar.Skickat %s till köSeriesorteringServer %s kräver användarnamn/lösenordServer %s kommer att ignoreras i %s minuterServeruppgifterServeradressen "%s:%s" är ej giltig.Kräver serveradressServerkonfigurationServern avslutades under inloggningServern kräver användarnamn och lösenord.ServrarSätt pausintervallSätt rättigheter för färdiga filer och mappar.
    Använd siffror. Till exempel: "755" or "777"Ställ in API-nyckel för NzbMatrix här.Ställ in din ISP's server för utgående e-mail.Ställ in ditt användarlösenord här.Ställ in ditt användarnamn här.Installationen är nu utförd!Visa allaVisa RedigeringsalternativVisa MisslyckadeVisa loggShow NamnVisa Namn på mappVisa webbloggVisa detaljerVisa filerVisa gränssnittShow.NamnShow_NamnVisar %s till %s av %s resultatStäng AvStäng av PCStäng av SABnzbdPåbörjar nedstängning av SABnzbd..Signal %s mottagen, sparar och stänger...StorlekStrunta i par2 kontroll när filerna är 100% giltiga.Some files failed to verify against "%s"SorteraSorteringssträngSortera efter ålderSortera efter Ålder (Nyast→Äldst)Sortera efter Ålder (Äldst→Nyast)Sortera efter ålder Nyast→ÄldstSortera efter ålder Äldst→NyastSortera efter Namn (A→Z)Sortera efter Namn (Z→A)Sortera efter namn A→ZSortera efter namn Z→ASortera efter Storlek (Störst→Minst)Sortera efter Storlek (Minst→Störst)Sortera efter storlek Störst→MinstSortera efter storlek Minst→StörstSortera efter ålderSortera efter namnSortera efter storlekSorteringSorteringskonfigurationKällaSpeciellHastighetHastighetsgränsHastighetsgränsSparläge PCStartar reparationStarta/StängStatusSteg femSteg fyraSteg ettSteg treSteg tvåStoppStänger...LagringÄmneSöndagSwitcharParameterkonfigurationSystembelastningSystemmapparFÖR STORUppgiftTemporär nedladdningsmappTesta E-mailTesta notifikationTestserverTestar serverdetaljer...The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.Det automatiska usenet nedladdningsverktygetKryssrutan bredvid flödesnamnet ska aktiveras för att flödet automatiskt ska kontrolleras för nya objekt.
    När ett flöde läggs till kommer det bara att välja nya objekt och inte allt som redan finns i RSS-flöded så länge du inte klickar på "Tvinga nedladdning".Adressen är inte angiven.Antalet anslutningar som tillåts av din leverantörInga anslutningar är aktiverade. Var vänlig aktivera minst en anslutning.Det finns övergivna jobb i nedladdningsmappen.
    Du kan välja mellan att radera dem (inklusive filer) eller skicka tillbaka dem i kön.Detta fält krävs.Denna nyckel ger tredjepartsprogram möjlighet att lägga till NZB:er i SABnzbd.Denna nyckel ger tredjepartsprogram full tillgång till SABnzbd.Denna månadDenna veckaDetta kommer att starta om SABnzbd.
    Använd det när du tror att programmet har stabilitetsproblem.
    Nerladdningar kommer att pusas innan omstarten och återupptas efteråt.Detta kommer att skicka ett test e-mail till ditt konto.TrådTorsdagTimeoutTimeout: Försök aktivera SSL eller anslut via en annan port.Återstående tidTitelTill: %s Från: %s Datum: %s Ämne: SABnzbd rapporterar att disk är full Hej, SABnzbd har stoppat nerladdningen på grund av att din disk inte har tillräckligt med utrymme kvar. Frigör utrymme och återuppta nerladdningen manuellt. I dagVisa/Dölj Lägg till NZBFör lite diskutrymme pausar systemetFör många anslutningar till server %s:%sFör många anslutningar, pausa en nedladdning eller försök igen senareToppTotaltFelsökFörsök igenFörsöker verifiera SFVFörsöker att hämta NZB från %sFörsöker att sätta status på icke existerande server %sFörsöker att packa upp med lösenord %sTisdagJusteringarTypPUNC sökväg "%s" är inte tillåten härURL hämtning misslyckades; %sANVÄND PÅ EGEN RISK!Ta bort bokmärke efter nedladdningObehörig, kontrollera ditt newzbin användarnamn/lösenordTa bort blockeringOkänt fel under avkodning av %sOkänd åtgärd: %sPacka uppUppackad %s filer/mappar i %sPackar uppUppackning misslyckades, %sUppackning misslyckades, CRC-felUppackning misslyckades, en väntad fil är inte uppackadUppackning misslyckades, arkivet kräver lösenordUppackning misslyckades, sökvägen är för långUppackning misslyckades, se loggUppackning misslyckades, dessa filer saknas:Uppackning misslyckades, gick inte att hitta %sUppackning misslyckades, skrivfel eller disken full?Oanvändbar NZB filUppUppdatering tillgängligLadda upp: .nzb .rar .zip .gzUpptidAnvänd V23 om inte din leverantör kräver annat!Använd temporära namn under efterbehandling. Avslaget när ditt system inte stöder det.Används innan en NZB tas in i kön.Använt cacheAnvänds när efterbehandlingen är bestämd efter kategori.Använd när ingen prioritet är bestämd av kategori.Används när användarskript är bestämd efter kategori.AnvändarmapparAnvändardefinierade kategorierAnvändarnamnVerifieringen lyckades med SFV-filerVerifierarVerifierar...VersionVisa skriptloggVisa skriptutmatningVÄNTA %s SEKUNDERVARNING:Varning: avbröt jobbet %s på grund av att RAR-filen är krypteradWARNING: Paused job "%s" because of encrypted RAR fileVARNINGARVäntarVarningVarning: LOCALHOST är tvetydigt, använda numerisk IP-adress .VarningarÖvervakad MappSkanningsintervall för Övervakade mapparWebbkontrollsutseendeWebbserver autentiserngOnsdagKolla efter ny utgåva av SABnzbd varje vecka.NärNär artiklars CRC-kontrollsumma ger fel, försök att hämta dem från en annan server.Vem ska vi skicka e-mailet från?WikiXÅrÅr-Månads mapparDu har ingen kredit på ditt Newzbin kontoDu har ingen behörighet för att använda port %sDu behöver ett nzbmatrix VIP-konto för att använda APIDin version av UNRAR rekommenderas inte, få UNRAR från http://www.rarlab.com/rar_add.htm
    [%s] Fel "%s" under filsammanslagning[%s] Fel "%s" under uppackning av RAR fil(er)[%s] Slår ihop %s filer[%s] Ingen par2 sats[%s] PAR2 har fått felaktiga alternativ, ändra dessa via Config->Switches inställningarna[%s] Snabbkontroll OK[%s] Reparerad i %s[%s] Verifierad i %s, alla filer är ok[%s] Verifiering i %s, kräver reparation_yenc modul... EJ funnen!rensaddagdagaravaktivera serveraktivera serverHämtar msgid %s från www.newzbin2.esfilhtimmetimmarkvarmhandbokminutmin.minuter(ej installerat)avavdenellersidapar2 binär... EJ funnen!pyopenssl modul saknas, var vändlig installera för https åtkomstsekundsekunderse loggfilokändunrar binär... EJ funnen!unzip binär... EJ funnen!veckaSABnzbd-0.7.20/po/email/da.po0000644000000000000000000001307212433712554015667 0ustar00usergroup00000000000000# Danish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-08-03 17:24+0000\n" "Last-Translator: shypike \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Standard Email skabelon til SABnzbd\n" "## Dette er en Cheetah skabelon\n" "## Dokumentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Linjeskift og blanktegn er betydelig!\n" "##\n" "## Disse er e-mail-headerne \n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Efter dette kommer body, den tomme linje kræves!\n" "\n" "Hej,\n" "\n" "SABnzbd har hentet \"$name\" \n" "\n" "SABnzbd kunne ikke hente \"$name\" \n" "\n" "Færdig kl. $end_time\n" "Hentet $size\n" "\n" "Resultat af job:\n" "\n" "Etape $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output fra bruger script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email skabelon til SABnzbd\n" "## Dette er Cheetah skabelon\n" "## Dokumentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Linjeskift og blanktegn er betydelig!\n" "##\n" "## Dette er email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har tilføjet $antal jobs til køen\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Efter dette kommer body, den tomme linje kræves!\n" "\n" "Hej,\n" "\n" "SABnzbd har tilføjet $antal job(s) til køen.\n" "De er fra RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Farvel\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Dårlig URL Fetch E-mail skabelon for SABnzbd\n" "## Dette er en Cheetah skabelon\n" "## Dokumentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Linjeskift og blanktegn er betydelig!\n" "##\n" "## Dette er email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd kunne ikke hente en NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Efter dette kommer body, den tomme linje kræves!\n" "\n" "Hej,\n" "\n" "SABnzbd kunne ikke hente NZB fra $url.\n" "Fejl meddelelsen er: $msg\n" "\n" "Farvel\n" SABnzbd-0.7.20/po/email/de.po0000644000000000000000000001357712433712554015705 0ustar00usergroup00000000000000# German translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-12-28 10:58+0000\n" "Last-Translator: Thomas Lucke (Lucky) \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "#encoding UTF-8\n" "## Translation by Severin Heiniger\n" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd Auftrag " "$name \n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd hat \"$name\" heruntergeladen\n" "\n" "SABnzbd konnte \"$name\" nicht herunterladen\n" "\n" "Fertiggestellt: $end_time\n" "Heruntergeladen: $size\n" "\n" "Ergebnis des Auftrages:\n" "\n" "Stufe $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Ausgabe des Benutzerskripts \"$script\" (beendet mit Code $script_ret):\n" "$script_output\n" "\n" "\n" "Viel Spass!\n" "\n" "Entschuldigung!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hallo,\n" "\n" "SABnzbd hat $amount Aufträge zur Warteschlange hinzugefügt.\n" "Sie stammen vom RSS-Feed \"$feed\".\n" "\n" " $job \n" "\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "## Translation by Thomas Lucke (Lucky)\n" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd konnte eine NZB-Datei nicht herunterladen\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hallo,\n" "\n" "SABnzbd konnte die NZB-Datei von $url nicht herrunterladen.\n" "Die Fehlermeldung war: $msg\n" SABnzbd-0.7.20/po/email/en.po0000644000000000000000000001530112433712554015702 0ustar00usergroup00000000000000# # SABnzbd Translation Template file # Copyright (C) 2010 by the SABnzbd Team # team@sabnzbd.org # msgid "" msgstr "" "Project-Id-Version: SABnzbd-0.6.x\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-01-15 19:19+0000\n" "PO-Revision-Date: 2010-09-27 18:49+0000\n" "Last-Translator: shypike \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2011-01-16 05:17+0000\n" "X-Generator: Launchpad (build 12177)\n" "Language: en\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" #~ msgid "" #~ "##\n" #~ "## Default Email template for SABnzbd\n" #~ "## This a Cheetah template\n" #~ "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" #~ "##\n" #~ "## Newlines and whitespace are significant!\n" #~ "##\n" #~ "## These are the email headers\n" #~ "to: $to\n" #~ "from: $from\n" #~ "date: $date\n" #~ "subject: SABnzbd has " #~ "job $name\n" #~ "X-priority: 5\n" #~ "X-MS-priority: 5\n" #~ "## After this comes the body, the empty line is required!\n" #~ "\n" #~ "Hi,\n" #~ "\n" #~ "SABnzbd has downloaded \"$name\" \n" #~ "\n" #~ "SABnzbd has failed to download \"$name\" \n" #~ "\n" #~ "Finished at $end_time\n" #~ "Downloaded $size\n" #~ "\n" #~ "Results of the job:\n" #~ "\n" #~ "Stage $stage \n" #~ "\n" #~ " $result \n" #~ "\n" #~ "\n" #~ "\n" #~ "Output from user script \"$script\" (Exit code = $script_ret):\n" #~ "$script_output\n" #~ "\n" #~ "\n" #~ "Enjoy!\n" #~ "\n" #~ "Sorry!\n" #~ "\n" #~ msgstr "" #~ "##\n" #~ "## Default Email template for SABnzbd\n" #~ "## This a Cheetah template\n" #~ "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" #~ "##\n" #~ "## Newlines and whitespace are significant!\n" #~ "##\n" #~ "## These are the email headers\n" #~ "to: $to\n" #~ "from: $from\n" #~ "date: $date\n" #~ "subject: SABnzbd has " #~ "job $name\n" #~ "X-priority: 5\n" #~ "X-MS-priority: 5\n" #~ "## After this comes the body, the empty line is required!\n" #~ "\n" #~ "Hi,\n" #~ "\n" #~ "SABnzbd has downloaded \"$name\" \n" #~ "\n" #~ "SABnzbd has failed to download \"$name\" \n" #~ "\n" #~ "Finished at $end_time\n" #~ "Downloaded $size\n" #~ "\n" #~ "Results of the job:\n" #~ "\n" #~ "Stage $stage \n" #~ "\n" #~ " $result \n" #~ "\n" #~ "\n" #~ "\n" #~ "Output from user script \"$script\" (Exit code = $script_ret):\n" #~ "$script_output\n" #~ "\n" #~ "\n" #~ "Enjoy!\n" #~ "\n" #~ "Sorry!\n" #~ "\n" #~ msgid "" #~ "##\n" #~ "## RSS Email template for SABnzbd\n" #~ "## This a Cheetah template\n" #~ "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" #~ "##\n" #~ "## Newlines and whitespace are significant!\n" #~ "##\n" #~ "## These are the email headers\n" #~ "to: $to\n" #~ "from: $from\n" #~ "date: $date\n" #~ "subject: SABnzbd has added $amount jobs to the queue\n" #~ "X-priority: 5\n" #~ "X-MS-priority: 5\n" #~ "## After this comes the body, the empty line is required!\n" #~ "\n" #~ "Hi,\n" #~ "\n" #~ "SABnzbd has added $amount job(s) to the queue.\n" #~ "They are from RSS feed \"$feed\".\n" #~ "\n" #~ " $job \n" #~ "\n" #~ "\n" #~ "Bye\n" #~ msgstr "" #~ "##\n" #~ "## RSS Email template for SABnzbd\n" #~ "## This a Cheetah template\n" #~ "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" #~ "##\n" #~ "## Newlines and whitespace are significant!\n" #~ "##\n" #~ "## These are the email headers\n" #~ "to: $to\n" #~ "from: $from\n" #~ "date: $date\n" #~ "subject: SABnzbd has added $amount jobs to the queue\n" #~ "X-priority: 5\n" #~ "X-MS-priority: 5\n" #~ "## After this comes the body, the empty line is required!\n" #~ "\n" #~ "Hi,\n" #~ "\n" #~ "SABnzbd has added $amount job(s) to the queue.\n" #~ "They are from RSS feed \"$feed\".\n" #~ "\n" #~ " $job \n" #~ "\n" #~ "\n" #~ "Bye\n" SABnzbd-0.7.20/po/email/es.po0000644000000000000000000001355112433712554015714 0ustar00usergroup00000000000000# Spanish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-04-03 09:00+0000\n" "Last-Translator: shypike \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Plantilla de correo predeterminada para SABnzbd\n" "## This a Cheetah template\n" "## Documentación: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## !Los saltos de línea y espacios en blanco son significativos¡\n" "##\n" "## Cabeceras de correo electrónico\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## !Después de esto viene el cuerpo del mensaje, la línea en blanco es " "necesaria!\n" "\n" "Hola,\n" "\n" "SABnzbd he bajado \"$name\" \n" "\n" "SABnzbd fallo en bajar \"$name\" \n" "\n" "Terminado a las $end_time\n" "$size bajado\n" "\n" "Resultado de la transferencia:\n" "\n" "Etapa $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Producción desde el script de usuario \"$script\" (Exit code = " "$script_ret):\n" "$script_output\n" "\n" "\n" "Que lo disfrutes!\n" "\n" "Perdon!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Plantilla de correo RSS para SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## !Los saltos de línea y espacios en blanco son significativos¡\n" "##\n" "## Cabeceras de correo electrónico\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd he añadido $amount transferencia(s) a la cola\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## !Después de esto viene el cuerpo del mensaje, la línea en blanco es " "necesaria!\n" "\n" "Hola,\n" "\n" "SABnzbd he añadido $amount transferencia(s) a la cola.\n" "Originaron desde el RSS \"$feed\".\n" "\n" "$job \n" "\n" "\n" "Adios\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Plantilla de correo para URLs incorrectas de SABnzbd\n" "## Esta es una plantilla Cheetah\n" "## Documentación: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Líneas nuevas y espacios en blanco IMPORTAN!\n" "##\n" "## Estas son las cabeceras del email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd ha encontrado un error al recuperar un NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hola,\n" "\n" "SABnzbd ha encontrado un error al descargar un NZB desde $url.\n" "El error ha sido: $msg\n" "\n" "Un saludo\n" SABnzbd-0.7.20/po/email/fi.po0000644000000000000000000001352412433712554015703 0ustar00usergroup00000000000000# Finnish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2013-02-19 15:28+0000\n" "Last-Translator: Matti Ylönen \n" "Language-Team: Finnish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Oletus sähköpostipohja SABnzbd:lle\n" "## Tämä on Cheetah pohja\n" "## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rivinvaihdot ja välilyönnit ovat merkitseviä!\n" "##\n" "## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa!\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd on työssä $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on " "pakollinen!\n" "\n" "Hei,\n" "\n" "SABnzbd on ladannut \"$name\" \n" "\n" "SABnzbd on epäonnistunut \"$name\" latauksessa\n" "\n" "Valmistui $end_time\n" "Ladattu $size\n" "\n" "Työn lopputulos:\n" "\n" "Tila $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Käyttäjän skriptin tuloste \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Nauti!\n" "\n" "Pahoittelut!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS sähköpostipohja SABnzbd:lle\n" "## Tämä on Cheetah pohja\n" "## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rivinvaihdot ja välilyönnit ovat merkitseviä!\n" "##\n" "## Nämä ovat otsaketiedot. Rivien ensimmäisiä sanoja ei saa vaihtaa!\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd on lisännyt $amount työtä jonoon\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Tämän jälkeen tulee viestin runko, ensimmäinen rivinvaihto on " "pakollinen!\n" "\n" "Hei,\n" "\n" "SABnzbd on lisännyt $amount työtä jonoon.\n" "Ne ovat RSS syötteestä \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Heippa\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Virheellisen URL-noudon sähköpostin pohja SABnzbd ohjelmalle\n" "## Tämä on Cheetah pohja\n" "## Dokumentaatio: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rivinvaihdot ja välilyönnit ovat merkitseviä!\n" "##\n" "## Tässä on sähköpostin otsikkotiedot\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd ei voinut hakea NZB tiedostoa\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Tämän jälkeen tulee viestin sisältö, tyhjä rivi on pakollinen!\n" "\n" "Hei,\n" "\n" "SABnzbd ei voinut hakea NZB tiedostoa osoitteesta $url.\n" "Virheviesti: $msg\n" SABnzbd-0.7.20/po/email/fr.po0000644000000000000000000001341412433712554015712 0ustar00usergroup00000000000000# French translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-03-18 07:02+0000\n" "Last-Translator: Fox Ace \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "#encoding UTF-8\n" "##\n" "## Template Email pour SABnzbd\n" "## Ceci est un template Cheetah\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Les retours à la ligne et les espaces sont importants !\n" "##\n" "## Entêtes de l'email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd SuccèsEchec " "du téléchargement $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Après cela vient le contenu, la ligne vide est nécessaire! \n" "\n" "Bonjour,\n" "\n" "SABnzbd a téléchargé avec succès \"$name\" \n" "\n" "SABnzbd a téléchargé sans succès \"$name\" \n" "\n" "Terminé à $end_time\n" "Téléchargé $size\n" "\n" "Résultat du téléchargement :\n" "\n" "Etape $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Sortie du script utilisateur \"$script\" (Code Retour = $script_ret):\n" "$script_output\n" "\n" "\n" "A bientôt !\n" "\n" "Désolé !\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Template Email pour SABnzbd\n" "## Ceci est un template Cheetah\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Les retours à la ligne et les espaces sont importants !\n" "##\n" "## Entêtes de l'email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd a ajouté $amount fichier(s) à la file d'attente\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Après cela vient le contenu, la ligne vide est nécessaire!\n" "\n" "Bonjour,\n" "\n" "SABnzbd a ajouté $amount fichier(s) à la file d'attente.\n" "Ils proviennent du Flux RSS \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Au Revoir\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" SABnzbd-0.7.20/po/email/nb.po0000644000000000000000000001327412433712554015706 0ustar00usergroup00000000000000# Norwegian Bokmal translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2013-12-10 20:12+0000\n" "Last-Translator: shypike \n" "Language-Team: Norwegian Bokmal \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "#encoding UTF-8\n" "## Translation by ProtX\n" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har " "jobb $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hei,\n" "\n" "SABnzbd har lastet ned \"$name\" \n" "\n" "SABnzbd mislyktes med å laste ned \"$name\" \n" "\n" "Ferdig $end_time\n" "Nedlastet $size\n" "\n" "Resultat av jobben:\n" "\n" "Steg $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Utskrift fra brukerskript \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Gratulerer!\n" "\n" "Synd!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd har lagt $amount jobber til køen\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Etter dette kommer meldingen, den tomme linjen er nødvendig!\n" "\n" "Hei,\n" "\n" "SABnzbd har lagt $amount jobb(er) til køen.\n" "Disse er fra RSS feeden \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Hade\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd ikke klarte å hente en NZB fil\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Etter dette kommer meldingen, den tomme linjen er nødvendig!\n" "\n" "Hei,\n" "\n" "SABnzbd klarte ikke å hente NZB fra $url.\n" "Feilmeldingen var: $msg\n" "\n" "Hade\n" SABnzbd-0.7.20/po/email/nl.po0000644000000000000000000001334012433712554015712 0ustar00usergroup00000000000000# Dutch translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2013-11-03 22:34+0000\n" "Last-Translator: markheloking \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Standaard Email sjabloon voor SABnzbd\n" "## Dit is een Cheetah sjabloon\n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Lege regels en witruimte zijn belangrijk!\n" "##\n" "## Dit zijn de email koppen\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd: opdracht $name is \n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Hier onder volgt de hoofdtekst, de lege regel is noodzakelijk!\n" "\n" "Hallo,\n" "\n" "SABnzbd heeft \"$name\" gedownload\n" "\n" "SABnzbd is niet geslaagd in het downloaden van \"$name\" \n" "\n" "Klaar om $end_time\n" "Hoeveelheid gedownload $size\n" "\n" "Resultaat van de opdracht:\n" "\n" "Fase $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Bericht van het script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Veel plezier!\n" "\n" "Sorry!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email sjabloon voor SABnzbd\n" "## Dit is een Cheetah sjabloon\n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Lege regels en spaties zijn belangrijk!\n" "##\n" "## Dit zijn de email koppen\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Hierna komt de inhoud, de lege regel is benodigd!\n" "\n" "Hallo,\n" "\n" "SABnzbd heeft $amount opdrachten aan de wachtrij toegevoegd.\n" "Ze komen van de RSS bron \"$feed\".\n" "\n" " $job \n" "\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Ongeldige URL Ophaal Email sjabloon voor SABnzbd\n" "## Dit is een Cheetah sjabloon\n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Lege regels en spaties zijn belangrijk!\n" "##\n" "## Dit zijn de email koppen\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: Ophalen van NZB door SABnzbd is mislukt\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Hierna komt het bericht, de lege regel is noodzakelijk!\n" "\n" "Hi,\n" "\n" "Het is SABnzbd niet gelukt om een NZB bestand op te halen van $url.\n" "De foutmelding was $msg\n" "\n" "Sorry\n" SABnzbd-0.7.20/po/email/pl.po0000644000000000000000000001322412433712564015716 0ustar00usergroup00000000000000# Polish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-05-02 09:57+0000\n" "Last-Translator: Tomasz 'Zen' Napierala \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Domyslny szablon maila w SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znak nowego wiersza i spacji ma znaczenie!\n" "##\n" "## To sa naglowki maila\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd zadanie $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Nastepnie tresc maila, wymagana jest pusta linia!\n" "\n" "Czesc,\n" "\n" "SABnzbd pobral \"$name\" \n" "\n" "SABnzbd nie pobral \"$name\" \n" "\n" "Zakonczono o $end_time\n" "Pobrano $size\n" "\n" "Rezultat zadania:\n" "\n" "Etap $stage \n" "\n" "$result \n" "\n" "\n" "\n" "Odpowiedz od skryptu \"$script\" (kod wyjscia = $script_ret):\n" "$script_output\n" "\n" "\n" "Baw sie dobrze!\n" "\n" "Przykro mi!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Szablon wiadomosci RSS dla SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znak nowego wiersza i spacji ma znaczenie!\n" "##\n" "## To sa naglowki maila\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd dodal $amount zadan/zadania do kolejki\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Nastepnie tresc maila, wymagana jest pusta linia!\n" "\n" "Czesc,\n" "\n" "SABnzbd dodal $amount zadanie/zadan do kolejki.\n" "Pochodza one z wiadomosci RSS \"$feed\".\n" "\n" "$job \n" "\n" "\n" "Nara\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Szablon wiadomosci blednego pobierania URL SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znaki nowego wiersza i biale znaki maja znaczenie!\n" "##\n" "## To sa naglówki wiadomosci\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd nie udalo sie pobrac pliku NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Po tym nastepuje tresc. Pusty wiersz jest wymagany!\n" "\n" "Czesc,\n" "\n" "SABnzbd nie udalo sie pobrac pliku NZB z $url.\n" "Komunikat bledu: $msg\n" "\n" "Do uslyszenia.\n" SABnzbd-0.7.20/po/email/pl.px0000644000000000000000000001331412433712554015726 0ustar00usergroup00000000000000# Polish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-05-02 09:57+0000\n" "Last-Translator: Tomasz 'Zen' Napierala \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Domyślny szablon maila w SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znak nowego wiersza i spacji ma znaczenie!\n" "##\n" "## To są nagłowki maila\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd zadanie $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Następnie treść maila, wymagana jest pusta linia!\n" "\n" "Cześć,\n" "\n" "SABnzbd pobrał \"$name\" \n" "\n" "SABnzbd nie pobrał \"$name\" \n" "\n" "Zakończono o $end_time\n" "Pobrano $size\n" "\n" "Rezultat zadania:\n" "\n" "Etap $stage \n" "\n" "$result \n" "\n" "\n" "\n" "Odpowiedź od skryptu \"$script\" (kod wyjścia = $script_ret):\n" "$script_output\n" "\n" "\n" "Baw się dobrze!\n" "\n" "Przykro mi!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Szablon wiadomości RSS dla SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znak nowego wiersza i spacji ma znaczenie!\n" "##\n" "## To są nagłowki maila\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd dodał $amount zadań/zadania do kolejki\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Następnie treść maila, wymagana jest pusta linia!\n" "\n" "Cześć,\n" "\n" "SABnzbd dodał $amount zadanie/zadań do kolejki.\n" "Pochodzą one z wiadomości RSS \"$feed\".\n" "\n" "$job \n" "\n" "\n" "Nara\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Szablon wiadomości błędnego pobierania URL SABnzbd\n" "## To jest szablon Cheetah\n" "## Dokumentacja: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Znaki nowego wiersza i białe znaki mają znaczenie!\n" "##\n" "## To są nagłówki wiadomości\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd nie udało się pobrać pliku NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Po tym następuje treść. Pusty wiersz jest wymagany!\n" "\n" "Cześć,\n" "\n" "SABnzbd nie udało się pobrać pliku NZB z $url.\n" "Komunikat błędu: $msg\n" "\n" "Do usłyszenia.\n" SABnzbd-0.7.20/po/email/pt_BR.po0000644000000000000000000001356412433712555016320 0ustar00usergroup00000000000000# Brazilian Portuguese translation for sabnzbd # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-03-10 04:16+0000\n" "Last-Translator: lrrosa \n" "Language-Team: Brazilian Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Template padrão de e-mail para SABnzbd\n" "## Este é um template Cheetah\n" "## Documentação: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Novas linhas e espaços em branco são significativos!\n" "##\n" "## Estes são os cabeçalhos de e-mail\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd a " "tarefa $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Depois daqui vem o corpo. A linha vazia é necessária!\n" "\n" "Olá,\n" "\n" "SABnzbd baixou \"$name\" \n" "\n" "SABnzbd falhou no download de \"$name\" \n" "\n" "Completado em $end_time\n" "Baixados $size\n" "\n" "Resultados da tarefa:\n" "\n" "Etapa $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Retorno do script de usuário \"$script\" (Código de retorno = $script_ret):\n" "$script_output\n" "\n" "\n" "Aproveite!\n" "\n" "Lamento!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## Template de e-mail RSS para SABnzbd\n" "## Este é um template Cheetah\n" "## Documentação: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Novas linhas e espaços em branco são significativos!\n" "##\n" "## Estes são os cabeçalhos de e-mail\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd adicionou $amount à fila\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Depois daqui vem o corpo. A linha vazia é necessária!\n" "\n" "Olá,\n" "\n" "SABnzbd adicionou $amount à fila.\n" "Elas são do feed RSS \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Tchau!\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Template de e-mail de busca em URL ruim para SABnzbd\n" "## Este é um template Cheetah\n" "## Documentação: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Novas linhas e espaços em branco são significativos!\n" "##\n" "## Estes são os cabeçalhos de e-mail\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd falhou ao buscar um NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Depois daqui vem o corpo. A linha vazia é necessária!\n" "\n" "Olá,\n" "\n" "SABnzbd não conseguiu obter o NZB de $url.\n" "A mensagem de erro foi: $msg\n" "\n" "Tchau!\n" SABnzbd-0.7.20/po/email/ro.po0000644000000000000000000001342212433712564015723 0ustar00usergroup00000000000000# Romanian translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-04-16 03:32+0000\n" "Last-Translator: nicusor \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Sablon Email Original pentru SABnzbd\n" "## Acesta este un Sablon Cheetah\n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "##Rândurile noi si caracterele spatiu sunt importante!\n" "##\n" "## Acestea sunt antetele email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd \n" "SABnzbd a descãrcat \"$name\" \n" "\n" "SABnzbd nu a reusit sã descarce \"$name\" \n" "\n" "Terminat la $end_time\n" "Mãrime $size\n" "\n" "Rezultatele sarcinii:\n" "\n" "Stagiu $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Rezultatul script-ului utilizatorului \"$script\" (Exit code = " "$script_ret):\n" "$script_output\n" "\n" "\n" "Bucurati-vã!\n" "\n" "Ne pare rau!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "## Sablon Email RSS pentru SABnzbd\n" "## Acesta este un sablon Cheetah \n" "## Documentatie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rândurile noi si caracterele spatiu sunt importante!\n" "##\n" "## Acestea sunt antetele email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd a adãugat $amount sarcini în coadã\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Dupã acesta urmeazã continutul, este necesar o linie goalã!\n" "\n" "Salut,\n" "\n" "SABnzbd a adãugat $amount sarcinã(e) în coadã.\n" "Ele sunt din fluxuri RSS \"$feed\".\n" "\n" " $job \n" "\n" "\n" "La revedere !\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Adresã URL Gresitã sablon Email pentru SABnybd \n" "## Acesta este un sablon Cheetah\n" "## Documentatie : http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Liniile noi si spatiile sunt importante!\n" "##\n" "## Acestea sunt headerele email\n" "Cãtre: $to\n" "De la: $from\n" "Datã: $date\n" "Subiect: SABnzbd nu a reusit sã descarce un NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## Dupã aceasta urmeazã corpul email, linia goalã e necesarã !\n" "\n" "Salut,\n" "\n" "SABnzbd nu a putut descãrca NZB-ul de la adresa $url.\n" "Mesajul de eroare a fost: $msg\n" "\n" "La revedere!\n" SABnzbd-0.7.20/po/email/ro.px0000644000000000000000000001345012433712555015735 0ustar00usergroup00000000000000# Romanian translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-04-16 03:32+0000\n" "Last-Translator: nicusor \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "##\n" "## Șablon Email Original pentru SABnzbd\n" "## Acesta este un Șablon Cheetah\n" "## Documentație: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "##Rândurile noi și caracterele spațiu sunt importante!\n" "##\n" "## Acestea sunt antetele email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd \n" "SABnzbd a descărcat \"$name\" \n" "\n" "SABnzbd nu a reuşit să descarce \"$name\" \n" "\n" "Terminat la $end_time\n" "Mărime $size\n" "\n" "Rezultatele sarcinii:\n" "\n" "Stagiu $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Rezultatul script-ului utilizatorului \"$script\" (Exit code = " "$script_ret):\n" "$script_output\n" "\n" "\n" "Bucuraţi-vă!\n" "\n" "Ne pare rau!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "## Şablon Email RSS pentru SABnzbd\n" "## Acesta este un şablon Cheetah \n" "## Documentaţie: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Rândurile noi și caracterele spațiu sunt importante!\n" "##\n" "## Acestea sunt antetele email\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd a adăugat $amount sarcini în coadă\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## După acesta urmează conţinutul, este necesar o linie goală!\n" "\n" "Salut,\n" "\n" "SABnzbd a adăugat $amount sarcină(e) în coadă.\n" "Ele sunt din fluxuri RSS \"$feed\".\n" "\n" " $job \n" "\n" "\n" "La revedere !\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Adresă URL Greşită şablon Email pentru SABnybd \n" "## Acesta este un şablon Cheetah\n" "## Documentaţie : http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Liniile noi şi spaţiile sunt importante!\n" "##\n" "## Acestea sunt headerele email\n" "Către: $to\n" "De la: $from\n" "Dată: $date\n" "Subiect: SABnzbd nu a reuşit să descarce un NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## După aceasta urmează corpul email, linia goală e necesară !\n" "\n" "Salut,\n" "\n" "SABnzbd nu a putut descărca NZB-ul de la adresa $url.\n" "Mesajul de eroare a fost: $msg\n" "\n" "La revedere!\n" SABnzbd-0.7.20/po/email/SABemail.pot0000644000000000000000000000564512433712554017113 0ustar00usergroup00000000000000# # SABnzbd Translation Template file EMAIL # Copyright (C) 2011-2012 by the SABnzbd Team # team@sabnzbd.org # msgid "" msgstr "" "Project-Id-Version: SABnzbd-0.7.x\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: shypike@sabnzbd.org\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 7bit\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" SABnzbd-0.7.20/po/email/sv.po0000644000000000000000000001335112433712555015734 0ustar00usergroup00000000000000# Swedish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-12-10 20:31+0000\n" "PO-Revision-Date: 2012-05-15 19:28+0000\n" "Last-Translator: Andreas Lindberg \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-11 06:16+0000\n" "X-Generator: Launchpad (build 16869)\n" #: email/email.tmpl:1 msgid "" "##\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has downloaded \"$name\" \n" "\n" "SABnzbd has failed to download \"$name\" \n" "\n" "Finished at $end_time\n" "Downloaded $size\n" "\n" "Results of the job:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Output from user script \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Enjoy!\n" "\n" "Sorry!\n" "\n" msgstr "" "## Translation by Andreas Lindberg andypandyswe@gmail.com\n" "## Default Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "Till: $to\n" "Från: $from\n" "Datum: $date\n" "Ämne: SABnzbd has " "job $name\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hej,\n" "\n" "SABnzbd har laddat ned \"$name\" \n" "\n" "SABnzbd misslyckades med att ladda ned \"$name\" \n" "\n" "Färdig $end_time\n" "Nedladdat $size\n" "\n" "Resultat:\n" "\n" "Stage $stage \n" "\n" " $result \n" "\n" "\n" "\n" "Utmatning från användarskript \"$script\" (Exit code = $script_ret):\n" "$script_output\n" "\n" "\n" "Lycka till!\n" "\n" "Beklagar!\n" "\n" #: email/rss.tmpl:1 msgid "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd has added $amount jobs to the queue\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has added $amount job(s) to the queue.\n" "They are from RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Bye\n" msgstr "" "##\n" "## RSS Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "Till: $to\n" "Från: $from\n" "Datum: $date\n" "Ämne: SABnzbd har lagt till $amount jobb i kön\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hej,\n" "\n" "SABnzbd har lagt till $amount jobb i kön.\n" "De kommer från RSS feed \"$feed\".\n" "\n" " $job \n" "\n" "\n" "Hej då\n" #: email/badfetch.tmpl:1 msgid "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "To: $to\n" "From: $from\n" "Date: $date\n" "Subject: SABnzbd failed to fetch an NZB\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hi,\n" "\n" "SABnzbd has failed to retrieve the NZB from $url.\n" "The error message was: $msg\n" "\n" "Bye\n" msgstr "" "##\n" "## Bad URL Fetch Email template for SABnzbd\n" "## This a Cheetah template\n" "## Documentation: http://sabnzbd.wikidot.com/email-templates\n" "##\n" "## Newlines and whitespace are significant!\n" "##\n" "## These are the email headers\n" "Till: $to\n" "Från: $from\n" "Datum: $date\n" "Ämne: SABnzbd misslyckades med att hämta en NZB -fil\n" "X-priority: 5\n" "X-MS-priority: 5\n" "## After this comes the body, the empty line is required!\n" "\n" "Hej,\n" "\n" "SABnzbd har misslyckats med att hämta NZB -filen från $url.\n" "Felmeddelandet lyder: $msg\n" "\n" "Hej då\n" SABnzbd-0.7.20/po/main/da.po0000644000000000000000000036711712433712555015541 0ustar00usergroup00000000000000# Danish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2014-07-02 18:01+0000\n" "Last-Translator: Jonas Bæk \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:53+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Kunne ikke starte web-interface" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Kan ikke finde webskabeloner: %s, forsøger med standardskabelon" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "_yenc modul... IKKE fundet!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "par2 binær... IKKE fundet!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "unrar binær... IKKE fundet!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "unzip binær... IKKE fundet!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Vær opmærksom på at 0.0.0.0 værtsnavn har brug for en IPv6-adresse for " "ekstern adgang" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS fejlede på grund af manglende CERT og KEY filer" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s startet" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnzbd lukning udført." #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s modtaget, gemmer og lukker..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "henter msgid %s fra www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Fejl ved hentning af msgid %s fra www.newzbin2.es - Kontroller, at dit " "brugernavn og din adgangskode er korrekt" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Forsøger at hente NZB fra %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Kan ikke oprette temp fil for %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Forsøger at sætte status på ikke eksisterende server %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "For lidt diskplads tvinger system i PAUSE" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Fejl i tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Gemmes %s mislykkedes" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Downloadning af %s mislykkedes" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Afprøv notifikation" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Ingen" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Standard" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "ADVARSEL:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "FEJL:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "Ukendt" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Det lykkedes ikke at kompilere regex for søgestreng: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disken er fuld! Pauser..." #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Diskfejl ved oprettelse af fil %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "WARNING: Paused job \"%s\" because of encrypted RAR file" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "ADVARSEL: afbrudt job \" %s\" på grund af krypteret RAR fil" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Afbrudt, kryptering registreret" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s mangler" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Kvote brugt, pause downloading" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s er ikke en godkendt e-mail adresse" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Kræver serveradresse" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Kan ikke oprette %s mappe %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Kan ikke skrive til INI fil %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Kan ikke oprette backup fil for %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Forkert kodet password%s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s er ikke et korrekt ciffer værdi" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "UNC søgning \"%s\" er ikke tilladt her" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Fejl: Køen er ikke tom, kan ikke skifte mappe." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Mappen \"%s\" findes ikke" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "SQL Kommando mislykkedes, se logg" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "SQL Commit mislykkedes, se logg" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Det lykkedes ikke at lukke databasen, se logg" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Forkert loggning i historiken av %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Afkodning af %s mislykkedes" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "CRC Fejl i %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Forkert udformet yEnc artikel i %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Ukendt fejl under afkodning af %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => mangler fra alle servere, afviser" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Fejl ved fjernelse af %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Kan ikke læse %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Kan ikke læse overvåget mappe %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Sat på pause" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Server %s vil blive ignoreret for i %s minutter" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Det lykkedes ikke at initialisere %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "For mange tilslutninger til server %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Sandsynligt delt konto" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Det lykkedes ikke at logge på serveren %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Kan ikke tilslutte til server %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Tilslutning af%s@%s:%s mislykkedes, besked =%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Server %s kræver brugernavn/password" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Påbegynder lukning af SABnzbd.." #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Det lykkedes ikke at tilslutte mailserver" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Det lykkedes ikke at initialisere TLS tilslutning" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Godkendelse til mailserver mislykkedes" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Det lykkedes ikke at sende e-mail" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Det lykkedes ikke at lukke e-mail tilslutning" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "E-mail afsendelse mislykkedes" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Kan ikke finde e-mail skabeloner i %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Ingen modtagere givet, ingen e-mail sendt" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Ugyldig kodning af e-mail skabelon %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Ingen e-mail skabeloner fundet" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd rapportere Disk Fuld\n" "\n" "Hej,\n" "\n" "SABnzbd er stoppet med at downloade, fordi disken er næsten fuld.\n" "Vær venlig at give plads og genoptage SABnzbd manuelt.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Start / Lukning" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "Tilføjet NZB" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Efterbehandling i gang" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Job afsluttet" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Andre beskeder" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Varning: Localhost er tvetydig, bruge numerisk IP-adresse." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Serveradressen \"%s:%s\" er ikke gyldigt." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Mangler sessionsnøgle" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Fejl: Kræver sessionsnøgle" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Fejl: Fejl sessionsnøgle" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "API-nøgle mangler, indtast api-nøglen fra Konfiguration-> Generelt i dit " "tredjepartsprogram:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Forkert API-nøgle, anvend api-nøglen fra Konfiguration-> Generelt i dit " "tredjepartsprogram:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Brugeroplysninger mangler, indtast brugernavn / password fra Konfiguration-> " "Generelt i dit tredjepartsprogram:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Fejl: Ingen sekundær bruger grænseflade defineret." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Din unrar version kan ikke anbefales, hent UNRAR fra " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "Ingen unrar program fundet, udpakning RAR filer er ikke mulig
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Ingen PAR2 program fundet, reparationer ikke muligt
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Forbereder genstart...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd genstart færdig.
    Vent i ca 5 sekunder og klik " "derefter på knappen nedenunder..

    Opdater
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Daglig" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Mandag" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Tirsdag" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Onsdag" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Torsdag" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Fredag" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Lørdag" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Søndag" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "slået fra" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr "  Server løsning" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Fejl parameter" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Tilbage" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Job \"%s\" er genoptaget i køen" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Jobs markeret med '*' vil ikke blive hentet automatisk." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Matchede" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Matchede ikke" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Hentet" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Hentet indtil videre" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Fejl værdi før %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Kan ikke oprette mappe %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s mappe: %s adgang mislykkedes" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Kan ikke tilslutte til registreringsdatabasen HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Kan ikke åbne nøgle i registreringsdatabasen \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Kunne ikke læse nøgler i registreringsdatabasen for specielle mapper" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Oprettelse af (%s) mislykkedes" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Det lykkedes ikke at flytte %s til %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Fejl, Ubrugelig arkivfil" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Forsøg igen" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "URL hentning mislykkedes; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "pyopenssl modul mangler, du skal installere for HTTPS-adgang" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Fejl ved oprettelse af SSL-nøgle og certifikat." #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Det lykkedes ikke at ændre rettigheder på %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Sammenlægger" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Ufuldstændig sekvens af joinable filer" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Filsammenlægning af %s mislykkedes" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fejl \"%s\" under filsammenlægning" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Fejl \"%s\" når du køre file_join på %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Sammen lagte %s filer" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Udpakning mislykkedes, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fejl \"%s\" under udpakning af RAR fil(er)" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fejl \"%s\" når du køre rar_unpack på %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Fjernelse af %s mislykkedes!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Forsøger unrar med adgangskode \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Udpakning mislykkedes, arkivet kræver password" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Udpakker" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Udpakning mislykkedes, kunne ikke finde %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "FEJL: lykkedes ikke at finde \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Udpakning mislykkedes, CRC-fejl" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "FEJL: CRC mislykkedes i \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Udpakning mislykkedes, skrivefejl eller disken fuld?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "FEJL: skrivefejll (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Udpakningen mislykkedes, stien er for lang" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "FEJL: stien for lang (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Udpakning mislykkedes, se logg" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "FEJL: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "Ubrugelig RAR fil" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Manglede forventet fil: %s => unrar fejl?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Udpakning mislykkedes, en ventet fil er ikke udpakket" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Udpakning mislykkedes, disse fil (er) mangler:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Udpakket %s filer/mapper i %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s filer i %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Fejl \"%s\" når du køre unzip() på %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Hurtig kontrollerende" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Reparerer" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Hurtig kontrol OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Starter reparation" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparation mislykkedes, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Fejl %s når du køre par2_repair på %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fejl \"%s\" mens par2_repair kørte på %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 modtog forkerte indstillinger, tjek din konfiguration->Skifter " "indstillinger" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Bekræftelse i %s, alle filer er ok" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Bekræftelse i %s, kræver reparation" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Hovedarkiv mangler..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Ugyldig PAR2 filer, kan ikke kontrollere eller reparere" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparation mislykkedes, ikke nok reparation blokke (%s mangler)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Henter %s block..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Henter" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Reparerer" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Repareret i %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Bekræfter" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Mislykkedes med importering af OpenSSL modul. Tilslutter uden SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Kunne ikke opdatere newzbin job %s" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB tilføjet i køen" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Newzbin server ændrede sin protokol" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Du har ingen kredit på din konto Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Ingen adgang, kontroller din newzbin brugernavn / adgangskode" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin rapporterede %s ikke fundet" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin giver udokumenterede fejlkode (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Newzbin server mislykkedes at give information til %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Kunne ikke slette newzbin bogmærke %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin giver udokumenterede fejlkode (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Ødelagt queuefile fundet, kan ikke fortsætte" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Downloadnings fejl %s, ødelagt fil fundet" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Det lykkedes ikke at tilføje %s, slette" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Ukendt kodning" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Fil %s er tom, springer over" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Det lykkedes ikke at importere %s filer fra %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Ufuldstændig NZB fil %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Ødelagt NZB fil %s, springer over (årsag=%s, linje=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Tom NZB fil %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorerer identiske NZB \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Pause duplikeret NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Afbrudt, kan ikke afsluttes" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLIKERE" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "KRYPTEREDE" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "FOR STOR" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "Ufuldstændig" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "VENT %s sekunder" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Hentede i %s med et gennemsnit på %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artikler misdanned" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s artikler mangled" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artikler havde ikke-matchende dubletter" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s artikler blev fjernet" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Det lykkedes ikke at importere %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Advarsler" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Inaktiv" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Opsætning" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Kø" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Rens køen" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historik" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Tøm historik" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Hastighedsbegrænsning" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pause" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Genoptag" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Henter Newzbin bogmærker" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Scan overvåget mappe" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Færdig mappe" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Ufuldstændig mappe" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Fejlfinding" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Genstart" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Genstart uden login" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Afslut" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Kø (de første 10 poster)" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Tom" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Historik (de 10 seneste poster)" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Ny version tilgænglig" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Gå til guiden" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Standser" #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problem med" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd er ikke kompatibel med visse software firewalls.
    \n" " %s
    \n" " Beklager, men vi kan ikke løse denne uforenelighed lige nu.
    \n" " Du kan indsende en klage til din firewall leverandør.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd har brug for en ledig TCP / IP-port til sine interne " "webserver.
    \n" " Port %s på %s blev forsøgt, men den er ikke til rådighed .
    \n" " Nogle andre programmer bruger porten eller SABnzbd kører allerede.
    \n" "
    \n" " Genstart venligst SABnzbd med et andet portnummer." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "Hvis du får denne fejlmeddelelse igen, prøv et andet portnummer.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd brug for en ledig TCP / IP-port til sin intern webserver .
    \n" " Port %s på %s blev forsøgt , men den konto, der anvendes til SABnzbd har " "ikke tilladelse til at bruge det.
    \n" " På OSX og Linux systemer, skal brugere normalt bruge porte over " "1023.
    \n" "
    \n" " Venligst genstart SABnzbd med et andet port nummer." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd har brug for en gyldig vært adresse til intern webserver .
    \n" " Du har angivet en ugyldig adresse.
    \n" " Sikkert valg er localhost og 0.0.0.0
    \n" "
    \n" " Venligst genstart SABnzbd med en gyldig host adresse ." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd har fundet gemt data fra en anden SABnzbd version
    \n" " men kan ikke genbruge dataene fra det andet program.

    \n" " Du ønsker måske at afslutte din kø først med det andet program.

    \n" " Efter dette, start programmet med \"- rene\" valgmulighede.
    \n" " Dette vil slette den nu værende kø og historik!
    \n" " SABnzbd læser filen \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd kan ikke finde sin webgrænseflade filer i %s.
    \n" " Venligst installer programmet igen.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd fandt en alvorlig fejl:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd opdagede en kø og historik fra en ældre (0.4.x) " "udgivelse.

    \n" " Begge køer og historiker vil blive ignoreret og måske gå tabt!

    \n" " Du ønsker måske at stoppe SABnzbd og færdigøre køen med det gamle " "program.

    \n" " Klik på OK for at gå videre til SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd opdagede, at filen sqlite3.dll mangler .

    \n" " Nogle dårligt designet virus-scannere fjernede denne fil .
    \n" " Tjek venligst din virus-scanner, du kan prøve at geninstallere SABnzbd " "og klage til din virus-scanner leverandør .
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Tryk Startkey + R og skriv linjen (eksempel):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Åben et terminalvindue og tast linjen (eksempel):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Det er sandsynligt, at du bruger ZoneAlarm på Vista .
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Programmet startede ikke!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Du har ingen tilladelse til at bruge port %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Alvorlig fejl" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Kan ikke starte browseren, sandsynligvis ikke fundet" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Adgang nægtet" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Fejl %s: Du skal angive et gyldigt brugernavn og adgangskode." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Kunne ikke indlæse efterbehandle kø: Forkert version (kræver:%s, fundet:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Det lykkedes ikke at fjerne nzo fra efterbehandlings køen (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "Overførslen kan mislykkes, kun %s af det krævet %s tilgængelige" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Hentning mislykkedes – Findes ikke hos din server's retention?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Kan ikke oprette endelig mappe %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Ingen efterbehandling på grund af mislykket bekræftigelse" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Flytter" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Sendt %s til kø" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Det lykkedes ikke at omdøbe \"%s\" til \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Kunne ikke flytte filer" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Køre script" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Kør bruger script %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Kørte %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Mere" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Vis script udlæsning" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Overførsel fuldført" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Download mislykkedes" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Efterbehandling mislykkedes for %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "se logfil" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Efterbehandling blev afbrudt (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Fjernelse af %s mislykkedes." #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Det lykkedes ikke at fjerne arbejdsmappen (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Efterbehandling" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Ingen par2 sæt" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Forsøger SFV verifikation" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Some files failed to verify against \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Kontrolleret korrekt ved hjælp af SFV filer" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Fjernelse af%s mislykkedes" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Det lykkedes ikke systemet at gå i dvale" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Det lykkedes ikke systemet at gå i standby" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Fejl ved lukning af system" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Forkert RSS-feed beskrivelse \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Mislykkedes at hente RSS fra %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Har ikke gyldig godkendelse til feed %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "RSS Feed %s er tom" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Inkompatibel feed" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Tom RSS post blev fundet (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Vis grænseflade" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Åben færdig mappe" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Luk ned" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Tilbageværende" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Forkert tidsplan %s ved %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Ukendt handling: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Tidsplan for ikke-eksisterende server %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Downloader" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Sammenlægger filer" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Udpak" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "script" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Kilde" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Mislykkedes" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Færdig" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Mislykkedes" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Venter" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparerer..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Udpakning..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Flytter..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Kør script..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Henter ekstra block..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Hurtig kontrol..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Bekræftelse..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Downloader" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Hent NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Kontrollerer" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Forekomst" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Udfør" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argumenter" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Opgave" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "deaktivere server" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "aktivere server" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Hastighedsbegrænsning" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Pause alt" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pause efterbehandling" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Genoptag efterbehandling" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Læs RSS feeds" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Fjern mislykkede jobs" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "time" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "timer" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "minut" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minutter" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sekund" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "sekunder" #: sabnzbd/skintext.py:79 msgid "day" msgstr "dag" #: sabnzbd/skintext.py:80 msgid "days" msgstr "dage" #: sabnzbd/skintext.py:81 msgid "week" msgstr "uge" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Måned" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "År" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Månedsdag" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Denne uge" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Denne måned" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "I dag" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Totalt" #: sabnzbd/skintext.py:97 msgid "on" msgstr "på" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parameter" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Python-version" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Startside" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "eller" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Vært" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "Kommentar" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "Send" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "Annullér" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "Andet" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "Rapportér" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "Video" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "Audio" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Det automatiske usenet download værktøj" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Gem" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Køen" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Er du sikker?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Slet alle hentede filer?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Hjem" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Konfiguration" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Status" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Hjælp" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Generelt" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Mapper" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Parameter" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Server" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Planlægning" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Meddelelser" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "E-mail" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Index-sider" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Kategorier" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortering" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Speciel" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Midlertidig download mappe" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Færdig download mappe" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Download hastighed" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "PAUSET" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "Cached %s artikler (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Sysload" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "ADVARSLER" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Ny version %s tilgængelig" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Tilføj nye downloads" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Er du sikker på du vil lukke SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Tilføj" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Rapport-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Tilføj fil" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Kategori" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Forløb" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioritet" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparere" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Udpakke" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Slette" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "P" #: sabnzbd/skintext.py:177 msgid "D" msgstr "T" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Tvinge" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Høj" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Lav" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stop" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " eller Report ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Sortere efter navn" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Sortere efter alder" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Sortere efter størrelse" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Skjul filer" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Vis filer" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Når køen er færdig" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Luk computer" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Sæt computer i standby" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Sæt computer i dvale" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Afslut SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Hastighedsbrgrænsning" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pause i" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Rækkefølge" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Navn" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Tilbage/Totalt" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Tid tilbage" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "Alder" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Fjern" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Forsøg igen" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Handlinger" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Scripts" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Fjern alt fra køen?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Rens NZB'er" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Rens NZB'er & slet filer" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Fjern NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Fjern NZB & slet filer" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "fra" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Mangler artikler" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Kvota tilbage" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "manuelt" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Nulstil kvota nu" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Rens mislykket historie" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Slet alle afsluttede emner fra historie?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Slet alle mislykkedes emner fra historie?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Skjul detaljer" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Vis detaljer" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Størrelse af Historik" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Vis mislykket" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Vis Alt" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Størrelse" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Rens mislykket NZB'er" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Rens mislykket NZB'er & slet filer" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Rens komplette NZB'er" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Valgfri Supplerende NZB" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Sti" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "Virus/spam" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "Behov adgangskode" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "Udenfor retention" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "Et andet problem" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Gennemtving afbrydelse" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Dette vil sende en test E-mail til din konto." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Vis log" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Vis webblog" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Test E-mail" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Logning" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Fejl/Advarsel" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "Fejlfinding" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Forbindelser" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Tråd" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "E-mail testresultat" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Seneste advarsler" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "Slet" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Ophæv blokering" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Artikel identifikator" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Fil sæt" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Når" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Type" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Advarsel" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Aktiveret" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Konfigurations fil" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Brugt chace" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Knappen vil genstarte SABnzbd..
    \r\n" "Andvend den hvis du oplever stabilitets problem.
    \r\n" "Downlodning vil blive sat på pause før genstart og genoptages automatisk " "igen efter genstart." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Der er forældreløse jobs i download mappen.
    Du kan vælge at slette " "dem (herunder filer) eller sende dem tilbage til køen." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "\"Reparation\" knappen vil genstarte SABnzbd og lave en komplet
    " "rekonstruktion af køens indhold, bevare allerede downloadede filer.
    " "Dette vil ændre køens orden." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Udgave" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Oppetid" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Sikkerhedskopi" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "OZnzb" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Generel konfiguration" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Ændringer kræver genstart af SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "SABnzbd Webserver" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "SABnzbd Adresse" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Adresse som SABnzbd ska lytte på." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "SABnzbd Port" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Port som SABnzbd ska lytte på." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Webgrænseflade" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Vælg et Web-grænseflade udseende." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Sekundær udseende" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Aktivere et alternativ udseende." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Webserver godkendelse" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "SABnzbd brugernavn" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Valgfrit brugernavn." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "SABnzbd password" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Valgfrit password." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "HTTPS Support" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "HTTPS Aktivering" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "ikke installeret" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Aktiver adgang til interface fra en HTTPS-adresse." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "HTTPS Port" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Hvis tom, vil standard-porten kun lytte til HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "HTTPS Certifikat" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Filnavn eller sti til HTTPS Certifikat." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "HTTPS Nøgle" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Filnavn eller sti til HTTPS Nøgle." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "HTTPS kæde certifikater" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Filnavn eller sti til HTTPS kæde." #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Justering" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Automatisk opdaterings interval af kø:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "opdaterings interval af kø-siden (sek, 0= ingen)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "RSS Opdaterings interval" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Kontrol af interval (i minutter, i hvert fald 15). Ikke aktiv, når du bruger " "skemaer!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Hastighedsbegrænsning for Download" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Hastighedsbegrænsning for Download (i KB/s - kilobyte per sekund)." #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Cache størrelse af artikler" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Cache artikler i hukommelsen for at reducere diskadgang.
    I bytes, " "efterfulgt af K,M,G. For eksempel: \"64M\" eller \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Ryd listen" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Liste over filtypenavne, der skal slettes efter download.
    . For " "eksempel: .nfo or .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Gem ændringer" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Sprog" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Vælg et web-grænseflade sprog." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "API-nøgle" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Denne nøgle vil give 3. parts programmer fuld adgang til SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "NZB nøgle" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Denne nøgle vil give 3. parts programmer til at tilføje NZBs til SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Generere Ny Nøgle" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Deaktivere API-nøgle" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Kræver ingen API-nøgle." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "ANDVEND PÅ EGEN RISIKO!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "QR kode" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "API nøgle QR kode" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Mappe konfiguration" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "OBS: Mapper vil blive oprettet automatisk, når du gemmer. Du kan " "bruge absolutte stier til at gemme uden for standardmapperne." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Brugermapper" #: sabnzbd/skintext.py:345 msgid "In" msgstr "Ligger i" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Midlertidig download mappe" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Sted at gemme uforarbejdede downloads.
    Kan kun ændres, når køen er " "tom." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimum fri plads til midlertidige download mappe" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pause, når ledig plads kommer under denne værdi.
    I bytes, " "evt. efterfulgt af K, M, G, T. For eksempel: '800M 'eller '8 G'" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Færdig download mappe" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Sted at opbevare færdige, fuldt forarbejdede downloads.
    Kan " "tilsidesættes af bruger-definerede kategorier." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Tilladelser til fuldførte overførsler" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Angive tilladelses mønster for afsluttede filer.
    Anvend ciffer. For " "eksempel: \"755\" eller \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Overvåget Mappe" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Mappe til at gennemsøge for. Nzb filer.
    Skanner også for .zip .rar " "og .tar.gz arkiver efter .nzb filer." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Skannings interval for overvåget mappe" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Sekunder mellem skanninger for .nzb filer." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Efterbehandlings scripts mappe" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Mappe, der indeholder bruger scripts til efterbehandling." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "E-mail-mappe skabeloner" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Mappe, der indeholder brugerdefinerede e-mail-skabeloner." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Password-fil" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fil, der indeholder alle passwords. Vil blive brugt på password beskyttede " "RAR filer." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Systemmapper" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Administrativ mappe" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Placering for kø administrativ og historik database.
    Kan kun ændres, " "når køen er tom." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Data vil ikke blive flyttet. Kræver SABnzbd genstartet!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Log mappe" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Placering af logfiler for SABnzbd.
    Kræver genstart af SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr ".nzb Backup mappe" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Sted hvor .nzb filer gemmes." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Standard Base Folder" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Parameterkonfiguration" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Forløbs parameter" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Aktiver hurtig tjek" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Spring par2 kontrol over, når filerne er 100% gyldige." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Aktivere Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Aktivere indbygget Unrar funktion." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Aktivere Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Aktivere indbygget Unzip funktion." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Aktiver Fil Sammenføjning (Filejoin)" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Sammenføjer filer, der ender med .001, .002 osv. til en fil." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Aktivere TS Sammenføjning (TS Joining)" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "Sammenføjer filer, der ender med, 001.ts, .002.ts osv. til en fil." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Aktiver Par rensning (Par Cleanup)" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Oprydning af par filer (hvis kontrollerede / reparation lykkedes)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Ved fejl på yEnc CRC" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "Anvend backup-server ved yEnc CRC fejl." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Kun artiklerne fra starten af køen" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Aktiver til mindre brug af hukommelse. Deaktiver for at forhindre langsom " "job fra at blokerer køen" #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Efterbehandling kun verificerede jobs" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "Kun udføre efterbehandling af jobs som har bestået PAR2 kontrollen." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Handling når krypteret RAR er downloadet" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "I tilfælde af \"Pause\", skal du angive en adgangskode og genoptage jobbet." #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Find identiske downloads" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Find identiske navngivne NZB filer (kræver NZB backup) og dobbelt titler på " "tværs af RSS-feeds" #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Slået fra" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Kassér" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Afbryd" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Aktiver SFV-baseret kontrol" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Udfør en ekstra kontrol baseret på SFV-filer." #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Tjek resultat af udpakning" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Tjek resultat af udpakning (skal være slukket for nogle filsystemer)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Aktiver mappe omdøbning" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Brug midlertidig navne under efterbehandling. Deaktiver når dit system ikke " "kan håndtere det ordentligt." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Standard efterbehandling" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Anvedes når efterbehandlingen er bestemt efter kategori." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Standard bruger scripts" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Anvendes når bruger scripts er bestemt efter kategori." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Før kø bruger script" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Brugt før, en NZB kommer ind i køen." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Standard prioritet" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Anvendes når ingen prioritet er bestemt af kategori." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Aktivere MultiCore Par2" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Læs mere om dette på Wiki Help!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Ekstra PAR2 parameter" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "God parameter" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "IONice parametrar" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Andre parameter" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Afbryd når køen er tom" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Afbryd fra usenet-serverne når køen er tom eller sat på pause." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Send gruppe" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Send gruppe kommandoen, før du anmoder om artikler." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sortere efter alder" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Sortere automatisk efter (gennemsnits) alder." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Kontroller for ny version" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Kontroller for ny version af SABnzbd hver uge." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Test også udgivelser" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Erstat mellemrum i mappenavn" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Erstat mellemrum med understreg i mappenavn." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Erstat punktummer i mappenavn" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Erstat punktum med mellemrum i mappenavn" #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Erstat ugyldige tegn i mappenavn." #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Erstat ugyldige tegn i mappenavn med modsvarende tegn (ellers fjern)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Start web browser ved opstart" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Starter standard web browser når SABnzbd starter." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Pause downloading under efterbehandling" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Pauser downloadet i begyndelsen af efterbehandling og igen når den er færdig." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignorer Sample-filer" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Filtrerer prøve filer (f.eks. video eksempler)." #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Fjern efter download" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Download ikke." #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "SSL type" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Anvend V23 hvis ikke din leverandør (ISP) kræver andet!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Brug 12 timers ur (AM / PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Vis tider i AM / PM notation (påvirker ikke skemalægger)." #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Server" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Efterbehandling" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Navngivning" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Kvota" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "Indeksering" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Hvor meget der kan downloades i denne måned (K / M / G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Nulstil dag" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "På hvilken dag i måneden eller ugen (1 = mandag) nulstiller din " "internetudbyder kvota? (Valgfrit med tt: mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Automatisk genoptag" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "Skal download genoptages efter kvotaen er nulstillet?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Kvota periode" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Bliver kvota nulstillet hver dag, uge ​​eller måned?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Tjek før download" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Prøv at forudsige en vellykket afslutning, før selve download (langsom!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Maksimalt antal forsøg" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Maksimalt antal forsøg per server" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Kun for ekstra servere" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Påfør maksimalt antal forsøg kun til valgfri servere" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Afbryd job, der ikke kan færdiggøres" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Når under download det bliver klart, at for meget data mangler, afbryd jobbet" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "Aktiver OZnzb integration" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" "Udvidet funktioner inklusiv anmeldelser og ekstra status information bliver " "tilgængelige hvis forbundet med OZnzb indekseringen." #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "Sidens API nøgle" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" "Denne nøgle kobler profilen til indekseringen. Se " "https://www.oznzb.com/profile." #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "Se https://www.oznzb.com/profile" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "Automatisk tilbagemelding" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" "Send automatisk kalkuleret validerings resultater for downloads til " "indekseringen." #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Serverkonfiguration" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Server definition" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Tilføj server" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Brugernavn" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Adgangskode" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Tidsudløb" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Tilgængelighed i dage" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Backup server" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Valgfri" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Aktivere" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Fjern server" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Testserver" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Nulstil tæller" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Tester serverdetaljer..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Klik nedenfor for at teste." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Båndbredde" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Planlægningskonfiguration" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Opret planlægning" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Slet" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Aktuel planlægning" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "RSS-konfiguration" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Ny Feed URL" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Afkrydsningsfeltet ud for feed navn skal afkrydses for at feeds vil være " "aktiveret og automatisk kontrolleres for nye emner.
    Når et feed er " "tilføjet, vil det kun hente nye informationer og ikke noget, der allerede " "findes i RSS-feed, medmindre du trykker på \"Force Download\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Tilføj feed" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Fjern Feeds" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Læs Feed" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Gennemtving download" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filter" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Spring over" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Acceptere" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Afvise" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Kræver" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "Kræver Cat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Matchede ikke" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Feeds" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Læs alle Feeds nu" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Indstillinger" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtre" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "E-mail alternativ" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "E-mail påmindelse når job er fuldført" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Aldrig" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Altid" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Kun ved fejl" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Påmindelse når harddisk er fyldt" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Send e-mail når harddisken er fyldt og SABnzbd er pauset." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Send RSS meddelelser" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Send e-mail når en RSS-feed tilføjer job i køen." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "E-mail kontoinstillinger" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "SMTP-server" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Indtast ISP's server for udgående e-mail." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "E-mail modtagere" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "E-mail adresse hvor den skal sendes til." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "E-mail sendere" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Hvem skal vi sige sendte e-mailen?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "VALGFRIT konto brugernavn" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Brugernavn for e-mail som kræver godkendelse." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "VALGFRIT Bruger password" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Password for e-mail som kræver godkendelse." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Aktiver Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Send meddelelser til Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Serveradresse" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Bruges kun ved Growl fjern server (vært: port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Serverkodeord" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Valgfri adgangskode til Growl server" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Aktiver NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Send meddelelser til NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Notification Center" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Send notifications to Notification Center" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Notification klasser" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Aktiver klasser af meddelelser der skal indberettes (ingen, én eller flere)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Hvis du har en konto til www.newzbin2.es, kan du angive din " "konto info her. < br / > dette vil låse ekstra funktionaliteter op." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Brugerinformationer" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Newzbin Brugernavn" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Indtast dit brugernavn her." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Newsbin adgangskode" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Indtast dit password her." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Håndtering af bogmærker" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Hent bogmærker automatisk" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Henter jobs fra bogmærker automatisk." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Hent bogmærker nu." #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Skjul bogmærker" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Vis bogmærker" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Fjern bogmærker efter downloadning." #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Fjern fra bogmærkelisten når downloadning er gennemført." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Opdaterings interval" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "I minutter (mindst 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Bearbejdede bogmærker" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Hvis du har en konto til www.nzbmatrix.com, kan du skrive " "dine bruger informationer her.
    Dette er nødvendigt, hvis du ønsker at " "bruge RSS-feeds på nzbmatrix." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "NzbMatrix Brugernavn" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "NzbMatrix API-nøgle" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Indtast API-nøglen til NzbMatrix her." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Bruger definerede kategorier" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Definerer post-behandling og opbevaring." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Brug 'Gruppe / Index tags' kolonnen til at kortlægge dine grupper og tags " "til dine kategorier.
    \r\n" "Jokertegn understøttes. Brug kommaer for separate vilkår." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Slutter stien med en stjerne *, vil forhindre oprettelse af ​​job mapper." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Relative mapper er baseret på" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Mappe/Søgesti" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Gruppe / Index tags" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Sorteringskonfiguration" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Serie sortering" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Aktivere TV sortering" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Aktiverer sortering og omdøbning af episoder." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Hjælp til Sorteringsstræng" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Ryd" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Forudindstillinger" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Eksempel" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Almindelig sortering" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Aktivere filmsortering" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Aktiverer sortering og omdøbning af filer." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Behold løse download i ekstra mapper" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Aktivere hvis ikke download er flyttet til egen mappe." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Påvirkede Kategorier" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Betyder" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Mønster" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Sæsonmappe" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Sæsonmappe" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Episodemappe" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Episodemappe" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Film Navn" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Film.Navn" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Film_Navn" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Vis navn" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Vis.Navn" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Vis_Navn" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Sæsonnummer" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Episodenummer" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Episodenavn" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Episode.Navn" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Episode_Navn" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Filtype" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "endelse" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Delnummer" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Årti" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Originalfilnavn" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Orginal Mappenavn" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Små bogstaver" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py:667 msgid "text" msgstr "tekst" #: sabnzbd/skintext.py:668 msgid "file" msgstr "fil" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "mappe" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Sorteringsstræng" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Multi-del etikette" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "I mappe" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Ingen mappe" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Dato sortering" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Aktivere datosortering" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Aktiverer sortering og omdøbning af datomarkeret filer." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Vis Navn på mappe" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "År-Måned mapper" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Daglige mapper" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "sag-justeret" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Forarbejdede resultat" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Sjældent anvendte indstillinger. Deres betydning og forklaring, klik på " "knappen Hjælp for at gå til siden Wiki.
    Ændre ikke disse uden at " "kontrollere wiki'en først, da disse kan give alvorlige side " "følger.
    Standardværdierne er mellem parenteserne." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Værdier" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Ændre NZB detaljer" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Slet" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Øverst" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Op" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Ned" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Bunden" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Alle" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Invertere" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Filnavn" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Emne" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Alder" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Udvælgelse" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Er du sikker på at du vil slette" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Opdatere" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Muligheder" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Side" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Foregående" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Næste" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Først" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Sidste" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Luk" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Sæt pause interval" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sortere" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Tøm køen?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Pause interval" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pause 5 minutter" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pause 15 minutter" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pause 30 minutter" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pause 1 time" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pause 3 timer" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pause 6 timer" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pause 12 timer" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pause 24 timer" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sortere efter alder Ældst→Nyeste" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sortere efter alder Nyeste→Ældst" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sortere efter navn A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sortere efter navn Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sortere efter størrelse Mindst→Størst" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sortere efter størrelse Størst→Mindst" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Omdøbe" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Venster" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Vil du virkelig tømme historiken?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Ændringerne er ikke gemt og vil blive mistet." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Åbn kildekode URL" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Åbn informations URL" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Opbevaring" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Vis scriptlogg" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Du skal aktivere JavaScript for at få Plush til virke!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Tilføj NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Plush Instillninger" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Opdatering tilgængelig" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Pause i hvor mange minutter?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pause i..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Multi-operationer" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Topmenu" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Ved afslutning" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sortere efter Alder (Ældst→Nyeste)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sortera efter Alder (Nyeste→Ældst)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sortere efter Navn (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sortere efter Navn (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sortere efter Størrelse (Mindst→Størst)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sortere efter Størrelse (Størst→Mindst)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Slet" #: sabnzbd/skintext.py:781 msgid "left" msgstr "tilbage" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Max hastighed" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Omfang" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Gendan" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Anvend på markerede" #: sabnzbd/skintext.py:786 msgid "page" msgstr "side" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Alt" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Deaktiveret" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Opdateringsinterval" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Beholder Bredde" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Bekræft Kø-fjernelse" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Bekræft Historik-fjernelse" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Dette vil forhindre indhold i at blive opdateret når musens markør kører hen " "over køen" #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Bloker genopfriskninger ved Hover" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Hente" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Send" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Upload: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Angiv et valgfrit filnavn" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Fremgang" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Ikke nok diskplads til at fuldføre downloads." #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Ledig diskplads" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Ledig tempdiskplads" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "Venter" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Hentede filer" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Kø reparation" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Læs Feedhenter det nuværende feed indholdet. Tving " "hent vil hente alle matchende NZBs nu." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Time:Minut" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Slet komplette" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Slet alle mislykkedes emner fra historiken?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Slet mislykket" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Links" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Viser %s til %s af %s resultat" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Ingen resultater" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Viser et resultat" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Sendt E-mail!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Notifikation sendt" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Gemmer.." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Gemt" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Hastighed" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Vis/Skjul Tilføj NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "Flerskærme1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "Flerskærme2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Tilpasse" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Hent bogmærker" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Er du sikker på at du vil genstarte SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Opdateringsfrekvens" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Fjern alle" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Skjul Redigeringsalternativ" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Vis Redigeringsalternativ" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Rediger" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Resterende tid" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Hurtigstart’s Guide" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "SABnzbd version" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Forrige" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Adgang" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "Jeg ønsker at SABnzbd skal være synlige fra enhver pc på netværket." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Jeg ønsker kun at SABnzbd skal være synlige fra min computer." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Password beskytte adgangen til SABnzbd (anbefales)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Aktiver HTTPS-adgang til SABnzbd." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Diverse" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Start webbrowseren med SABnzbd's siden når programmet startes." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Serverdetaljer" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Angiv detaljerne fra din primære usenet udbyder." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "For at hente fra usenet kræves der adgang fra en udbyder. Din " "internetudbyder kan give dig adgang, men en præmie udbyder anbefales." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Har du ingen usenet leverandør? Vi anbefaler at prøve %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Antallet af forbindelser tilladt af din udbyder" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "F.eks. 8 eller 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Vælg kun hvis din udbyder tillader SSL-forbindelser." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Klik for at teste de indtastede informationer." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Dette fælt kræves." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Angiv et helt tal." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Hvis du er medlem af newzbin eller nzbmatrix, kan du indtaste dit brugernavn " "og password her, så du kan hente deres nzb's. Denne fase kan springes over, " "hvis du ikke bruger nogen af disse tjenester." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Hent automatisk bogmærket poster." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Eks." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Genstarter SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Installationen er nu fuldført!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd vil nu køre i baggrunden." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Lukning af alle browservinduer / faneblade vil ikke lukke SABnzbd." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Efter SABnzbd har genstartet vil du være i stand til at få adgang til det på " "følgende placering: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Det anbefales, at du højreklikker og bogmærker denne placering, og bruger " "dette bogmærke for at få adgang SABnzbd, når det kører i baggrunden." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Øvrig hjælp kan du finde på vores" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Gå til SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Trin et" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Trin to" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Trin tre" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Trin fire" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Trin fem" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "F.eks. 119 eller 563 for SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Afslut SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Start guide" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "Hvis du ikke har en konto, kan den oprettes på " #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd kommer med ABSOLUT INGEN GARANTI. \n" "Det er gratis software, og du er velkommen til at videredistribuere det " "under visse betingelser. \n" "Den er licenseret under GNU General Public License version 2 eller (efter " "eget valg) enhver senere version\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Det lykkedes ikke at hente TV info (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Det lykkedes ikke at omdøbe: %s til %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Kunne ikke omdøbe lignende fil: %s til %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Ugyldigt nzbmatrix rapport nummer %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Du skal bruge en nzbmatrix VIP konto for at bruge API'EN" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Ugyldig nzbmatrix legitimationsoplysninger" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Problem at få adgang til nzbmatrix server (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Værtsnavnet er ikke indstillet." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "Der er ingen forbindelser angivet. Angiv mindst én forbindelse." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Password maskeret med ******, forsøg igen" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Ugyldige serverdetaljer" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Timeout: Forsøg at aktivere SSL eller tilslut via en anden port." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Timeout" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Ugyldig server adresse." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Server afslut under login-sekvens." #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Serveren kræver brugernavn og password." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Tilslutning lykkedes!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Godkendelse mislykkedes, kontrollere brugernavn / adgangskode." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Alt for mange forbindelser, pause en download eller forsøg igen senere" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Det lykkedes ikke at tilslutte (%s)" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "henter msgid %s fra www.newzbin.com" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Fejl ved hentning af msgid %s fra www.newzbin.com - Sørg for at dit " #~ "brugernavn og kodeord er fastsat" #~ msgid "Expected size did not equal actual size" #~ msgstr "Forventede størrelse er ikke ligmed faktiske størrelse" #~ msgid "Could not compile regex: %s" #~ msgstr "Kunne ikke kompilere regex: %s" #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Hvis du har en konto til www.newzbin.com, kan du skrive " #~ "dine bruger informationer her.
    Dette vil frigøre ekstra funktionalitet." #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Du bliver nødt til at angive en adgangskode og genoptage jobbet." #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Pause job, når krypterede RAR er hentet" #~ msgid "Email Notifications" #~ msgstr "Email notifikationer" #~ msgid "Should downloading resume after the quotum is reset?" #~ msgstr "Skal download genoptages efter kvotaen er nulstillet?" #~ msgid "Quotum" #~ msgstr "Kvota" #~ msgid "Quotum left" #~ msgstr "Kvota tilbage" #~ msgid "Does the quotum get reset each day, week or month?" #~ msgstr "Bliver kvota nulstillet hver dag, uge ​​eller måned?" #~ msgid "Quotum period" #~ msgstr "Kvota periode" #~ msgid "" #~ "On which day of the month or week (1=Monday) does your ISP reset the quotum? " #~ "(Optionally with hh:mm)" #~ msgstr "" #~ "På hvilken dag i måneden eller ugen (1 = mandag) nulstiller din " #~ "internetudbyder kvota? (Valgfrit med tt: mm)" SABnzbd-0.7.20/po/main/de.po0000644000000000000000000040023712433712555015534 0ustar00usergroup00000000000000# German translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2013-12-10 20:10+0000\n" "Last-Translator: Clément Meur \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:54+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Fehler beim Starten der Weboberfläche." #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "" "Konnte Web-Vorlage nicht finden: %s Versuche die Standard-Vorlage zu " "verwenden." #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "_yenc-Modul nicht gefunden!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "par2-Programmdatei nicht gefunden!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "unrar-Programmdatei nicht gefunden!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "unzip-Programmdatei nicht gefunden!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Bitte beachten Sie, dass der 0.0.0.0-Hostname eine IPv6-Adresse benötigen " "wird für den externen Zugriff." #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS wegen fehlenden Zertifikats- und Schlüsseldateien deaktiviert." #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s gestartet" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnzbd wurde beendet" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s erkannt. Speichern und beenden..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "Hole msgid %s von www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Fehler beim Abrufen msgid %s from www.newzbin2.es - Bitte stelle sicher das " "Benutzername und Passwort korrekt eingestellt sind" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Versuche NZB-Datei von %s abzurufen" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Temporäre Datei für %s konnte nicht angelegt werden" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Versuche Status für nicht existierenden Server %s zu setzen" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Angehalten wegen zu wenig freiem Speicherplatz" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Fehler in tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Fehler beim Speichern von %s" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Fehler beim Laden von %s" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Benachrichtigungen testen" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Nichts" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Standard" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "WARNUNG:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "FEHLER:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "unbekannt" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "" "Kompilieren des regulären Ausdrucks für den Suchbegriff %s fehlgeschlagen." #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "t" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Festplatte voll! Downloads werden angehalten." #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Festplatten-Fehler beim Anlegen der Datei %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "WARNING: Paused job \"%s\" because of encrypted RAR file" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "WARNUNG: Job \"%s\" abgebrochen wegen verschlüsselter RAR Datei" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Abgebrochen, Verschlüsselung vorhanden" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s fehlt" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Kontingent aufgebraucht, Downloads werden angehalten" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s ist keine gültige E-Mail-Adresse" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Server-Adresse wird benötigt" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Kann kein %s Ordner %s erstellen" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Kann INI-Datei %s nicht schreiben" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Kann keine Sicherungsdatei erstellen für %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Ungültig kodiertes Passwort %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s ist kein gültiger Oktal-Wert" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "UNC-Pfad \"%s\" ist hier nicht erlaubt" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "" "Fehler: Ordner kann nicht geändert werden, da die Warteschlange nicht leer " "ist." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Ordner \"%s\" existiert nicht" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "SQL-Befehl fehlgeschlagen. Beachten Sie das Nachrichtenprotokoll." #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "SQL-Commit fehlgeschlagen. Beachten Sie das Nachrichtenprotokoll." #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "" "Fehler beim Schliessen der Datenbank. Beachten Sie das Nachrichtenprotokoll." #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Ungültiges Stufen-Protokoll im Verlauf für %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Fehler beim Dekodieren von %s." #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "CRC-Fehler in %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Ungültiger yEnc-Artikel in %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Unbekannter Fehler %s beim Dekodieren" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s wurde auf keinem Server gefunden und daher übersprungen" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Fehler beim Entfernen von %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "%s kann nicht gelesen werden" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Überwachter Ordner %s kann nicht gelesen werden" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Angehalten" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Server %s wird für %s Minuten ignoriert" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Initialisierung fehlgeschlagen %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Zu viele Verbindungen zum server %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Möglicherweise wird das Konto geteilt" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Anmelden beim Server fehlgeschlagen. %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Verbindung zum Server %s kann nicht hergestellt werden. %s" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Verbindung zu %s@%s:%s konnte nicht hergestellt werden. %s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Server %s benötigt ein Benutzername und ein Passwort" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Beenden..." #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Verbindung zum Mail-Server konnte nicht hergestellt werden" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Aufbau der TLS-Verbindung fehlgeschlagen" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Authentifizierung beim Mail-Server fehlgeschlagen" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Senden des E-Mails fehlgeschlagen" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Schliessen der Mail-Verbindung fehlgeschlagen" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "E-Mail erfolgreich versendet" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "In %s konnten keine E-Mail-Vorlagen gefunden werden" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Keine E-Mail gesendet da keine Empfänger angegeben" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Ungültige Kodierung der E-Mail-Vorlage %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Keine E-Mail-Vorlagen gefunden" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd meldet eine volle Festplatte\n" "\n" "Hallo,\n" "\n" "SABnzbd hat mit dem Herunterladen aufgehört, da die Festplatte fast voll \"\n" "ist.\n" "Bitte geben Sie manuell Speicherplatz frei und setzen Sie die Downloads \"\n" "danach fort.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Starten/Beenden" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "Hinzugefügte NZB" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Nachbearbeitung gestartet" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Auftrag ausgeführt" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Andere Nachrichten" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "" "Warnung: localhost ist mehrdeutig. Verwenden Sie eine numerische IP-Adresse." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Server-Adresse \"%s:%s\" ist ungültig." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Sitzungs-Schlüssel fehlt" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Fehler: Sitzungs-Schlüssel wird benötigt" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Fehler: Sitzungs-Schlüssel ungültig" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "API-Schlüssel fehlt. Bitte API-Schlüssel aus Einstellungen->Allgemein in die " "externe Anwendung eingeben:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API-Schlüssel ungültig. Bitte API-Schlüssel aus Einstellungen->Allgemein in " "die externe Anwendung eingeben:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Authentifizierung fehlt. Bitte Benutzernamen und Passwort aus Einstellungen-" ">Allgemein in die externe Anwendung eingeben:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Fehler: Keine sekundäre Oberfläche angegeben." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Das verwendete UNRAR-Programm wird nicht empfohlen. Laden Sie UNRAR " "stattdessen herunter von http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Kein UNRAR-Programm gefunden. Das Entpacken von RAR-Dateien ist nicht " "möglich
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Kein PAR2-Programm gefunden. Eine Reparatur ist nicht möglich
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Neustart wird durchgeführt...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd wurde beendet.
    Warten Sie 5 Sekunden und klicken Sie " "danach auf folgenden Knopf.

    Aktualisieren
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Täglich" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Montag" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Dienstag" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Mittwoch" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Donnerstag" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Freitag" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Samstag" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Sonntag" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "Aus" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Adresse wird aufgelöst..." #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Fehlerhafter Parameter" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Zurück" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Auftrag \"%s\" wurde wieder zur Warteschlange hinzugefügt" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "" "Aufträge, die mit '*' markiert sind, werden nicht automatisch " "heruntergeladen." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Entspricht" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Entspricht nicht" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Heruntergeladen" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Bis jetzt heruntergeladen" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Fehlerhafter Wert für %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Verzeichnis %s konnte nicht angelegt werden" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "Zugriff auf das Verzeichnis %s fehlgeschlagen: %s" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "" "Verbindung zu Registry-Umgebung HKEY_CURRENT_USER konnte nicht hergestellt " "werden." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Registry-Schlüssel %s konnte nicht geöffnet werden." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Lesen der Registry-Schlüssel für spezielle Ordner fehlgeschlagen." #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Erstellen von %s fehlgeschlagen" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Verschieben von %s nach %s fehlgeschlagen" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Ungültige NZB-Datei." #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Erneut versuchen" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Abrufen der URL fehlgeschlagen; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "pyopenssl-Modul fehlt. Bitte installieren für SSL-Unterstützung." #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Fehler beim Anlegen des SSL-Schlüssels und -Zertifikats." #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Rechte von %s konnten nicht geändert werden" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Zusammenfügen" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Unvollständiger Ablauf beim zusammenführen von Dateien" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Fehler beim Zusammenfügen von %s" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fehler \"%s\" beim Zusammenfügen der Dateien" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Fehler \"%s\" beim Ausführen von file_join auf %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] %s Dateien zusammengefügt" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Entpacken fehlgeschlagen. %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fehler \"%s\" beim Entpacken der RAR-Dateien" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fehler \"%s\" beim Ausführen von rar_unpack auf %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Löschen von %s fehlgeschlagen!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Versuche entpacken mit Passwort \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Entpacken fehlgeschlagen. Archiv benötigt ein Passwort." #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Entpacken" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Entpacken fehlgeschlagen. Konnte %s nicht finden." #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "%s konnte nicht gefunden werden." #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Entpacken fehlgeschlagen. CRC-Fehler" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "CRC-Fehler in %s." #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "" "Entpacken fehlgeschlagen. Fehler beim Schreiben oder volle Festplatte?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "Fehler beim Schreiben: %s" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Entpacken fehlgeschlagen, Pfad ist zu lang" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "Fehler: Pfad ist zu lang (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Entpacken fehlgeschlagen. Beachten Sie das Protokoll." #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "Fehler: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Erwartete Datei %s nicht gefunden. Unrar-Fehler?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Entpacken fehlgeschlagen. Eine erwartete Datei wurde nicht entpackt." #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Entpacken fehlgeschlagen. Diese Dateien fehlten:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "%s Datei(en)/Ordner entpackt in %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s Dateien in %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Fehler \"%s\" beim Ausführen von unzip auf %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Schnelle Überprüfung" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Reparieren" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Schnelle Überprüfung erfolgreich" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Beginn der Reparatur" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparatur fehlgeschlagen. %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Fehler \"%s\" beim Ausführen von par2_repair auf %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fehler \"%s\" beim Ausführen von par2_repair auf dem Satz %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] Ungültige PAR2-Optionen. Überprüfen Sie die Angaben in Einstellungen -> " "Schalter." #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Überprüft in %s. Alle Dateien fehlerfrei." #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Überprüft in %s. Reparatur wird benötigt." #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Hauptpaket nicht gefunden..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Ungültige PAR2-Dateien. Überprüfung oder Reparatur nicht möglich." #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Reparatur fehlgeschlagen. Nicht genug Reparatur-Blöcke vorhanden (%s zu " "wenig)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "%s Blöcke werden abgerufen..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Abrufen" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Reparieren" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Repariert in %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Überprüfen" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "" "Fehler beim Importieren des OpenSSL-Moduls. Stelle Verbindung ohne SSL her." #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Aktualisieren des Newzbin-Auftrages %s fehlgeschlagen." #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB zur Warteschlange hinzugefügt" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Das Protokoll des Newzbin-Servers wurde geändert" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Ihr Newzbin-Konto verfügt über keine Credits." #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "" "Zugriff verweigert. Überprüfen Sie den Newzbin-Benutzernamen und -Passwort" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin-Bericht %s nicht gefunden" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin gibt einen undokumentierten Fehler-Code zurück: (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Newzbin-Server konnte keine Informationen zu %s bereitstellen" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Newzbin-Lesezeichen %s konnte nicht gelöscht werden." #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin gibt einen undokumentierten Fehler-Code zurück: (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "" "Inkompatible Warteschlangen-Datei gefunden. Fortsetzen nicht möglich." #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Fehler beim Laden von %s. Beschädigte Datei gefunden." #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Fehler beim Hinzufügen von %s. Entferne." #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Unbekannte Kodierung" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Die Datei %s ist leer und wird daher übersprungen" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Importieren von %s Dateien von %s fehlgeschlagen" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Unvollständige NZB-Datei %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Ungültige NZB-Datei %s wird übersprungen: %s auf Zeile %s" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Leere NZB-Datei %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Doppelte NZB \"%s\" wird ignoriert" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Doppelt vorhandene NZB \"%s\" angehalten" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Abgebrochen, kann nicht fertiggestellt werden" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLIKAT" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "VERSCHLÜSSELT" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "ZU GROSS" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "UNVOLLSTÄNDIG" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "WARTE %s Sek" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "" "Heruntergeladen in %s mit einer Durchschnittsgeschwindigkeit von %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s Artikel hatten ein ungültiges Format" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s Artikel fehlten" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s Artikel hatten nicht übereinstimmende Duplikate" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s Artikel wurden entfernt" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Fehler beim Importieren von %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Warnungen" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Leerlauf" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Einstellungen" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Warteschlange" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Warteschlange leeren" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Verlauf" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Verlauf leeren" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Geschwindigkeit begrenzen" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Anhalten" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "Min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Fortsetzen" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Newzbin-Lesezeichen abrufen" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Überwachter Ordner lesen" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Fertige Downloads" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Unfertige Download" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Fehler suchen" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Neu starten" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Neustart ohne Anmeldung" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Beenden" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Warteschlange mit den 10 obersten Einträgen" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Leer" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Verlauf mit den letzten 10 Einträgen" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Neue Version verfügbar" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Assistent öffnen" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Beenden..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problem mit" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd funktioniert nicht in Kombination mit manchen Software-" "Firewalls.
    \n" " %s
    \n" " Dieses Problem können Sie zur Zeit nicht selber lösen.
    \n" " Beschweren Sie sich bitte beim Hersteller der Firewall.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " Für seinen internen Web-Server benötigt SABnzbd einen freien TCP/IP-" "Port.
    \n" " Port %s auf %s wurde probiert, ist aber nicht verfügbar.
    \n" " Entweder verwendet eine andere Software den Port oder SABnzbd läuft " "bereits.
    \n" "
    \n" " Starten Sie SABnzbd bitte mit einer anderen Portnummer neu." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "" "Wenn Sie diesen Fehler wieder erhalten, probieren Sie eine andere Nummer.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " Für seinen internen Web-Server benötigt SABnzbd einen freien TCP/IP-" "Port.
    \n" " Port %s auf %s wurde probiert, aber das für SABnzbd verwendete Konto " "darf ihn nicht verwenden.
    \n" " Auf OS X und Linux-Systemen müssen normale Benutzer Ports über 1023 " "verwenden.
    \n" "
    \n" " Starten Sie SABnzbd bitte mit einer anderen Portnummer neu." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " Für seinen internen Web-Server benötigt SABnzbd eine gültige Rechner-" "Adresse.
    \n" " Sie haben eine ungültige Adresse angegeben.
    \n" " Sichere Werte sind localhost und 0.0.0.0
    \n" "
    \n" " Starten Sie SABnzbd bitte mit einer gültigen Rechner-Adresse neu." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd hat die gespeicherten Daten einer anderen SABnzbd-Version " "erkannt,
    \n" " kann diese aber nicht wiederverwenden.

    \n" " Es wird empfohlen, die ausstehenden Downloads mit der anderen Version " "fertigzustellen.

    \n" " Starten Sie dieses Programm danach mit der \"--clean\"-Option.
    \n" " Dies löscht die Download-Warteschlange und den Download-Verlauf!
    \n" " SABnzbd hat die Datei \"%s\" gelesen." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd kann die Dateien für die Web-Oberfläche in %s nicht finden.
    \n" " Installieren Sie bitte das Programm erneut.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd hat einen schwerwiegenden Fehler erkannt:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd hat den Verlauf und die Warteschlange einer älteren Version " "(0.4.x) erkannt.

    \n" " Beide werden ignoriert und können verloren gehen!

    \n" " Es wird empfohlen, SABnzbd anzuhalten und die ausstehenden Downloads mit " "der älteren Version fertigzustellen.

    \n" " Wählen Sie OK, um fortzufahren." #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd hat erkannt, dass die Datei sqlite3.dll fehlt.

    \n" " Manche unausgereiften Viren-Scanner löschen diese Datei.
    \n" " Bitte überprüfen Sie den Viren-Scanner, versuchen Sie eine " "Neuinstallation von SABnzbd und beschweren Sie sich beim Hersteller des " "Viren-Scanners.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Drücken Sie Start+R und geben Sie folgenden Zeile ein (Beispiel):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Öffnen Sie ein Terminal und geben Sie folgende Zeile ein (Beispiel):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Sie verwenden wahrscheinlich ZoneAlarm auf Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Programm wurde nicht gestartet!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Sie haben nicht die Berechtigung, Port %s zu verwenden" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Schwerwiegender Fehler" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "" "Der Standard-Browser konnte nicht gestartet werden, da er wahrscheinlich " "nicht gefunden wurde." #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Zugriff verweigert" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "" "Fehler %s: Sie müssen einen gültigen Benutzername und ein Passwort angeben." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Laden der Nachbearbeitungs-Warteschlange fehlgeschlagen: Falsche Version " "(benötige %s anstatt %s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "" "Fehler beim Entfernen der NZB-Datei von der Nachbearbeitungs-Warteschlange " "(id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "" "Download wahrscheinlich fehlgeschlagen, nur %s von benötigten %s verfügbar" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Fehler beim Herunterladen. Ist die Datei zu alt?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Konnte Download-Ordner %s nicht anlegen" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Keine Nachbearbeitung wegen fehlgeschlagener Überprüfung" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Verschieben" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "%s wurde an die Warteschlange gesendet" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Fehler beim Umbenennen von \"%s\" nach \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Dateien verschieben fehlgeschlagen" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Ausführen des Skripts" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Ausführen des Benutzer-Skripts %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "%s ausgeführt" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Mehr" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Skript-Ausgabe anzeigen" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Download fertig" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Download Fehlgeschlagen" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Nachbearbeitung von %s fehlgeschlagen (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "Beachten Sie die Protokolldatei" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Nachbearbeitung wurde abgebrochen (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Aufräumen von %s fehlgeschlagen" #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Fehler beim Entfernen des Arbeitsverzeichnisses %s." #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Nachbearbeitung" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Keine PAR2-Sätze" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Versuche SFV-Überprüfung" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Überprüfung einiger Dateien mittels %s fehlgeschlagen" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Überprüfung mit SFV-Datei(en) erfolgreich" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Entfernen von %s fehlgeschlagen" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Fehler beim Wechsel in den Ruhezustand" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Fehler beim Wechsel in den Bereitschaftsmodus" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Fehler beim Herunterfahren des Systems" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Ungültige RSS-Feed-Beschreibung \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Abrufen des RSS-Feeds von %s fehlgeschlagen: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Keine gültige Berechtigung für Feed %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "RSS-Feed %s war leer" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Inkompatibeler RSS-Feed" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Leerer RSS-Feed gefunden: %s" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Interface anzeigen" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Öffne Zielverzeichnis" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Beenden" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Verbleibend" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Ungültige Regel %s um %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Unbekannte Aktion: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Regel für nicht existierenden Server %s." #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Herunterladen" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Dateien zusammenfügen" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Entpacken" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Skript" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Quelle" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Fehler" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Fertiggestellt" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Fehlgeschlagen" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Warten" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparieren..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Entpacken..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Verschieben..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Ausführen des Skripts..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Abrufen von zusätzlichen Blöcken..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Schnelle Überprüfung..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Überprüfen..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Am herunterladen" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "NZB abrufen" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Wird überprüft" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Häufigkeit" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Aktion" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argumente" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Aufgabe" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "Server deaktivieren" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "Server aktivieren" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Geschwindigkeitsbegrenzung" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Alle anhalten" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Nachbearbeiten anhalten" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Nachbearbeiten fortsetzen" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "RSS-Feeds lesen" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Entferne fehlgeschlagene Jobs" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "Stunde" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "Stunden" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "Minuten" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "Minuten" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "Sekunde" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "Sekunden" #: sabnzbd/skintext.py:79 msgid "day" msgstr "Tag" #: sabnzbd/skintext.py:80 msgid "days" msgstr "Tage" #: sabnzbd/skintext.py:81 msgid "week" msgstr "Woche" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Monat" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "Jahr" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Tag im Monat" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Diese Woche" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Dieser Monat" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Heute" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Gesamt" #: sabnzbd/skintext.py:97 msgid "on" msgstr "An" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parameter" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Python Version" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Startseite" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "oder" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Adresse" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Automatisiertes Programm für Usenet-Downloads" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Speichern" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "In der Warteschlange" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Sind Sie sicher?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Alle heruntergeladenen Dateien löschen?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Startseite" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Einstellungen" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Status" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Hilfe" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Allgemein" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Ordner" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Schalter" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Server" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Planung" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Benachrichtigungen" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "E-Mail" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Index-Seiten" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Kategorien" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortierung" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Spezial" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Downloads" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Fertige Downloads" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Geschwindigkeit" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "ANGEHALTEN" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "%s Artikel im Cache (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Systemlast" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "WARNUNGEN" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Neue Version %s verfügbar unter" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Neue Downloads hinzufügen" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Möchten Sie SABnzbd wirklich beenden?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Hinzufügen einer" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "ID" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Datei hinzufügen" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Kategorie" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Verarbeiten" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Priorität" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparieren" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Entpacken" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Löschen" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "E" #: sabnzbd/skintext.py:177 msgid "D" msgstr "L" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Erzwingen" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Hoch" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Gering" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Anhalten" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " oder Report-ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Nach Name sortieren" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Nach Alter sortieren" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Nach Größe sortieren" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Dateien verbergen" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Dateien anzeigen" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Wenn fertig" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Rechner ausschalten" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Rechner in Bereitschaft versetzen" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Rechner in den Ruhezustand versetzen" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "SABnzbd beenden" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Geschwindigkeitsbegrenzung" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Anhalten für" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Reihenfolge" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Name" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Verbleibend/Insgesamt" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "ETA" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "Alter" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Löschen" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Erneut versuchen" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Aktionen" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Skripte" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Alle Elemente in der Warteschlange löschen?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "NZBs löschen" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "NZBs und Dateien löschen" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "NZB löschen" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "NZBs und Dateien löschen" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "von" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Fehlende Artikel" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Verbleibendes Kontingent" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "Manuell" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Kontingent jetzt zurücksetzen" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Fehlgeschlagene aus Verlauf entfernen" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Alle fertigen Downloads aus dem Verlauf entfernen?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Alle fehlgeschlagenen Downloads aus dem Verlauf entfernen?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Details verbergen" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Details anzeigen" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Grösse des Verlaufs" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Nur Fehlgeschlagene" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Alle anzeigen" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Grösse" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Fehlgeschlagene NZBs löschen" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Fehlgeschlagene NZBs und Dateien löschen" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Fertige NZBs löschen" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Optionale ergänzende NZB-Datei" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Pfad" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Verbindung trennen" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Sendet eine Test-E-Mail an Ihr Konto." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Protokoll anzeigen" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Web-Protokoll anzeigen" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "E-Mail testen" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Protokoll" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Fehler/Warnungen" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Fehlersuche" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Verbindungen" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Thread" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Resultat des E-Mail-Tests" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Neuste Warnungen" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "Leeren" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Freigeben" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Artikelbezeichner" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Dateimenge" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Wann" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Typ" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Warnung" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Aktiv" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Konfigurationsdatei" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Verwendeter Cache" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Ein Klick auf den Knopf \\\"Neu starten\\\" startet SABnzbd neu.
    \r\n" "Benutzen Sie ihn, falls ein Stabilitätsproblem vorliegt.
    \r\n" "Die Downloads werden vor dem Neustart angehalten und danach fortgesetzt." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Der Download-Ordner enthält verwaiste Aufträge.
    Diese können gelöscht " "(zusammen mit den Dateien) oder zurück in die Warteschange verschoben werden." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "Ein Klick auf den Knopf \"Reparieren\" startet SABnzbd neu
    und baut die " "Warteschlange neu auf, wobei bereits
    heruntergeladene Dateien bestehen " "bleiben. Die Reihenfolge
    der Warteschlange wird dabei verändert." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Version" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Zeit seit Start" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Sicherheitskopie" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Allgemeine Einstellungen" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Änderungen benötigen einen Neustart von SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "SABnzbd-Webserver" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "SABnzbd-Host" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Host, auf dem SABnzbd auf Anfragen warten soll." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "SABnzbd-Port" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Port, auf dem SABnzbd auf Anfragen warten soll." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Web-Oberfläche" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Gestaltung der Web-Oberfläche verändern." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Sekundäre Weboberfläche" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Gestaltung der sekundären Web-Oberfläche verändern." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Authentifizierung für Web-Server" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "SABnzbd-Benutzername" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Optionaler Benutzername für Authentifizierung." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "SABnzbd-Passwort" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Optionales Passwort für Authentifizierung." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "HTTPS-Unterstützung" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "HTTPS aktivieren" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "nicht installiert" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Zugriff auf die Oberfläche über HTTPS-Adressen erlauben" #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "HTTPS-Port" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Wenn leer, hört der Standard-Port nur auf HTTPS-Anfragen." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "HTTPS-Zertifikat" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Dateiname oder Pfad des HTTPS-Zertifikats." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "HTTPS-Schlüssel" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Dateiname oder Pfad des HTTPS-Schlüssels." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Feinabstimmung" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Warteschlange automatisch neu laden" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Zeitintervall zwischen dem erneuten Laden der Warteschlange (in Sekunden). 0 " "schaltet die Funktion ab." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "RSS-Überprüfung" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Überprüfungs-Intervall (in Minuten, mindestens 15). Nicht aktive wenn Regeln " "aktiv sind!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Begrenzung der Downloadgeschwindigkeit" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "In KB/s, Kilobytes pro Sekunde." #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Begrenzung des Artikel-Caches" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Artikel werden zwischengespeichert, um die Anzahl der Zugriffe auf die " "Festplatte zu reduzieren.
    In Bytes, gefolgt von einem optionalen K, " "M oder G. Zum Beispiel: \"64M\" oder \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Unerwünschte Dateien" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Liste der Dateiendungen, die nach dem Herunterladen gelöscht werden " "sollen.
    Zum Beispiel: .nfo or .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Änderungen speichern" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Sprache" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Wählen Sie die Sprache der Weboberfläche." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "API-Schlüssel" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Dieser Schlüssel gibt Drittprogrammen uneingeschränkten Zugriff auf SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "NZB-Schlüssel" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Dieser Schlüssel erlaubt Drittprogrammen das Hinzufügen von NZB-Dateien zu " "SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Neuen Schlüssel generieren" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "API-Key deaktivieren" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Keinen API-Schlüssel verwenden." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "AUF EIGENE GEFAHR VERWENDEN!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "QR-Code" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "API-Key OR-Code" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Ordner-Einstellungen" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "HINWEIS: Ordner werden beim Speichern automatisch erstellt. Sie " "können absolute Pfade angeben, um Ordner ausserhalb der standardmässigen " "Ordner zu verwenden." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Benutzer-Ordner" #: sabnzbd/skintext.py:345 msgid "In" msgstr "In" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Temporärer Download-Ordner" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Hier werden noch nicht verarbeitete Downloads abgelegt.
    Kann nur " "geändert werden wenn die Warteschlange leer ist." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimaler freier Speicherplatz im temporären Ordner" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "SABnzbd hält automatisch an, wenn der freie Speicherplatz unter diesen Wert " "fällt.
    In Bytes, gefolgt von einem optionalen K, M oder G. Zum " "Beispiel: \"800M\" or \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Ordner für fertige Downloads" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Hier werden fertige, verarbeitete Downloads abgelegt.
    Kann von " "benutzerdefinierten Kategorien ausser Kraft gesetzt werden." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Rechte für fertige Downloads" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Rechte für Dateien und Ordner festlegen.
    In oktaler Notation. Zum " "Beispiel: \"755\" oder \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Überwachter Ordner" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Ordner, der auf neue NZB-Dateien überwacht werden soll.
    Erkennt auch " "ZIP-, RAR- und TAR.GZ-Archive mit NZB-Dateien." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Geschwindigkeit der Ordner-Überwachung" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Anzahl der Sekunden zwischen zwei Überprüfungen." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Ordner mit Nachbearbeitungs-Skripts" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "" "Ordner, der benutzerdefinierte Skripts für die Nachbearbeitung von Downloads " "enthält." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Ordner mit E-Mail-Vorlagen" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Ordner, der benutzerdefinierte E-Mail-Vorlagen enthält." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Passwortdatei" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Datei mit allen Passwörtern, die bei verschlüsselten RAR-Dateien probiert " "werden sollen." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "System-Ordner" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Administrativer Ordner" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Ordner, der die für die Warteschlange und den Verlauf verwendeten " "Datenbanken enthält.
    Kann nur geändert werden, wenn die " "Warteschlange leer ist." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Es werden keine Dateien entfernt. Benötigt einen Neustart von " "SABnzbd!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Protokoll-Ordner" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Hier werden Protokoll-Dateien von SABnzbd abgelegt.
    Benötigt einen " "Neustart von SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "NZB-Backup-Ordner" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Hier werden NZB-Dateien abgelegt." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Standardmässiger Basis-Ordner" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Verschiedene Schalter" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Verarbeitungs-Schalter" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Schnelle Überprüfung aktivieren" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "PAR2-Überprüfung überspringen, wenn die Dateien 100% korrekt sind." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "unrar aktivieren" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Eingebaute Entpack-Funktion für RAR-Archive aktivieren." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "unzip aktivieren" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Eingebaute Entpack-Funktion für ZIP-Archive aktivieren." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Zusammenfügen von Dateien aktivieren" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "" "Dateien, die mit .001, .002 usw. enden, zu einer Datei zusammenfügen." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Zusammenfügen von TS-Dateien aktivieren" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "" "Dateien, die mit .001.ts, .002.ts usw. enden, zu einer Datei zusammenfügen." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "PAR-Dateien aufräumen" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "" "PAR-Dateien entfernen, wenn die Überprüfung und Reparatur erfolgreich war." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "yEnc-CRC-Fehler nicht ignorieren" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "Bei yEnc-CRC-Fehlern Ersatz-Server verwenden." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Nur Artikel für obersten Warteschlangen-Eintrag herunterladen" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Für geringere Speicher-Verwendung aktivieren.
    Deaktivieren, um zu " "verhindern, dass langsame Aufträge
    die anderen Einträge in der " "Warteschlange blockieren." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Nur überprüfte Aufträge nachbearbeiten" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Die Nachbearbeitung nur für Aufträge durchführen,
    die alle PAR2-" "Überprüfungen bestanden haben." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Aktion wenn eine verschlüsselte RAR Datei geladen wird" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Im Fall von \"Pause\" müssen Sie ein Kennwort setzen und den Job fortsetzen." #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Doppelte Downloads erkennen" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "NZB-Dateien mit identischem Namen sowie doppelt vorhandende Titel in RSS-" "Feeds erkennen (benötigt NZB-Backup-Option)." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Nein" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Verwerfen" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Abbrechen" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "SFV-basierte Überprüfung aktivieren" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Zusätzliche Überprüfung mittels SFV-Dateien durchführen" #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Resultat des Entpackens überprüfen" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Resultat des Entpackens überprüfen (muss bei manchen Dateisystemen " "deaktiviert sein)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Ordner-Umbenennung aktivieren" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Temporäre Namen während der Nachbearbeitung verwenden. Deaktivieren, wenn " "das System nicht damit klar kommt." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Standardmässige Nachbearbeitung" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "" "Wird verwendet, wenn die Kategorie keine Nachbearbeitung vorschreibt." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Standardmässiges Benutzer-Skript" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Wird verwendet, wenn die Kategorie kein Benutzer-Skript vorschreibt." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Benutzer-Skript vor Warteschlange" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "" "Wird verwendet, bevor eine NZB-Datei zur Warteschlange hinzugefügt wird." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Standardmässige Priorität" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Wird verwendet, wenn die Kategorie keine Priorität vorschreibt." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Mehrkernprozessor-Unterstützung von PAR2 verwenden" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Lesen Sie dazu die Hilfe im Wiki!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Zusätzliche PAR2-Parameter" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Nice-Parameter" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "IONice-Parameter" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Andere Schalter" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Bei leerer Warteschlange Verbindung trennen" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Verbindung zu Usenet-Servern trennen,
    wenn die Warteschlange leer ist " "oder SABnzbd angehalten wurde." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Gruppe senden" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Gruppen-Befehl senden, bevor Artikeln angefordert werden." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Nach Alter sortieren" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "" "Einträge automatisch nach ihrem (durchschnittlichen) Alter sortieren." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Auf neue Version prüfen" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Wöchentlich überprüfen, ob eine neue SABnzbd-Version verfügbar ist." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Auch Test-Veröffentlichungen" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Leerzeichen in Ordnernamen ersetzen" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Leerzeichen in Ordnernamen durch Unterstriche ersetzen." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Punkte in Ordner-Namen ersetzen" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Punkte in Ordner-Namen durch Leerzeichen ersetzen." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Ungültige Zeichen in Ordnernamen ersetzen" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Ungültige Zeichen in Ordnernamen durch äquivalente Zeichen ersetzen
    (oder ansonsten entfernen)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Browser beim Start öffnen" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Den Standard-Browser öffnen, wenn SABnzbd gestartet wird." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Downloads während der Nachbearbeitung anhalten" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Hält die Downloads zu Beginn der Nachbearbeitung an
    und setzt sie " "danach fort." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Beispieldateien ignorieren" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Beispieldateien herausfiltern (z.B. Videoausschnitte)" #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Nach dem Download löschen" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Nicht herunterladen" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "SSL-Typ" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "V23 verwenden, ausser wenn der Provider etwas anderes benötigt." #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "12-Stunden-Uhr verwenden (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Zeiten in der AM/PM-Notation anzeigen (betrifft die Regeln nicht)." #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Server" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Nachbearbeitung" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Benennung" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Kontingent" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Wie viel kann in diesem Monat heruntergeladen werden (K/M/G)?" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Tag zurücksetzen" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "An welchem Tag des Monats oder der Woche (1=Montag) setzt Ihr ISP das " "Kontingent zurück (optional mit hh:mm)?" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Automatisch fortsetzen" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "" "Soll wieder Heruntergeladen werden, nachdem das Kontingent zurückgesetzt " "wurde?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Kontingents-Periode" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "" "Wird das Kontingent jeden Tag, jede Woche oder jeden Monat zurückgesetzt?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Vor dem Herunterladen überprüfen" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Versuche die erfolgreiche Fertigstellung noch vor dem Herunterladen " "vorherzusagen (langsamer!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Maximale Wiederholungen" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Maximale Anzahl wiederholter Versuche pro Server" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Nur für optionale Server" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Die Anzahl Wiederholungen nur auf optionale Server anwenden" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Jobs abbrechen die nicht abgeschlossen werden können" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Job abbrechen falls während des Downloads klar wird, dass zuviele Daten " "fehlen" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Server-Einstellungen" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Server-Definition" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Server hinzufügen" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Benutzername" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Passwort" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Zeitüberschreitung" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Rückhaltezeit" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Ersatz-Server" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Optional" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Aktivieren" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Server entfernen" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Server überprüfen" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Zähler zurücksetzen" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Server-Angaben werden überprüft..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Unten Klicken zum Überprüfen." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Bandbreite" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Planung" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Regel hinzufügen" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Entfernen" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Aktuelle Regeln" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "RSS-Einstellungen" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Neue Feed-URL" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Aktivieren Sie das Feld neben dem Feed-Namen, wenn automatisch auf neue " "Einträge geprüft werden soll.
    Wenn ein Feed hinzugefügt wird, werden " "nur neue Einträge verarbeitet und nicht diejenigen, die bereits im RSS-Feed " "enthalten waren, ausser Sie klicken \"Download erzwingen\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Feed hinzufügen" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Feed löschen" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Feed lesen" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Download erzwingen" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filter" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Überspringen" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Akzeptieren" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Verwerfen" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Benötigt" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "Benötigt Kategorie" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Entspricht nicht" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Feeds" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Jetzt alle Feeds lesen" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Einstellungen" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filter" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Email-Optionen" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Email-Benachrichtigung beim Fertigstellen von Aufträgen" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Nie" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Immer" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Nur bei Fehlern" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Benachrichtigung bei voller Festplatte" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "E-Mail senden, wenn die Festplatte voll ist und SABnzbd angehalten wird." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "RSS-Benachrichtigungen senden" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" "E-Mail senden, wenn ein RSS-Feed einen Auftrag zur Warteschlange hinzufügt." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "E-Mail-Kontoeinstellungen" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "SMTP-Server" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "ISP-Server für ausgehende E-Mails angeben." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "E-Mail-Empfänger" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "E-Mail-Adresse, an die die E-Mails gesendet werden." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "E-Mail-Absender" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Wer soll die E-Mail versandt haben?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "Optionaler Konto-Benutzername" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Für authentifizierte E-Mails wird der Kontoname benötigt." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "Optionales Konto-Passwort" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Für authentifizierte E-Mails wird das Passwort benötigt." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Growl aktivieren" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Benachrichtigungen an Growl senden" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Server-Adresse" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Nur für entfernten Growl-Server verwenden (Rechnername:Port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Server-Passwort" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Optionales Passwort für den Growl-Server" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "NotifyOSD aktivieren" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Benachrichtigungen an NotifyOSD senden" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Benachrichtigungscenter" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Benachrichtigung an Benachrichtigungscenter schicken" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Benachrichtigungsarten" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Benachrichtigung für Nachrichtengruppen aktivieren (keine, eine oder " "mehrere)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Wenn Sie ein Konto bei www.newzbin2.es haben, können Sie " "hier Ihre Zugangsdaten eingeben.
    Dies wird Zusatzfunktionen " "freischalten." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Konto-Informationen" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Newzbin-Benutzername" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Hier den Konto-Benutzernamen eingeben." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Newzbin-Passwort" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Hier das Konto-Passwort eingeben." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Verarbeiten von Lesezeichen" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Lesezeichen automatisch abrufen" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Automatisch Aufträge basierend Ihren Lesezeichen erzeugen." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Jetzt Lesezeichen abrufen" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Lesezeichen ausblenden" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Lesezeichen anzeigen" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Lesezeichen entfernen, wenn der Download fertig ist" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "" "Lesezeichen aus der Lesezeichenliste entfernen, wenn der Download fertig ist." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Überprüfungs-Interval" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "In Minuten (mindestens 15 Minuten)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Verarbeitete Lesezeichen" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Wenn Sie ein Konto bei www.nzbmatrix.com haben, können Sie " "die entsprechenden Informationen hier eintragen.
    Dies wird benötigt, " "wenn Sie RSS-Feeds von dieser Seite verwenden möchten." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "NzbMatrix-Benutzername" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "NzbMatrix-API-Schlüssel" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Hier den API-Schlüssel eingeben." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Benutzerdefinierte Kategorien" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Beeinflusst die Nachbearbeitung und Speicherung von Downloads." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Verwenden Sie die Spalte \"Gruppen/Indexer-Tags\", um Gruppen und Tags mit " "Kategorien in Verbindung zu setzen.
    \r\n" "Wildcards werden unterstützt. Terme können mit Kommas getrennt werden." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Ein Sternchen * am Pfad-Ende verhindert die Erzeugung von Auftrags-Ordnern." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Relative Ordner basieren auf" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Ordner/Pfad" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Gruppen/Indexer-Tags" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Sortier-Einstellungen" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Sortieren von TV-Serien" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "TV-Sortierung aktivieren" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Sortieren und Umbenennen von Episoden aktivieren." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Muster-Schlüssel" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Löschen" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Voreinstellungen" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Beispiel" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Allgemeines Sortieren" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Film-Sortierung aktivieren" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Allgemeines Sortieren und Umbenennen von Dateien aktivieren." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Unbestimmte Downloads in einem zusätzlichen Ordner speichern." #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "" "Aktivieren, wenn Downloads nicht in ihre eigenen Ordner abgelegt werden." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Betroffene Kategorien" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Bedeutung" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Muster" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Staffel-Ordner" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Staffel-Ordner" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Episoden-Ordner" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Episoden-Ordner" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Film Name" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Film.Name" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Film_Name" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Sendungs Name" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Sendungs.Name" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Sendungs_Name" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Staffel-Nummer" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Episoden-Nummer" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Episoden-Name" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Episoden.Name" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Episoden_Name" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Dateiendung" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Endung" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Teilnummer" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Jahrzehnt" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Ursprünglicher Dateiname" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Ursprünglicher Ordnername" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Kleinschreibung" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py:667 msgid "text" msgstr "text" #: sabnzbd/skintext.py:668 msgid "file" msgstr "Datei" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "Ordner" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Sortieranweisung" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Markierung für mehrere Teile" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "In Ordnern" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Keine Ordner" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Sortieren nach Datum" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Sortieren nach Datum aktivieren" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "" "Sortieren und Umbenennen von Dateien mit Daten im Dateinamen aktivieren." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Ordner mit Name der Sendung" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Jahr-Monat-Ordner" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Tägliche Ordner" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "Groß- / Kleinschreibung berücksichtigen" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Ergebnis" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Selten genutzte Funktionen. Bedeutung und Erklärungen finden Sie per klick " "auf den Hilfe-Button um auf die Wiki-Seite zu gelangen.
    Änder nichts ohne " "vorher das Wiki gelesen zu haben, da sonst schwerwiegende Nebeneffekte " "auftreten können.
    Die Ursprungswerte stehen zwischen den runden Klammern." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Werte" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "NZB-Details bearbeiten" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Löschen" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Ganz nach oben" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Nach oben" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Nach unten" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Ganz nach unten" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Alle" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Invertieren" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Dateiname" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Betreff" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Alter" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Auswahl" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Möchten Sie wirklich löschen" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Neu laden" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Optionen" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Seite" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Zurück" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Weiter" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Anfang" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Ende" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Schliessen" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Eine bestimmte Zeit lang anhalten" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sortieren" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Warteschlange leeren?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Anhalten" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "5 Minuten anhalten" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "15 Minuten anhalten" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "30 Minuten anhalten" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Eine Stunde anhalten" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "3 Stunden anhalten" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "6 Stunden anhalten" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "12 Stunden anhalten" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "24 Stunden anhalten" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sortieren nach Alter Älteste→Neuste" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sortieren nach Alter Neuste→Älteste" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sortieren nach Name A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sortieren nach Name Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sortieren nach Grösse Kleinste→Grösste" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sortieren nach Grösse Grösste→Kleiste" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Umbenennen" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Verbleibend" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Verlauf wirklich leeren?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Die Änderungen wurden nicht gespeichert und werden verloren gehen." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Open Source-URL" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Open Informational-URL" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Speicherort" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Skript-Protokoll anzeigen" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Sie müssen JavaScript aktivieren, damit Plush funktioniert!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "NZB hinzufügen" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Plush-Einstellungen" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Neue Version verfügbar!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Wie viele Minuten angehalten werden soll." #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Anhalten für..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Mehrfach-Funktionen" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Hauptmenü" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Wenn fertig" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sortieren nach Alter Älteste→Neuste" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sortieren nach Alter Neuste→Älteste" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sortieren nach Name A→Z" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sortieren nach Name Z→A" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sortieren nach Grösse Kleinste→Grösste" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sortieren nach Grösse Grösste→Kleiste" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Leeren" #: sabnzbd/skintext.py:781 msgid "left" msgstr "rest" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Maximale
    Geschwindigkeit" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Bereich" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Zurücksetzen" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Auf Auswahl anwenden" #: sabnzbd/skintext.py:786 msgid "page" msgstr "Seite" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Alles" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Deaktiviert" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Aktualisierungsrate" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Breite" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Löschen von Downloads bestätigen" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Löschen von Verlaufeinträgen bestätigen" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Verhindert, dass die Inhalte aktualisiert werden, wenn sich der Mauszeiger " "über der Warteschlange befindet." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Aktualisierung durch Mauszeiger verhindern" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Abrufen" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Hochladen" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Hochladen: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Wahlweise einen Dateinamen angeben:" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Fortschritt" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Nicht genug freier Speicherplatz für fertige Downloads!" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Freier Speicherplatz" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Freier Speicherplatz (Ordner mit temporären Dateien)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "LEERLAUF" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Downloads" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Reparatur der Warteschlange" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Feed lesen ruft den momentanen Inhalt des Feeds ab. " "Download erzwingen lädt sogleich alle passenden NZB-Dateien " "herunter." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Stunde:Min" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Fertige entfernen" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "" "Möchten Sie alle fehlergeschlagenen Downloads aus dem Verlauf löschen?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Fehlgeschlagene entfernen" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Links" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Einträge %s bis %s von insgesamt %s werden angezeigt" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Keine Ergebnisse" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Ein Resultat wird angezeigt" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "E-Mail gesendet!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Benachrichtigung gesendet!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Speichern..." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Gespeichert" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Geschwindigkeit" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "NZB hinzufügen" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "DualView 1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "DualView 2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Benutzerdefiniert" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Lesezeichen abrufen" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Möchten Sie SABnzbd wirklich neu starten?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Aktualisierungsrate" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Alle löschen" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Bearbeitungs-Einstellungen verbergen" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Bearbeitungs-Einstellungen anzeigen" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Bearbeiten" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Verbleibend" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd-Einrichtungsassistent" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "SABnzbd-Version" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Zurück" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Zugriff" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "Alle Rechner in meinem Netzwerk sollen auf SABnzbd zugreifen können." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Nur mein Rechner soll auf SABnzbd zugreifen können." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Passwortgeschützter Zugriff auf SABnzbd (empfohlen)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Zugriff auf SABnzbd über HTTPS ermöglichen" #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Verschiedenes" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "SABnzbd in meinem Webbrowser öffnen, wenn es gestartet wird." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Server-Details" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Geben Sie bitte die Informationen zu Ihrem Usenet-Provider an." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Um aus dem Usenet herunterladen zu können, benötigen Sie Zugriff auf einen " "Usenet-Provider. Ihr ISP bieten dies möglicherweise an, jedoch werden " "kostenpflichtige Provider empfohlen." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Wenn Sie noch keinen Usenet-Provider haben, empfehlen wir Ihnen %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Die Anzahl der Verbindungen, die der Provider erlaubt." #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "Z.B. 8 oder 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Nur auswählen, wenn der Provider SSL-Verbindungen erlaubt." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Klicken um die eingegebenen Informationen zu überprüfen." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Dieses Feld wird benötigt." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Bitte geben Sie eine ganze Zahl ein." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Wenn Sie Mitglied von Newzbin oder NZBMatrix sind, können Sie hier den " "jeweiligen Benutzernamen und das Passwort angeben, so dass NZB-Dateien von " "diesen Seiten abgerufen werden können. Wenn Sie keinen dieser beiden Dienste " "verwenden, können Sie diesen Schritt überspringen." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Mit Lesezeichen versehene Beiträge automatisch herunterladen." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Z. B." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "SABnzbd wird neu gestartet..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Die Einrichtung ist nun abgeschlossen." #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd läuft nun im Hintergrund." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" "Das Schliessen des Browser-Fensters oder -Tabs beendet SABnzbd NICHT." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Nach dem Neustart von SAbnzbd können Sie über folgende Adresse darauf " "zugreifen: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Es ist empfehlenswert, diese Seite mit einem Lesezeichen zu versehen und " "dieses verwenden, um SABnzbd aufzurufen, wenn es im Hintergrund läuft." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Weiterführende Informationen finden Sie in unserem" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "SABnzbd anzeigen" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Schritt 1" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Schritt 2" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Schritt 3" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Schritt 4" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Schritt 5" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "Z.B. 119 oder 563 für SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "SABnzbd beenden" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Assistenten starten" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "Für SABnzbd besteht KEINERLEI GARANTIE.\n" "SABnzbd ist freie Software, die Sie unter bestimmten Bedingungen weitergeben " "dürfen.\n" "Sie steht unter der GNU GENERAL PUBLIC LICENSE Version 2 oder (nach Ihrer " "Option) jeder späteren Version.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Fehler beim Abrufen der TV-Informationen: %s" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Umbenennen von %s nach %s fehlgeschlagen." #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Umbenennen der gleichen Datei von %s nach %s fehlgeschlagen." #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Ungültige nzbmatrix.com-Bericht-ID %s." #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Sie benötigen einen NZBMatrix VIP-Konto, um die API zu nutzen" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Fehlerhafte nzbmatrix Anmeldedaten" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Problem beim Zugriff auf den nzbmatrix.com-Server: %s" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Der Hostname wurde nicht angegeben" #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Keine Verbindungen angegeben. Bitte geben Sie mindestens eine Verbindung ein." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Passwort ist als ****** maskiert. Bitte erneut eingeben." #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Ungültige Server-Angaben" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Zeitüberschreitung: Versuchen Sie, SSL oder einen anderen Port zu verwenden." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Zeitüberschreitung" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Ungültige Server-Adresse." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Sever beendet beim Anmeldeverlauf." #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Server benötigt ein Benutzername und ein Passwort." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Verbindung erfolgreich hergestellt!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "" "Authentifizierung fehlgeschlagen. Überprüfen Sie Benutzername und Passwort." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Zu viele Verbindungen. Bitte halten Sie die Downloads an oder versuchen Sie " "es später erneut." #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Die Verbindung konnte nicht überprüft werden. (%s)" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "Abrufen der Download-ID %s von newzbin.com" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Fehler beim Abrufen der Download-ID %s von newzbin.com - Überprüfen Sie, ob " #~ "der Benutzername und das Passwort korrekt eingegeben wurden." #~ msgid "Expected size did not equal actual size" #~ msgstr "Die tatsächliche Grösse entsprach nicht der erwarteten Grösse." #~ msgid "Could not compile regex: %s" #~ msgstr "Regulärer Ausdruck konnte nicht kompiliert werden: %s" #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Auftrag anhalten, wenn heruntergeladene RAR-Datei verschlüsselt ist" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Um fortzufahren, muss ein Passwort angegeben werden." #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Wenn Sie ein Konto bei www.newzbin.com haben, können Sie " #~ "die entsprechenden Informationen hier eintragen.
    Dies gibt weitere " #~ "Funktionen frei." SABnzbd-0.7.20/po/main/es.po0000644000000000000000000037347312433712555015566 0ustar00usergroup00000000000000# Spanish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2013-01-29 04:34+0000\n" "Last-Translator: Juan Garcia \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:55+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Error al iniciar la interfaz web" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "" "No se puede encontrar la plantilla web: %s, intentando con la plantilla " "estandar" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "módulo _yenc... NO encontrado!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "par2 binario... NO encontrado!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "unrar binario... NO encontrado" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "unzip binario... NO encontrado!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Tenga en cuenta que el nombre de equipo 0.0.0.0 necesitará una dirección " "IPv6 para el acceso externo" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS deshabilitado debido a la falta de archivos CERT y KEY" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s comenzó" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "Cierre de SABnzbd terminado" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Señal %s capturado, guardando y saliendo..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "Obteniendo msgid %s desde www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Error al obtener msgid %s desde www.newzbin2.es - Por favor asegurese que su " "nombre de usuario y contraseña estan configurados" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Tratando de buscar NZB de %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "No se puede crear el archivo temporal para %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Intentando cambiar el estado de servidor inexistente %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Muy poco espacio en disco forzando PAUSA" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Fallo en tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Guardar de %s no se pudo completar." #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Cargar de %s no se pudo completar." #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Notificación de prueba" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Ninguno" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Predeterminado" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "AVISO:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "ERROR:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "desconocido" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Compilación de regex para término fallo: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disco lleno! Pausando la cola" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Error de disco al crear el archivo %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "NOTICIA: Transferencia \"%s\" pausado por archivo cifrado" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "AVISO: Abortadeo el trabajo \"%s\" por un archivo RAR cifrado" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Abortado, detectamos cifrados" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "Falta %s" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Quota gastado, pausando cola" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s no es una dirección de correo electrónico válida." #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Se necesita la dirección del servidor" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "No se puede crear %s la carpeta %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "No se puede escribir al archivo INI %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "No se puede crear copia de seguridad del archivo %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Contraseña incorrectamente codificado %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s no es un valor octal correcto" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "Ruta de acceso UNC \"%s\" no permitido aqui" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Error: Cola no esta vacía, no se puede cambiar el directorio" #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "La carpeta «%s» no existe" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "Comando SQL ha fallado, vea el registro" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "Compromiso SQL ha fallado, vea el registro" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "No se pudo cerrar el base de datos, vea el registro" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Registro de etapa invalido para transferencia terminada %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Descodificación %s fallo" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "Error CRC en %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Articulo yEnc corrupto en %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Error inespecifico mientras descodificando %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => faltando de todos servidores, desechando" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Error al quitar %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "No se puede leer %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Directorio Watched %s no se puede leer" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "En pausa" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "El servidor %s se ignorará por %s minutos" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Initializacion %s@%s:%s fallo" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Demasiadas conexiones al servidor %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Compartiendo de cuenta probable" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Registraccion fallo para servidor %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Error en inicio de conexion a servidor %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Conexión %s@%s:%s ha fallado, mensaje=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Servidor %s requiere cuenta/contraseña" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Apagando" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "No se pudo conectar al servidor de correo" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "No se pudo inicializar la conexión TLS" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "No se pudo autenticar con el servidor de correo" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "No se pudo enviar correo electrónico" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "No se pudo cerrar la conexión de correo" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Email exitoso" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "No se pudo encontrar plantillas de email en %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Sin destinatarios no se pudo enviar el email" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Codificación de plantilla invalido %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "No se encontraron plantillas de correo-e" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "Para: %s\n" "De: %s\n" "Fecha: %s\n" "Asunto: SABnzdb reporta Disco Lleno\n" "\n" "Hola,\n" "\n" "SABnzdb ha detenido las descargas, porque el disco esta casi lleno.\n" "Por favor has espacio y resume SABnzdb manualmente.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Inicio/Apagado" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "NZB añadido" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Procesamiento posterior empezado" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Tarea finalizada" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Otros mensajes" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Alerta: LOCALHOST es ambiguo, use dirección de IP numérica" #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "La dirección del servidor «%s:%s» no es válida." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Falta clave de sesión" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Error: Clave de sesión requerido" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Error: Clave de sesión erróneo" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "Falta clave de API, favor ingresar la clave desde Config->General en tu " "aplicacion externa:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Clave de API erróneo, favor ingresar la clave correcta desde Config->General " "en tu aplicacion externa:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Faltaron datos de cuenta, favor ingresar usuario/contraseña desde Config-" ">General en tu aplicacion externa:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Error: Interfaz secundario no iniciado" #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Su versión de UNRAR no está recomendada, obténgalo desde " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Programa Unrar no encontrado, descomprimir de archivos RAR no posible
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Programa Par2 no encontrado, reparacion no posible
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Reiniciando...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    Apago de SABnzbd exitoso.
    Espere unos 5 segundos y entonces " "seleccione el boton abajo.

    Refrescar
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Canal" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Diariamente" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Lunes" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Martes" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Miércoles" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Jueves" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Viernes" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Sábado" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "domingo" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "desactivado" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Resolviendo sitio" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Parámetro incorrecto" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Atrás" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "La tarea \"%s\" ha sido re-agregada a la cola" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Tareas marcadas con un '*' no serán descargadas automaticamente." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Encontrado(s)" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "No encontrado(s)" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Descargado" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Descargado hasta ahora" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Valor incorrecto para %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "No se pudo crear el directorio %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "Directorio %s: Error al acceder a %s" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "" "Imposible conectar a la clave HKEY_CURRENT_USER del registro de Windows" #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "No se puede abrir la llave de registro \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Falla al leer las llaves de registro para los directorios especiales" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Error al crear (%s)" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Error al mover %s a %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Archivo NZB inusable" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Inténtelo de nuevo" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Error al recuperar la URL; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "Falta el módulo pyopensll, favor de instalarlo para acceso https" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Error al crear la llave SSL y el certificado" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "No se puede cambiar los permisos de %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Uniendo" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Secuencia incompleta de archivos a unir" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Error al unir el fichero %s" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Error \"%s\" al unir archivos" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Error \"%s\" al ejecutar file_join en %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] %s ficheros unidos." #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Error al descomprimir, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Error \"%s\" al descomprimir ficheros RAR" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Error \"%s\" al ejecutar rar_unpack sobre %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "¡Error al eliminar %s!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Intentado descomprimir rar con contraseña \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Error al descomprimir; El archivo está protegido por contraseña" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Descomprimiendo" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Error al descomprimir; Imposible encontrar %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "ERROR: Imposible encontrar \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Error de CRC al descomprimir" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "ERROR: Ha fallado la comprobación CRC sobre \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "" "Error al descomprimir; ¿Error de escritura, o tal vez el disco está lleno?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "ERROR: Error de escritura (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Aperture de archivo fallo, la via es muy larga" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "ERROR: via es muy larga (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Error al descomprimir, chequea el log" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "ERROR: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Falta el siguiente archivo: %s => ¿Error al descomprimir?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "" "Error al descomprimir; se esperaba un archivo que no se ha podido " "descomprimir" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Error al descomprimir, faltan este(os) archivo(s):" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Descompresos %s archivos/directorios en %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s archivos en %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Error \"%s\" al ejecutar unzip() sobre %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Chequeo Rápido" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Reparar" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Chequeo Rápido OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Iniciando reparación" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "La reparación falló, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Error %s al ejecutar par2_repair en el conjunto %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Error %s al ejecutar par2_repair en el conjunto %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 ha recibido opciones incorrectas, chequea tus ajustes en " "Preferencias->Switches" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificado en %s, todos los archivos correctos" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificado en %s, se necesita reparar" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Paquete principal no encontrado..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Ficheros par2 inválidos, no se puede verificar o reparar" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Ha fallado la reparación, no existen bloques de reparación suficientes (%s " "short)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Recuperando %s bloques..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Recuperando" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Reparando" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Reparado en %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Verificando" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Error al importar módulo OpenSSL. Conectando sin SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Error al actualizar el trabajo %s de newzbin" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB añadido a la cola" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "El servidor Newzbin ah cambiado su protocolo" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "No tienes suficientes créditos en tu cuenta de Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Sin autorización, chequea tu usuario/contraseña de Newzbin" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "No se encuentra el informe %s de Newzbin" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin ha revuelto un código de error no documentado (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "El servidor de Newzbin no ha devuelto información para %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Imposible eliminar el favorito %s de Newzbin" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin ha devuelto un código de error no documentado (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "" "Se ha encontrado un fichero de cola incompatible, no se puede continuar" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Error al cargar %s, archivo corrupto" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Error al añadir %s, eliminando" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Codificación desconocida" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "El fichero%s está vacío, omitiendo" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Error al importar %s ficheros desde %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Fichero NZB %s incompleto" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Fichero NBZ inválido: %s, omitiendo (razón=%s, línea=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Fichero NZB vacío: %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorando NZB Duplicado \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Pausando NZB duplicados \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Abortado, No puede ser completado" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLICADO" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "ENCRIPTADO" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "DEMASIADO GRANDE" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "INCOMPLETO" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "ESPERAR %s seg" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Descargado en %s a una media de %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artículos estaban mal formados." #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s artículos no encontrados" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artículos contenían duplicados inconexos" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s articulos removidos" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Error importando %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Advertencias" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Inactivo" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Configuración" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Cola" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Limpiar Cola" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historial" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Purgar historial" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Limitar Velocidad" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pausar" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "mín." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Reanudar" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Obtener favoritos de Newzbin" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Escanear directorio bajo observación" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Carpeta Completa" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Carpeta Incompleta" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Resolver un problema" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Reiniciar" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Reiniciar sin sesión iniciada" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Salir" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Encolar los primeros 10 elementos" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Vacía" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Histórico últimos 10 elementos" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Nueva versión disponible" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Ir al Asistente" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Deteniendo..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problema con" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABNZBD no es compatible con algunos cortafuegos.
    \n" " %s
    \n" " Lo sentimos, pero no se puede resolver esta incompatibilidad en este " "momento.
    \n" " Por favor contacta con el proveedor de tu cortafuegos.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd necesita un puerto tcp/ip libre para su servidor web " "interno.
    \n" " Se ha intentado en el puerto %s en %s, pero no está disponible.
    \n" " Puede que otro software ya esté utilizando este puerto, o que SABnzbd ya " "esté en ejecución.
    \n" "
    \n" " Por favor reinicia SABnzbd indicando un número de puerto diferente." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "" "Si obtiene este mensaje de error consecutivamente, por favor inténtelo de " "nuevo con otro número.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd necesita un puerto tcp/ip libre para su servidor web " "interno.
    \n" " Se ha intentado con el puerto %s en %s, pero la cuenta utilizada por " "SABnzbd no tiene permisos para usarlo.
    \n" " En equipos OSX y Linux, los usuarios normales han de usar puertos por " "encima de 1023.
    \n" "
    \n" " Por favor reinicie SABnzbd con un número de puerto diferente." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd necesita una dirección IP para su servidor web interno.
    \n" " Has especificado una dirección inválida.
    \n" " Valores seguros son localhost y 0.0.0.0
    \n" "
    \n" " Por favor reinicia SABnzbd con una dirección o nombre de host correctos." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd ha detectado información guardada de otra versión de " "SABnzbd
    \n" " pero no puede ser reutilizada por la otra versión.

    \n" " Tal vez quieras finalizar primero tu cola actual con la otra " "versión.

    \n" " Tras ello, ejecuta este programa con la opción \"--clean\".
    \n" " Esto eliminará la cola e historial actuales!.
    \n" " SABnzbd leer el archivo \"%s\"" #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd no puede encontrar sus ficheros de la interfaz web en %s.
    \n" " Por favor instala el programa de nuevo.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd ha detectado un error grave:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd ha tecetado el Historial y Cola de una versión anterior " "(0.4.x).

    \n" " Tanto la cola como el historial serán ignorados y eliminados!

    \n" " Puedes optar por parar SABnzbd y finalizar la cola con la versión " "anterior del programa.

    \n" " Haz clic en Aceptar para continuar con SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "Aceptar" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd ha detectado que el fichero sqlite3.dll no existe.

    \n" " Algunos virus de de pésima calidad eliminan este fichero.
    \n" " Por favor revisa la configuración de tu antivirus y quéjate a tu " "proveedor del AntiVirus. Tras ello reinstala SABnzbd.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Presiona la Tecla de Windows+R y teclea la línea (ejemplo)" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Apre una ventana de Consola y teclea la línea (ejemplo)" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Parece que estás usando ZoneAlarm con Windows Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "El programa no ha arrancado!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "No tienes permisos para usar el puerto %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Error grave" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "" "Imposible iniciar el navegador, probablemente no se le haya encontrado" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Acceso denegado" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Error %s: Necesitas introducir un usuario y contraseña válidos." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Error al cargar la cola de post-procesado: Versión incorrecta (se " "necesita:%s, se encontró:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Error al eliminar nzo desde la cola de postprocesado (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "La descarga fallo, solo %s de los %s requeridos estan disponibles" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "" "Error en la descarga - ¡Tal vez está fuera del límite de retención de tu " "proveedor?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Imposible crear directorio final %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "No se ha podido post-procesar debido a un fallo en la verificación" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Moviendo" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Enviado(s) %s a la cola" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Error al renombrar \"%s\" a \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Error al mover ficheros" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Ejecutando script" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Ejecutando script de usuario %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Se ejecutó %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Más" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Ver salida del script" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Descarga Completada" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "La descarga falló" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Error al post-procesar %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "ver fichero de log" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Se ha abortado el PostProcesamiento (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Ha fallado la limpieza de %s" #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Error al eliminar el directorio de trabajo (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Post-Procesado" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] No hay conjuntos par2" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Intentando verificación por SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Han fallado algunos ficheros al verificarse \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Se ha verificado correctamente utilizando ficheros SFV" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Error al eliminar %s" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Error al hibernar el sistema" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Error al suspender el sistema" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Error al apagarel sistema" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "iaDescripción de canal RSS incorrecta \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Error al recuperar RSS desde %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "No se encontró autenticación válida para el feed %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "El canal RSS %s estaba vacío" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Canal Incorrecto" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Entrada RSS vacía (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Mostrar interfaz" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Abrir todo el folder" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Apagar" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Restante" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Planificación incorrecta %s a las %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Acción desconocida: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Planificación para servidor %s inexistente" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Descargar" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Unir ficheros" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Descomprimir" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Script" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Fuente" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Fallo" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Completado" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Fallido" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "En espera" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparando..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Extrayendo..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Moviendo..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Ejecutando script..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Recuperando bloques extra..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Chequeo Rápido..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Verificando..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Descargando" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Obtener NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Verificando" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Frecuencia" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Acción" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argumentos" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Tarea" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "deshabilitar servidor" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "habilitar servidor" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Límite de Velocidad" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Pausar todo" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pausar post-procesamiento" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Reanudar post-procesamiento" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Leer entradas RSS" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Eliminar trabajos fallidos" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "hora" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "horas" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "mín" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "mins" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "seg" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "segundos" #: sabnzbd/skintext.py:79 msgid "day" msgstr "día" #: sabnzbd/skintext.py:80 msgid "days" msgstr "días" #: sabnzbd/skintext.py:81 msgid "week" msgstr "semana" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Mes" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "Año" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Día del mes" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Esta semana" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Este mes" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Hoy" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Total" #: sabnzbd/skintext.py:97 msgid "on" msgstr "activado" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametros" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Version de Python" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Pagina principal" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "o" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Equipo" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "La herramienta de descarga automática para usenet" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Guardar" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "En cola" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "¿Estás seguro?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "¿Elimiar todos los ficheros descargados?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Inicio" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Config." #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Estado" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Ayuda" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Foro" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "General" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Directorios" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Switches" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Servidores" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Planificación" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Notificaciones" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Correo" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Sites de búsqueda" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Categorías" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Ordenación" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Especial" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Dir de Descarga" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Dir para completados" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Velocidad de Descarga" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "PAUSADO" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "%s artículos cacheados (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Carga del Sistema" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "AVISOS" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Nueva versión %s disponible en" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Añadir nuevas descargas" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "¿Seguro que deseas detener SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Añadir" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "ID de reporte" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Añadir fichero" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Categoría" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "En proceso" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioridad" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparar" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Descomprimir" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Eliminar" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "U" #: sabnzbd/skintext.py:177 msgid "D" msgstr "D" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Forzar" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Alta" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Baja" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Parar" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Introduzca la URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr "  ó ID de Reporte" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Ordenar por nombre" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Ordenar por antigüedad" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Ordenar por tamaño" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Ocultar Ficheros" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Mostrar archivos" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Al finalizar cola" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Apagar PC" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Suspender PC" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Hibernar PC" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Apagar SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Límite de velocidad" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pausar durante" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Orden" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nombre" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Restante/Total" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Tiempo estimado" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "ANTIGÜEDAD" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Borrar" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Reintentar" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Acciones" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Scripts" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "¿Eliminar todos los elementos de la cola?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Purgar NZBs" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Purgar NZBs y Eliminar Ficheros" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Eliminar NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Eliminar NZB y Eliminar Ficheros" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "de" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Artículos no encontrados" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Quota disponible" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "manual" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Reinicializar Quota ahora" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Purgar historial de errores" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "¿Eliminar todos los elementos completados del Historial?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "¿Eliminar todos los elementos que han fallado del Historial?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Ocultar detalles" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Mostrar detalles" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Tamaño del Historial" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Mostrar los Fallidos" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Mostrar Todo" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Tamaño" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Purgar los NZBs fallidos" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Purgar NZBs fallidos y sus ficheros" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Purgar NZBs completados" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "NZB Suplementario Opcional" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Ruta" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Forzar desconexión" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Se enviará un email de prueba a tu cuenta" #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Ver Logging" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Mostrar Logging de la web" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Email de prueba" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Registros de sucesos" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Errores/Advertencias" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+Depuración" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Conexiones" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Hilo" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Resultado del email de prueba" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Últimas advertencias" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "limpiar" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Desbloquear" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Identificador de artículo" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Conjunto de ficheros" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Cuando" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Tipo" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Advertencia" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Habilitado" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Fichero de Config" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Caché utilizada" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Esto reiniciará SABnzbd.
    Usalo cuando creas que el programa está " "colgado.
    Las descargas se pausarán antes de reiniciar, y se reanudarán " "a continuación." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Existen trabajos huérfanos en la carpeta de descarga.
    Puedes escoger " "por eliminarlos (incluyendo los ficheros) o enviarlos de nuevo a la cola." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "El botón \"Reparar\" reiniciará SABnzbd y hará una reconstrucción
    completa del contenido de la cola, preservando las descargas ya " "terminadas.
    Esto modificará el orden de la cola." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Versión" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Tiempo en Activo" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Copia de seguridad" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Configuración general" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Los cambios requieren reiniciar SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Servidor web de SABnzbd" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Host de SABnzbd" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Dónde debería escuchar el Host de SABnzbd" #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Puerto de SABnzbd" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Puerto en que SABnzbd debería escuchar" #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Interfaz web" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Elije una piel" #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Interfaz web secundaria" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Habilitar una piel alternativa" #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Identificación contra el Servidor Web" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Usuario SABnzbd" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Nombre de usuario opcional" #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Contraseña de SABnzbd" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Contraseña opcional" #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "Soporte HTTPS" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Habilitar HTTPS" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "no instalado" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Habilia el acceso a la interfaz con una dirección HTTPS" #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "Puerto HTTPS" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Si se deja vacío, el puerto estándar escuchará por HTTPS" #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "Certificado HTTPS" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Nombre de archivo o ruta al Certificado SSL" #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "Clave privada SSL" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Nombre de archivo o ruta a la clave privada SSL" #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "Cadena de Certificados HTTPS" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Nombre de archivo o ruta de acceso a la cadena de HTTPS." #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Ajustes" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Intervalo automático de refresco de la cola" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Intervalo de refresco de la página web de la cola (en segundos, 0= ninguno)" #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "Intervalo de chequeo RSS" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Intervalo de Chequeo (en minutos, mínimo 15). No toma efecto si utilizas el " "Planificador!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Límite de velocidad de descarga" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Límite de descarga (en KB/s - kilobytes por segundo)" #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Límite de cacheo de artículos" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Cachear artículos en memoria para reducir el acceso a disco.
    En " "bytes, opcionalmente seguido de K,M,G. Por ejemplo: \"64M\" o \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Lista de elementos a limpiar" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista de las extensiones de fichero que deberían ser eliminadas después de " "cada descarga.
    Por ejemplo: .nfo ó .nfo,.sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Guardar cambios" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Idioma" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Selecciona un idioma para la interfaz web." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "Clave API" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Esta clave le permitirá a programas de terceros acceso completo a SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "Clave NZB" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Esta clave permitirá acceso a programas de terceros para añadir NZBs a " "SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Generar nueva clave" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Desactivar Clave-API" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "No solicitar clave API." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "USALO BAJO TU RESPONSABILIDAD" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "Codigo QR" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "Código QR de la clave API" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Configuración Directorios" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTA: Los directorios se crean automáticamente al guardar. Puedes " "usar una ruta absoluta, exterior a los directorios predefinidos." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Directorios del usuario" #: sabnzbd/skintext.py:345 msgid "In" msgstr "En" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Directorio de descarga temporal" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Localización donde guardar descargas incompletas.
    Sólo se puede " "cambiar si la cola est&aa; vací" #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Espacio libre mínimo para el directorio de descargas temporales" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Parar automáticamente cuando el espacio libre esté por debajo de este " "valor.
    En bytes, opcionalmente seguido de K,M,G,T. Por ejemplo: " "\"800M\" ó \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Directorio de descargas completadas" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Ubicación donde guardar descargas finalizadas, totalmente procesaddas.
    Puede ser obviado debido a categorías definidas por el usuario." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Permisos para descargas completadas" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Ajustar patrón de permisos para ficheros/directorios completados.
    En " "notación ocal. Por ejemplo:\"755\" ó \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Directorio a vigilar" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Directorio a monitorizar en busca de ficheros .nzb.
    También escanea " "ficheros .zip .rar y .tar.gz en busca de ficheros .nzb." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Velocidad de escaneo de la carpeta vigilada" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Número de segundos entre pasadas en busca de ficheros .nzb." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Directorio de Scripts de post-procesado" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "" "Directorio que contiene los scripts de usuario para el post-procesado." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Directorio de plantillas de Email" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "" "Directorio que contiene plantillas de email definidas por el usuario." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Archivo de contraseñas" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fichero que contiene todas las contraseñas a usar en ficheros RAR protegidos." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Directorios del sistema" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Directorio de administración" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Ubicación de la base de datos de historial y administración.
    Sólo se " "puede cambiar si la cola está vacía." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Los datos no se moverán. Requiere queu SABnzbd sea reiniciado!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Directorio de Historial" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Ubicación de los ficheros de log para SABnzbd.
    Requiere reiniciar " "SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Directorio de Backups de .nzbs" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Ubicación donde se guardarán los ficheros .nzb." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Directorio base por defecto" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Configuración de Switches" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Procesando Switches" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Habilitar Chequeo Rápido" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Ignorar chequeo de par2 cuando los ficheros son 100% correctos." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Habilitar Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Habilitar funcionalidad nativa de unrar" #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Habilitar Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Habilitar funcionalidad nativa de unzip." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Habilitar Filejoin" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Une los ficheros terminados en .001, .002 etc en un sólo fichero." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Habilitar Unión TS" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "" "Une los ficheros terminados en .001.ts, .002.ts etc en un sólo fichero." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Habilitar limpieza Par" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Limpiar ficheros par (si la reparación/verificación es correcta)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Fallar si hay errores de CRC en yEnc" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "" "Cuando un artículo tiene un error de CRC, intentar conseguirle desde otro " "servidor." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Sólo obtener artículos para el primer elemento de la Cola" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Habilitar para usar menos memoria. Deshabilitar para prevenir que trabajos " "que se ralentizen bloqueen la cola." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Post-procesar sólo trabajos verificados" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Sólo realiza el post-procesado en trabajos que han pasado todos los chequeos " "PAR2." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Accion cuando un archivo RAR cifrado es bajado" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "In caso de PAUSA, necesitara escribir una contrasena para continuar el " "trabajo." #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Detectar descargas duplicadas" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Detectar ficheros NZB de nombre idéntico (necesita de la opción de NZB " "habilitada) y títulos duplicados de entre las fuentes RSS." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Apagado" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Descartar" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Abortar" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Habilitar verificacion basada en SFV" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Realiza una verificación extra basada en ficheros SFV." #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Chequear el resultado de la descompresión" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Chequea el resultado de la descompresión (necesita deshabilitarse si tienes " "un sistema de ficheros muy grande)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Habilitar renombrado de directorios" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Usa nombres temporales durante el procesado. Deshabilitalo si tu sistema se " "vuelve inestable con ello habilitado." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Post-Procesado por defecto" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "" "Este es el post-procesado a utilizar cuando no se ha definido nada especial " "según la categoría de la descarga." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Script de Usuario predefinido" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Usado cuando la categoría no imponte ningún script de usuario." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Script de usuario Pre-cola" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Se usa precediendo a la entrada de un NZB en la cola del sistema." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Prioridad Predefinida" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Se usa cuando la categoría no impone ninguna prioridad." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Habilitar Par2 Multi-núcleo" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Lee la ayuda en la Wiki (inglés) acerca de esto!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Parámetros PAR2 extra" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Parámetros Nice" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "Parámetros IONice" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Otros parámetros" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Desconectar si la cola está vacía" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Desconecta del servidor de Usenet cuando la cola está vacía, o pausada." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Enviar Group" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Enviar comando group antes de solicitar los artículos." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Ordenar por antigüedad" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Automáticamente ordenar elementos por antigüedad (promedio)." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Buscar Nva Versión" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Chequear semanalmente por nuevas versiones de SABnzbd." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "También libera de prueba" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Reemplazar espacios en el nombre de directorio" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "" "Reemplaza los espacios con guiones bajos en los nombres de directorio." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Reemplazar puntos en los directorios" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Reemplaza los puntos con espacios en los nombres de directorio." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Reemplazar caracteres no admitidos en los directorios" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Reemplaza los caracteres inválidos del nombre del directorio por lso " "equivalentes (si no puede los elimina)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Lanzar navegador al Arrancar" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Ejecuta el navegador por defecto del sistema al arrancar SABnzbd." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Pausar Descargas Durante el Post-Procesado" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Pausa las descargas al principio del post-procesado, y reanuda al terminar." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignorar Samples" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Filtra la descarga de ficheros de ejemplo (e.g. un sample de vídeo)." #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Eliminar tras descargar" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "No descargar" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "Tpo de SSL" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "¡sa V23 salvo que tu proveedor indique lo contrario!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Usar reloj de 12 horas (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Muestra las horas en notación AM/PM (no afecta al planificador)." #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Servidor" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Post procesado" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Nombrado" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Cuota" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Cantidad de descarga permitida este mes (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Día de reinicio del conteo" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "En qué día del mes o semana (1=Lunes) resetea tu proveedor la cuota mensual? " "(Opcional con hh:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Auto reanudar" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "¿Deberían las descargas resumirse tras reiniciarse la cuota?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Periodo de la cuota" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "¿Cada cuánto se resetea la cuota?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Chequear antes de descargar" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Intenta predecir si la descarga actual se completará con éxito (ojo, esto " "tarda!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Reintentos máximos" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Máximo número de reintentos por servidor" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Sólo para servidores opcionales/alternativos" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Aplica un máximo de reintentos a los servidores opcionales" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Trabajos abortados no pueden ser completados" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Cuando este bajando, si es claro que mucha data esta faltando, aborte el " "trabajo." #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Configuración del servidor" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Definición de Servidor" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Añadir servidor" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Puerto" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Nombre de usuario" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Contraseña" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Expiración del plazo (Timeout)" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Periodo de retención" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Servidor de Backup" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Opcional" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Habilitar" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Eliminar servidor" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Probar Servidor" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Resetear contadores" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testeando información del servidor" #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Haga clic debajo para testear." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Ancho de Banda" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Config. de Planificación" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Añadir planificación" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Eliminar" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Tareas Programadas Actuales" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "Configuración de RSS" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "URL de la fuente RSS" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "La casilla junto al nombre de la fuente debería marcarse para habilitar la " "fuente y que se marquen automáticamente los nuevos elementos.
    Cuando " "una fuente se añade, sólo se cogerán los elementos nuevos y nada de lo que " "ya exista, salvo que presiones \"Forzar Descarga\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Añadir una fuente" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Borrar fuente" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Leer Fuente" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Forzar Descarga" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filtrar" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Omitir" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Aceptar" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Rechazar" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Necesita" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "RequiereCat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "No encontrado" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Fuentes" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Leer todas las fuentes ahora" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Preferencias" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtros" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Opciones de e-mail" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Notificación por email al terminar" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Nunca" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Siempre" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Sólo Errores" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Notificaciones de Disco Lleno" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Envía un email cuando el disco se ha llenado y SABnzbd se ha tenido que " "parar." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Enviar notificaciones RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Enviar email cuando una fuente RSS añade un trabajo a la cola." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Ajustes de E-Mail" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "Servidor SMTP" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Indica los ajustes de tu correo electrónico saliente." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Destinatario" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Dirección de correo electrónico a la que enviar el mensaje." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Remitente" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "¿Quién quieres que aparezca como remitente?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "Nombre de usuario OPCIONAL" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "" "Para correos electrónicos con autentificación, poner el nombre de usuario." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "Contraseña de usuario OPCIONAL" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Para correos electrónicos con autentificación, poner la contraseña." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Habilitar Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Enviar notificaciones a Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Dirección del Servidor" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Usar sólo para un servidor Growl remoto (servidor:puerto)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Contraseña de servidor" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Contraseña opcional para el servidor Growl" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Habilitar NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Enviar notificaciones a NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Centro de Notificación" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Envía notificaciones al Centro de Notificación" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Clases de notificación" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Activar clases de mensajes que deben notificarse (ninguno, uno o múltiples)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Si tienes una en www.newzbin2.es, puedes introducir tus " "datos de cuenta aquí.
    Esto desbloquea funcionalidades extra." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Info de cuenta" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Usuario de Newzbin" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Introduce aquí tu nombre de usuario." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Contraseña de Newzbin" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Introduce aquí tu contraseña." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Procesar Favoritos" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Auto-Descargar los favoritos" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "" "Automáticamente se conecta y recibe los trabajos que se encuentren en tus " "favoritos." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Descargar favoritos ahora" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Ocultar Favoritos" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Mostrar Favoritos" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Desmarcar como favorito si la descarga se completa" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "" "Elimina de la lista de favoritos el elemento descargado correctamente." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Frecuencia de chequeo" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "En minutos (al menos 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Favoritos procesados" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Si tienes una cuenta en www.nzbmatrix.com, puedes " "introducir sus datos aquí.
    Esto es necesario si quieres usar las " "fuentes RSS de este sitio." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Usuario de NzbMatrix" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "Clave API de NzbMatrix" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Introduce aquí tu clave API de NzbMatrix." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Categorías definidas por el usuario" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Define tareas de post-procesado y el almacenamiento." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Usa la columna \"Grupos / Etiquetas del indizador\" para enlazar grupos y " "etiquetas a tus categorías.
    Se aceptan comodines. Usa comas para " "separar términos." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Terminar la ruta con un * previene que se creen directorios de trabajo." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Los directorios relativos, lo son a" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Directorio/Ruta" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Grupos / Etiquetas del indizador" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Preferencias de ordenación" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Ordenación de Series" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Habilitar la ordenación de Series de TV" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Habilitar ordenación y renombrado de episodios." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Patrón" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Limpiar" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Preajustes" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Ejemplo" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Ordenado Genérico" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Habilitar Ordenado de Películas" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Habilitar ordenado y renombrado genérico de los ficheros." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Mantener descargas en directorios extra." #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Habilitar si las descargas no quedan en sus propios directorios." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Categorías Afectadas" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Significado" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Patrón" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Resultado" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Temporada Directorio" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Temporada Directorio" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Episodio Directorio" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Episodio Directorio" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Título" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Nombre de Película" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Nombre.de.pelicula" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Nombre_de_pelicula" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Nombre de la Serie" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Nombre.serie" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Nombre_serie" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Número de la temporada" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Número del capítulo" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Nombre del capítulo" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Nombre.capítulo" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Nombre_capítulo" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Extensión de archivo" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Extensión" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Numero de Parte" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Década" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Nombre fichero original" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Nombre directorio original" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Minúsculas" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEXTO" #: sabnzbd/skintext.py:667 msgid "text" msgstr "texto" #: sabnzbd/skintext.py:668 msgid "file" msgstr "archivo" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "carpeta" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Ordenar cadena" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Etiqueta" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "En directorios" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Sin Directorios" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Ordenar por fecha" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Habilitar ordenar por fecha" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Habilitar ordenación y renombrado de nombres de ficheros con fechas." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Carpeta de la serie" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Directorios Año-Mes" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Directorios diarios" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "ajustado a mayus-minus" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Resultado del procesado" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Opciones usadas raramente. Para su significado y explicación, haga clic en " "el botón de Ayuda para ir al Wiki.
    No cambie esto sin chequear primero en " "la wiki,ya que algunos ajustes tienen severas consecuencias.
    Los valores " "por defecto se muestran entre paréntesis." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Valores" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Editar Detalles de NZB" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Eliminar" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Superior" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Encima" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Abajo" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Último" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Todos" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Invertir" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Nombre de archivo" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Asunto" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Edad" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Selección" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "¿Está seguro de querer borrar?" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Actualizar" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Opciones" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Página" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Anterior" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Siguiente" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Primero" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Último" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Cerrar" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Ajustar Intervalo de Parada" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Ordenar" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "¿Limpiar la Cola?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Intervalo de Parada" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pausar 5 minutos" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pausar 15 minutos" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pausar 30 minutos" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pausar 1 hora" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pausar 3 horas" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pausar 6 horas" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pausar 12 horas" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pausar 24 horas" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Ordenar por Fecha Más viejo→Más nuevo" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Ordenar por Fecha Más nuevo→Más viejo" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Ordenar por nombre A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Ordenar por nombre Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Ordenar por Tamaño Más pequeño→Más grande" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Ordenar por Tamaño Más grande→Más pequeño" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Renombrar" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Restante" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "¿Vaciar el historial?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "No se han guardado los cambios, y se perderán." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Abrir URL Fuente" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Abrir URL de informacion" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Almacenamiento" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Ver bitacora de Scripts" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Debes activar JavaScript para que pueda funcionar Plush!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Añadir NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Opciones de Plush" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "¡Actualización Disponible!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "¿Por cuántos minutos realizar la pausa?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pausar durante..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Op.Múltiples" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Menú superior" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Al terminar" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Ordenar por Fecha (Más viejo→Más nuevo)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Ordenar por Fecha (Más nuevo→Más viejo)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Ordenar por nombre (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Ordenar por nombre (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Ordenar por Tamaño (Más pequeño→Más grande)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Ordenar por Tamaño (Más grande→Más pequeño)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Purgar" #: sabnzbd/skintext.py:781 msgid "left" msgstr "Restante" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Velocidad máx." #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Intervalo" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Reiniciar" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Aplicar a seleccionados" #: sabnzbd/skintext.py:786 msgid "page" msgstr "página" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Todo" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Deshabilitado" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Frecuencia de actualización" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Ancho del contenedor" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Confirmar eliminación de la cola" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Confirmar eliminación del historial" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Esto evitará que se actualizen los contenidos cuando el cursor del ratón " "esté sobre la cola." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Bloquear actualizaciones al pasar por encima" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Obtener" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Subir" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Subir: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Opcionalmente especificar un nombre de fichero" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Progreso" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "¡No hay espacio suficiente para completar las descargas!" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Espacio libre" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Libre (Temp)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "INACTIVO" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Descargas" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Reparar cola" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Leer Fuente recogerá los contenidos actuales de la fuente. " "Forzar Descarga para descargar ahora cualquier NZB " "coincidente." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Hora:Minuto" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Eliminar completados" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "¿eliminar los elementos fallidos del historial?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Eliminar Fallidos" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Enlaces" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Mostrando %s a %sde %s resultados" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Sin resultados" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Mostrando un resultado" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "¡Email enviado!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "¡Notificación enviada!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Guardando..." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Guardado" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Velocidad" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Activar-desactivar Añadir NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "Vista Dual 1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "Vista Dual 2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Personalizar" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Obtener Favoritos" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "¿Seguro que desea reiniciar SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Frecuencia de actualización" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Eliminar todo" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Ocultar opciones de edición" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Mostrar opciones de edición" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Modificar" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "TiempoRestante" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "Asistente de Configuración de SABnzbd" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "Versión de SABnzbd" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Anterior" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Acceso" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "Quiero que SABnzbd sea visible para cualquier ordenador en mi red." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Quiero que SABnzbd sólo sea visible desde este ordenador." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Proteger el acceso a SABnzbd con contraseña (recomendado)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Habilitar HTTPS para acceder a SABnzbd." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Miscelánea" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "" "Lanzar mi navegador de interner con la página de SABnzbd al arrancar el " "programa." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Detalles del servidor" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Por favor introduce los datos de tu proveedor principal de Usenet." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Para poder descargar de Usenet, necesitas acceso con un proveedor. Tu " "proveedor de acceso a internet te lo puede dar, aunque recomendamos " "proveedores premium." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "¿No tienes proveedor de Usenet? Nosotros recomendamos probar %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Número de conexiones permitidas a tu proveedor" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "P.ej. 8 ó 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Selecciona sólo si tu proveedor permite conexiones SSL." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Haz clic para probar los detalles introducidos." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Este campo es obligatorio" #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Por favor introduzca un número completo." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Si eres miembro de Newzbin ó NzbMatrix, puedes introducir tu usuario y " "contraseña aquí para que podamos recibir sus nzb. Esta etapa la puedes " "omitir si no usas ninguno de estos servicios." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Automáticamente descargar posts marcados como favoritos." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Por ej." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Reiniciando SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "¡La configuración ha terminado!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd ahora quedará ejecutando en segundo plano." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Si cierras las pestañas o el navegador, SABnzbd NO se cerrará." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Después de que se reinicie SABnzbd, podrás acceder a él en la siguiente " "dirección: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Se recomienda que guardes esta ubicación como favorito y la añadas a tu " "navegador para acceder a SABnzbd cuando quieras." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Puedes encontrar más ayuda en nuestro" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Ir a SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Primer Paso" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Segundo Paso" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Tercer Paso" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Cuarto Paso" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Quinto Paso" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "P.ej. 119 ó 563 si es SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Salir SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Iniciar Asistente" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd se entrega SIN NINGUNA GARANTÍA.\n" "Este es un software libre, y eres bienvenido a redistribuirlo bajo " "determinadas condiciones.\n" "Está licenciado bajo la versión 2 ó posterior de GNU GENERAL PUBLIC " "LICENSE.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Error al recuperar info de la serie (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Error al renombrar: %s a %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Error al renombrar ficheros similares: %s a %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Número de informe de nzbmatrix incorrecto: %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Necesitas una cuenta VIP en nzbmatrix para usar la API" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Credenciales de nzbmatrix incorrectas" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Error al acceder al servidor de nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "El hostname no está definido." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "No se han configurado conexiones. Configure al menos una conexión." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Contraseña protejido por ******, favor reingresar" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Detalles de servidor invalidos" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Tiempo agotado: Trate conectar en puerto diferente o encender SSL." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Tiempo agotado" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Dirección del servidor no válida." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "El servidor se ha cerrado durante el login" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "El servidor necesita usuario y contraseña." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "¡Conexión exitosa!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Autenticación fallida, compruebe el usuario o la contraseña." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Demasiadas conexiones; pause las descargas o inténtelo de nuevo más tarde" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "No se pudo determinar el resultado de la conexión (%s)" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Error en accesar reporte %s de www.newzbin.com - Favor asegurar que los " #~ "datos de cuenta estan correctas." #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "accesando reporte numero %s desde www.newzbin.com" #~ msgid "Could not compile regex: %s" #~ msgstr "No se puede compilar la expresión regular: %s" #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Pausar trabajo cuando se descarga un RAR protegido" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Necesitarás introducir la contraseña y reanudar el trabajo." #~ msgid "Email Notifications" #~ msgstr "Notificaciones por correo electrónico" SABnzbd-0.7.20/po/main/fi.po0000644000000000000000000037444112433712555015551 0ustar00usergroup00000000000000# Finnish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2014-04-19 08:54+0000\n" "Last-Translator: Matti Ylönen \n" "Language-Team: Finnish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:53+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Web-käyttöliittymän käynnistys epäonnistui" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Web-mallia %s ei löydy, yritetään käyttää oletusmallia" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "_yenc moduulia... EI löydy!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "par2 ohjelmaa... EI löydy!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "unrar ohjelmaa... EI löydy!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "unzip ohjelmaa... EI löydy!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Huomioithan, että 0.0.0.0 isäntänimi vaatii IPv6 osoitteen jotta pääset " "ulkoverkkoon" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS poistettu käytöstä puuttuvien CERT ja KEY tiedostojen vuoksi" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s käynnistetty" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnzbd sammutus valmis" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Signaali %s kaapattu, tallennetaan ja lopetetaan..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "noudetaan viesti-id %s osoitteesta www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Virhe noudettaessa viesti-id %s osoitteesta www.newzbin2.es - Varmista, että " "käyttäjänimi ja salasana ovat oikein" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Yritetään noutaa NZB osoitteesta %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Väliaikaistiedostoa ei voida luoda kohteelle %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Yritettiin asettaa tila ei olemassa olevalle palvelimelle %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Levytilaa ei ole tarpeeksi, pakotetaan KESKEYTYS" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Virhe tiedostossa tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "%s tallentaminen epäonnistui" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "%s lataaminen epäonnistui" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Testaa huomautusta" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Ei mitään" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Oletus" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "VAROITUS:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "VIRHE:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "tuntematon" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Regex käännös epäonnistui hakutermille: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "pv" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "t" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Levy täynnä! Pakotetaan keskeytys" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Levyvirhe luotaessa tiedostoa %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "VAROITUS: Keskeytetty työ \"%s\" salatun RAR tiedoston vuoksi" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "VAROITUS: Keskeytettiin työ \"%s\" salatun RAR arkiston vuoksi" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Keskeytty, salattu arkisto tunnistettu" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s puuttuu" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Latausrajoitus saavutettu, keskeytetään lataukset" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s ei ole kelvollinen sähköpostiosoite" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Palvelimen osoite vaaditaan" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Ei voitu luoda %s kansiota %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Ei voitu kirjoittaa INI tiedostoa %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Ei voitu luoda varmuuskopiota %s :lle" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Virheellisesti koodattu salasana %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s ei ole oikea oktaalinen arvo" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "TUNT polku \"%s\" ei ole sallittu" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Virhe: Jono ei ole tyhjä, kansiota ei voida vaihtaa." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Kansiota \"%s\" ei ole olemassa" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "SQL komento epäonnistui, katso loki" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "SQL muutos epäonnistui, katso loki" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Tietokannan sulkeminen epäonnistui, katso loki" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Virheellinen tila lokihistoriassa kohteelle %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "%s dekoodaus epäonnistui" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "CRC virhe tiedostossa %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Huonosti muotoiltu yEnc artikkeli %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Tuntematon virhe dekoodattaessa %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => puuttuu kaikilta palvelimilta, hylätään" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Virhe poistettaessa %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Ei voida lukea %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Vahdittua kansiota %s ei voida lukea" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Keskeytetty" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Palvelin %s ohitetaan %s minuutiksi" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Virhe initialisoidessa %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Liikaa yhteyksiä palvelimelle %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Mahdollinen tilin jakaminen" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Kirjautuminen palvelimelle %s epäonnistui" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Palvelimeen %s ei voida yhdistää [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Virhe yhdistäessä %s@%s:%s, viesti=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Palvelin %s vaatii käyttäjänimen/salasanan" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Sammutetaan" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Postipalvelimeen yhdistäminen epäonnistui" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "TLS yhteyden aloittaminen epäonnistui" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Postipalvelimen varmennus epäonnistui" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Sähköpostin lähetys epäonnistui" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Sähköpostiyhteyden sulkeminen epäonnistui" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Sähköpostitus onnistui" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Sähköpostipohjia ei löydy hakemistosta %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Vastaanottajaa ei määritelty, sähköpostia ei lähetetty" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Virheellinen koodaus sähköpostipohjassa %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Sähköpostipohjia ei löydy" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd raportoi levy täynnä\n" "\n" "Hei,\n" "\n" "SABnzbd on lopettanut lataamasta, koska levy on lähes täynnä.\n" "Ole hyvä ja tee lisää tilaa ja jatka SABnzbd käsin.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Käynnistys/Sammutus" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "Lisätty NZB" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Jälkikäsittely aloitettu" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Työ valmistunut" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Muut viestit" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Varoitus: LOCALHOST on hämärä, käytä numeerista IP-osoitetta." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Palvelimen osoite \"%s:%s\" ei ole kelvollinen." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Istuntoavain puuttuu" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Virhe: Istuntoavain vaaditaan" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Virhe: Istuntoavain on virheellinen" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "API avain puuttuu, ole hyvä ja syötä Asetukset->Yleiset löytyvä api avain " "käyttämääsi kolmannen osapuolen ohjelmaan:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API avain virheellinen, käytä Asetukset->Yleiset löytyvää api avainta " "käyttämääsi kolmannen osapuolen ohjelmaan:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Authentikointi puuttuu, ole hyvä ja syötä käyttäjänimi/salasana Asetukset-" ">Yleiset kolmannen osapuolen ohjelmaasi:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Virhe: Toissijaista käyttöliittymää ei ole määritelty." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Käyttämäsi UNRAR versio ei ole suositeltu, nouda oikea osoitteesta " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "UNRAR ohjelmaa ei löydy, RAR-tiedostojen purkaminen ei ole mahdollista
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "PAR2 ohjelmaa ei löydy, korjaukset eivät ole mahdollista
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Aloitetaan uudelleenkäynnistys...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd sammutus valmis.
    Odota noin 5 sekuntia ja paina " "sitten alapuolella olevaa nappia.

    Päivitä
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Syöte" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Päivittäin" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Maanantai" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Tiistai" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Keskiviikko" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Torstai" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Perjantai" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Lauantai" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Sunnuntai" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "ei käytössä" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Selvitetään osoitetta" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Virheellinen parametri" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Takaisin" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Työ \"%s\" lisättiin uudelleen jonoon" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "" "Töitä jotka ovat merkitty '*' merkillä ei ladata automaattisesti uudelleen." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Vastaa" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Ei vastaa" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Ladattu" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Ladattu tähän mennessä" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Virheellinen arvo %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Ei voi luoda kansiota %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s kansio: %s virhe käytettäessä" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Ei voida yhdistää rekisteripolkuun HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Ei voida avata rekisteriavainta \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Erikoiskansioiden rekisteriavainten lukeminen epäonnistui" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Kohteen (%s) luominen epäonnistui" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Kohteen %s siirtäminen kohteeseen %s epäonnistui" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "NZB tiedostoa ei voida käyttää" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Yritä uudelleen" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Osoitteen nouto epäonnistui; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "" "pyopenssl moduuli puuttuu, ole hyvä ja asenna se https käyttöä varten" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Virhe luotaessa SSL avainta ja sertifikaattia" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Käyttöoikeuksien muuttaminen epäonnistui kohteelle %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Yhdistetään" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Puutteellinen joukko yhdistettäviä tiedostoja" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Tiedostoliitos %s epäonnistui" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Virhe \"%s\" yhdistettäessä tiedostoja" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Virhe \"%s\" ajettaessa file_join kohteelle %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Liitetty %s tiedostoa" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Purkaminen epäonnistui, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Virhe \"%s\" purettaessa RAR tiedostoja" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Virhe \"%s\" ajettaessa rar_unpack kohteelle %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Kohteen %s poisto epäonnistui!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Yritetään purkaa rar arkistoa salasanalla \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Purkaminen epäonnistui, arkisto vaatii salasanan" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Puretaan" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Purkaminen epäonnistui, %s ei löydy" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "VIRHE: kohdetta \"%s\" ei löydy" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Purkaminen epäonnistui, CRC virhe" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "VIRHE: CRC epäonnistui kohteessa \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Purkaminen epäonnistui, kirjoitusvirhe tai levy täynnä?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "VIRHE: kirjoitusvirhe (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Purkaminen epäonnistui, polku on liian pitkä" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "VIRHE: polku liian pitkä (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Purkaminen epäonnistui, katso loki" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "VIRHE: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "Käyttökelvoton RAR arkisto" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Odotettu tiedosto: %s puuttuu => purkuvirhe?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Purkaminen epäonnistui, odotettua tiedostoa ei purettu" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Purkaminen epäonnistui, nämä tiedostot puuttuvat:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Purettiin %s tiedostoa/kansiota kohteeseen %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s tiedostoa kohteessa %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Virhe \"%s\" ajettaessa unzip() kohteelle %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Pikatarkistetaan" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Korjaa" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Pikatarkistus OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Aloitetaan korjaus" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Korjaus epäonnistui, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Virhe %s ajettaessa par2_repair setille %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Virhe \"%s\" ajettaessa par2_repair setille %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 vastaanotti vääränlaiset asetukset, tarkista Asetukset->Muuttujat" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Varmennettiin ajassa %s, kaikki tiedostot kelvollisia" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Varmennetiin ajassa %s, vaatii korjauksen" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Pääpakettia ei löydy..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Virheelliset par2 arkistot, varmennus ja korjaus ei mahdollista" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Korjaaminen epäonnistui, ei tarpeeksi korjauslohkoja (%s puuttuu)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Noudetaan %s lohkoa..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Noudetaan" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Korjataan" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Korjattiin ajassa %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Varmennetaan" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Virhe tuotaessa OpenSSL moduulia. Yhdistetään EI-SSL kautta." #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Newzbin työn %s päivitys epäonnistui" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB lisätty jonoon" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Newzbin palvelin vaihto protokollaansa" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Sinulla ei ole maksettua aikaa Newzbin tililläsi" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Käyttö estetty, tarkista newzbin käyttäjänimi/salasana" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin raporttia %s ei löydy" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin antaa tuntemattoman virhekoodin (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Newzbin palvelin ei onnistunut antamaan tietoja kohteesta %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Newzbin kirjanmerkkiä %s ei voitu poistaa" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin antaa tuntemattoman virhekoodin (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Ei-tuettu jonotiedosto löytyi, ei voida jatkaa" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Virhe ladattaessa %s, korruptoitunut tiedosto havaittu" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Virhe lisättäessä %s, poistetaan" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Tuntematon koodaus" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Tiedosto %s on tyhjä, ohitetaan" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Virhe tuotaessa %s tiedostoa kohteesta %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Keskeneräinen NZB tiedosto %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Virheellinen NZB tiedosto %s, ohitetaan (syy=%s, rivi=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Tyhjä NZB tiedosto %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ohitetaan kaksoiskappale NZB \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Keskeytetään kaksoiskappale NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Keskeytetty, ei voi valmistua" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "KAKSOISKAPPALE" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "SALATTU" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "LIIAN SUURI" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "KESKENERÄINEN" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "Odota %s sekunttia" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Ladattiin ajassa %s keskilatausnopeudella %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artikkelia oli väärin muotoiltuja" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s artikkelia puuttui" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artikkelissa oli ei-vastaavia kaksoiskappaleita" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s artikkelia poistettiin" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Virhe tuotaessa %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Varoitukset" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Toimeton" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Asetukset" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Jono" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Tyhjennä jono" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historia" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Tyhjennä historia" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Nopeusrajoitus" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Keskeytä" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Jatka" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Nouda Newzbin kirjanmerkit" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Tarkista vahdittu kansio" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Valmistuneet-kansio" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Lataukset-kansio" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Vianmääritys" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Käynnistä uudelleen" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Käynnistä uudelleen ilman kirjautumista" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Lopeta" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Vie ensimmäiset 10 kohdetta jonoon" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Tyhjä" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Vie viimeiset 10 kohdetta historiaan" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Uusi versio saatavilla" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Mene velhoon" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Pysäytetään..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Ongelma" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd ei ole yhteensopiva kaikkien ohjelmistopalomuurien kanssa.
    \n" " %s
    \n" " Pahoittelumme, mutta emme voi ratkaista tätä yhteensopivuusongelmaa " "juuri nyt.
    \n" " Ole hyvä ja lähetä valitus palomuurin toimittajallesi.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-" "palvelimelleen.
    \n" " Porttia %s kohteessa %s yritettiin käyttää , mutta se ei ollut " "vapaana.
    \n" " Jokin toinen ohjelmisto käyttää porttia tai SABnzbd on jo " "käynnissä.
    \n" "
    \n" " Ole hyvä ja uudelleenkäynnistä SABnzbd toisella porttinumerolla." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "Jos saat tämän virhesanoman uudestaan, kokeile toista numeroa.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-" "palvelimelleen.
    \n" " Porttia %s kohteessa %s yritettiin käyttää , mutta tilillä jolla SABnzbd " "käynnistettiin ei ollut oikeuksia käyttää sitä.
    \n" " OSX ja Linux järjestelmissä normaalien käyttäjien tulee käyttää portteja " "jotka ovat suurempia kuin 1023.
    \n" "
    \n" " Ole hyvä ja uudelleenkäynnistä SABnzbd toisella porttinumerolla." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd tarvitsee vapaan tcp/ip portin sisäiselle web-" "palvelimelleen.
    \n" " Olet määritellyt epäkelvon osoitteen.
    \n" " Turvalliset arvot ovat localhost ja 0.0.0.0
    \n" "
    \n" " Ole hyvä ja uudelleenkäynnistä SABnzbd kunnollisella isäntäosoitteella." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd havaitsi tallennettua tietoa toisesta SABnzbd versiosta
    \n" " mutta ei voi uudelleenkäyttää tietoja toisesta ohjelmasta.

    \n" " Haluat ehkä ladata jonon loppuun toisella ohjelmallasi.

    \n" " Tämän jälkeen, käynnistä ohjelma \"--clean\" muuttujalla.
    \n" " Tämä tyhjentää nykyisen jonon ja historiasi!
    \n" " SABnzbd luki tiedostoa \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd ei löydä sen web-käyttöliittymän tiedostoja polusta %s.
    \n" " Ole hyvä ja asenna ohjelma uudelleen.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd havaitsi vakavan virheen:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd tunnisti Jonon ja Historian vanhemmasta (0.4.x) " "julkaisusta.

    \n" " Molemmat, jono ja historia ohitetaan ja ne saattavat hävitä!

    \n" " Haluat ehkä lopettaa SABnzbd-ohjelman ja ladata jonon loppuun " "vanhemmalla ohjelmalla.

    \n" " Klikkaa OK jatkaaksesi SABnzbd-ohjelmaan" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd havaitsi, että tiedosto sqlite3.dll puuttuu.

    \n" " Jotkin huonosti suunnitellut viruksentorjunta ohjelmistot poistavat " "tämän tiedoston.
    \n" " Tarkista virustorjunta ohjelmistosi, yritä asentaa SABnzbd uudelleen ja " "valita virustorjunta ohjelmistosi valmistajalle.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Paina Windows-nappia+R ja kirjoita seuraava rivi (esimerkki):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Avaa pääte ja kirjoita rivi (esimerkki):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "" "On todennäköistä, että käytössäsi on ZoneAlarm ja käyttöjärjestelmäsi on " "Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Ohjelma ei käynnistynyt!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Sinulla ei ole käyttöoikeuksia porttiin %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Vakava virhe" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Selainta ei voida käynnistää, todennäköisesti ei löydy" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Ei käyttöoikeutta" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Virhe %s: Syötä kelvollinen käyttäjänimi ja salasana." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Jälkikäsittelyjonon lataaminen epäonnistui: Väärä versio (tarvitaan:%s, " "löytyi:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Ei voitu poistaa nzo:ta jälkikäsittelyn jonosta (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "Lataaminen saattaa epäonnistua, vain %s osaa %s osasta saatavilla" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Lataus epäonnistui - Työ on palvelimesi säilytyksen ulkopuolella?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Ei voitu luoda lopullista kansiota %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Jälkikäsittelyä ei suoritettu, koska varmennus epäonnistui" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Siirretään" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Lähetettiin %s jonoon" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Virhe uudelleennimettäessä \"%s\" nimelle \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Tiedostojen siirto epäonnistui" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Ajetaan skripti" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Ajetaan käyttäjän skripti %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Ajettiin %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Lisää" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Näytä skriptin tuloste" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Lataus valmistui" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Lataus epäonnistui" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Jälkikäsittely epäonnistui kohteelle %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "katso lokitiedosto" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Jälkikäsittely peruutettiin (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "%s puhdistaminen epäonnistui." #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Virhe poistettaessa työkansiota (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Jälkikäsittely" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Ei par2 arkistoja" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Yritetään SFV tarkistusta" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Jotkin tiedostot eivät varmentuneet \"%s\" kanssa" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Tarkastus käyttäen SFV tapauksia oli onnistunut" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "%s poistaminen epäonnistui" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Järjestelmän lepotilaan laittaminen epäonnistui" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Järjestelmän valmiustilaan laittaminen epäonnistui" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Virhe sammutettaessa järjestelmää" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Virheellinen RSS syötteen kuvaus \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "RSS noutaminen epäonnistui kohteesta %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Ei ole käyttöoikeutta syötteeseen %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "RSS syöte %s oli tyhjä" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Puutteellinen syöte" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Tyhjä RSS kohde löytyi (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Näytä käyttöliittymä" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Avaa valmistuneet-kansio" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Sammuta" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Jäljellä" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Virheellinen ajastus %s kohteessa %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Tuntematon toiminto: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Ajastettu tuntemattomalle palvelimelle %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Lataa" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Yhdistä tiedostot" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Pura" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Skripti" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Lähde" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Epäonnistui" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Valmistunut" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Epäonnistunut" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Odotetaan" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Korjataan..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Puretaan..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Siirretään..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Ajetaan skripti..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Noudetaan ylimääräiset lohkot..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Pikatarkistus..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Varmennetaan..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Ladataan" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Nouda NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Tarkistetaan" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Toisto" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Toiminto" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Parametrit" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Tehtävä" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "poista palvelin käytöstä" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "ota palvelin käyttöön" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Nopeusrajoitus" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Keskeytä kaikki" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Keskeytä jälkikäsittely" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Jatka jälkikäsittelyä" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Lue RSS syötteet" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Poista epäonnistuneet työt" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "kt/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "Mt" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "Gt" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "tunti" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "tuntia" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "minuutti" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minuuttia" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sekunti" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "sekuntia" #: sabnzbd/skintext.py:79 msgid "day" msgstr "päivä" #: sabnzbd/skintext.py:80 msgid "days" msgstr "päivää" #: sabnzbd/skintext.py:81 msgid "week" msgstr "viikko" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Kuukausi" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "Vuosi" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Kuukauden päivä" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Tällä viikolla" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Tässä kuussa" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Tänään" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Yhteensä" #: sabnzbd/skintext.py:97 msgid "on" msgstr "käytössä" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametrit" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Python versio" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Kotisivu" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "tai" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Isäntä" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "Kommentti" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "Lähetä" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "Peruuta" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "Muu" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "Ilmoita" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "Video" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "Ääni" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Automaattinen usenet lataustyökalu" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Tallenna" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Jonossa" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Oletko varma?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Poistetaanko kaikki ladatut tiedostot?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Alkuun" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Asetukset" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Tila" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Ohje" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Foorumi" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Yleiset" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Kansiot" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Muuttujat" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Palvelimet" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Ajastus" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Huomautukset" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Sähköposti" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Indeksointisivustot" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Kategoriat" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Lajittelu" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Erikoisasetukset" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Lataukset-kansio" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Valmistuneet-kansio" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Latausnopeus" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "KESKEYTETTY" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "%s artikkelia välimuistitettu (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Kuorma" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "VAROITUKSET" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Uusi versio %s saatavilla osoitteesta" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Lisää uusia latauksia" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Oletko varma, että haluat sammuttaa SABnzbdn?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Lisää" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Raportti-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Lisää tiedostosta" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Kategoria" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Käsitellään" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioriteetti" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Korjaa" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Pura" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Poista" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "U" #: sabnzbd/skintext.py:177 msgid "D" msgstr "D" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Pakota" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normaali" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Korkea" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Matala" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Pysäytä" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Syötä osoite" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " tai Raportti ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Lajittele nimen mukaan" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Lajittele iän mukaan" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Lajittele koon mukaan" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Piilota tiedostot" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Näytä tiedostot" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Kun jono on tyhjä" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Sammuta tietokone" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Lepotila" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Horrostila" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Sammuta SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Nopeusrajoitus" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Keskeytä ajaksi" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Järjestys" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nimi" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Jäljellä/Yhteensä" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Aikaa jäljellä" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "IKÄ" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Poista" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Yritä uudelleen" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Toiminnot" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Skriptit" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Poistetaanko kaikki kohteet jonosta?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Puhdista NZBt" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Puhdista NZBt & poista tiedostot" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Poista NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Poista NZB ja tiedostot" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "/" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Puuttuvat artikkelit" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Latausrajoitusta jäljellä" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "käsikäyttöinen" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Resetoi latausrajoitus nyt" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Tyhjennä epäonnistuneiden historia" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Poistetaanko kaikki valmistuneet kohteet historiasta?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Poistetaanko kaikki epäonnistuneet kohteet historiasta?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Piilota yksityiskohdat" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Näytä yksityiskohdat" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Historian koko" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Näytä epäonnistuneet" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Näytä kaikki" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Koko" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Puhdista epäonnistuneet NZBt" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Puhdista epäonnistuneet NZBt & poista tiedostot" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Puhdista valmistuneet NZBt" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Valinnainen täyte-NZB" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Polku" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "Virus/roskaposti" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "Salasanasuojattu" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "Säilytyksen ulkopuolella" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "Muu ongelma" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Pakota yhteyden katkaisu" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Tämä lähettää testiviestin sähköpostiosoitteeseesi." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Näytä loki" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Näytä webloki" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Testaa sähköpostia" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Lokiinkirjaus" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Virheet/varoitukset" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Tiedot" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Debug" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Yhteydet" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Ketju" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Sähköpostitestin tulokset" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Viimeisimmät varoitukset" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "tyhjennä" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Poista esto" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Artikkelin tunniste" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Tiedostojoukko" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Milloin" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Tyyppi" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Varoitus" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Käytössä" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Asetustiedosto" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Käytetty välimuisti" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Tämä uudelleenkäynnistää SABnzbdn.
    Käytä sitä kun luulet ohjelman " "toimivan epävakaasti.
    Lataaminen keskeytyy uudelleenkäynnistyksen " "ajaksi ja jatkuu ohjelman käynnistyttyä." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Latauskansiossa on orpoja töitä.
    Voit valita niiden poistamisen " "(sisältäen tiedostot) tai voit lähettää ne takaisin jonoon." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "\"Korjaa\" painike käynnistää SABnzbd uudelleen ja luo jonon
    sisällön " "täydellisesti uudelleen, säilyttäen jo ladatut tiedostot.
    Tämä muuttaa " "jonon järjestystä." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Versio" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Käynnissäoloaika" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Varmuuskopioi" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "OZnzb" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Yleisasetukset" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Muutokset vaativat SABnzbdn uudelleenkäynnistyksen!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "SABnzbd web-palvelin" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "SABnzbd isäntä" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Osoite jota SABnzbdn tulisi kuunnella." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "SABnzbd portti" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Portti jota SABnzbdn tulisi kuunnella." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Web-käyttöliittymä" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Valitse teema." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Toissijainen web-käyttöliittymä" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Aktivoi toissijainen teema." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Web-palvelimen todennus" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "SABnzbd käyttäjänimi" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Vaihtoehtoinen käyttäjänimi todennukseen." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "SABnzbd salasana" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Vaihtoehtoinen salasana todennukseen." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "HTTPS-tuki" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "HTTPS käytössä" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "ei asennettu" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Ota käyttöön käyttöliittymän käyttäminen HTTPS-osoitteesta." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "HTTPS portti" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Jos tyhjä, oletusportti kuuntelee ainoastaan HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "HTTPS sertifikaatti" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Tiedostonimi tai polku HTTPS sertifikaattiin." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "HTTPS avain" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Tiedostonimi tai polku HTTPS avaimeen." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "HTTPS ketjun sertifikaatit" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Tiedostonimi tai polku HTTPS ketjuun." #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Hienosäätö" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Jonon automaattinen päivitysväli:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "Jonon päivitysväli web-käyttöliittymässä(sek, 0= ei päivitä)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "RSS tarkistusväli" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Tarkistusväli (minuutteina, vähintään 15). Ei aktiivinen kun käytät " "Ajastinta!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Lataamisen nopeusrajoitus" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Latausnopeuden rajoitus (kt/s, kilotavuina sekunnissa)." #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Välimuistirajoitus artikkeleille" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Välimuistita artikkelit muistissa levytapahtumien vähentämiseksi.
    Tavuina, vaihtoehtoisesti lisää pääte K,M,G. Esimerkiksi: \"64M\" tai " "\"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Puhdistuslista" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista tiedostopäätteistä jotka tulisi poistaa lataamisen jälkeen.
    Esimerkiksi: .nfo tai .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Tallenna muutokset" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Kieli" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Valitse web-käyttöliittymän kieli." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "API avain" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Tämä avain antaa kolmannen osapuolen ohjelmille täyden pääsyn SABnzbd-" "ohjelmaan." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "NZB avain" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Tämä avain antaa kolmannen osapuolen ohjelmille oikeudet lisätä NZB-" "tiedostoja SABnzbd-ohjelmaan." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Luo uusi avain" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Poista käytöstä API avain" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Älä vaadi API avainta." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "KÄYTÄ OMALLA VASTUULLA!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "QR-koodi" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "API avaimen QR-koodi" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Kansion asetukset" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "HUOM: Kansiot luodaan automaattisesti tallennuksen yhteydessä. Voit " "käyttää täydellisiä polkuja jos haluat tallentaa oletuskansioiden " "ulkopuolelle." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Käyttäjähakemistot" #: sabnzbd/skintext.py:345 msgid "In" msgstr "Kohteessa" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Väliaikaiset lataukset kansio" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Sijainti jonne tallennetaan latauksessa olevat kohteet ennen käsittelyä.
    Voidaan muuttaa vain kun jono on tyhjä." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Pienin vapaan tilan määrä väliaikaisille latauksille" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Keskeytä automaattisesti kun vapaan tilan määrä on vähemmän kuin tämä " "arvo.
    Tavuina, mutta voit laittaa perään K,M,G,T kirjaimen. " "Esimerkiksi: \"800M\" tai \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Valmistuneet kansio" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Sijainti jonne tallennetaan valmistuneet ja täysin käsitellyt ladatut " "kohteet.
    Käyttäjän asettamat kategoriat voivat kumota tämän." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Käyttöoikeudet valmistuneille latauksille" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Aseta käyttöoikeusmalli valmistuneille tiedostoille/kansioille.
    Oktaalilukuna. Esimerkiksi: \"755\" tai \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Vahdittu kansio" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Kansio jota vahditaan .nzb tiedostojen varalta.
    Etsii .nzb " "tiedostoja myös .zip .rar ja .tar.gz arkistojen sisältä." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Vahditun kansion tarkistusväli" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Skannausväli sekunteina .nzb tiedostoille." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Jälkikäsittelyskriptien kansio" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "" "Kansio jossa ovat käyttäjän skriptit joita käytetään jälkikäsittelyssä." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Sähköpostipohjien kansio" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Kansio joka sisältää käyttäjän luomat sähköpostipohjat." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Salasanatiedosto" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Tiedosto joka sisältää kaikki salasanat joita kokeillaan salattuihin RAR " "tiedostoihin." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Järjestelmäkansio" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Hallinnollinen kansio" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Sijainti jonne tallennetaan jonon hallinnan ja historian tietokannat.
    Voidaan muuttaa vain jonon ollessa tyhjä." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Tiedostoja ei tulla siirtämään. Vaatii SABnzbd " "uudelleenkäynnistyksen!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Lokikansio" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Sijainti jonne SABnzbd ohjelman lokitiedostot tallennetaan.
    Vaatii " "SABnzbd uudelleenkäynnistyksen!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr ".nzb varmuuskopiokansio" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Sijainti jonne .nzb tiedostot tallennetaan." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Oletuskansio" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Parametrien asetukset" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Käsittelyparametrit" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Pikatarkistus käytössä" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Ohita par2 tarkistus kun tiedostot ovat 100% kunnollisia." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Unrar käytössä" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Ottaa käyttöön sisäänrakennetun unrar toiminnon." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Unzip käytössä" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Ottaa käyttöön sisäänrakennetun unzip toiminnon." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Tiedostojen yhdistäminen käytössä" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "" "Yhdistää tiedostot jotka päättyvät .001,.002 jne. yhdeksi tiedostoksi." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "TS-tiedostojen yhdistäminen käytössä" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "" "Yhdistää tiedostot jotka päättyvät .001.ts,.002.ts jne. yhdeksi tiedostoksi." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Par puhdistus käytössä" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Puhdistaa par tiedostot (jos varmennus/korjaus onnistui)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Huomioi yEnc CRC virheet" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "" "Jos artikkelissa on CRC virhe, yritetään hakea se toiselta palvelimelta." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Hae artikkelit vain jonon huipulta" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Laita päälle jos haluat ohjelman käyttävän vähemmän muistia. Ota pois päältä " "jos haluat estää hitaiden töiden aiheuttavan ruuhkaa jonossa." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Jälkikäsittele vain onnistuneet työt" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Suorittaa jälkikäsittelyn vain niille töille jotka läpäisevät kaikki PAR2 " "tarkistukset." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Toiminto kun salattu RAR havaitaan" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Jos valitsit \"Keskeytä\", sinun täytyy asettaa salasana ja jatkaa työn " "lataamista." #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Tunnista päällekkäiset lataukset" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Tunnistaa identtisesti nimetyt NZB tiedostot (vaatii NZB varmuuskopio -" "valinnan) ja päällekkäiset otsikot RSS syötteissä." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Ei käytössä" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Hylkää" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Lopeta" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "SFV-pohjaiset tarkistukset käytössä" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Suorittaa ylimääräisen varmennuksen SFV tiedostojen avulla." #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Tarkista purkamisen lopputulos" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Tarkistaa purkamisen lopputulokset (täytyy olla pois päältä joissain " "tiedostojärjestelmissä)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Kansion uudelleennimeäminen käytössä" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Käyttää väliaikaisia nimiä kun jälkikäsittely on käynnissä. Poista käytöstä " "jos järjestelmäsi ei toimi oikein asetuksen ollessa päällä." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Oletus jälkikäsittely" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "" "Käytetään kun mitään jälkikäsittelyä ei ole määriteltynä kategorialle." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Käyttäjän oletusskripti" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "" "Käytetään kun mitään käyttäjän skriptiä ei ole määritettynä kategorialle." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Esijonon käyttäjän skripti" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Käytetään ennen NZB lisäämistä jonoon." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Oletusprioriteetti" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Käytetään kun mitään prioriteettiä ei ole määritettynä kategorialle." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Moniydin Par2 käytössä" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Lue Wikin ohjeet tähän!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Ylimääräiset PAR2 parametrit" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Nice muuttujat" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "IONice muuttujat" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Muut valinnat" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Katkaise yhteys kun jono on tyhjä" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Katkaise yhteys Usenet palvelimeen/palvelimiin kun jono on tyhjä tai tila on " "keskeytetty." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Lähetä ryhmä" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Lähettää ryhmäkomennon ennen artikkeleiden pyytämistä." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Järjestä iän mukaan" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Järjestelee kohteet (keskimääräisen) iän mukaan." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Tarkista uusi versio" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Tarkistaa viikottain uusimman SABnzbd version." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Myös testiversiot" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Korvaa välilyönnit kansionimessä" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Korvaa välilyönnit alaviivoilla kansionimissä." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Korvaa pisteet kansionimessä" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Korvaa pisteet välilyönneillä kansionimissä." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Korvaa kielletyt merkit kansionimissä" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Korvaa kielletyt merkit kansionimissä vastaavalla merkillä (jos ei " "vastaavaa, poistaa)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Käynnistä selain käynnistyksen yhteydessä" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Käynnistää oletusselaimen kun SABnzbd käynnistetään." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Keskeytä lataus jälkikäsittelyn ajaksi" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Keskeyttää lataamisen kun jälkikäsittely alkaa ja jatkaa lataamista kun se " "lopetetaan." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ohita näytteet" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Ohittaa näytetiedostot (esim. videonäytteet)." #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Poista lataamisen jälkeen" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Älä lataa" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "SSL tyyppi" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Käytä V23 ellei tarjoajasi vaadi toisin!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Käytä 12-tuntista kelloa (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Näyttää ajat AM/PM muodossa (ei vaikuta ajastuksiin)" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Palvelin" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Jälkikäsittely" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Nimeäminen" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Latausrajoitus" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "Indeksoidaan" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Kuinka paljon voidaan ladata tässä kuussa (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Resetointipäivä" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Minä päivänä kuusta tai viikosta (1=Maanantai) palveluntarjoajasi resetoi " "rajoituksen? (Voit syöttää kellonajan perään hh:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Jatka automaattisesti" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "Pitäisikö latauksia jatkaa kun latausrajoitus on resetoitu?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Latausrajoituksen pituus" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Resetoidaanko rajoitus joka päivä, viikko vai kuukausi?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Tarkista ennen lataamista" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "Yritä ennustaa latauksen valmistuminen ennen lataamista (hitaampi!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Enimmäismäärä uudelleenyrityksille" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Enimmäismäärä uudelleenyrityksiä yksittäiselle palvelimelle." #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Vain valinnaisille palvelimille" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Käytä uudelleenyritysten määrää vain valinnaisille palvelimille" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Peruuta työt jotka eivät voi valmistua" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Keskeytetään työ, jos latauksen yhteydessä huomataan liikaa dataa puuttuvan" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "OZnzb integraatio käytössä" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" "Lisää enemmän toimintoja, kuten arvostelut ja lisätiedot jotka saadaan kun " "yhdistetään OZnzb indeksointiin." #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "Sivuston API avain" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" "Tämän avaimen avulla indeksoija tietää kuka olet. Tarkista avain osoitteesta " "https://www.oznzb.com/profile." #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "Tarkista osoitteesta https://www.oznzb.com/profile" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "Automaattinen palaute" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" "Lähetä automaattisesti laskettu latauksen vahvistustulos indeksoijalle." #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Palvelinasetukset" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Palvelimen tyyppi" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Lisää palvelin" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Portti" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Käyttäjänimi" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Salasana" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Aikakatkaisu" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Säilytysaika" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Varapalvelin" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Valinnainen" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Ota käyttöön" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Poista palvelin" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Testaa palvelinta" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Nollaa laskurit" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testataan pavelimen tietoja..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Klikkaa alapuolelta testataksesi." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Kaista" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Ajastimen asetukset" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Lisää ajastus" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Poista" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Nykyiset ajastukset" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "RSS asetukset" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Uuden syötteen osoite" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Valintaruutu syötteen nimen vieressä täytyy olla valittuna jotta syöte on " "päällä ja uusia kohteita tarkistetaan automaattisesti.
    Kun syöte " "lisätään, siitä lisätään vain uusia kohteita eikä niitä jotka ovat jo " "julkaistu syötteessä ellet paina \"Pakota lataus\" -painiketta." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Lisää syöte" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Poista syöte" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Lue syöte" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Pakota lataus" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Suodata" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Ohita" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Hyväksy" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Hylkää" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Vaatii" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "VaadittuCat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Ei vastaavuutta" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Syötteet" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Lue kaikki syötteet nyt" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Asetukset" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Suodattimet" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Sähköpostiasetukset" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Sähköposti-ilmoitus onnistuneesta työstä" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Ei koskaan" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Aina" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Vain virheet" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Levy täynnä tiedotteet" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Lähetä sähköposti kun levy on täynnä ja SABnzbd on keskeytetty." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Lähetä RSS ilmoitukset" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Lähetä sähköpostia kun RSS syötteestä lisätään töitä jonoon." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Sähköpostitilin asetukset" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "SMTP-palvelin" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Sähköpostin lähtevän postin palvelimen osoite." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Sähköpostin vastaanottaja" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Sähköpostiosoite johon viestit lähetetään." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Sähköpostin lähettäjä" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Kuka näytetään viestin lähettäjänä?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "VALINNAINEN tilin käyttäjänimi" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Kirjautumisen vaativalle sähköpostille, tilin käyttäjänimi." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "VALINNAINEN tilin salasana" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Kirjautumisen vaativalle sähköpostille, tilin salasana." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Growl käytössä" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Lähetä ilmoitukset Growliin" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Palvelimen osoite" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Käytä vain Growl etäpalvelimelle (isäntä:portti)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Palvelimen salasana" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Valinnainen salasana Growl palvelimelle" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "NotifyOSD käytössä" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Lähetä ilmoitukset NotifyOSD:hen" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Ilmoituskeskus" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Lähetä ilmoitukset ilmoituskeskukseen" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Ilmoituksien luokat" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Ottaa luokat käyttöön viesteille joita raportoidaan (ei mitään, yksi tai " "monta)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Jos sinulla on tili osoitteessa www.newzbin2.es, voit " "syöttää tilisi tiedot tähän.
    Tämä avaa lisätoimintoja." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Tilitiedot" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Newzbin käyttäjänimi" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Syötä tilisi käyttäjänimi tähän." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Newzbin salasana" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Kirjoita tilin salasana tähän." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Kirjanmerkkien käsittely" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Nouda kirjanmerkit automaattisesti" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Noutaa työt automaattisesti kirjanmerkeistäsi." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Nouda kirjanmerkit nyt" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Piilota kirjanmerkit" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Näytä kirjanmerkit" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Poista kirjanmerkki latauksen valmistuessa" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Poistaa kirjanmerkin listalta kun lataus on valmistunut." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Tarkistusväli" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "Minuutteina (vähintään 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Käsitellyt kirjanmerkit" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Jos sinulla on tili osoitteessa www.nzbmatrix.com, voit " "syöttää tilisi tiedot tähän.
    Nämä vaaditaan jos haluat käyttää RSS " "syötteitä kyseiseltä sivustolta." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "NzbMatrix käyttäjänimi" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "NzbMatrix API avain" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Kirjoita NzbMatrix API avain tähän." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Käyttäjän määrittämät kategoriat" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Määrittää jälkikäsittelyn ja tallennuksen." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Käytä \"Ryhmien / Indeksoijan tunnisteet\" -saraketta ryhmien ja " "tunnisteiden määrittämiseksi kategorioillesi.
    Jokerimerkkejä saa " "käyttää. Käytä pilkkuja termien erottelemiseen." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "Polun päättäminen tähteen * estää työkansioiden luomisen." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Suhteelliset kansiot jotka perustuvat" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Kansio/Polku" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Ryhmien / Indeksoijan tunnisteet" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Lajittelun asetukset" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Sarjojen lajittelu" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "TV lajittelu käytössä" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Ottaa jaksojen lajittelun ja uudelleennimeämisen käyttöön." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Mallin avain" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Tyhjennä" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Esiasetukset" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Esimerkki" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Yleinen lajittelu" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Elokuvien lajittelu käytössä" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Ottaa yleisen lajittelun ja uudelleennimeämisen käyttöön." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Pidä irralliset lataukset ylimääräisissä kansioissa" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Ota käyttöön jos latauksia ei ole laitettu omiin kansioihinsa." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Kategoriat joita koskee" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Merkitys" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Malli" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Tulos" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Tuotantokausi kansio" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Tuotantokausi kansio" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Jakso kansio" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Jakso kansio" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Otsikko" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Elokuvan nimi" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Elokuvan.nimi" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Elokuvan_nimi" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Ohjelman nimi" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Ohjelman.nimi" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Ohjelman_nimi" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Tuotantokauden numero" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Jakson numero" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Jakson nimi" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Jakson.nimi" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Jakson_nimi" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Tiedostotunniste" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Tunniste" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Osan numero" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Vuosikymmen" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Alkuperäinen tiedostonimi" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Alkuperäinen kansionimi" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Pienaakkoset" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEKSTI" #: sabnzbd/skintext.py:667 msgid "text" msgstr "teksti" #: sabnzbd/skintext.py:668 msgid "file" msgstr "tiedosto" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "kansio" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Lajittelumerkkijono" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Moniosainen selite" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "Kansioissa" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Ei kansioita" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Päivämäärän lajittelu" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Päivämäärän lajittelu käytössä" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "" "Ottaa päivämäärän mukaan nimettyjen tiedostojen lajittelun ja " "uudelleennimeämisen käyttöön." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Ohjelman nimi kansio" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Vuosittaiset-Kuukausittaiset kansiot" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Päivittäiset kansiot" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "kirjainkokoa säätävä" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Käsitellyt tulokset" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Harvoin käytetyt asetukset. Paina Ohje-painiketta Wiki-sivustolle " "päästäksesi, jotta saat tietää näiden tarkoituksen ja ohjeet " "käyttöön.
    Älä muuta ennen Wikin lukemista, koska näiden muuttamisella voi " "olla vakavia sivuvaikutuksia.
    Oletusarvot ovat kirjoitettuna sulkeiden " "sisään." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Arvot" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "NZB tietojen muokkaus" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Poista" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Ylin" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Ylös" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Alas" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Alin" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Kaikki" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Käänteinen" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Tiedostonimi" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Otsikko" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Ikä" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Valinta" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Oletko varma, että haluat poistaa" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Päivitä" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Asetukset" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Sivu" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Edellinen" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Seuraava" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Ensimmäinen" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Viimeinen" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Sulje" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Aseta keskeytysväli" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Lajittele" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Puhdistetaanko jono?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Keskeytysväli" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Keskeytä 5:ksi minuutiksi" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Keskeytä 15:ksi minuutiksi" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Keskeytä 30:ksi minuutiksi" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Keskeytä tunniksi" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Keskeytä 3:ksi tunniksi" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Keskeytä 6:ksi tunniksi" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Keskeytä 12:ksi tunniksi" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Keskeytä 24:ksi tunniksi" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Järjestä iän mukaan Vanhin→Uusin" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Järjestä iän mukaan Uusin→Vanhin" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Järjestä nimen mukaan A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Järjestä nimen mukaan Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Järjestä koon mukaan Pienin→Suurin" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Järjestä koon mukaan Suurin→Pienin" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Uudelleennimeä" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Jäljellä" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Puhdistetaanko historia?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Muutoksia ei ole tallennettu ja ne menetetään." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Avaa lähdeosoite" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Avaa tietoja sisältävä osoite" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Tallennusasema" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Näytä skriptien loki" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Ota JavaScript käyttöön, jotta Plush toimii oikein!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Lisää NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Plush asetukset" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Päivitys saatavilla!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Keskeytetään kuinka moneksi minuutiksi?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Keskeytä ajaksi..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Monioperaatiot" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Päävalikko" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Valmistuessa" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Järjestä iän mukaan(Vanhin→Uusin)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Järjestä iän mukaan(Uusin→Vanhin)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Järjestä nimen mukaan (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Järjestä nimen mukaan (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Järjestä koon mukaan (Pienin→Suurin)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Järjestä koon mukaan (Suurin→Pienin)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Puhdista" #: sabnzbd/skintext.py:781 msgid "left" msgstr "jäljellä" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Enimmäisnopeus" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Väli" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Nollaa" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Käytä valittuihin" #: sabnzbd/skintext.py:786 msgid "page" msgstr "sivu" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Kaikki" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Ei käytössä" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Päivitysväli" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Säiliön leveys" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Varmista jonon poistot" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Varmista historian poistot" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Tämä estää sisällön päivittämisen kun hiiren kursori on jonon päällä." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Estä päivitykset kun hiiri on päällä" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Nouda" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Lähetä" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Lähetä: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Vaihtoehtoisesti anna tiedostonimi" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Edistyminen" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Ei tarpeeksi levytilaa latauksien valmistumiseen!" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Vapaa tila" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Vapaana (Temp)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "EI TÖITÄ" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Lataukset" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Jonon korjaus" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Lue syöte hakee vain syötteen uuden sisällön. " "Pakota lataus hakee kaikki vastaavat NZB:t heti." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Tunti:Min" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Poista valmistuneet" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Poistetaanko kaikki epäonnistuneet historiasta?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Poista epäonnistuneet" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Linkit" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Näytetään %s - %s tulosta %s tuloksesta" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Ei tuloksia" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Näytetään yksi tulos" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Sähköposti lähetetty!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Ilmoitus lähetetty!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Tallennetaan..." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Tallennettu" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Nopeus" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Päälle/Pois Lisää NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "Kaksoisnäkymä1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "Kaksoisnäkymä2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Mukautettu" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Hae kirjanmerkit" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Oletko varma, että haluat käynnistää SABnzbd uudelleen?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Päivitysväli" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Poista kaikki" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Piilota muokkausvalinnat" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Näytä muokkausvalinnat" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Muokkaa" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Aikaa jäljellä" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd pika-aloitus velho" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "SABnzbd versio" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Edellinen" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Pääsy" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Tahdon, että SABnzbd on käytettävissä jokaiselta verkossani olevalta PC:ltä." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Tahdon, että SABnzbd on käytettävissä vain omalta PC:ltäni." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Suojaa SABnzbd käyttö salasanalla (suositeltavaa)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Aktivoi HTTPS pääsy SABnzbd-ohjelmaan." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Muut" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Käynnistä internet selaimeni SABnzbd-sivulle kun ohjelma käynnistyy." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Palvelimen tiedot" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Syötä pääasiallisen usenet tarjoajasi tiedot." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Jotta voit ladata usenetistä tarvitset tarjoajan. Palveluntarjoajasi saattaa " "tarjota sinulle sellaisen, mutta on suositeltavaa hankkia premium-tarjoaja." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Eikö sinulla ole usenet tarjoajaa? Suosittelemme kokeilemaan %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Tarjoajasi sallimien yhteyksien lukumäärä." #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "Esim. 8 tai 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Valitse vain jos tarjoajasi sallii SSL yhteydet." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Klikkaa testataksesi syötettyjä tietoja." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Tämä kenttä on pakollinen." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Syötä kokonaisluku." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Mikäli olet newzbin tai nzbmatrix jäsen, voit syöttää käyttäjänimesi ja " "salasanasi tähän jotta ohjelma voi hakea nzb-tiedostot heiltä suoraan. Voit " "ohittaa tämän vaiheen jos et käytä kummankaan sivuston palveluita." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Lataa automaattisesti kirjanmerkkeihin lisätyt postaukset." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Esim." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Käynnistetään SABnzbd uudelleen..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Asennus on nyt valmis!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd on nyt käynnissä taustalla." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Selaimen tai sen välilehtien sulkeminen EI sammuta SABnzbd:tä." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Kun SABnzbd on käynnistynyt uudelleen, voit käyttää sitä seuraavasta " "osoitteesta: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "On suositeltavaa, että painat linkistä hiiren oikealla ja lisäät sen " "kirjanmerkkeihin. Sitten voit käyttää kirjanmerkkiä kun haluat käyttää " "SABnzbd ohjelmaa sen ollessa käynnissä taustalla." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Lisää ohjeita löytyy" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Siirry SABnzbd:hen" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Vaihe yksi" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Vaihe kaksi" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Vaihe kolme" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Vaihe neljä" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Vaihe viisi" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "Esim. 119 tai 563 SSL yhteyksille" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Poistu SABnzbd:stä" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Käynnistä velho" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "Jos sinulla ei ole vielä tiliä, voit luoda sen osoitteessa " #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd ohjelmalla EI OLE MINKÄÄNLAISTA TAKUUTA.\n" "Tämä on ilmainen ohjelma ja olet vapaa levittämään sitä tiettyjen ehtojen " "ollessa voimassa.\n" "Se on lisensoitu GNU GENERAL PUBLIC LICENSE Versio 2 alaiseksi ja (oman " "valinnan mukaan) myös myöhempien versioiden.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Virhe noudettaessa TV tietoja (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Virhe uudelleennimettäessä: %s %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Samankaltaisen tiedoston uudelleennimeäminen epäonnistui: %s %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Virheellinen nzbmatrix raporttinumero %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Tarvitset nzbmatrix VIP-tilin käyttääksesi API:a" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Virheelliset nzbmatrix käyttäjätiedot" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Ongelma nzbmatrix palvelimeen pääsyssä (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Isäntänimeä ei ole asetettu." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "Yhteyksiä ei ole asetettu. Aktivoi ainakin yksi yhteys." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Salasana on piilotettu ******, syötä uudelleen" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Virheelliset palvelimen tiedot" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Aikakatkaistu: Yritä laittaa SSL päälle tai yhdistä toiseen porttiin." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Aikakatkaistiin" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Virheellinen palvelimen osoite." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Palvelin lopetettiin kesken kirjautumisen" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Palvelin vaatii käyttäjänimen ja salasanan." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Yhdistäminen onnistui!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Varmennus epäonnistui, tarkista käyttäjänimi/salasana." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "Liikaa yhteyksiä, keskeytä lataaminen tai yritä myöhemmin uudelleen" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Yhteystestin lopputulosta ei voitu määrittää (%s)" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Virhe noudettaessa msgid %s osoitteesta www.newzbin.com - Tarkista " #~ "käyttäjänimi ja salasana" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "noudetaan msgid %s osoitteesta www.newzbin.com" #~ msgid "Expected size did not equal actual size" #~ msgstr "Odotettu koko ei vastannut todellista kokoa" SABnzbd-0.7.20/po/main/fr.po0000644000000000000000000040350212433712555015551 0ustar00usergroup00000000000000# French translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2014-06-10 17:11+0000\n" "Last-Translator: Fox Ace \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:53+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Impossible de démarrer l'interface web" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "" "Impossible de trouver le template de l'interface web: %s, essayer le " "template standard" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "module _yenc... Introuvable!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "binaire par2... Introuvable!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "binaire unrar... Introuvable!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "binaire unzip... Introuvable!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "S'il vous plaît soyez conscient que l'Hôte 0.0.0.0 aura besoin d'une adresse " "IPv6 pour les accès externes" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS désactivé car le certificat et la clé n'ont pas été trouvés" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s démarré" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "Arrêt terminé de SABnzbd" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s intercepté, enregistrement et fermeture en cours..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "Récupération msgid %s from www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Erreur d'obtention msgid %s à partir de www.newzbin2.es - S'il vous plaît " "assurez-vous que votre nom d'utilisateur et mot de passe soient définit" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Essai de récupération du NZB depuis %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Ne peut créer le fichier temporaire pour %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Essaie de définir l'état du serveur %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Espace disque faible PAUSE forcée" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Échec dans tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Enregistrement %s echoué" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Chargement %s echoué" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Test de Notification" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Aucun" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Par défaut" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "AVERTISSEMENT:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "ERREUR:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "inconnu" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Echec de la compilation de regex pour la recherche du terme : %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "j" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disque plein! Pause Forcée" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Erreur de disque lors de la création du fichier %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "" "AVERTISSEMENT: Mise en pause de \"%s\" en raison de fichiers RAR cryptés" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "" "AVERTISSEMENT: Tâches \"%s\" interrompus en raison de fichiers RAR cryptés" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Interrompu, cryptage détecté" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" "AVERTISSEMENT : Le fichier RAR\"%s\" contient une extension indésirables. Le " "fichier indésirable est %s " #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "Abandonné, extension indésirable détecté" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s manquants" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Quota atteint, téléchargement mis en pause" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s n'est pas une adresse email valide" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Adresse du serveur requis" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Impossible de créer %s dossier %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Impossible d'écrire dans le fichier INI %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Impossible de créer le fichier de sauvegarde de %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Mot de passe incorrect %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s n'est pas une valeur octale correcte" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "Le chemin UNC \"%s\" n'est pas autorisé ici" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "" "Erreur : La file d'attente n'est pas vide, impossible de changer le dossier." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Le dossier \"%s\" n'existe pas" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "Echec de la commande SQL, voir le journal" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "Echec du commit SQL, voir le journal" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Impossible de fermer la base de données, voir le journal" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Étape de journalisation invalide dans l'historique pour %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Échec du décodage de %s" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "Erreur CRC dans %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Article yEnc mal construit dans %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Erreur inconnue lors du décodage de %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => absents de tous les serveurs, rejeté" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Erreur lors de la suppression de %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Ne peut lire %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Impossible de lire le dossier a surveillé %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "En pause" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Le serveur %s sera ignoré pendant %s minutes" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Échec de l'initialisation %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Trop de connexions au serveur %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Partage de compte probable" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Échec de la connexion au serveur %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Impossible de se connecter au serveur %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Échec de la connexion à %s@%s:%s, message=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Le serveur %s requiert des identifiant/mot de passe" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Arrêt en cours..." #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Échec lors de la connexion au serveur de courriel" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Échec de l'initialisation de la connexion TLS" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Échec de l'authentification au serveur de mail" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Échec de l'envoi de l'email" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Échec de la fermeture de la connexion mail" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Succès de l'envoi du mail" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Impossible de trouver les modèles d'email dans %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Aucun destinataire déterminé, aucun email envoyé" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Codage non valide pour le modèle d'email %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Aucun modèle email trouvés" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "Pour: %s\n" "De: %s\n" "Date: %s\n" "Sujet: SABnzbd rapporte Disque Plein\n" "\n" "Salut,\n" "\n" "SABnzbd a arrêté le téléchargement, car le disque est presque plein.\n" "S'il vous plaît faite de la place avant de reprendre SABnzbd manuellement.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Démarrage/Arrêt" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "NZB ajouté" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Post-traitement démarré" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Tâche terminé" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Autres messages" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "" "Avertissement: LOCALHOST est ambigü, utilisez une adresse IP numérique." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "L' adresse du serveur \"%s:%s\" n'est pas valide." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Clé de session manquante" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Erreur : Clé de session requise" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Erreur : Clé de session incorrecte" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "Clé API manquante, entrez la clé API de la configuration générale dans votre " "application tierce :" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Clé API incorrecte, utilisez la clé API de la configuration générale dans " "votre application tierce :" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Authentification manquante, entrez vos identifiant/mot de passe dans la " "configuration générale dans votre application tierce :" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Erreur : Pas d'interface secondaire définie." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "La version de votre binaire UNRAR n'est pas recommandée, Vous pouvez " "l'obtenir ici http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Le binaire UNRAR n'a pas été trouvé, la décompression des fichiers RAR ne " "sera pas possible
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "" "Le binaire PAR2 n'a pas été trouvé, les réparations ne seront pas " "possibles
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Initialisation du redémarrage...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    Extinction de SABnzbd terminée.
    Veuillez attendre plus de 5 " "secondes et cliquer sur le bouton ci-dessous.

    Rafraîchir
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Flux RSS" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Quotidien" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Lundi" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Mardi" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Mercredi" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Jeudi" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Vendredi" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Samedi" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Dimanche" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "non" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Résoudre l'adresse" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Paramètre incorrect" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Retour" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "%s a été remis en file d'attente" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "" "Les éléments marqués avec '*' ne seront pas automatiquement téléchargés." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Correspond" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Ne correspond pas" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Téléchargé" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Téléchargé jusqu'à présent" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Valeur incorrecte pour %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Impossible de créer le dossier %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s dossier : %s Erreur d'accès" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Impossible de se connecter au registre HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Impossible d'ouvrir la clé de registre \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Échec de la lecture des clés de registre pour les dossiers spéciaux" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Échec lors de la création de (%s)" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Échec lors du déplacement de %s vers %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Fichier NZB inutilisable" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Réessayer" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Échec de récupération de l'URL; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "module pyopenssl manquant, nécessaire pour l'accès HTTPS" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Erreur lors de la création de la clé et du certificat SSL" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Impossible de changer les permissions pour %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Concaténation" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Séquence incomplète de fichiers pouvant être joints" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "La concaténation du fichiers %s a échoué" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Erreur \"%s\" lors de la concaténation des fichiers" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Erreur \"%s\" lors de l'exécution de file_join sur %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Concaténation %s fichiers" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Échec de la décompression, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Erreur \"%s\" lors de la décompression des fichiers RAR" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Erreur \"%s\" lors de l'exécution de rar_unpack sur %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Impossible de supprimer %s !" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Essaie unrar avec le mot de passe \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Échec de la décompression, l'archive nécessite un mot de passe" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Décompression" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Échec de la décompression, %s n'a pas été trouvé" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "ERREUR : impossible de trouver \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Échec de la décompression, erreur CRC" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "ERREUR : échec CRC pour \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "" "Échec de la décompression, erreur d'écriture ou espace disque insuffisant ?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "ERREUR : erreur d'écriture (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Extraction échoué, le chemin est trop long" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "ERREUR: le chemin trop long (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Échec de la décompression, voir le journal" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "ERREUR : %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "Fichier RAR inutilisable" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Le fichier attendu est manquant : %s => erreur unrar ?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "" "Échec de la décompression, un fichier attendu n'a pas été décompressé" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Extraction échoué, ces fichiers sont manquants :" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "%s fichier(s)/dossier(s) décompressé(s) en %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s fichiers en %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Erreur \"%s\" lors de l'exécution de unzip sur %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Contrôle Rapide" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Réparation" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Contrôle Rapide OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Réparation en cours" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Échec de la réparation, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Erreur %s lors de l'exécution de par2_repair sur %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Erreur \"%s\" lors la réparation de %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 a des options incorrectes, vérifiez votre configuration-> " "Paramètres Switches" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Vérifié en %s, tous les fichiers sont corrects" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Vérifié en %s, une réparation est nécessaire" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Le paquet principal n'a pas été trouvé..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Fichiers par2 non valides, impossible de vérifier ou réparer" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Échec de la réparation, blocs de réparation insuffisants (manque %s)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Récupération de %s blocs..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Récupération en cours" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Réparation en cours" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Réparé en %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Vérification en cours" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Erreur lors de l'importation du module OpenSSL. Connection sans SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Échec de la mise à jour du travail newzbin %s" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB ajouté à la file d'attente" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Le serveur Newzbin a changé son protocole" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Pas de crédits sur votre compte Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Non autorisé, vérifiez vos identifiant/mot de passe pour newzbin" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Rapport Newzbin %s non trouvé" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Erreur Newzbin non documentée (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Impossible d'obtenir les informations pour %s du serveur Newzbin" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Impossible de retirer le marque-page newzbin %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Erreur Newzbin non documentée (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Fichier de file d'attente incompatible, impossible à traiter" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Erreur lors du chargement de %s, fichier corrompu détecté" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Erreur lors de l'ajout de %s, supprimé" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Encodage inconnu" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Fichier %s vide, rejeté" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Echec lors de l'importation des fichiers %s depuis %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Fichier NZB %s incomplet" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Fichier NZB invalide %s, rejeté (raison=%s, ligne=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Fichier NZB %s vide" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorer NZB dupliqué \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Mise en pause de \"%s\" en raison de NZB dupliqué" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Interrompu, ne peut pas être achevée" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLIQUÉE" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "CRYPTÉE" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "TROP GRANDE" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "INCOMPLET" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "INDÉSIRABLES" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "PATIENTER %s sec" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Téléchargé en %s à %sB/s de moyenne" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s articles ont été mal formés" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s articles sont manquants" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s articles ne correspondaient pas a la copie" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s articles ont été retirés" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Erreur lors de l'importation de %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Avertissements" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Inactif" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Configuration" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "File d'attente" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Vider file d'attente" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historique" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Vider l'historique" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Vitesse limite" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pause" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Reprendre" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Récupérer favoris Newzbin" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Analyser le dossier des Nzbs" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Dossier complet" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Dossier incomplet" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Résoudre les problèmes" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Redémarrer" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Redémarrer sans se connecter" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Quitter" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Mettre en file d'attente les 10 premiers articles" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Vide" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Historique les 10 derniers articles" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Nouvelle version disponible" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Aller à l'assistant" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Arrêt en cours..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problème avec" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd n'est pas compatible avec certains pare-feu logiciels.
    \n" " %s
    \n" " Désolé, mais nous ne pouvons pas résoudre cette incompatibilité pour le " "moment.
    \n" " S'il vous plaît faite une demande à l'éditeur de votre pare-feu.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd a besoin d'un port tcp/ip libre pour le serveur Web " "interne.
    \n" " Port %s à %s a été essayé, mais il n'est pas disponible.
    \n" " Un autres logiciels utilise ce port ou SABnzbd est déjà en cours " "d'exécution.
    \n" "
    \n" " S'il vous plaît redémarrer SABnzbd avec un numéro de port différent." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "" "Si vous obtenez ce message d'erreur à nouveau, veuillez essayer un nombre " "différent.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd a besoin d'un port tcp/ip libre pour le serveur Web " "interne.
    \n" " Port %s a %s a été essayé , mais le compte utilisé pour SABnzbd n'a pas " "la permission de l'utiliser.
    \n" " Sur les systèmes OSX et Linux, les utilisateurs normaux doivent utiliser " "des ports supérieurs à 1023.
    \n" "
    \n" " S'il vous plaît redémarrer SABnzbd avec un numéro de port différent." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd a besoin d'une adresse hôte valide pour son serveur Web " "interne.
    \n" " Vous avez spécifié une adresse non valide.
    \n" " sont des valeurs sûres localhost et 0.0.0.0
    \n" "
    \n" " S'il vous plaît redémarrer SABnzbd avec une adresse hôte approprié." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd a détecté des données sauvegardées avec une autre version de " "SABnzbd
    \n" " il ne peut pas réutiliser les données de l'autre programme.

    \n" " Vous devez terminer votre première file d'attente avec l'autre " "programme.

    \n" " Après cela, lancer ce programme avec l'option \"--clean\".
    \n" " Cette opération efface la file d'attente actuelle et l'historique!
    \n" " SABnzbd lis le fichier \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd ne peut pas trouver ses fichiers %s dans l'interface web .
    \n" " S'il vous plaît installer le programme.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd a détecté une erreur fatale:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd a détecté une file d'attente et un historique d'une version " "ancienne (0.4.x).

    \n" " La file d'attente et l'historique seront ignorés et peuvent aussi être " "perdus!

    \n" " Vous pouvez choisir d'arrêter SABnzbd et de finir la file d'attente avec " "l'ancien programme.

    \n" " Cliquez sur OK pour ouvrir SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd a détecté que le fichier sqlite3.dll est manquant.

    \n" " Certains antivirus mal conçu peuvent supprimer ce fichier.
    \n" " S'il vous plaît vérifier votre antivirus, essayez de ré-installer " "SABnzbd et plaignez vous à l'éditeur de l'antivirus.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Appuyez sur la touche Drapeau+R et tapez la ligne (exemple):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Ouvrez une fenêtre de Terminal et tapez la ligne (exemple):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Il est probable que vous utilisez ZoneAlarm sur Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Le Programme ne démarre pas!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Le port %s n'est pas accessible" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Erreur fatale" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Impossible de lancer le navigateur web, probablement pas trouvé" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Accès refusé" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "" "Erreur %s: Vous devez fournir un nom d'utilisateur et un mot de passe valide." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Échec lors du chargement de la file d'attente de post-traitement : Mauvaise " "version (nécessaire:%s, trouvée:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "" "Échec de la suppression du nzo de la file d'attente de post-traitement (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "" "Le téléchargement pourrait échouer, seulement %s des requis %s sont " "disponibles" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Échec de téléchargement - Rétention du serveur dépassée ?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Impossible de créer le dossier %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Pas de post-traitement car la vérification a echoué" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Déplacement" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "%s mis en file d'attente" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Erreur lors du renommage de \"%s\" en \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Impossible de déplacer les fichiers" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Exécution de script" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Exécution du script utilisateur %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "%s exécuté" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Plus" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Voir le résultat du script" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Téléchargement terminé" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Téléchargement échoué" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Échec du post-traitement pour %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "voir le fichier journal" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Post-traitement interrompu (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Échec du nettoyage de %s." #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Erreur lors de la suppression du dossier de travail (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Post-traitement" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Pas de fichiers par2" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Essai vérification SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Certains fichiers n'ont pas pu être vérifiés \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Vérifié avec succès en utilisant des fichiers SFV" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Échec de la suppression de %s" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Échec de la mise en hibernatation" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Échec de la mise en veille" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Erreur lors de l'arrêt du système" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Description du flux RSS incorrecte \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Échec de la récupération RSS de %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Vous n'avez pas d'authentification valide pour ce flux %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "Le Flux RSS %s était vide" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Flux incompatible" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Entrée vide de flux RSS trouvée (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Afficher l’interface" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Ouvrir le dossier terminé" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Arrêter" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Restant" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Mauvaise planification %s à %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Action inconnue : %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Planification pour un serveur non existant %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Télécharger" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Concaténation" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Décompression" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Script" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Source" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Échec" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Terminés" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Échoué" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "En attente" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Réparation en cours..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Décompression en cours..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Déplacement en cours..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Exécution de script en cours..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Récupération des blocs supplémentaires ..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Vérification rapide..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Vérification..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Téléchargement" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Récupérer NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Vérification" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Fréquence" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Action" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Arguments" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Tâche" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "désactiver le serveur" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "activer le serveur" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Limite de vitesse" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Suspendre tout" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pause post-traitement" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Reprendre post-traitement" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Lire les flux RSS" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Retirer les tâches qui ont échoué" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "kbit/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "Mo" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "Go" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "heure" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "heures" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "min" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "mins" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sec" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "secondes" #: sabnzbd/skintext.py:79 msgid "day" msgstr "jour" #: sabnzbd/skintext.py:80 msgid "days" msgstr "jours" #: sabnzbd/skintext.py:81 msgid "week" msgstr "semaine" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Mois" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "Année" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Jour du mois" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Cette semaine" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Ce mois" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Aujourd'hui" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Total" #: sabnzbd/skintext.py:97 msgid "on" msgstr "oui" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Paramètres" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Version de Python" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Page d'accueil" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "ou" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Hôte" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "Commentaire" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "Envoyé" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "Annuler" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "Autre" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "Signaler" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "Vidéo" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "Audio" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "L'outil de téléchargement usenet tout inclus" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Enregistrer" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Mis en file d'attente" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Êtes-vous sûr ?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Supprimer tous les fichiers téléchargés?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Accueil" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Configuration" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Statut" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Aide" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Général" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Répertoires" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Switches" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Serveurs" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Planification" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Notifications" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Email" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Sites Index" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Catégories" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Triage" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Spécial" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Dossier Téléchargement" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Dossier Complet" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Vitesse de téléchargement" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "EN PAUSE" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "%s Articles en cache (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Sysload" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "AVERTISSEMENTS" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Une nouvelle version %s est disponible" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Ajouter de nouveaux téléchargements" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Etes-vous sûrs de vouloir arrêter SABnzbd ?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Ajouter" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Rapport-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Ajouter un fichier" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Catégorie" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Traitement en cours" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Priorité" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Réparer" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Décompresser" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Supprimer" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "D" #: sabnzbd/skintext.py:177 msgid "D" msgstr "S" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Forcer" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normale" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Haute" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Basse" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Arrêt" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Saisir une URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " ou Report ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Trier par nom" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Trier par âge" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Trier par taille" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Cacher les fichiers" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Afficher les fichiers" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "En fin de file d'attente" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Éteindre PC" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Mettre le PC en veille" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Mettre le PC en hibernation" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Arrêter SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Vitesse limite" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pause de" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Ordre" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nom" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Restant/Total" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "TRE" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "ÂGE" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Suppr." #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Réessayer" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Actions" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Scripts" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Supprimer tous les éléments de la file d'attente ?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Vider les NZB" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Vider les NZB & Supprimer les fichiers" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Supprimer NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Supprimer les NZB & Supprimer les fichiers" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "de" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Articles manquants" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Quota restant" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "manuel" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Réinitialisation Quota maintenant" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Purger Historique erronés" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Supprimer tous les éléments terminés de l'historique?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Supprimer tous les éléments erronés de l'historique?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Masquer détails" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Afficher détails" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Taille Historique" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Afficher les Erreurs" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Afficher Tout" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Taille" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Vider les NZB avec erreur" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Vider les NZB avec erreur & Supprimer les fichiers" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Vider les NZB terminés" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Option supplémentaire NZB" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Chemin d'accès" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "Virus/spam" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "Protégé par un mot de passe" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "En dehors de la rétention" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "Autre problème" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Forcer Déconnexion" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Ceci enverra un email de test sur votre compte." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Afficher le journal" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Afficher les weblogs" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Email de Test" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Journalisation" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Erreurs/Avertissements" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Debug" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Connections" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Traitement" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Résultat de l'Email de test" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Avertissements Récents" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "éffacer" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Débloquer" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Identifiant de l'article" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Ensemble de fichiers" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Quand" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Type" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Avertissement" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Activé" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Fichier de configuration" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Cache utilisé" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Ceci redémarrera SABnzbd.
    \r\n" "Utilisez cette fonction si vous pensez avoir un problème de stabilité.
    \r\n" "Les téléchargements en cours seront mis en pause puis repris." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Il y a des dossiers orphelins dans le répertoire de téléchargement.
    Vous pouvez choisir de les supprimer (y compris les fichiers) ou de les " "renvoyer dans la file d'attente." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "Ceci redémarre SABnzbd et fait une complète reconstruction
    de la file " "d'attente, tout en conservant les fichiers déjà téléchargés.
    Ceci " "modifiera l'ordre de la file d'attente." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Version" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Temps de fonctionnement" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Secours" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "OZnzb" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Configuration générale" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Les modifications nécessiteront un redémarrage de SABnzbd !" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Serveur web SABnzbd" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Hôte SABnzbd" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Hôte sur lequel SABnzbd doit attendre les connexions." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Port que SABnzbd doit surveiller." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Interface Web" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Choisissez un thème." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Interface Web secondaire" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Choisissez un thème pour la 2nde interface web." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Authentification Serveur Web" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Identifiant SABnzbd" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Nom d'utilisateur pour l'authentification (facultatif)." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Mot de passe SABnzbd" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Mot de passe pour l'authentification (facultatif)." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "Support HTTPS" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Activer HTTPS" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "non installé" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Active l'accès à l'interface via une adresse HTTPS." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Si vide, le port standard écoutera seulement HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "Certificat HTTPS" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Nom du fichier ou chemin du certificat HTTPS." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "Clé HTTPS" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Nom du fichier ou chemin de la clé HTTPS." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "Certificats Chaîne HTTPS" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Nom du fichier ou chemin d'accès de la chaîne HTTPS." #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Réglages" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Intervalle de rafraîchissement automatique de la file d'attente:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Intervalle de rafraichissement dans l'interface web (en sec, 0=aucun)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "Invervalle de vérification RSS" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Intervalle de vérification (en minutes, au moins 15). Non actif lorsque vous " "utilisez le Planificateur!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Vitesse limite de téléchargement" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Vitesse limite de téléchargement en kilobytes par seconde (kB/s)" #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Limite d'article en cache" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Permet de mettre en cache les articles pour réduire les accès disques.
    En Octets, peut être suivi de K,M,G.Par exemple : \"64M\" ou " "\"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Liste de nettoyage" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Liste des extensions de fichiers qui doivent être supprimés après " "téléchargement
    Par exemple: .nfo ou .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Enregistrer les modifications" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Langue" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Séléction de la langue de l'interface web." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "Clé API" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Cette clé permettra aux programmes tierces d'avoir un accès complet à " "SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "Clé NZB" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Cette clé permettra aux programmes tierces de pouvoir ajouter des NZB à " "SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Générer une nouvelle clé" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Désactiver la clé API" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "La clé API ne sera plus nécessaire pour l'interaction avec SABnzbd." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "A utiliser à vos risques et périls!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "Code QR" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "Clé API code QR" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Configuration des dossiers" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTE: Les dossiers seront créés automatiquement lors de " "l'enregistrement. Il est possible d'utiliser des chemins absolus." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Dossiers utilisateur" #: sabnzbd/skintext.py:345 msgid "In" msgstr "Dans" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Dossier de téléchargement temporaire" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Pour le stockage des téléchargements en cours, non post-traités.
    Ne " "peut être modifié que lorsque la file d'attente est vide." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Espace disque minimum pour le Dossier téléchargement temporaire" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pause lorsque l'espace libre est en-dessous de cette valeur.
    En " "octets, peut être suivi de O,M,G,T. Par exemple : \"800M\" ou \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Dossier de téléchargement terminé" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Pour le stockage des téléchargements terminés et post-traités.
    Peut " "être outrepassé par les catégories définies par l'utilisateur." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Permissions pour le dossier de téléchargement terminé" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Affecter les permissions au dossier de téléchargement terminé.
    En " "notation octale. Par exemple : \"755\" ou \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Dossier à surveiller" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Dossier à surveiller pour vérifier s'il contient des fichiers .nzb.
    Prends en compte également les nzb contenus dans les fichiers .zip, " ".rar et .tar.gz." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Intervalle de scan" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "" "Nombre de secondes entre chaque scan du dossier pour vérifier la présence de " "fichiers .nzb." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Dossier des scripts de post-traitement" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Dossier contenant les scripts utilisés lors du post-traitement." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Dossier des modèles d'email" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Dossier contenant les modèles d'email définis par l'utilisateur." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Fichier de mot de passe" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "Fichiers contenant tous les mots de passe des fichiers RAR cryptés." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Dossiers système" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Dossier administrateur" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Situation de la file d'attente et de la base de données historique.
    Ne peut être changé que lorsque la file d'attente est vide." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Les données ne seront pas déplacées. Requiert un redémarrage de " "SABnzbd !" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Dossier du fichier journal" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Emplacement des fichiers journaux de SABnzbd.
    Redémarrage requis " "!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Dossier de sauvegarde NZB" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Pour la sauvegarde des fichier .nzb." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Dossier racine par défaut" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Configuration des options" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Options de traitement" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Activer contrôle rapide" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Ne pas vérifier avec par2 si tous les fichiers sont valides à 100%." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Activer Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Activer la fonctionnalité unrar intégrée." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Activer Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Activer la fonctionnalité unzip intégrée." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Activer assemblage" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Assemble les fichiers .001, .002, etc. en un seul fichier." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Activer assemblage TS" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "Assemble les fichiers .001.ts, .002.ts, etc. en un seul fichier." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Activer nettoyage Par" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "" "Supprime les fichiers Par2 (uniquement si la vérification/réparation a " "réussie)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Échec lors d'erreurs CRC yEnc" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "Utilise les serveurs de soutien si il y a des erreurs CRC yEnc." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Uniquement les articles en tête de file d'attente" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Activer pour dimininuer l'utilisation de la RAM. Désactiver pour éviter que " "les téléchargements lents bloquent la file d'attente." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Ne post-traiter que les fichiers vérifiés" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Limite le post-traitement aux téléchargements qui ont passés avec succès les " "vérifications par2." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Action quand RAR crypté est téléchargé" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "En cas de «Pause», vous aurez besoin de mettre un mot de passe et de " "reprendre le travail." #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Détecter les téléchargements dupliqués" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Détection des NZB portant le même nom (nécessite l'option de sauvegarde NZB) " "et des titres en double dans les flux RSS." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "Action si une extension indésirable est détecté" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" "Action si une extension indésirable est détecté dans les fichiers RAR" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "Extensions indésirables" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Désactivé" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Rejeter" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Annuler" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Activer les contrôles SFV" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Fait une vérification supplémentaire basée sur les fichiers SFV." #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Vérifier le résultat de l'extraction" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Vérifie le résultat de l'extraction (doit être désactivée pour certains " "systèmes de fichiers)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Activer le renommage du dossier" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Utilise des noms de répertoires temporaires au cours du post-traitement. " "Désactiver lorsque votre système ne gère pas cela correctement." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Post-traitement par défaut" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Utilisé quand la catégorie ne précise pas de choix." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Script utilisateur par défaut" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Utilisé quand la catégorie ne précise pas de script." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Script utilisateur de pré-file d'attente" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Employé avant qu'un NZB n'entre dans la file d'attente." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Priorité par défaut" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Utilisé quand la catégorie ne précise pas de priorité." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Utilisé 'Par2 Multi-processeur'" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Consultez le Wiki pour plus d'info à ce sujet (en anglais) !" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Paramètres PAR2 supplémentaires" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Paramètres 'Nice'" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "Paramètres 'IONice'" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Autres options" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Déconnexion lorsque la file d'attente est vide" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Déconnecte du serveur(s) Usenet lorsque la file d'attente est vide ou en " "pause." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Envoyer 'Group'" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Envoyer la commande 'group' avant la demande des articles." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Trier par âge" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Trie automatiquement les fichiers par âge (moyen)." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Vérifier la présence d'une nouvelle version" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "" "Vérifie hebdomadairement la disponibilité d'une nouvelle version de SABnzbd." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Versions de test également" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Remplacer les espaces dans les noms de dossier" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "" "Remplace les espaces par des underscores ( _ ) dans les noms de dossiers." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Remplacer les points dans les noms de dossier" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Remplace les points par des espaces dans les noms de dossier" #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Remplacer les caractères illégaux dans les noms de dossier" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Remplace les caractères illégaux dans les noms de dossier par des " "équivalents (sinon les supprime)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Lancer le navigateur web au démarrage" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Lance le navigateur web au démarrage de SABnzbd." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Mettre en pause les téléchargements lors du post-traitement" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Met en pause les téléchargements lors des post-traitements et les reprends " "ensuite." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Gestion des échantillons (Samples)" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Filtre les fichiers échantillons de la file d'attente." #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Supprimer après téléchargement" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Ne pas télécharger" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "Type SSL" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Utiliser V23 à moins que votre fournisseur exige un autre type!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Utiliser l'horloge 12 heures (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Affiche l'heure au format AM/PM (n'affecte pas la planification)." #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Serveur" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Post-traitement" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Appellation" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Quota" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "Indexation" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Combien peut-être télécharger ce mois (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Jour de RAZ" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Quel jour du mois ou de la semaine (1=lundi) votre fournisseur réinitialise " "le quota? (Optionnel avec hh:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Continuation auto" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "" "Le téléchargement peut t-il reprendre après que le quota soit réinitialisé?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Quota période" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Le quota doit se réinitialiser chaque jour, semaine ou mois?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Vérifiez avant de télécharger" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Tente de prédire l’achèvement complet avant le téléchargement réel (lent!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Tentatives maximum" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Nombre maximal de tentatives par serveur" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Uniquement pour les serveurs optionnels" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Applique tentatives maximums uniquement aux serveurs optionnels" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Interrompre les tâches qui ne peuvent être remplis" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Lorsque pendant le téléchargement il apparaît clairement que les données " "trop grande fasse défaut, annuler le travail." #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "Activer l'intégration de OZnzb" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" "Cette fonctionnalité améliorée qui comprend des notes et des informations " "d'état supplémentaire est disponible lorsque vous êtes connecté à OZnzb " "indexeur." #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "Clé API du site" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" "Cette clé fournit l'identité de l'indexeur. Reportez-vous à " "https://www.oznzb.com/profile." #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "Reportez-vous à https://www.oznzb.com/profile" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "Commentaires automatique" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" "Envoyer les résultats de la validation calculées automatiquement pour les " "téléchargements à l'indexeur." #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Configuration du Serveur" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Définition du Serveur" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Ajouter un serveur" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Nom d'utilisateur" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Mot de passe" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Délai d'expiration" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Temps de rétention" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Serveur de soutien" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Optionnel" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Activer" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Supprimer le Serveur" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Tester le Serveur" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Effacer compteurs" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Test des détails du serveur en cours..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Cliquer ci-dessous pour tester." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Bande passante" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Configuration de la planification" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Ajouter planification" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Supprimer" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Planifications actuelles" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "Configuration RSS" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "URL Nouveau Flux" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "La case à cocher à coté du nom du flux doit être cochée pour que le flux " "soit activé et qu'il soit pris en compte dans la vérification des nouveaux " "téléchargements.
    Quant un flux est ajouté, seuls les nouveaux " "téléchargements seront pris en compte à moins de cliquer sur \"Forcer " "téléchargements\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Ajouter un flux" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Supprimer le flux" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Lire RSS" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Forcer téléchargements" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filtre" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Passer" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Accepter" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Rejeter" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Obligatoire" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "ObligatoireCat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Ne correspond pas" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Flux" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Lire tous les Flux Maintenant" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Paramètres" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtres" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Options email" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Notification par email lorsque des téléchargements sont terminés" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Jamais" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Toujours" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Erreurs-uniquement" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Notifications de disque dur plein" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Envoie un email lorsque le disque dur est plein et que SABnzbd a été mis en " "pause." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Envoyer les notifications RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" "Envoie un email quand un flux RSS ajoute un fichier dans la file d'attente." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Paramètres du compte email" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "Serveur SMTP" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Entrez le serveur de courrier sortant de votre FAI." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Adresse email de réception" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Adresse email à laquelle seront envoyées les notifications." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Adresse email d'envoi" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Adresse email de provenance des notifications." #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "Identifiant (facultatif)" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "" "Si une authentification pour l'envoi est requise, saisissez votre " "identifiant." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "Mot de passe (facultatif)" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "" "Si une authentification pour l'envoi est requise, saisissez votre mot de " "passe." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Activer Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Envoie une notification Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Adresse du serveur" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Utiliser seulement pour Growl à distance (hôte:port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Mot de passe du serveur" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Mot de passe optionnel pour Growl" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Activer NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Envoie les notifications à NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Centre de notification" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Envoyer des notifications au centre de notification" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Classes de notification" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Activer les classes de messages qui doivent être communiqués (aucun, un ou " "plusieurs)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Si vous avez un compte www.newzbin2.es, vous pouvez entrer " "vos informations de compte ici.
    Cela débloquera des fonctionnalités " "supplémentaires." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "information compte" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Identifiant Newzbin" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Entrez votre identifiant ici." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Mot de passe Newzbin" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Entrez votre mot de passe ici." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Traitement des favoris" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Téléchargement automatique des favoris" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Télécharge automatiquement les favoris." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Récupérer les favoris maintenant" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Masquer les favoris" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Afficher les favoris" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Retirer le favori s'il a été téléchargé" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "" "Retire de la liste des favoris lorsque le téléchargement est terminé." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Intervalle de vérification" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "En minutes (minimum 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Favoris traités" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Si vous avez un compte sur www.nzbmatrix.com, vous pouvez " "entrer vos informations de compte ici.
    Ceci est obligatoire si vous " "désirez utilisez les flux RSS de ce site." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Identifiant NzbMatrix" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "NzbMatrix clé API" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Entrez ici votre clé API NzbMatrix." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Catégories utilisateur" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Définit le post-traitement et le stockage." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Utilisez les colonnes \"Groupes/Tags indexeur\" pour classer les groupes et " "les tags de vos catégories.
    \r\n" "Utilisez des virgules pour séparer les termes." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "En terminant le chemin avec une étoile *, ceci évite la création des " "dossiers de la tâche." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Dossiers relatifs à" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Dossier/Chemin" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Groupes/Tags indexeur" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Configuration du tri" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Tri des séries" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Activer le tri TV" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Active le classement et le renommage des épisodes." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Model de clé" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Effacer" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Prédéfinis" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Exemple" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Tri générique" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Activer le tri des Films" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Active le tri et le renommage générique des fichiers." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Garder les téléchargements perdus dans des dossiers" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Activer si les téléchargement ne sont pas dans leur propre dossier." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Catégories affectées" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Signification" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Modèle" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Résultat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Dossier Saison" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Dossier Saison" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Dossier Épisode" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Dossier Épisode" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Titre" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Nom Film" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Nom.Film" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Nom_Film" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Nom Série" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Nom.Série" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Nom_Série" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Numéro Saison" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Numéro Épisode" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Nom Épisode" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Nom.Épisode" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Nom_Épisode" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Extension de fichier" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Extension" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Numéro Partie" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Décade" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Nom De Fichier Original" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Nom du dossier Original" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Minuscule" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEXTE" #: sabnzbd/skintext.py:667 msgid "text" msgstr "texte" #: sabnzbd/skintext.py:668 msgid "file" msgstr "fichier" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "dossier" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Chaîne de trie" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Étiquette Multi-partie" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "Dans Dossiers" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Pas De Dossiers" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Tri par date" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Activer le tri par date" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Active le tri et le renommage des fichiers par date." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Dossier Nom Série" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Dossiers Année-Mois" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Dossiers Quotidiens" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "Lettre Capitale" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Résultat traité" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Options rarement utilisé. Pour leur sens et leur explication, cliquez sur le " "bouton Aide pour accéder à la page Wiki.
    Ne pas modifier celles-ci sans " "vérifier en premier le wiki, certaines ont de graves effets secondaires. " "
    Les valeurs par défaut sont indiquées entre parenthèses." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Valeurs" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Éditer les détails du NZB" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Supprimer" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Premier" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Monter" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Descendre" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Dernier" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Tous" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Inverser" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Nom de fichier" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Sujet" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Age" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Sélection" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Etes-vous sûr de vouloir supprimer ?" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Rafraîchir" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Options" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Page" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Préc." #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Suiv." #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Premier" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Dernier" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Fermer" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Intervalle de pause" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Trier" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Vider la file d'attente?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Intervalle pause" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pause pour 5 minutes" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pause pour 15 minutes" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pause pour 30 minutes" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pause pour 1 heure" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pause pour 3 heures" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pause pour 6 heures" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pause pour 12 heures" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pause pour 24 heures" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Trier par Age Moins récent→Plus récent" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Trier par Age Plus récent→Moins récent" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Trier par Nom A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Trier par Nom Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Trier par Taille Plus petit→Plus grand" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Trier par Taille Plus grand→Plus petit" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Renommer" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Restant" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Vider l'Historique ?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Les modifications n'ont pas été enregistrées et seront perdues." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Ouvrir URL Source" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Ouvrir URL Info." #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Stockage" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Afficher journal des Scripts" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Vous devez activer JavaScript pour que Plush puisse fonctionner!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Ajouter NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Options Plush" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Mise à Jour Disponible!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Pause pour combien de minutes?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pause pour..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Multi-Operations" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Afficher/Masquer menu" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Une fois terminé" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Trier par Age (Moins récent→Plus récent)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Trier par Age (Plus récent→Moins récent)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Trier par Nom (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Trier par Nom (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Trier par Taille (Plus petit→Plus grand)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Trier par Taille (Plus grand→Plus petit)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Vider" #: sabnzbd/skintext.py:781 msgid "left" msgstr "restant" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Vitesse Maxi" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Plage" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Réinitialiser" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Appliquer à la sélection" #: sabnzbd/skintext.py:786 msgid "page" msgstr "page" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Tout" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Désactivé" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Fréquence de rafraîchissement" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Largeur de L'affichage" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Confirmer Suppressions File d'attente" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Confirmer Suppressions Historique" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Permet d'éviter le rafraîchisssment du contenu quand la souris survole la " "file d'attente." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Bloquer Rafraîchissements Au Survol" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Charger" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Envoyer" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Envoyer : .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Vous pouvez également indiquer un nom de fichier" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Avancement" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Espace disque insuffisant pour terminer les téléchargements !" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Espace Libre" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Libre (Temp)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "EN ATTENTE" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Téléchargements" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Réparation File D'Attente" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Lire RSS obtient le contenu du flux en cours. " "Forcer téléchargements pour télécharger de suite tous les " "NZB correspondants." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Heure:Min" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Supprimer Terminé" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Supprimer tous les éléments échoués de l'historique ?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Supprimer échoués" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Liens" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Affiche %s de %s sur %s résultats" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Aucun résultat" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Affichage d'un seul résultat" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Email Envoyé !" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Notification envoyée!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Enregistrement.." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Enregistré" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Vitesse" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Afficher / Cacher Ajout NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "VueDuoV" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "VueDuoH" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Personnalisé" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Récupérer Favoris" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Êtes-vous sûr de vouloir redémarrer SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Taux de rafraîchissement" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Supprimer Tout" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Cacher les options d'édition" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Afficher les options d'édition" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Éditer" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Temps Restant" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Assistant Configuration" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "Version de SABnzbd" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Précédent" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Accès" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Je veux que SABnzbd soit accessible à partir de tous les ordinateurs de mon " "réseau." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Je veux que SABnzbd ne soit accessible que depuis mon ordinateur." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "" "Protection de l'interface de SABnzbd par un mot de passe (recommandé)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Activer l'accès à SABnzbd via HTTPS." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Divers" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "" "Lancer mon navigateur internet avec l'adresse de SABnzbd au démarrage de " "l'application." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Détails du serveur" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Entrez les informations de votre fournisseur principal usenet." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Pour pouvoir télécharger sur les newsgroups, il est nécessaire d'avoir un " "fournisseur usenet. Votre FAI peut vous fournir un accès, cependant un " "fournisseur usenet premium est recommandé." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "" "Vous n'avez pas de fournisseur usenet? Nous vous recommendons d'essayer %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Le nombre de connexions autorisées par votre fournisseur usenet" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "Ex: 8 ou 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "" "Cochez uniquement si votre fournisseur usenet permet les connexions SSL." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Cliquez pour tester les informations entrées." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Ce champ est obligatoire." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Entrez un numéro." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Si vous être membres de newzbin ou nzbmatrix, vous pouvez entrer vos " "identifiants et mot de passe pour pouvoir utiliser ces services. Si vous " "n'utilisez pas ces services, vous pouvez passer à l'étape suivante." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Télécharger automatiquement les marque-pages." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Par ex. :" #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Redémarrage de SABnzbd en cours..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "La configuration est terminée !" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd s'exécute en arrière plan." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" "Fermer la fenêtre/onglet de votre navigateur NE QUITTERA PAS SABnzbd." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Après que SABnzbd a terminé de redémarrer, vous serez en mesure d'y accéder " "à l'adresse suivante: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Il est recommandé de mettre un marque-page sur cette adresse pour la " "retrouver facilement ultérieurement." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "De l'aide peut être trouvée sur le" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Aller à SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Étape 1" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Étape 2" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Étape 3" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Étape 4" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Étape 5" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "Ex: 119 ou 563 pour le SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Quitter SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Démarrer l'Assistant" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "Si vous n'avez pas un compte, il peut être créé sur " #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd est fourni sans AUCUNE GARANTIE.\n" "Ce logiciel est gratuit, et vous êtes invité à le redistribuer sous " "certaines conditions.\n" "Il est distribué sous licence GNU GENERAL PUBLIC LICENSE Version 2 ou toute " "autre version ultérieure.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Erreur lors de l'obtention des information TV (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Échec du renommage : %s en %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Impossible de renommer le fichier similaire : %s en %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Numéro de rapport nzbmatrix invalide %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Vous avez besoin d'un compte VIP NZBMatrix pour utiliser l'API" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Identification NZBMatrix invalide" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Problème d'accès au serveur nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Le nom d'hôte n'est pas défini." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Pas de connexions configurées. Veuillez s'il vous plaît définir au moins une " "connexion." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "" "Mot de passe masqués en ******, s'il vous plaît veuillez le ressaisir" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Détails sur le serveur invalide" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Délai dépassé : Essayez d'activer la connexion SSL ou un port différent." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Délai dépassé" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Adresse du serveur erronée" #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Serveur arrêté pendant la séquence de connexion." #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Le serveur requiert un identifiant et un mot de passe." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Connexion réussie !" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Echec d'authentification, vérifiez les identifiant/mot de passe." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Trop de connexions, s'il vous plaît mettez en pause les téléchargements ou " "essayez plus tard" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Impossible de déterminer le résultat de la connexion (%s)" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "récupération msgid %s depuis www.newzbin.com" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Erreur Récupération msgid %s depuis www.newzbin.com - Vérifiez que vos " #~ "identifiant / mot de passe soient bien renseignés" #~ msgid "Expected size did not equal actual size" #~ msgstr "La taille ne correspond pas à la taille attendue" #~ msgid "Could not compile regex: %s" #~ msgstr "Impossible de compiler la regex : %s" #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Pause lorsque le RAR téléchargé est crypté" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Vous devrez définir un mot de passe avant de reprendre." #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Si vous avez un compte sur www.newzbin.com, vous pouvez " #~ "entrer vos informations de compte ici.
    Cela débloquera des " #~ "fonctionnalités supplémentaires." #~ msgid "Email Notifications" #~ msgstr "Notifications par email" #~ msgid "Should downloading resume after the quotum is reset?" #~ msgstr "Le téléchargement doit t'il reprendre après la RAZ du quota?" #~ msgid "Quotum" #~ msgstr "Quota" #~ msgid "Quotum left" #~ msgstr "Quota restant" #~ msgid "Does the quotum get reset each day, week or month?" #~ msgstr "Réinitialisation du quota tous les jours, semaines ou mois?" #~ msgid "Quotum period" #~ msgstr "Période de quota" #~ msgid "" #~ "On which day of the month or week (1=Monday) does your ISP reset the quotum? " #~ "(Optionally with hh:mm)" #~ msgstr "" #~ "Quel jour du mois ou de la semaine (1=lundi) votre fournisseur réinitialise " #~ "le quota? (Optionnel avec hh:mm)" SABnzbd-0.7.20/po/main/nb.po0000644000000000000000000036230712433712555015550 0ustar00usergroup00000000000000# Norwegian Bokmal translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2014-07-02 18:02+0000\n" "Last-Translator: einar \n" "Language-Team: Norwegian Bokmal \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:54+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Kunne ikke starte webgrensesnittet" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Kan ikke finne webmal: %s, prøver standardmal" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "_yenc-modul... IKKE funnet!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "par2-binærfil... IKKE funnet!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "unrar-binærfil... IKKE funnet!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "unzip-binær... IKKE funnet!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Husk at vertsnavnet 0.0.0.0 krever en IPv6-adresse for ekstern tilgang" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Deaktiverte HTTPS på grunn av manglende CERT- og KEY-filer." #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s startet" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnzbd er nå avsluttet" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s mottatt, lagrer og avslutter..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "henter meldings-id %s fra www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Feil under henting av meldings-id %s fra www.newzbin2.es - Kontrollér at " "brukernavn og passord er satt" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Forsøker å hente NZB fra %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Kan ikke lage midlertidig fil for %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Forsøker å sette status på ikke-eksisterende server %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "For lite diskplass, nedlasting satt på pause" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Feil i tempfil.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Lagring av %s mislyktes" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Lasting av %s mislyktes" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Test varslingen" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Ingen" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Standard" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "ADVARSEL:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "FEIL:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "ukjent" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Kunne ikke lage regex for søkestreng: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disken er full! Pauser..." #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Diskfeil under opprettelse av fil %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "ADVARSEL: Jobb \"%s\" satt på pause pga. kryptert RAR-fil" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "ADVARSEL: Avbrutt jobb \"%s\" grunnet kryptert RAR fil" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Avbrutt, kryptering funnet" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s mangler" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Kvote oppbrukt, setter nedlasting på pause" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s er ikke en godkjent e-post-adresse" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Krever server-adresse" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Kan ikke opprette %s mappe %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Kan ikke skrive til INI-fil %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Kan ikke sikkerhetskopiere fil %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Feil kodet passord %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s er ikke en korrekt oktal verdi" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "UNC-sti \"%s\" er ikke tillatt her" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Feil: Køen er ikke tom, kan ikke bytte mappe." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Mappen \"%s\" finnes ikke" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "SQL-kommando mislyktes, se logg" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "SQL Innsetting mislyktes, se logg" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Kunne ikke stenge databasen, se logg" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Ugyldig scenen logging i historien for %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Dekoding av %s mislyktes" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "CRC-feil i %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Feilaktigt utformet yEnc artikkel i %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Ukjent feil oppstod under dekoding av %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => mangler på alle servere, fjerner" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Feil ved fjerning av %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Kan ikke lese %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Kan ikke lese den overvåkede mappen %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Pauset" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Server %s vil bli ignorert i løpet av %s minutter" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Kunne ikke initialisere %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "For mange oppkoblinger til server %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Mistenkt kontodeling" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Kunne ikke logge inn på server %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Kan ikke koble til server %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Tilkobling mot %s@%s:%s mislyktes, melding=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Server %s krever brukernavn/passord" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Starter avslutning av SABnzbd.." #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Kunne ikke koble til mailserver" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Kunne ikke starte TLS-tilkobling" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Autentisering mot mailserveren mislyktes" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Kunne ikke sende e-post" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Kunne ikke stenge e-post-tilkobling" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "E-post sendning lykkes" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Kan ikke finne e-post-maler i %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Ingen mottaker oppgitt, e-post ikke sendt" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Ugyldig koding av e-post mal %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Ingen e-post-mal funnet" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd rapporterer at disken er full\n" "\n" "Hei,\n" "\n" "SABnzbd har stoppet all nedlasting da lagringsdisken nesten er full.\n" "Frigjør mer diskplass og gjenoppta nedlasting manuelt.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Oppstart/avsluttning" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "La til NZB-fil" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Etterbehandling startet" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Jobb fullført" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Andre meldinger" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Advarsel: LOCALHOST er tvetydig, bruk numerisk IP-adresse." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Serveradressen \"%s:%s\" er ikke gyldig." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Mangler sesjonsnøkkel" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Feil: Krever sesjonsnøkkel" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Feil: Feil sesjonsnøkkel" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "API-nøkkel mangler, skriv inn API-nøkkelen fra Konfigurasjon->Generelt i " "ditt tredjepartsprogram:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API-nøkkel er feil, bruk API-nøkkel fra Konfigurasjon->Generelt i ditt " "tredjepartsprogram:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Autentisering mangler, angi brukernavn/passord fra Konfigurasjon->Generelt i " "ditt tredjepartsprogram:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Feil: Sekundært grensesnitt er ikke definert." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Din versjon av UNRAR er ikke anbefalt, hent en ny versjon fra " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "Kunne ikke finne noen UNRAR program, utpakking er ikke mulig
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Kunne ikke finne noen PAR2 program, reparasjon er ikke mulig
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Forbereder omstart...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd er avsluttet.
    Vent rundt 5 sekunder og klikk " "deretter på knappen under.

    Last på " "nytt
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "RSS-kilde" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Daglig" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Mandag" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Tirsdag" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Onsdag" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Torsdag" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Fredag" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Lørdag" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Søndag" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "av" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Løs adresse" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Feil parameter" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Tilbake" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "\"%s\" jobber er igjen i køen" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Nedlasting markert med '*' kommer ikke å bli lastet ned automatisk." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Like" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Ulike" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Nedlastet" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Nedlastet en så lenge" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Feil verdi for %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Kan ikke opprette mappe %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s mappe: %s tilgang mislyktes" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Kan ikke koble til registret HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Kan ikke åpne registernøkkel \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Kunne ikke lese registernøkkel for spesialmapper" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Opprettelse av (%s) mislyktes" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Kunne ikke flytte %s til %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Feil, Ubrukelig akrivfil" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Forsøk igjen" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "URL henting mislyktes; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "pyopenssl modul mangler, vennligst installer den for https tilgang" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Kunne ikke lage SSL-nøkkel eller sertifikat." #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Kunne ikke endre rettigheter på %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Slår sammen filer" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Ufullstendig sekvens av oppdelte filer" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Filsammenslåing av %s mislyktes" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Feil \"%s\" under filsammenslåing" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Feil \"%s\" under kjøring av file_join på %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Slår sammen %s filer" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Utpakking mislyktes, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Feil \"%s\" under utpakking av RAR fil(er)" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Feil \"%s\" under kjøring av rar_unpack på %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Fjerning av %s mislyktes!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Prøver unrar med passord \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Utpakking mislyktes, arkivet krever passord" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Utpakker" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Utpakking mislyktes, kunne ikke finne %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "FEIL: kunne ikke finne \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Utpakking mislyktes, CRC-feil" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "FEIL: CRC mislyktes i \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Utpakking mislyktes, skrivefeil eller er disken full?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "FEIL: skrive feil (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Utpakking feilet, stien er for lang" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "FEIL: sti er for lang (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Utpakking mislyktes, se logg" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "FEIL: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Mangler forventet fil: %s => unrar feil?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Utpakking mislyktes, en forventet fil er ikke utpakket" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Utpakking feilet, fil(er) mangler:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Utpakket %s filer/mapper på %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s filer på %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Feil \"%s\" under kjøring av unzip() på %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Hurtigkontrollerer" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Reparerer" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Hurtigkontroll OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Starter reparasjon" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparasjon mislyktes, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Feil %s under kjøring av par2_repair på %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Feil \"%s\" under kjøring av par2_repair på %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 mottok feil kommandoer, undersøk brytere i Konfigurasjon->Brytere" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verifiseing tok %s, alle filer er ok" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verifisering tok %s, krever reparasjon" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Hovedarkiv mangler..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Ugyldige par2-filer, kan ikke kontrollere eller reparere" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Mislykket reparasjon, finner ikke nødvendige reparasjonsblokker (%s mangler)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Henter %s blokker..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Henter" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Reparerer" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Reparert på %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Verifiserer" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Mislyktes med importering av OpenSSL modul. Kobler til uten SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Kunne ikke oppdatere newzbin jobb %s" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB er lagt til i køen" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Newzbin serveren endret sin protokoll" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Du har ikke kreditt på din Newzbin konto" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Uautorisert, kontroller ditt newzbin brukernavn/passord" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin rapporterte at %s ble ikke funnet" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin gir udokumentert feilkode (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Newzbin serveren mislyktes gi info for %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Kunne ikke fjerne newzbin bokmerke %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin gir udokumentert feilkode (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Feilaktig kø-fil funnet, kan ikke fortsette" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Lastingsfeil %s, feilaktig fil oppdaget" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Kunne ikke legge til %s, tar bort" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Ukjent koding" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Fil %s er tom, hopper over" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Kunne ikke importere %s filer fra %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Ufullstendig NZB-fil %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Feilaktig NZB fil %s, hopper over (årsak=%s, linje=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Tom NZB-fil %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorerer duplikatfil \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Stanser duplikatfil \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Avbrutt, kan ikke fullføres" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLIKAT" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "KRYPTERT" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "FOR STOR" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "UFULLSTENDIG" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "VENT %s sek" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Hentet filer på %s med gjenomsnitts hastighet på %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artikler var korrupte" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s artikler manglet" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artikler hadde ulike duplikater" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s artikler ble slettet" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Kunne ikke importere %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Advarsler" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Ledig" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Konfigurasjon" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Kø" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Slett kø" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historikk" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Slett historikk" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Hastighetsbegrensning" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Stans midlertidig" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Gjenoppta" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Hente Newzbin bokmerker" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Sjekk overvåkingsmappe" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Ferdig mappe" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Ufullstendig mappe" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Feilsøking" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Starte på nytt" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Restart uten å logge inn" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Avslutte" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Kø (10 første)" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Tom" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Historikk (10 siste)" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Ny utgave er tilgjengelig" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Gå til guiden" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Avslutter..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problem med" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd har problemer med visse programvare-baserte brannmurer.
    \n" " %s
    \n" " Uheldigvis kan ikke dette problemet løses akkurat nå.
    \n" " Forhør deg med leverandøren av brannmuren din for støtte.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd trenger en ledig TCP/IP-port for sin interne webserver.
    \n" " Port %s på %s ble forsøkt brukt, men er utilgjengelig.
    \n" " Enten er porten allerede i bruk av et annet program, eller så kjører " "SABnzbd fra før av.
    \n" "
    \n" " Start SABnzbd på nytt med et annet portnummer." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "Prøv et annet nummer hvis du får denne feilmeldingen på nytt.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd trenger en ledig TCP/IP-port for sin interne webserver.
    \n" " Port %s på %s ble forsøkt brukt, men kontoen brukt av SABnzbd har ikke " "tilgang til å bruke den.
    \n" " På OSX og Linux-systemer må standardbrukere benytte seg av port 1023 " "eller høyere.
    \n" "
    \n" " Start SABnzbd på nytt med et annet portnummer." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd krever en gyldig adresse for sin interne webserver.
    \n" " Du har spesifisert en ugyldig adresse.
    \n" " Korrekte verdier er localhost og 0.0.0.0
    \n" "
    \n" " Vennligst start SABnzbd på ny med en gyldig adresse." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd oppdaget instillinger fra en annen SABnzbd-versjon
    \n" " men kan ikke bruke disse.

    \n" " Kanskje vil du fullføre nedlastingskøen i det gamle programmet " "først?

    \n" " Etter det kan du starte dette programmet med \"--clean\"-" "parameteren.
    \n" " Dette vil slette nedlastingskø og historie!
    \n" " SABnzbd leste filen \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd kan ikke finne filene for webgrensesnittet i %s.
    \n" " Vennligst installer programmet på nytt.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd oppdaget en kritisk feil:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd oppdaget nedlastingskø og historie fra en eldre (0.4.x)-" "utgave.

    \n" " Både nedlastingskø og historie vil bli slettet!

    \n" " Du kan velge å avslutte SABnzbd og fullføre nedlastingskøen i det eldre " "programmet.

    \n" " Klikk OK hvis du vil starte den nye versjonen av SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd oppdaget at filen sqlite3.dll is mangler.

    \n" " Enkelte antivirus-programmer fjerner denne filen.
    \n" " Vennligst sjekk ditt antivirusprogram og forsøk å installer SABnzbd på " "nytt.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Trykk Start+R og skriv inn linjen (eksempel):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Åpne et terminalvindu og skriv inn linjen (eksempel):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Du bruker mest sannsynlig ZoneAlarm under Vista." #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Programmet startet ikke!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Du har ikke tilgang for å bruke port %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Kritisk feil" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Kan ikke starte webserveren, ble sannsynlig vis ikke funnet" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Ingen tilgang" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Feil %s: Du må oppgi et gyldig brukernavn og passord." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Kunne ikke laste etterbehandlings køen: Feil versjon (krever:%s, fant:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Kunne ikke fjerne nzo fra etterbehandlings køen (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "Nedlasting kan feile, kun %s av kravet på %s tilgjengelig" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Henting mislyktes - Overskrevet din servers retensjon?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Kan ikke opprette mappe %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Ingen etterbehandling, på grunn av misslykket verifisering" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Flytter" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Sendte %s til køen" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Kunne ikke endre navn fra \"%s\" til \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Klarte ikke å flytte filer" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Kjører skript" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Kjør brukerskript %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Kjørte i %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Mer" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Vis skript kjøringen" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Nedlasting ferdig" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Nedlasting mislyktes" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Etterbehandling mislyktes for %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "se loggfil" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Etterbehandling ble avbrutt (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Rensning av %s mislyktes" #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Kunne ikke fjerne arbeidsmappe (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Etterbehandling" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Ingen par2 deler" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Prøver SFV-verifisering" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Some files failed to verify against \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Verifisering med SFV-filer var vellykket" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Fjerning av %s mislyktes" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Dvalemodus feilet" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Kunne ikke sette systemet i ventemodus" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Feil under avslutting av systemet" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Feilaktig RSS-kilde beskrivelse \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Kunne ikke hente RSS-kilde fra %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Ugyldig autentisering for nyhetsstrøm %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "RSS-kilde %s var tom" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Ukompatibel nyhetsstrøm" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Tom RSS post funnet (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Vis grensesnitt" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Åpne fullført mappe" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Avslutt" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Gjenstår" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Feil skjema %s ved %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Ukjent handling: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Skjema for ikke eksisterende server %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Nedlastning" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Slå sammen filer" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Utpakking" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Skript" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Kilde" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Feil" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Ferdig" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Mislyktes" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Venter" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparerer..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Trekker ut..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Flytter..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Kjører skript..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Henter ektra blokk..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Hurtigkontroll..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Verifserer..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Laster ned" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Hent NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Undersøker" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Hyppighet" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Handling" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argument" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Oppgave" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "Deaktiver server" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "Aktiver server" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Hastighetsgrense" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Pause Allt" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pause etterbehandling" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Gjenoppta etterbehandling" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Les RSS-kilde" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Fjerne mislykkede jobber" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "time" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "timer" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "minutt" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minutter" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sekund" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "sekunder" #: sabnzbd/skintext.py:79 msgid "day" msgstr "dag" #: sabnzbd/skintext.py:80 msgid "days" msgstr "døgn" #: sabnzbd/skintext.py:81 msgid "week" msgstr "uke" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Måned" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "År" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Dag i måneden" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Denne uken" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Denne måneden" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "I dag" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Totalt" #: sabnzbd/skintext.py:97 msgid "on" msgstr "på" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametere" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Python-versjon" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Startside" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "eller" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Adresse" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Det automatiske usenet nedlastnings verktøyet" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Lagre" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Satt i kø" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Er du sikker?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Slett alle nedlastninger?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Hjem" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Konfigurasjon" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Status" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Hjelp" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Generelt" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Mapper" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Svitsjer" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Servere" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Nedlastingsplan" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Varsler" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "E-Post" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Index-sider" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Kategorier" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortering" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Spesiell" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Midlertidig nedlastingsmappe" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Ferdig nedlastingsmappe" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Nedlastingshastighet" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "Pause" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "Lagret %s artikler (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Systemlast" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "ADVARSLER" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Ny utgave %s tilgjengelig" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Legg til ny nedlasting" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Er sikker på at du vil slå av SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Legg-til" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Rapport-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Legg til fil" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Kategori" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Bearbeidinger" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioritet" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparere" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Pakker opp" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Fjern" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "P" #: sabnzbd/skintext.py:177 msgid "D" msgstr "T" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Tving" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Høy" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Lav" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stopp" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " eller Rapport ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Sortere etter navn" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Sortere etter alder" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Sortere etter størrelse" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Skjul filer" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Vis filer" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Når køen er ferdig" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Slå av PC" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Ventemodus PC" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Dvalemodus PC" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Avslutning av SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Hastighetsgrense" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pause for" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Sortering" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Navn" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Gjenstår/Totalt" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Tid igjen" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "Alder" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Fjern" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Prøv igjen" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Hendelser" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Skripts" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Slett alt fra køen?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Slett NZB-filer" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Slett NZB & tilhørende filer" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Fjern NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Fjern NZB & slett filer" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "av" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Manglende artikler" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Gjenværende kvote" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "manuelt" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Nullstill kvote nå" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Slett feil-historie" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Slett alle fullførte nedlastinger fra historie?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Vil du slette alle feilete nedlastinger fra historien?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Skjul detaljer" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Vis detaljer" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Historikk størrelse" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Vis Mislykkede" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Vis alle" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Størrelse" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Fjern Mislykkede NZBer" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Fjern Mislykkede NZBer & Slett Filer" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Fjern Ferdige NZBer" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Snarvei" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Tving frakobling" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Dette vil sende en test e-post til din konto." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Logg" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Weblogg" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Test E-post" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Logging" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Feil/Advarsel" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Feilsøking" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Tilkoblinger" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Tråd" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "E-post testresultat" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Seneste Advarsler" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "slette" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Fjern blokkering" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Artikkel-id" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Filsett" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Når" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Type" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Advarsel" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Aktivert" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Konfig fil" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Brukt hurtigbuffer" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Dette vil starte om SABnzbd.
    Brukes når du tror programmet er " "ustabilt.
    Nedlastning vil bli satt på pause før omstarten og gjenoppta " "etterpå." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Versjon" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Oppetid" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Sikkerhetskopi" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Generell konfigurasjon" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Endringer krever omstart av SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "SABnzbd Webbserver" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "SABnzbd Adresse" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Adressen som SABnzbd skal bruke." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "SABnzbd-port" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Porten som SABnzbd skal bruke." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Webgrensesnitt" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Velg et skall." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Endre utseende til Webgrensesnittet." #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Aktiver ett alternativt skin." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Webserver autentisering" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "SABnzbd Brukernavn" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Kan velge autentiserings brukernavn." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "SABnzbd Passord" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Kan velge autentiserings passord." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "HTTPS Støtte" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "HTTPS Aktivere" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "(ikke installert)" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Aktiverer tilgangen til webgrensesnittet med HTTPS adresse." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "HTTPS-port" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Om tom, så vil standardporten bare lytte til HTTPS" #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "HTTPS Sertifikat" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Filnavn eller søkesti til HTTPS Sertifikat." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "HTTPS Nyckel" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Filnavn eller søkesti til HTTPS Nøkkel." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "HTTPS-lenke sertificater" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Filnavn eller sti til HTTPS-lenke" #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Justeringer" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Automatisk oppdateringsintervall av kø:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "Oppdateringsintervall av kø-siden (sek, 0= ingen)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "RSS Oppdateringsintervall" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Sjekk intervall (i minutter, minst 15). Ikke aktiv når du bruker " "nedlastingsplan!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Hastighetsbegrensning for Nedlastning" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "" "Middelhastighetsbegrensning for Nedladlasting (i KB/s - kilobyte per sekund)." #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Cachestørrelse for artikkler" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Lagrer artikler i minnet for å redusere diskaktivitet.
    I bytes, " "fulgt av K,M,G. For eksempel: \"64M\" eller \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Rens liste" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Liste med filendelser som skal slettes etter nedlastning.
    For eksempel: " ".nfo or .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Lagre endringer" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Språk" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Velg språket til Webgrensesnittet." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "API-nøkkel" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Denne nøkkelen vil gi tredjepartsprogrammer full tilgang til SABnzbd" #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "NZB-nøkkel" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Denne nøkkelen vil gi tredjepartsprogrammer lov til å legge til NZBer til " "SABnzbd" #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Generer Ny Nøkkel" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Slå av API-nøkkel" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Ikke krev API-nøkkel." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "BRUK PÅ EGET ANSVAR!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "QR-kode" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "API-nøkkel QR-kode" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Mappekonfigurasjon" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "OBS: Mapper kommer til å bli opprettet automatiskt når du Lagrer. " "Du må angi korrekte søkestier til din mapper for å kunne lagre utenfor " "standardmappene." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Brukermapper" #: sabnzbd/skintext.py:345 msgid "In" msgstr "Hvor:" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Midlertidig nedlastingsmappe" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Plass for å lagre ikke bearbeidede nedlastinger.
    Kan kun endres når " "køen er tom." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimal fri plass for midlertidig nedlastingsmappe" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pause når fri plass er nærme grensen.
    I bytes, fulgt av " "K,M,G,T. For eksempel: \"800M\" eller \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Ferdig nedlastingsmappe" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Plass for å lagre bearbeidede og ferdige nedlastinger.
    Kan " "overstyres av brukerdefinerte kategorier." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Rettigheter for ferdige nedlastinger" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Sett rettigheter for ferdige filer og mapper.
    Bruk tall. For " "eksempel: \"755\" or \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Overvåket Mappe" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Mappe som automatiskt søkes igjennom etter .nzb filer.
    Skanner også " "igjennom .zip .rar og .tar.gz arkiver etter .nzb filer." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Skanningsintervall for Overvåkede mappar" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Sekunder mellom skanninger for .nzb filer." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Etterbehandlings skriptmappe" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Mappe inneholder skript for etterbehandling." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Mappe for E-post maler" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Mappe som inneholder brukerdefinerte e-post maler." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Passordfil" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fil som inneholder alle passordene som skal forsøkes på krypterte RAR filer." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Systemmapper" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Administrativ Mappe" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "Data vil ikke bli flyttet. Krever SABnzbd restart!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Loggmappe" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Plass for lagrede loggfiler fran SABnzbd.
    Krever omstart av " "SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr ".nzb Reservemappe" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Plass der .nzb filer lagres." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Standard base filsti" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Parameterkonfigurasjon" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Bearbeider parameter" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Aktiver Hurtigsjekk" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Ikke kjør par2 kontroll når filene er 100% korrekte." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Aktiver Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Aktiverer den innbyggde Unrar funksjonen." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Aktiver Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Aktiverer den inbyggde Unzip funktionen." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Aktiver Filsammenslåing (Filejoin)" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Slår sammen filer med filendelsene .001, .002 etc. til en fil." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Aktiver TS Sammenslåing (TS Joining)" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "Slår sammen filer med filendelsene .001.ts, .002.ts etc. til en fil." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Aktiver Par rensing (Par Cleanup)" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Renser bort par filer (om verifisering/reperasjon var vellykket)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Ved feil på yEnc CRC" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "Hvis artikkelen har CRC feil, prøv å hent den fra en annen server." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Bara artiklene fra begynnelsen av køen" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Aktiveres for mindre minneforbruk. Deaktiver for å forhindre langsom jobb da " "køen blokkeres." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Etterbehandle kun verifiserte nedlastinger" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "Etterbehandle kun nedlastinger som har passert PAR2 kontrollen." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Reaksjon når kryptert RAR fil lastes ned" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "I tilfelle \"Pause\", så trenger du å sette et passord og gjenoppta jobben." #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Oppdag duplikatnedlastinger" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Oppdag NZB filer med identisk navn (krever NZB backup opsjon) og duplikat-" "titler i RSS feed'ene" #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Av" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Forkast" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Avbryt" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Aktiver SFV-baserte sjekker" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Utfør ekstra verifisering basert på SFV filer" #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Sjekk utpakkingsresultat" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "Sjekk utpakkingsresultat (må være av for noen filsystemer)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Aktiver omdøping av mappe" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Bruk midlertidige navn under postprosessering. Deaktiver når systemet ditt " "ikke håndtere dette skikkelig." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Standard etterbehandling" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Brukes når etterbehandlingen er bestemt etter kategori." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Standard brukerskript" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Brukes når brukerskript er bestemt etter kategori." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Før-kø bruker skript" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Brukes før en NZB blir lagt til kø" #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Standard prioritet" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Brukes når ingen prioritet er bestemt av kategori." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Aktiver MultiCore Par2" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Les Wiki Help fer dette!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Ekstra PAR2 parametere" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Nice parametere" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "IONice parametere" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Andre parametre" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Koble fra når køen er tom" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Kople fra usenet serverne når køen er tom eller pauset." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Send gruppe" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Send gruppekommando før du ber om artikler." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sortere etter alder" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Sortere automatisk etter(midt) alder." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Se etter ny utgave" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Se etter ny utgave av SABnzbd hver uke." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Også nye utgivelser" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Erstatt mellomrom i mappenavn" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Erstatt mellomrom med understrek i mappenavn." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Erstatt punktum i mappenavn" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Erstatt punktum med mellomrom i mappenavn" #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Erstatt ulovlige tegn i mappenavn." #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Erstatt ulovlige tegn i mappenavn med tilsvarende tegn(ellers fjernes de)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Starter webleseren ved oppstart" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Starter standard webleser når SABnzbd starter." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Pause nedlasting under etterbehandling" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Pauser nedlasting når etterbehandling begynner og gjenopptar nedlasting når " "etterbehandling er ferdig." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignorer Sample-filer" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Filtrere ut sample-filer (ex. video samplinger)." #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Fjern etter nedlasting" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Last ikke ned." #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "SSL type" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Bruk V23 om ikke din leverandør krever noe annet!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Bruk 12 timers klokke (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Vis tider i AM/PM (påvirker ikke kjøreplanen)" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Server" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Postprosessering" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Filnavn" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Kvote" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Hvor mye can lastes ned denne måneden (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Nullstillingsdag" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "På hvilken dag i måneden eller uken (1=mandag) resetter til nettilbyder " "kvoten? (Valgfritt med tt:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Gjenoppta automatisk" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "Skal nedlasting starte på nytt etter at kvoten er resatt?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Kvoteperiode" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Blirkvoten resatt hver dag, uke, eller måned?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Sjekk før nedlasting" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Prøve å beregne om ferdigstillelse er mulig før selve nedlastingen (tregere!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Maksimum antall forsøk" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Maksimum antall forsøk per server" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Kun for valgfrie servere" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Bruke maksimum forsøk kun på valgfrie servere" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Avbryt jobber som ikke kan fullføres" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Avbryt jobben om det blir klart under nedlasting at for mye data mangler" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Serverkonfigurasjon" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Server definisjon" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Legg til server" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Brukernavn" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Passord" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Tidsavbrudd" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Tidsrom for liggefrist" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Reserve server" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Valgfritt" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Aktivere" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Ta bort server" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Testserver" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Nullstill Tellere" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Tester serverinstillinger..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Klikk nedenfor for å teste." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Båndbredde" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Nedlastingsplan konfiguration" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Legg til nedlastingsplan" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Fjern" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Aktuelle nedlastingsplaner" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "RSS-konfigurasjon" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Ny RSS-kilde adresse" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Avkrysningsboksen ved kildenavnet må aktiveres for at kilden automatiskt " "skal kontrolleres for nye objekt.
    Når en kilde legges til, legges det " "kun til nye objekt(ikke objekt som allerede finnes). Alle objekter i kilden " "vises når du klikker på \"Tving nedlastning\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Legg til kilde" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Fjern feed" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Les kilde" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Tving nedlasting" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filter" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Hopp over" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Akseptere" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Avvise" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Krever" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "KreverKat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Ingen treff" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Kilder" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Les alle kilder nå" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Innstillinger" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtere" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "E-Post alternativer" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "E-Post varsling når nedlasting er ferdig" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Aldri" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Alltid" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Bara ved feil" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Full harddisk varsling" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Send e-post når harddisken er full og SABnzbd har pauset." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Send RSS varsler" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Send e-post nå en RSS feed legger til en nedlasting til køen." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "E-post konto innstillinger" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "SMTP-tjener" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Still inn din ISP's server for utgående e-post." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "E-post mottaker" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "E-post adresse til mottaker." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "E-post avsender" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Hvem skal vi sende e-posten fra?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "VALGFRITT Brukernavn" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Brukernavn for e-post som krever autentisering." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "VALGFRITT Passord" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Passord for e-post som krever autentisering." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Aktiver Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Send varsler til Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Tjeneradresse" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Brukes kun for fjerntliggende Growl tjener (vert:port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Passord for tjener" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Valgfritt passord for Growl tjener" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Aktiver NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Send varsler til NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Varselsenter" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Send varsler til Varselsenter" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Varselklasser" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Aktiver hvilke meldingsklasser som skal rapporteres (ingen, en eller flere)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Hvis du har konto ved www.newszbin2.es, så ka du skrive inn " "kontoinformasjon her.
    Dette vil låse opp ekstra funksjonalitet." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Brukerinformasjon" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Newzbin Brukernavn" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Skriv inn ditt brukernavn her." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Newzbin Passord" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Skriv inn passordet ditt her." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Bearbeider bokmerkene" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Hent bokmerkene automatisk" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Henter jobb fra bokmerkene automatisk." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Hente bokmerker nå" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Gjem bokmerker" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Vis bokmerker" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Fjern bokmerke etter nedlasting" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Ta bort fra bokmerkeslisten når nedlastingen er ferdig." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Oppdateringsintervall" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "I minutter (minst 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Bearbeider bokmerker" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Om du har en konto på www.nzbmatrix.com, så kan du skrive " "inn brukerinformasjonen her.
    Det kreves for at du skal kunnr bruke RSS-" "feeden fra nzbmatrix." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "NzbMatrix Brukernavn" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "NzbMatrix API-nøkkel" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Skriv inn API-nøkkelen for NzbMatrix her." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Brukerdefinerte kategorier" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Definierer etterbehandling og lagring." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Bruke \"Grupper / Indeksetiketter\" kolonnen for å koble grupper og " "etiketter til kategorier.
    Jokertegn er støttet. Bruk komma for å skille " "vilkårene." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Ved å avslutte filstien med en asterisk * vil arbeidsmapper ikke bli " "opprettet" #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Relative mapper er basert på" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Mappe/Søkesti" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Grupper / Indeks etiketter" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Sorteringskonfigurasjon" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Seriesortering" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Aktiverer TV sortering" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Aktiverer sortering endring av episodenavn." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Hjelp til Sorteringsstreng" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Rens" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "For innstillinger" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Eksempel" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Generell sortering" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Aktiver filmsortering" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Aktiverer sortering og endring av filnavn." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "La nedlastningen i ekstramappe være" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Aktiver om nedlastning ikke er flyttet til egen mappe." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Påvirkede kategorier" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Betyr" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Mønster" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Sesongmappe" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Sesongmappe" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Episodemappe" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Episodemappe" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Tittel" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Film Navn" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Film.Navn" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Film_Navn" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Show Navn" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Show.Navn" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Show_Navn" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Sesongnummer" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Episodenummer" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Episodenavn" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Episode.Navn" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Episode_Navn" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Filendelse" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "endelse" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Delnummer" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Titall" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Originalfilnavn" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Originalt mappenavn" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Små bokstaver" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py:667 msgid "text" msgstr "tekst" #: sabnzbd/skintext.py:668 msgid "file" msgstr "fil" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Sorteringsstreng" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Multi-del etikett" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "I mappe" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Ingen mappe" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Dato sortering" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Aktiver datosortering" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Aktiverer sortering og endring av navn på datomerkede filer." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Vis Navn på mappe" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "År-Måneds mapper" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Daglige mapper" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "justert for store og små bokstaver" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Prosesser resultat" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Sjeldent brukte valg. for å finne forklaring og betydning, klikk på " "hjelpknappen for å gå til Wiki siden.
    Ikke endre på disse uten å sjekke " "Wiki først, siden noen av dem har alvorlige bieffekter.
    Standardverdiene " "står i parantes." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Endre NZB detaljer" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Fjern" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Topp" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Opp" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Ned" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Bunn" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Alle" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Invertere" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Filnavn" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Emvne" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Tid" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Utvalg" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Er du sikker på at du vil fjerne" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Oppdatere" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Alternativer" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Side" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Forrige" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Neste" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Første" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Siste" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Steng" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Sett pauseintervall" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sortere" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Vil du virkelig slette køen?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Pauseintervall" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pause 5 minutter" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pause 15 minutter" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pause 30 minutter" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pause 1 time" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pause 3 timer" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pause 6 timer" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pause 12 timme" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pause 24 timer" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sorter etter alder Eldst→Ny" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sorter etter alder Ny→Eldst" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sorter etter navn A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sorter etter navn Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sorter etter størrelse Minst→Størst" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sorter etter størrelse Størst→Minst" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Endre navn" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Venstre" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Vil du virkelig slette historikken?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Endringer som ikke er lagret vil gå tapt." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Åpen kildekode URL" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Lagring" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Se skriptlogg" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Du må aktivere Javaskript for at Plush skal fungere!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Legg til NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Plush Valg" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Oppdatering tilgjengelig" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Pause i hvor mange minutter?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pause i..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Multioperasjoner" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Toppmeny" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Ved avslutning" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sorter på Alder (Eldst%rarr;Yngst)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sorter på Alder (Yngst%rarr;Eldst)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sorter på Navn (A%rarr;Å)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sorter på Navn (Å%rarr;A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sorter på Størrelse (Minst→Størst)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sorter på Størrelse (Størst→Minst)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Slett og rydd" #: sabnzbd/skintext.py:781 msgid "left" msgstr "" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Maks. hastighet" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Bruk på Valgte" #: sabnzbd/skintext.py:786 msgid "page" msgstr "" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Oppdateringsfrekvens" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Kontainer bredde" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Bekreft Sletting av Kø" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Bekreft Sletting av Historie" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "Dette vil hindre oppfrisking av innhold når muspekeren er over køen" #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Blokker oppfrisking når musen svever over" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Last opp: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Valgfritt spesifiser filnavn" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Jobb" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Ikke nok diskplass for å fullføre nedlastingen." #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Ledig (midlertidig)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Reparer Kø" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Les kildestrøm vil hente gjeldende kildestrømsinnhold. " "Tving Nedlasting Vil laste ned alle samsvarende NZB'er nå." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Time:Minutt" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Slett Ferdige" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Ta bort alle feilmeldinger fra historikken?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Slett Mislykkede" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Lenker" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Viser %s til %s av %s resultat" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Viser et resultat" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Sendte E-post!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Varsel sendt!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Lagrer.." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Lagret" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Hastighet" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Vis/Skjul Legg til NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "Visning 1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "Visning 2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Tilpasse" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Hente bokmerker" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Er du sikker på at du vil omstarte SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Oppdateringsfrekvens" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Ta bort alle" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Skjul redigeringsalternativer" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Vis redigeringsalternativer" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Endre" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Gjenstår" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Hurtigstart Guide" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "SABnzbd Versjon" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Forrige" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Tilgang" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Jeg vil at SABnzbd skal kunne brukes fra alle datamaskiner i mitt nettverk." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Jeg vil at SABnzbd kun skal kunne brukes fra min datamaskin." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Passordbeskytte tilgangen til SABnzbd (anbefales)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Aktiver HTTPS protokoll for tilgang til SABnzbd." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Diverse" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Start webleseren med SABnzbd's side når programmet startes." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Serverinstillinger" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Skriv inn opplysningene om din primære usenet leverandør." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "For å laste ned fra usenet trenger du tilgang til en leverandør. Din " "internettleverandør kan gi deg tilgang, men en \"proff\" leverandør " "anbefales." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Har du ikke noen usenet leverandør? Vi anbefaler å prøve %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Antallet tilkoblinger som er tillatt av din leverandør" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "F.eks 8 eller 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Velges kun om din leverandør tillater SSL-tilkoblinger." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Klikk her for å teste serverinstillingene." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Detta feltet kreves." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Bruk et heltall." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Om du er medlem på newzbin eller nzbmatrix kan du bruke ditt brukernavn og " "passord her så kan vi hente dine nzb filer. Dette kan hoppes over om du ikke " "bruker deres tjenester." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Last automatiskt ned bokmerkede poster." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Eks." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Starter SABnzbd på nytt..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Installasjonen er nå ferdig!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd kommer nå å kjøres i bakgrunnen." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" "SABnzbd kommer ikke til å avsluttes om du lukker vinduet eller fanen i " "webleseren." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Etter at SABnzbd har startet på nytt får du tilgang på følgende adresse: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Det er anbefalt at du lagrer denne siden som et bokmerke for å treffe " "SABnzbd når det kjøres i bakgrunnen." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Øvrig hjelp kan du finne på vår" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Gå til SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Steg en" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Steg to" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Steg tre" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Steg fire" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Steg fem" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "F.eks 199 eller 563 for SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Avslutt SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Start Veiviser" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "Hvis du ikke har en bruker, kan det opprettes på " #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd kommer HELT UTEN GARANTI.\n" "Dette er fri programvare, og du kan redistribuere det under visse vilkår.\n" "Det er lisensier under GNU GENERAL PUBLIC LICENSE Versjon 2 eller senere " "versjoner.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Kunne ikke hente TV info (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Kunne ikke endre navn fra: %s til %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Kunne ikke endre navn på lik fil: %s til %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Ugyldig nzbmatrix rapporteringsnummer %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Du trenger en nzbmatrix VIP konto for å bruke API'en" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Ugyldige nzbmatrix brukernavn og/eller passord" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Oppkoblingsproblem til nzbmatrix server (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Du har ikke stilt inn vertsnavn." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "Ingen tilkoblinger er aktivert. Du må aktivere minst en tilkobling." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Passordet er skjult med ******, prøv igjen" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Ugyldige server-innstillinger" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Tidsavbrudd: Prøv å aktivere SSL eller bruk en annen port." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Tidsavbrudd" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Ugyldig server-adresse." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Server avbrøt undet innloggingssekvens" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Server krever brukernavn og passord." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Tilkobling lyktes!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Godkjenning mislyktes, kontroller brukernavn og passord." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "For mange tilkoblinger, sett nedlasting på pause eller prøv igjen senere" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Kunne ikke koble til (%s)" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "henter msgid %s fra www.newzbin.com" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Feil ved henting av msgid %s fra www.newzbin.com - Sjekk at brukernavn og " #~ "passord er satt korrekt" #~ msgid "Expected size did not equal actual size" #~ msgstr "Forventet størrelse er ikke lik virkelig størrelse" #~ msgid "Could not compile regex: %s" #~ msgstr "Kunne ikke kompilere regex: %s" #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Om du har konto på www.newzbin.com, så kan du skrive inn " #~ "bruker informasjon her.
    Dette åpner for ekstra funksjoner." SABnzbd-0.7.20/po/main/nl.po0000644000000000000000000037017312433712555015562 0ustar00usergroup00000000000000# Dutch translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2014-07-02 18:08+0000\n" "Last-Translator: shypike \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:53+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Kan web interface niet starten" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Kan web sjabloon %s niet vinden, standaard sjabloon wordt gebruikt" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "_yenc module niet gevonden!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "par2 programma niet gevonden!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "unrar programma niet gevonden!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "unzip programma niet gevonden!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Let op, wanneer je 0.0.0.0 als hostnaam gebruikt, heb je voor externe " "toegang een IPv6 adres nodig" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS is uitgeschakeld vanwege ontbrekende CERT en KEY bestanden." #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s is gestart" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnzbd is afgesloten" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Signaal %s ontvangen, opslaan en afsluiten..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "msgid %s aan het ophalen van www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Fout tijdens ophalen van msgid %s van www.newzbin2.es - Zorg dat je " "gebruikersnaam en wachtwoord goed zijn ingesteld" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Probeer NZB op te halen van %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Kan geen tijdelijk bestand maken voor %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Poging om status van niet bestaande server %s te wijzigen" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Te weinig schijfruimte, pauze geforceerd" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Probleem met tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Opslaan van %s lukt niet" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Inlezen van %s lukt niet" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Test Melding" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Geen" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Standaard" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "WAARSCHUWING:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "FOUT:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "onbekend" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Samenstellen van reguliere expressie lukt niet: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Schijf is vol! Forceer Pauze" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Schrijf fout bij opslaan van bestand %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "WAARSCHUWING: Item \"%s\" gepauzeerd vanwege versleuteld RAR bestand" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "Waarschuwing: \"%s\" is afgebroken vanwege versleuteld RAR bestand" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Afgebroken, versleuteling ontdekt" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" "WAARSCHUWING: Ongewenste extensie ontdekt in \"%s\". Ongewenst bestand is " "\"%s\" " #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "Ongewenste extensie zit in RAR file %s" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "Afgebroken: ongewenste extensie ontdekt" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s ontbreekt" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Quotum verbruikt, downloaded is gestopt" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s is geen geldig email adres" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Server adres verplicht" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Kan %s map %s niet aanmaken" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Schrijven naar het INI bestand %s lukt niet" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Kan geen backup bestand voor %s maken" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Foutief gecodeerd wachtwoord %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s is geen correct octaal getal" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "Het UNC pad \"%s\" mag hier niet." #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Fout: Wachtrij is niet leeg, kan geen andere map kiezen." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Map \"%s\" bestaat niet." #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "SQL opdracht mislukt, zie log bestand" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "SQL opslag opdracht mislukt, zie log bestand" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Het lukt niet om de database te sluiten, zie log bestand" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Foutieve fase logging in geschiedenis voor %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Decoderen van %s mislukt" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "CRC fout in %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Foutief gevormd yEnc artikel in %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Onbekende fout tijdens het decoderen van %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => ontbreekt op alle servers, overslaan" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Fout bij verwijderen van %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Kan %s niet lezen" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Kan Bewaakte Map %s niet lezen" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Pauze" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Server %s wordt gedurende %s minuten genegeerd" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Kan geen verbinding maken %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Te veel verbindingen met server %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Mogelijk delen van account" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Kan niet aanmelden bij server %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Kan geen verbinding maken met server %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Verbinding %s@%s:%s mislukt, bericht=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Server %s heeft gebruikersnaam/wachtwoord nodig" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Afsluiten" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Kan geen verbinding maken met email server" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Kan geen TLS verbinding maken" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Kan niet aanmelden bij email server" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Verzenden van email is mislukt" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Afsluiten email verbinding lukt niet" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Email verzonden" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Kan geen email sjablonen vinden in %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Geen geadresseerden gegeven, geen e-mail gestuurd" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Foutieve codering van email sjabloon %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Geen email sjablonen gevonden" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd meldt een volle harde schijf\n" "\n" "Hallo,\n" "\n" "SABnzbd is gestopt met downloaden omdat de harde schrijf bijna vol is.\n" "Maak ruimte vrij en laat SABnzbd weer doorgaan.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Start/Stop" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "NZB toegevoegd" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Nabewerken gestart" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "NZB voltooid" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Andere berichten" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Let op: LOCALHOST is niet eenduidig, gebruik een numeriek IP-adres." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Server adres \"%s:%s\" is niet geldig." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Sessie sleutel ontbreekt" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Fout: Sessie sleutel nodig" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Fout: Sessie sleutel niet geldig" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "API Sleutel ontbreekt: Vul de API Sleutel van \"Algememe instellingen\" in " "bij je hulp programma:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API Sleutel is fout Vul de API Sleutel van \"Algememe instellingen\" in bij " "je hulp programma:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Authenticatie ontbreekt: Vul gebruikersnaam en wachtwoord van \"Algememe " "instellingen\" in bij je hulp programma:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Fout: geen secundaire interface ingesteld." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Versie van UNRAR wordt niet aanbevolen, download UNRAR van " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Geen UNRAR programma gevonden, uitpakken van RAR bestanden niet mogelijk
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Geen PAR2 programma, kan geen reparaties uitvoeren
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Begin met herstart...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd is nu afgesloten.
    Wacht ongeveer 5 seconden en klik " "dan op onderstaande knop.

    Verversen
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "dagelijks" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "maandag" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "dinsdag" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "woensdag" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "donderdag" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "vrijdag" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "zaterdag" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "zondag" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "uit" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Adres opzoeken" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Foute instelling" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Terug" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Opdracht \"%s\" terug naar de wachtrij" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Items met een ster '*' worden niet automatisch gedownload." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Geselecteerd" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Niet geselecteerd" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Gedaan" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Tot nu toe gedaan" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Foute waarde voor %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Kan map %s niet aanmaken" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s map: fout %s bij toegang" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Kan geen verbinding maken met register deel HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Kan register sleutel \"%s\" niet lezen" #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Kan register sleutels voor speciale mappen niet lezen" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Aanmaken %s mislukt" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Verplaatsen van %s naar %s mislukt" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Onbruikbaar NZB bestand" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Opnieuw" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "URL ophalen mislukt; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "Module \"pyopenssl\" ontbreekt, geen HTTPS mogelijk" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Fout bij aanmaken van SSL sleutel en certificaat" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Kan beveiliging van %s niet aanpassen" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Samenvoegen" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Onvolledige reeks van samenvoegbare bestanden" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Samenvoegen van Bestanden %s is mislukt" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fout \"%s\" bij samenvoegen van bestanden" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Fout %s bij samenvoegen van %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] %s bestanden samengevoegd" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Uitpakken mislukt, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fout \"%s\" bij het uitpakken van RAR bestanden" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fout \"%s\" bij uitvoeren van rar_unpack op %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Verwijderen van %s mislukt!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Probeer unrar met wachtwoord \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Uitpakken mislukt, archief heeft wachtwoord nodig" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Uitpakken" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Uitpakken mislukt, kan %s niet vinden" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "FOUT\" kan \"%s\" niet vinden" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Uitpakken mislukt, CRC fout" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "FOUT: Foutieve CRC \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Uitpakken mislukt, schrijffout of schijf vol?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "ERROR: schrijf fout (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Uitpakken mislukt, bestandspad is te lang" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "FOUT: bestandspad is te lang (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Uitpakken mislukt, zie log" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "FOUT: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "Onbruikbaar RAR bestand" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Verwacht bestand %s ontbreekt => unrar fout?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Uitpakken mislukt, er zijn te weinig bestanden uitgepakt" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Uitpakken is mislukt, deze bestand(en) ontbreken:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "%s bestanden/mappen uitgepakt in %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s bestanden in %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Fout \"%s\" bij uitvoeren van unzip() op %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Snelle Controle uitvoeren" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Repareren" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Snelle Controle OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Start reparatie" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparatie mislukt, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Fout %s bij uitvoeren van par2 reparatie op verzameling %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fout \"%s\" bij reparatie van groep %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "[%s] De PAR2 opties zijn niet goed, controleer Instellen->Opties" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificatie in %s, alle bestanden zijn goed" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificatie in %s, reparatie is nodig" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Hoofdpakket niet gevonden..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Ongeldige par2 bestanden, verificatie en reparatie is niet mogelijk" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparatie mislukt, te weinig herstelblokken (%s te weinig)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Ophalen van %s blokken..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Ophalen" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Repareren" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Reparatie in %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Verifiëren" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Fout bij importeren van module OpenSSL, probeer NON-SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Bijwerken newzbin opdracht %s mislukt" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB aan wachtrij toegevoegd" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Newzbin server gebruikt ander protocol" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Je hebt geen betaald Newzbin account" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Niet geauthoriseerd, controleer je newzbin gebruikersnaam/wachtwoord" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin rapport %s niet gevonden" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin meldt onbekende fout code (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Newzbin server geeft geen informatie over %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Verwijderen van newzbin bladwijzer %s mislukt" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin meldt onbekende fout code %s" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Onbruikbaar wachtrij bestand gevonden, kan niet verder" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Fout bij inladen van %s, corrupt bestand gevonden" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Fout bij toevoegen van %s, wordt weer verwijderd" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Onbekende codering" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Bestand %s is leeg, overslaan" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Importeren van %s bestanden van %s mislukt" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Onvolledig NZB bestand %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Foutief NZB bestand %s, overslaan (reden=%s, regel=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "NZB bestand %s is leeg" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Dubbele NZB \"%s\" overgeslagen" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Pauzeer dubbele NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Afgebroken, kan niet voltooid worden" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUBBEL" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "VERSLEUTELD" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "TE GROOT" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "ONVOLLEDIG" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "ONGEWENST" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "WACHT %s sec" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Gedownload in %s met een gemiddelde van %sB/sec" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artikelen zijn misvormd" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s artikelen ontbreken" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artikelen hadden afwijkende duplicaten" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s artikelen zijn verwijderd" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Fout bij importeren van %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Meldingen" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Rust" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Instellen" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Wachtrij" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Wis wachtrij" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Geschiedenis" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Wis de volledige geschiedenis" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Beperk snelheid" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pauze" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Doorgaan" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Haal Newzbin Bladwijzers op" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Bewaakte map uitlezen" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Map voltooid" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Map download" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Probleemoplosser" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Herstarten" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Herstarten zonder login" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Afsluiten" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Wachtrij Eerste 10 Items" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Leeg" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Geschiedenis Laaste 10 Items" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Nieuwe versie beschikbaar" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Ga naar Wizard" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Afsluiten..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Probleem met" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd werkt niet in combinatie met sommige firewall programma's.
    \n" "%s
    \n" "Het spijt ons, maar we kunnen dit probleem niet oplossen.
    \n" "Graag een klacht indienen bij je firewall leverancier.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd heeft een vrije TCP/IP poort nodig voor de interne web " "server.
    \n" "Poort %s op %s is geprobeerd, maar is niet beschikbaar.
    \n" "Een ander programma gebruikt de poort al of SABnzbd is al aktief.
    \n" "
    \n" "Start SABnzbd met een ander poort nummer." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "Als je dit bericht weer krijgt, probeer dan een ander nummer.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd heeft een vrije TCP/IP poort nodig voor de interne web " "server.
    \n" "Poort %s op %s is geprobeerd, maar het gebruikers account van SABnzbd heeft " "geen toestemming.
    \n" "Op OSX en Linux systemen mogen standaard gebruikers alleen poorten boven " "1023 gebruiken.
    \n" "
    \n" "Start SABnzbd met een ander poort nummer." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd heeft een geldig host adres voor de interne web server.
    \n" "Je hebt een onbruikbaar adres opgegeven.
    \n" "Veilige waarden zijn localhost en 0.0.0.0
    \n" "
    \n" "Start SABnzbd met een geldig host adres." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd heeft opgeslagen data van een andere SABnzbd versie " "gevonden
    \n" " maar kan de data van dit andere programma niet opnieuw " "gebruiken.

    \n" " Rond zo nodig eerst je werk met het andere programma af.

    \n" " Herstart daarna dit programma met de optie \"--clean\".
    \n" " Dit zal de huidige taak en geschiedenis wissen!
    \n" " SABnzbd las het bestand \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd kan de web interface bestanden niet vinden in %s.
    \n" "Installeer het programma opnieuw.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd heeft een fatale fout ontdekt:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd heeft een Wachtrij en Geschiedenis van een oudere (0.4.x) versie " "ontdekt.

    \n" "Beide kunnen verloren gaan!

    \n" "Je kunt nu SABnzbd stoppen en de wachtrij afmaken met de oude " "versie.

    \n" "Klik op OK om door te gaan." #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd heeft ontdekt dat het bestand sqlite3.dll " "ontbreekt.

    \n" "Sommige slecht ontworpen virus scanner verwijderen dit bestand.
    \n" "Controleer je virus scaner, probeer SABnzbd opnieuw te installeren en klaag " "bij je leverancier.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Gebruik Windowstoets-R en type deze regel in (voorbeeld):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Open een \"Terminal\" venster en type deze regel in (voorbeeld):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Mogelijk gebruik je ZoneAlarm op Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Programma is niet opgestart!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Je hebt geen toestemming om poort %s te gebruiken" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Fatale fout" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Kan de web-browser niet starten, geen gevonden" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Toegang geweigerd" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Fout %s: Je moet een geldige gebruikersnaam en wachtwoord invullen." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Fout bij laden van nabewerkingswachtrij: verkeerde versie (nodig:%s, " "gevonden:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Verwijderen van nzo van nabewerkingswachtrij mislukt" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "" "Download mislukt waarschijnlijk, slechts %s van de benodigde %s beschikbaar" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Download mislukt - Buiten de server bewaartijd?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Kan bestemmingsmap %s niet maken" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Geen nabewerking vanwege mislukte verificatie" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Verplaatsen" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "%s naar de wachtrij gestuurd" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Fout bij hernoemen van \"%s\" tot \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Verplaatsen van bestanden mislukt" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Script uitvoeren" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Gebruiker script %s loopt" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "%s is klaar" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Meer" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Toon script resultaat" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Download voltooid" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Download mislukt" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Nabewerking van %s mislukt (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "zie logbestand" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Nabewerking is afgebroken (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Opschonen van %s mislukt" #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Fout bij verwijderen van werkmap %s" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Nabewerking" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Geen par2 groepen" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Probeer SFV verificatie" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Sommige bestanden konden niet geverifieerd worden met \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Verificatie m.b.v. SFV bestanden is gelukt" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Verwijderen van %s mislukt" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Kan systeem niet in slaapstand krijgen" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Kan het systeem niet in standby krijgen" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Fout bij het afsluiten van het systeem" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Foutieve RSS-feed definitie \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Kan RSS-feed \"%s\" niet lezen vanwege: \"%s\"" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Geen geldige inlog gegevens beschikbaar voor feed %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "Server fout (code is %s); kon geen %s van %s krijgen" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "RSS-feed %s is leeg" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Ongeschikte feed" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Lege RSS-feed gevonden (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Toon Interface" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Open map met voltooide downloads" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Afsluiten" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Nog te doen" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Foutieve taak %s om %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Onbekende aktie: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Taak voor niet bestaande server %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Download" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Samenvoegen" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Uitpakken" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Script" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Bron" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Mislukt" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Voltooid" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Mislukt" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Wacht" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Repareren..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Uitpakken..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Verplaatsen..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Script uitvoeren..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Extra blokken ophalen..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Snelle Controle..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Verificatie..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Downloaden" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Ophalen" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Controleren" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Frequentie" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Aktie" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Parameters" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Taak" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "Server uit:" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "Server aan:" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Maximum snelheid" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Alles pauzeren" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pauzeer nabewerken" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Hervat nabewerken" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Uitlezen RSS feeds" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Verwijder mislukte opdrachten" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "uur" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "uren" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "min" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "min" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sec" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "seconden" #: sabnzbd/skintext.py:79 msgid "day" msgstr "dag" #: sabnzbd/skintext.py:80 msgid "days" msgstr "dagen" #: sabnzbd/skintext.py:81 msgid "week" msgstr "week" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "maand" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "jaar" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "dagnummer" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Deze Week" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Deze Maand" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Vandaag" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Totaal" #: sabnzbd/skintext.py:97 msgid "on" msgstr "aan" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parameters" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Python versie" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Startpagina" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "of" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Server naam" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "Commentaar" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "Verzenden" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "Annuleren" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "Overige" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "Overzicht" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "Video" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "Audio" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "De automatische Usenet downloader" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Opslaan" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Wacht" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Weet je het zeker?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Alle gedownloade bestanden verwijderen?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Opdrachten" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Instellen" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Status" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Hulp" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Algemeen" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Mappen" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Opties" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Servers" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Taakplanner" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Meldingen" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Email" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Index sites" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Categorieën" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sorteren" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Speciaal" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Map download" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Map voltooid" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Snelheid" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "PAUZE" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "%s artikelen (%s) gebuffered" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Sysload" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "MELDINGEN" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Nieuwe versie %s beschikbaar op" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Opdrachten toevoegen" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Weet je zeker dat je SABnzbd wilt afsluiten?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Toevoegen" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Newzbin rapport" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Bestand" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Categorie" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Modus" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioriteit" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Repareren" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Uitpakken" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Opschonen" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "U" #: sabnzbd/skintext.py:177 msgid "D" msgstr "O" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Forceren" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normaal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Hoog" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Laag" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stop" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " of Report ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Op naam" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Op leeftijd" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Op grootte" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Verberg bestanden" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Toon bestanden" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Bij lege rij" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "PC afsluiten" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "PC standby" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "PC slapen" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "SABnzbd afsluiten" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Max. snelheid" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pauzeer" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Volgorde" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Naam" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Te doen/Totaal" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Klaar om" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "Leeftijd" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Wis" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Opnieuw" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Akties" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Scripts" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Verwijder alle opdrachten uit de wachtrij?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Verwijder opdrachten" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Verwijderen incl. bestanden" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Verwijder NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Verwijder NZB incl. bestanden" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "van" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Ontbrekende artikelen" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Quotum over" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "handmatig" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Quotum nu herstellen" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Verwijder mislukte items" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Verwijder alle geslaagde items uit Geschiedenis?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Verwijder alle mislukte items uit Geschiedenis?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Verberg details" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Toon details" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Totaal" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Toon mislukte" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Toon Alles" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Omvang" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Verwijder mislukte opdrachten" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Verwijder mislukte opdrachten incl. bestanden" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Verwijder geslaagde opdrachten" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Eventuele extra NZB" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Pad" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "Virus/spam" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "Versleuteld" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "Buiten retentie" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "Ander probleem" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Verbreek verbindingen" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Hiermee stuur je een test email." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Toon log info" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Toon weblog info" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Email testen" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Loggen" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Fouten/Waarschuwingen" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+Debug" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Verbindingen" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Verbinding" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Test resultaat email" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Recentste meldingen" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "Wissen" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Deblokkeren" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Artikel nummer" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Bestandsverzameling" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Wanneer" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Soort" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Waarschuwing" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Actief" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Instellingen bestand" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Gebruikte buffer" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Deze knop zal SABnzbd herstarten.
    Dit kan nuttig zijn wanneer je " "vermoedt dat het programma niet stabiel is.
    Het downloaden zal vóór de " "herstart gestopt worden en daarna weer doorgaan." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Er staan verweesde opdrachten in de download map.
    Je kunt ze verwijderen " "(inclusief bestanden) of ze terug naar de wachtrij sturen." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "De \"Repareren\" knop herstart SABnzbd met een complete
    \r\n" "reconstructie van de wachtrij, met behoud van al gedownloade " "bestanden.
    \r\n" "Dit beïnvloedt wel de volgorde." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Versie" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Aktief" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Reserve" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "OZnzb" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Algemene instellingen" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Wijzigingen worden pas aktief na herstart!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Web server" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Host" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Host adres waar op SABnzbd luistert." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Poort" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Poort waar op SABnzbd luistert." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Gebruikersinterface" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Kies een bedieningsstijl (herstart nodig)." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Secundair Gebruikersinterface" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Aktiveer een tweede bedieningsstijl (herstart nodig)." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Web server authenticatie" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Gebruikersnaam" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Gebruikersnaam voor web login." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Wachtwoord" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Wachtwoord voor web login." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "HTTPS ondersteuning" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Maak HTTPS mogelijk" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "niet geinstalleerd" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Sta gebruik van HTTPS toe." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "HTTPS Poort" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Indien leeg, werkt de standaard poort uitsluitend met HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "HTTPS Certificaat" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Naam of pad van het HTTPS Certificaat bestand." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "HTTPS Sleutelbestand" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Naam of pad van het HTTPS Sleutel bestand." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "\"HTTPS Chain\" bestand" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Bestandsnaam of padnaam van \"HTTPS chain\" bestand" #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Afstelling" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Verversingsinterval van de Wachtrij" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "Verversingsinterval van het de Wachtrij pagina (sec, 0= geen)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "RSS uitlees interval" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Minuten tussen het uitlezen (minimaal 15). Niet aktief bij gebruik van de " "Taakplanner!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Download snelheidsbeperking" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Download snelheidsbeperking kilobytes per seconde (kB/s)." #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Artikel buffer grootte" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "Bewaar de artikelen in het werkgeheugen (verminderd schijf gebruik)." #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Opschoon lijst" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lijst van bestand extensies die verwijderd worden
    Voorbeeld: " ".nfo of .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Opslaan" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Taal" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Kies een taal" #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "API Sleutel" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" "Met deze sleutel heeft een hulp programma volledige toegang tot SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "NZB Sleutel" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Met deze sleutel kan een hulp programma NZB bestanden naar SABnzbd sturen." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Maak een nieuwe sleutel" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "API-sleutel niet gebruiken" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Gebruik van de API sleutel niet afdwingen." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "GEBRUIK OP EIGEN RISICO!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "QR Code" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "QR code van de API sleutel" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Map instellingen" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "Let op: mappen worden vanzelf aangemaakt bij \"Opslaan\"." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Gebruikersmappen" #: sabnzbd/skintext.py:345 msgid "In" msgstr "In" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Tijdelijke download map" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Plaats om onbewerkte downloads op te slaan
    Kan alleen gewijzigd " "worden als de wachtrij leeg is." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimale vrije ruimte voor tijdelijke download map" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "Download wordt gepauzeerd als er te weinig ruimte vrij is" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Map voor verwerkte downloads" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "(kan aangepast worden door de categorieën)." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Toegangsrechten voor verwerkte downloads" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Zet toegangsrechten voor verwerkte bestanden/mappen, alleen octale notatie!" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Bewaakte map" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr ".nzb en .zip bestanden in deze map worden automatisch gedownload." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Leestempo bewaakte map" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Aantal seconden tussen lezen van de bewaakte map." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Map met gebruikers scripts" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Map waarin zich de script bestanden voor nabewerking bevinden." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Map met email sjablonen" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Map waarin zich de email sjablonen bevinden." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Wachtwoordenbestand" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Bestand met alle wachtwoorden die uitgeprobeerd moeten worden op " "versleutelde RAR bestanden." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Systeem folders" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Administratieve map" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Map voor wachtrij administratie en geschiedenis bestand.
    Kan alleen " "wijzigen als de wachtrij leeg is." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "De bestanden worden niet verplaatst. SABnzbd herstart is nodig!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Map voor logging" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Map waarin de log bestanden worden opgeslagen
    Vereist een " "herstart." #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Map voor het bewaren van nzb bestanden" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Map waar reserve kopieën opgeslagen worden." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Standaard basis map" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Diverse instellingen" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Nabewerking instellingen" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Snelle controle toestaan" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Geen uitgebreide PAR2 controle als de bestanden 100% in orde zijn." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Unrar toestaan" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Uitpakken van RAR archieven toestaan." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Unzip toestaan" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Uitpakken van ZIP archieven toestaan." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Samenvoegen van bestanden toestaan" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Voeg bestanden eindigend met .001, .002 enz. samen tot één file." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Samenvoegen van TS bestanden toestaan" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "" "Voeg bestanden eindigend met .001.ts, .002.ts enz. samen tot één file." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "PAR bestanden opruimen" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Ruim PAR bestanden op (na succesvolle verificatie/reparatie)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Verwijder artikelen met yEnc crc fouten" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "Probeer deze artikelen opnieuw te downloaden van een reserve server." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Download alleen artikelen van het begin van de wachtrij" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Aanzetten zal leiden tot minder geheugen gebruik.
    Uitzetten om te " "voorkomen dat langzame opdrachten de wachtrij blokkeren." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Verwerk alleen correct geverifieerde downloads" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Voer de nabewerking alleen uit op downloads die alle PAR2 controles hebben " "doorlopen." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Aktie wanneer versleuteld RAR bestand wordt gedownload" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Als je \"Pause\" kiest, dan dien een wachtwoord in te stellen en de download " "vrij te geven" #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Detecteer dubbele opdrachten" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Herken identieke NZB namen (hiervoor is de NZB backup optie nodig) en " "identieke titels binnen RSS feeds." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "Aktie bij ontdekken van ongewenste extensie" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" "Aktie uit te voeren bij ontdekking van ongewenste extensie in een RAR bestand" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "Ongewenste extensies" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" "Lijst van alle ongewenste extensies. Voorbeeld: exe or exe, com" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Behouden" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Verwerpen" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Afbreken" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Voer SFV-gebaseerde controles uit" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Doe een extra verificatie m.b.v. SFV bestanden" #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Controleer resultaat van uitpakken" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Controleer resultaat van uitpakken (moet \"uit\" staan voor sommige " "bestandssystemen)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Gebruik tijdelijke mapnamen" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Gebruik tijdelijke mapnamen tijdens de nabewerking. Zet dit uit wanneer je " "systeem daar problemen mee heeft." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Standaard nabewerking" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Wordt gebruikt wanneer de categorie geen nabewerking opgeeft." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Standaard script" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Wordt gebruikt wanneer de categorie geen script opgeeft." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Wachtrij filter script" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Wordt uitgevoerd vóór een NZB de queue in gaat" #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Standaard prioriteit" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Wordt gebruikt wanneer de categorie geen prioriteit opgeeft." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "MultiCore Par2 toestaan" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Lees de Wiki pagina over dit onderwerp" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Extra PAR2 parameters:" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "\"Nice\" parameters" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "\"IONice\" parameters" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Diverse instellingen" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Verbreek verbindingen wanneer er niets te doen is" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Verbreek verbindingen wanneer de wachtrij leeg is of er gepauzeerd wordt." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Verzend groep" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Verzend de groepsnaam naar de server." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sorteer op leeftijd" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Automatisch sorteren op basis van gemiddelde leeftijd." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Informeer naar nieuwe versies" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Informeer iedere week naar nieuwe SABnzbd versies." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Ook test versies" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Vervang spaties in map namen" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Vervang spaties door onderliggende streepjes in namen van mappen." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Vervang punten in map namen" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Vervang punten door spaties in namen van mappen." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Vervang verboden tekens in map namen" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Vervang verboden tekens in map namen door gelijkende tekens (anders " "verwijderen)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Start web browser bij opstarten" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Start de web browser wanneer SABnzbd opstart." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Onderbreek downloaden tijdens nabewerken" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "Onderbreek downloaden tijdens nabewerken." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Verwerking van \"sample\" bestanden" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Wat te doen met \"sample\" bestanden?" #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Verwijderen na download" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Niet downloaden" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "SSL type" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Gebruik V23, behalve wanneer persé nodig voor je Internet provider!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Gebruik de 12-uren klok (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Toon tijden in AM/PM notatie (heeft geen invloed op de taakplanner)" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Server" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Nabewerking" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Naamgeving" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Quotum" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "Indexering" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Hoeval mag deze maand worden gedownload (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Herstel dag" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Op welke dag van de maand of week (1=maandag) wordt het quotum hersteld? " "(Eventueel met hh:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Automatisch doorgaan" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "" "Moet het downloaden automatisch doorgaan bij het ingaan van het nieuwe " "quotum?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Quotum periode" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Wordt het quotum elke dag, week of maand hersteld?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Controle vóór downloaden" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Probeer de succes kans van een download van te voren in te schatten " "(langzamer!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Maximum aantal pogingen" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Maximaal aantal pogingen per server" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Alleen voor optionele servers" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Stel alleen een maximaal aantal pogingen in voor optionele servers" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Afbreken als voltooien niet kan" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Als tijdens de download duidelijk wordt dat te veel data ontbreekt, breek " "dan de download af" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "OZnzb integratie inschakelen" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" "Uitgebreide functionaliteit met waarderingen en extra status informatie " "wanneer gekoppeld aan OZnzb indexer." #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "API sleutel van indexer" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" "Deze sleutel is het toegangsbewijs voor de indexer. Kijk op " "https://www.oznzb.com/profile." #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "Kijk op https://www.oznzb.com/profile" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "Automatische terugkoppeling" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "Verzend berekende validatie gegevens over downloads naar de indexer." #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Usenet servers" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Server definitie" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Voeg server toe" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Poort nummer" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Gebruikersnaam" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Wachtwoord" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Tijdslimiet" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Bewaartijd" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Reserve server" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Optioneel" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Aktief" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Verwijder" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Test Server" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Tellers op nul" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Server instellingen aan het testen..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Klik hier onder om te testen." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Bandbreedte" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Agenda instellen" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Taak toevoegen" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Verwijder" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Huidige taken" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "RSS-feed Definities" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "URL van nieuwe RSS-feed" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Om de RSS-feed automatisch te verwerken, vink het selectievlakje bij de " "definitie naam aan.
    Wanneer een nieuwe feed wordt gedefinieerd, zullen " "alleen nieuwe items gevonden worden en geen bestaande, behalve wanneer je de " "op \"Forceer download\" klikt." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Feed toevoegen" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Verwijder" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Uitlezen" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Forceer download" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filter" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Overslaan" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Accepteren" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Verwerpen" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Verplicht" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "VerplichteCat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Niet geselecteerd" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Feeds" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Alle feeds nu uitlezen" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Instellingen" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filters" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Email Opties" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Zend email na voltooien van elke download" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Nooit" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Altijd" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Alleen bij fouten" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Zend email wanneer de harde schijf vol is" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Zend email wanneer SABnzbd gestopt is vanwege een volle harde schijf." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Zend email voor RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" "Zend email wanneer een RSS bron opdrachten
    aan de wachtrij heeft " "toevoegd." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Email gegevens" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "SMTP email server" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Het adres van je Internet providers email server." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Email bestemming" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Adres waarnaar de email verstuurd wordt." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Email afzender" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Wie zou de email gestuurd moeten hebben?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "OPTIE: Account gebruikersnaam" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Wanneer authenticatie nodig is, gebruikersnaam." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "OPTIE: Account wachtwoord" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Wanneer authenticatie nodig is, wachtwoord." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Growl aanzetten" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Zend meldingen naar Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Server adres" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "" "Alleen gebruiken voor een Growl server op een ander systeem (server:poort)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Server wachtwoord" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Optioneel wachtwoord voor de Growl server" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "NotifyOSD aanzetten" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Zend meldingen naar NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Berichtencentrum" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Stuur berichten naar het Berichtencentrum" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Bericht types" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "Kies welke bericht types verstuurd moeten worden (geen, één of meer)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Als je een account bij www.newzbin2.es hebt dan kun je hier " "je gebruikersnaam en wachtwoord invullen. Je krijgt dan extra newzbin " "functies." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Abonnementsgegevens" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Gebruikersnaam" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Vul hier je gebruikersnaam in." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Wachtwoord" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Vul hier je wachtwoord in." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Automatische bladwijzer verwerking" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Bladwijzers ophalen" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Automatisch NZB bestanden van bladwijzers ophalen." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Bladwijzers nu ophalen" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Bladwijzers verbergen" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Bladwijzers tonen" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Bladwijzers achteraf verwijderen" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Bladwijzer automatisch verwijderen na succesvolle download." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Lees interval" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "In minuten (minimaal 15)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Verwerkte bookmarks" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Wanneer je een account bij www.nzbmatrix.com hebt, kun je " "hier je gegevens invullen.
    Dit is nodig om RSS feeds van deze site te " "kunnen verwerken." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Gebruikersnaam" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "NzbMatrix API sleutel" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Vul hier de NzbMatrix API sleutel in." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Categorieën voor nabewerking" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Bepalend voor nabewerking en opslag." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Gebruik de \"Groepen / Indexer markeringen\" kolom om groepen en " "markeringen\r\n" "op je categorieën af te beelden.
    Joker karakters zijn toegestaan.\r\n" "Gebruik komma's om elementen te scheiden." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Als het pad eindigt met een ster *, dan worden geen aparte taak folders " "gemaakt." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "De relatieve mappen zijn gebaseerd op" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Map/Pad" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Groepen / Indexer markeringen" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Sorteer instellingen" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Serie sorteren" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "TV sorteren aan" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Sta sorteren en hernoemen van afleveringen toe." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Uitleg" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Wissen" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Voorkeuzes" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Voorbeeld" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Algemeen sorteren" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Film sorteren aan" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Sta algemeen sorteren en hernoemen van bestanden toe." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Zet downloads in aparte mappen" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Sta opslaan van downloads in een eigen map toe." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Beïnvloede categorieën" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Betekenis" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Patroon" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Resultaat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Seizoensmappen" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Seizoensmap" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Episodemap" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Episodemap" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Film Naam" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Film.Naam" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Film_Naam" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Serie Naam" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Serie.Naam" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Serie_Naam" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Seizoen Nummer" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Episode Nummer" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Episode Naam" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Episode.Naam" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Episode_Naam" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Bestandsextensie" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Extensie" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Volgnummer" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Decade" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Originele Bestandsnaam" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Oorspronkelijke mapnaam" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Kleine letters" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py:667 msgid "text" msgstr "tekst" #: sabnzbd/skintext.py:668 msgid "file" msgstr "bestand" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "map" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Sorteer formule" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Meervoudig label" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "In mappen" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Geen mappen" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Datum sorteren" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Datum sorteren aanzetten" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Sta sorteren en hernoemen van datum-gebaseerde bestandsnamen toe." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Toon Naam map" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Jaar-Maand Mappen" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Dagelijkse Mappen" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "Aanpassen van hoofd- en kleine letters" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Bewerkt resultaat" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Zelden gebruikte opties. Voor betekenis en uitleg, klik op de Help knop om " "naar de Wiki te gaan.
    Wijzig hier niet zonder eerst de uitleg op de Wiki " "te lezen. Er kunnen nadelige bijwerkingen optreden.
    De standaard " "instellingen staan tussen haakjes." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Waarden" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Bewerk NZB Details" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Verwijder" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Boven" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Hoger" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Lager" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Onder" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "alles" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "omkeren" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Bestandsnaam" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Onderwerp" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Leeftijd" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Selectie" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Weet u zeker dat u wilt verwijderen" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Ververs" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Opties" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Pagina" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Vorige" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Volgende" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Eerste" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Laatste" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Sluiten" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Set Pauze Interval" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sorteren" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Verwijder uit de Wachtrij?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Pauze Interval" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pauzeer 5 minuten" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pauzeer 15 minuten" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pauzeer 30 minuten" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pauzeer 1 uur" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pauzeer 3 uur" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pauzeer 6 uur" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pauzeer 12 uur" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pauzeer 24 uur" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sorteer op Leeftijd Oud→Nieuw" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sorteer op Leeftijd Nieuw→Oud" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sorteer op Naam A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sorteer op Naam Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sorteer op Omvang Klein→Groot" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sorteer op Omvang Groot→Klein" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Naam" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Over" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Wis de volledige geschiedenis?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Wijzigingen niet opgeslagen en zullen verloren gaan." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Open Source URL" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Open Informatie URL" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Opslag" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Toon Script resultaat" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "JavaScript is nodig voor de werking van Plush!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "NZB toevoegen" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Plush instellingen" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Update beschikbaar!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Hoeveel minuten pauzeren?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pauzeer..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Meervoudige bewerking" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Top menu aan/uit" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Bij lege wachtrij" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sorteer op Leeftijd (Oud→Nieuw)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sorteer op Leeftijd (Nieuw→Oud)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sorteer op Naam (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sorteer op Naam (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sorteer op Omvang (Klein→Groot)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sorteer op Omvang (Groot→Klein)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Opschonen" #: sabnzbd/skintext.py:781 msgid "left" msgstr "over" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Max Snelheid" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Bereik" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Herstel" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Op selectie toepassen" #: sabnzbd/skintext.py:786 msgid "page" msgstr "Pagina" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Alles" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Uit" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Verversingstempo" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Breedte van kader" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Bevestig verwijderen uit wachtrij" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Bevestig verwijderen uit geschiedenis" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Dit voorkomt pagina verversing wanneer de muis aanwijzer in de wachtrij is." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Geen verversing bij popups" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Ophalen" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Ophalen" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Upload: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Geef eventueel een bestandsnaam op" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Voortgang" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Onvoldoende schijfruimte over!" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Vrije ruimte" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Vrij (tijdelijk)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "RUST" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Downloads" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Wachtrij reparatie" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Uitlezen leest/ververst de huidige feed inhoud. " "Forceer download zal alle geselecteerde NZBs nu downloaden." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Uur:Min" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Verwijder geslaagde" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Verwijder alle mislukte items uit de Geschiedenis?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Verwijder mislukte" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Koppelingen" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Toon %s t/m %s van %s resultaten" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Geen resultaten" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Eén resultaat" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Email verzonden!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Melding verzonden" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Opslaan.." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Opgeslagen" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Snelheid" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "\"NZB toevoegen\" uitklappen" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "Dubbel1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "Dubbel2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Aangepast" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Bookmarks ophalen" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Weet je zeker dat je SABnzbd wilt herstarten?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Verversen" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Alles wissen" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Verberg Opties" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Toon Opties" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Bewerk" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Te gaan" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Snelstart Hulp" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "SABnzbd versie" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Vorige" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Toegang" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Ik wil SABnzbd kunnen gebruiken vanaf iedere PC in mijn thuisnetwerk." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Ik wil SABnzbd alleen vanaf deze PC kunnen gebruiken." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Wachtwoord beveiliging voor SABnzbd (aanbevolen)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Maak HTTPS (beveiligd) verkeer mogelijk." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Diversen" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Start de web browser wanneer SABnzbd opstart." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Server instellingen" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Vul hier de gegevens van je primaire Usenet server in." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Om te kunnen downloaden van Usenet, heb je een provider nodig. Je Internet " "bedrijf heeft misschien een server, maar we bevelen een betaalde server aan." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Heb je nog geen Usenet provider? Wij bevelen %s aan." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Het aantal verbindingen dat je provider toestaat." #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "Bv. 8 of 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Vink dit alleen aan als je provider SSL verbindingen toestaat." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Klik om de verbinding te testen." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Verplicht veld" #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Vul hier een geheel getal in." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Wanneer je een Newzbin of een nzbmatrix abonnement hebt, kun je hier je " "gegevens invullen, zodat SABnzbd de NZB bestanden kan ophalen. Je kunt dit " "overslaan als je deze diensten niet gebruikt." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Automatisch ophalen van newzbin bookmarks." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Voorbeeld" #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "SABnzbd herstart nu..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Het instellen is klaar!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd werkt op de achtergrond." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Afsluiten van de browser vensters zal SABnzbd niet stoppen." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Als de SABnzbd herstart klaar is, kun je de bediening via deze koppeling " "bereiken: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Tip: maak een \"Bladwijzer\" of \"Favoriet\" voor deze lokatie, zodat je " "SABnzbd gemakkelijk terug kunt vinden." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Voor meer informatie: zie onze" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Ga naar SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Stap Een" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Stap Twee" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Stap Drie" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Stap Vier" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Stap Vijf" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "Bv. 119 of 563 voor SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Stop SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Wizard starten" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "Als je geen account hebt, kun je dat aanmaken op " #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd wordt aangeboden ZONDER ENIGE VORM VAN GARANTIE.\n" "Het is vrije software en je mag het, onder bepaalde voorwaarden, verder " "verspreiden.\n" "De licentie is de GNU GENERAL PUBLIC LICENSE Versie 2 of (naar eigen keuze) " "een latere versie.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Fout bij ophalen TV info (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Hernoemen van %s tot %s mislukt" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Hernoemen van gelijkaardig bestand %s tot %s mislukt" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Ongeldig nzbmatrix rapport nummer %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "" "Je hebt een nzbmatrix VIP account nodig om de API te kunnen gebruiken" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Ongeldige nzbmatrix gegevens" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Geen toegang tot nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Geen hostnaam opgegeven." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Er zijn geen verbindingen opgegeven. Er is minimaal één verbinding nodig." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Wachtwoord gemaskeerd met ******, voer opnieuw in" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Ongeldige servergegevens" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Tijdslimiet overschreden. Probeer met SSL aan of gebruik een andere poort." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Tijdslimiet overschreden" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Ongeldige servernaam" #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "De server stopte tijdens de login" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Server heeft een gebruikersnaam en een wachtwoord nodig." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Succesvol verbonden!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Inloggen mislukt, controleer gebruikersnaam en wachtwoord." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Te veel verbindingen, onderbreek het downloaden of probeer later nog eens." #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Kan verbindingsresultaat niet bepalen (%s)" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "Ophalen rapport %s van www.newzbin.com" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Fout bij ophalen van rapport %s van www.newzbin.com - Zorg dat je " #~ "gebruikersnaam en wachtwoord goed ingevuld zijn" #~ msgid "Expected size did not equal actual size" #~ msgstr "Verwachte lengte ongelijk aan echte lengte" #~ msgid "Could not compile regex: %s" #~ msgstr "Kan reguliere expressie \"%s\" niet verwerken" #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Wanneer je een account bij www.newzbin.com hebt, kun je " #~ "hier je gegevens invullen.
    Dit maakt extra mogelijkheden beschikbaar." #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Voeg een wachtwoord toe en hervat de taak." #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Pauzeer waneer een versleutelde RAR wordt gevonden" #~ msgid "Email Notifications" #~ msgstr "Email meldingen" #~ msgid "Should downloading resume after the quotum is reset?" #~ msgstr "" #~ "Moet het downloaden automatisch doorgaan bij het ingaan van het nieuwe " #~ "quotum?" #~ msgid "Quotum" #~ msgstr "Quotum" #~ msgid "Quotum left" #~ msgstr "Quotum over" #~ msgid "Does the quotum get reset each day, week or month?" #~ msgstr "Wordt het quotum elke dag, week of maand hersteld?" #~ msgid "" #~ "On which day of the month or week (1=Monday) does your ISP reset the quotum? " #~ "(Optionally with hh:mm)" #~ msgstr "" #~ "Op welke dag van de maand of week (1=maandag) wordt het quotum hersteld? " #~ "(Eventueel met hh:mm)" #~ msgid "Quotum period" #~ msgstr "Quotum periode" SABnzbd-0.7.20/po/main/pl.po0000644000000000000000000036466712433712564015577 0ustar00usergroup00000000000000# Polish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2014-07-02 18:04+0000\n" "Last-Translator: shypike \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:54+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Nie udalo sie uruchomic interfejsu www" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Nie ma szablonu: %s, uzyto standardowego szablonu" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "modul _yens... NIE znaleziono!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "program par2 ... NIE znaleziono!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "program unrar ... NIE znaleziono!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "program unzip ... NIE znaleziono!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "Nazwa hosta 0.0.0.0 wymaga adresu IPv6 do dostepu z zewnatrz" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Wylaczono HTTPS z powodu braku plików CERT oraz KEY" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnabd zostal wylaczony" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Odebrano sygnal %s. Zapisywanie i i zamykanie programu..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "pobieranie wiadomosci %s z www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Blad pobierania %s z www.newzbin2.es - Upewnij sie, ze ustawiles nazwe " "uzytkownika i haslo" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Próba pobrania NZB z %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Nie mozna utworzyc tymczasowego pliku dla %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Próba ustawienia statusu nieistniejacego serwera %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Zbyt malo miejsca, wymuszanie WSTRZYMANIA" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Blad w tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Nie udalo sie zapisac %s" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Nie udalo sie wczytac %s" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Powiadomienie testowe" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Brak" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Domyslny" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "UWAGA:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "BLAD:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "nieznany" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Blad kompilacji wyrazenia regularnego dla wyszukiwania: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "g" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Dysk pelny! wstrzymuje pobieranie" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Blad dysku podczas tworzenia pliku %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "UWAGA: wstrzymane zadanie \"%s\" z powodu zaszyfrowanego pliku RAR" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "UWAGA: Przerwano zadanie \"%s\" z powodu zaszyfrowanego pliku RAR" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Przerwano, wykryto szyfrowanie" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "brakuje %s" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Przekroczono limit, zatrzymywanie pobierania" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s nie jest prawidlowym adresem mail" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Wymagane jest podanie adresu serwera" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Nie moge utworzyc %s katalog %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Nie moge zapisac pliki INI %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Nie moge utworzyc kopii zapasowej %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Nieprawidlowo zakodowane haslo %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s jest nieprawidlowa wartoscia w systemie ósemkowym" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "Sciezka UNC %s niedozwolona" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Blad: Kolejka nie jest pusta, nie mozna zmienic katalogu" #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Folder \"%s\" nie istnieje" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "Blad polecenia SQL, sprawdz logi" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "Blad wykonania polecenia SQL, sprawdz logi" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Blad zamykania bazy danych, sprawdz logi" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Nieprawidlowy zapis dziennika etapu w historii dla %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Blad dekodowania %s" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "Blad CRC w %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Zle zbudowny artykul yEnc w %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Nieznany blad podczas dekodowania %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => nie znaleziono na zadnym serwerze, porzucam zadanie" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Blad podczas usuwania %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Nie mozna odczytac %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Nie mozna przeczytac Obserwowanego Katalogu %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Wstrzymano" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Serwer %s bedzie ignorowany przez %s minut" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Blad inicjowania %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Zbyt wiele polaczen z serwerem %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Prawdopodobny sharing konta" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Blad logowania do serwera %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Nie mozna polaczyc sie z serwerem %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Polaczenie z %s@%s:%s nieudane, odpowiedz serwera=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Serwer %s wymagania podania nazwy uzytkownika i hasla" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Wylaczanie" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Blad polacenia z serwerem pocztowym" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Blad polaczenia TLS" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Blad autoryzacji z serwerem pocztowym" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Blad wysylania maila" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Nie udalo sie zamknac polaczenia z serwerem pocztowym" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Wiadomosc wyslana" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Brak szablonów maili w %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Brak odbiorców, nie wyslano wiadomosci" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Nieprawidlowe kodowanie szablonu maila %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Nie znaleziono szablonów maili" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd raportuje przekroczenie zajetosci dysku\n" "\n" "Czesc,\n" "\n" "SABnzbd przestal pobierac pliki, poniewaz dysk jest prawie pelen.\n" "Opróznij troche miejsca i wznów SABnzbd recznie.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Uruchomienie/Wylaczenie" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "Dodano NZB" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Uruchomiono przetwarzanie koncowe" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Zadanie ukonczone" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Inne komunikaty" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Ostrzezenie: LOCALHOST jest wieloznaczny, uzyj adresu IP." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Nieprawidlowy adres serwera \"%s:%s\"" #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Brak klucza sesji" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Blad: wymagany klucz sesji" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Blad: nieparwidlowy klucz sesji" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "Brak klucza API, nalezy wprowadzic klucz API z Konfiguracja->Ogólne do " "innego programu:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Klucz API jest nieprawidlowy, uzyj klucza API z Konfiguracja->Ogólne w twoim " "drugim programie:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Brak danych uwierzytelniajacych, wprowadz nazwe uzytkownika/haslo z " "Konfiguracja->Ogólne do twojego zewnetrznego programu:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Blad: nie zdefiniowano drugiego interfejsu." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Twoja wersja programu UNRAR jest niezalecana, pobierz nowa z " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Nie znaleziono programu UNRAR, wypakowanie flików nie jest mozliwe
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Nie znaleziono programu PAR2, naprawa nie jest mozliwa
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Inicjuje restart...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd zostal wylaczony.
    Zaczekaj okolo 5 sekund i kliknij " "guzik ponizej.

    Odswiez
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Kanal" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Codziennie" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Poniedzialek" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Wtorek" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Sroda" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Czwartek" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Piatek" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Sobota" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Niedziela" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "wylaczone" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Rozwiazywanie odresu" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Bledny parametr" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Powrót" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Zadanie \"%s\" zostalo dodane ponownie do kolejki" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Zadanie oznaczone jako '*' nie zostanie automatycznie pobrane." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Dopasowano" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Nie dopasowano" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Pobrane" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Dotychczas pobrano" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Nieprawidlowa wartosc %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Nie mozna stworzyc katalogu %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s katalog: %s: blad dostepu" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Nie mozna sie polaczyc do galezi rejestru HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Nie mozna otworzyc klucza rejestru \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Nie udalo sie odczytac kluczy rejestru dla katalogów specjalnych" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Nie udalo sie utworzyc (%s)" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Nie udalo sie przeniesc %s do %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Nieprzydatny plik NZB" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Spróbuj ponownie" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Pobieranie URL nie powiodlo sie; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "brak modulu pyopenssl, nalezy go zainstalowac w celu dostepu https" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Blad tworzenie certyfikatu i klucza SSL" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Nie mozna zmienic uprawnien %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Laczenie" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Niekompletna sekwencja plików do laczenia" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Laczeni pliku %s nie powiodlo sie" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Blad %s podczas laczenia plików" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Blad \"%s\" podczas uruchamiania file_join na %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Polaczono %s plików" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Rozpakowywanie nie powiodlo sie, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Blad \"%s\" podczas rozpakowywania plików RAR" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Blad \"%s\" podczas uruchamiania rar_unpack na %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Usuwanie %s nie powiodlo sie!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Próba rozpakowania rar z haslem %s" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Rozpakowywanie nie powiodlo sie, archiwum wymaga podania hasla" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Rozpakowywanie" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Rozpakowywanie nie powiodlo sie, nie mozna znalezc %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "BLAD: nie mozna znalezc \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Rozpakowywanie nie powiodlo sie, blad sumy kontrolnej CRC" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "BLAD: nieprawidlowa suma kontrolna CRC w \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Rozpakowywanie nie powiodlo sie, byc moze dysk jest zapelniony." #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "BLAD: blad zapisu (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Rozpakowywanie nie powiodlo sie, za dluga sciezka" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "BLAD: za dluga sciezka (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Rozpakowywanie nie powiodlo sie, srpawdz dziennik zdarzen" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "BLAD: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "Nieuzywalny plik RAR" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Brak oczekiwanego pliku: %s =>blad unrar?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "" "Rozpakowywanie nie powiodlo sie, oczekiwany plik nie zostal wypakowany" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Rozpakowywanie nie powiodlo sie, brak nastepujacych plików:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Rozpakowano %s plików/katalogów w %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s plików w %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Blad \"%s\" podczas uruchamiania unzip() na %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Szybkie sprawdzanie" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Naprawa" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s} Szybkie sprawdzenie OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Rozpoczynanie naprawiania" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Naprawa nie powiodla sie, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Blad %s podczas uruchamiania par2_repair na zbiorze %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Blad \"%s\" podczas wykonywania par2_rapair na zestawie %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s} PAR2 otrzymal nieprawidlowe opcje, sprawdz ustawienia w Konfiguracja-" ">Przelaczniki" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Zweryfikowano w %s, wszystkie pliki prawidlowe" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Zweryfikowano w %s, wymagana naprawa" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Glówna paczka nieznaleziona..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Nieprawidlowe pliki par2, nie mozna zweryfikowac lub naprawic" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Naprawa nie powiodla sie, brak wystarczajacej ilosci bloków naprawczych " "(brakuje %s)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Pobieranie %s bloków..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Pobieranie" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Naprawianie" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Naprawiono w %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Sprawdzanie" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Blad importu modulu OpenSSL. Laczenie bez SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Nie udalo sie zaktualizowac zadania newzbin %s" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB dodany do kolejki" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Serwer Newzbin zmienil protokól" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Brak kredytów na koncie Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Nie uwierzytelniono, sprawdz nazwe uzytkownika/haslo do Newzbin" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Raport Newzbin %s nie zostal znaleziony" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin zwrócil nieudokumentowany kod bledu (%s,%s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Serwer Newzbin nie zwrócil informacji dla %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Nie mozna usunac zzakladki Newzbin dla %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin zwrócil nieudokumentowany kod bledu (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Znaleziono niekompatybilny plik kolejki, nie mozna kontynuowac" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Blad ladowania %s, wykryto uszkodzony plik" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Blad podczas dodawania %s, usuwanie" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Nieznane kodowanie" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Plik %s jest pusty," #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Nie udalo sie zaimportowac %s plików z %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Niekompletny plik NZB %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Nieprawidlowy plik NZB %s, pomijam (powód=%s, linia=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Pusty plik NZB %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignoruje zduplikowany NZB \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Zatrzymuje zduplikowany NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Przerwano, nie mozna ukonczyc" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "ZDUPLIKOWANY" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "ZASZYFROWANY" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "ZA DUZY" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "NIEKOMPLETNY" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "CZEKAM %s sek" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Pobrano w %s ze srednia %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artykulów bylo uszkodzonych" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "Brakowalo %s artykulów" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artykulów posiada niepasujace duplikaty" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "Usunieto %s artykulów" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Blad importu %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Ostrzezenia" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Bezczynny" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Konfiguracja" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Kolejka" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Czyszczenie kolejki" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historia" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "usuniecie historii" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Ograniczenie predkosci" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pauza" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Wznów" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Pobierz zakladki z Newzbin" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Przeszukaj obserwowany katalog" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Folder zakonczonych" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Folder niezakonczonych" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Rozwiaz problem" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Uruchom ponownie" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Restart bez logowania" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Zakoncz" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Zakolejkuj 10 pierwszych" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Brak" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Historia ostatnich 10" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Dostepne jest nowe wydanie" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Uruchom kreatora" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Zatrzymywanie..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problem z" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nie jest zgodny z niektórymi programai typu firewall.
    \n" " %s
    \n" " Przepraszamy, ale nie mozemy obecnie rozwiazac tego problemu.
    \n" " Zglos problem u dostawcy swojego programu.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd wymaga wolnego portu tcp/ip dla wewnetrznego serwera www.
    \n" " Próbowano portu %s na %s, ale nie jest dostepny.
    \n" " Inny program uzywa tego portu lub SABnzbd jest juz uruchomiony.
    \n" "
    \n" " Uruchom ponownie SABnzbd na innym porcie." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "Jesli ponownie otrzymasz ten sam blad, spróbuj zmienic port.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd wymaga wolnego portu tcp/ip dla wewnetrznego serwera WWW.
    \n" " Próbowano portu %s na %s, lecz uzytkownik dla SABnzbd nie ma uprawnien " "do jego uzycia.
    \n" " W systemach OSX oraz Linux normalny uzytkownik musi uzywac portów " "ponizej 1023.
    \n" "
    \n" " Zrestartuj SABnzbd na innym porcie." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd wymaga prawidlowego adresu hosta dla wewnetrznego serwera " "WWW.
    \n" " Podano nieprawidlowy adres.
    \n" " Bezpieczne wartosci to localhost i 0.0.0.0
    \n" "
    \n" " Zrestartuje SABnzbd z prawidlowym adresem." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd wykryl dane zapisane w innej wersji SABnzbd
    \n" " lecz nie moze ponownie uzyc tych danych.

    \n" " Powinienes najpierw zakonczyc kolejke w innym programie.

    \n" " Nastepnie nalezy uruchomic program z opcja \"--clean\".
    \n" " SPowoduje to wymazanie aktualnej kolejki i histori!
    \n" " SABnzbd czyta plik \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nie moze znalezc plików interfejsu WWW w %s.
    \n" " Nalezy zainstalowac program ponownie.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd wykryl krytyczny blad:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd wykryl kolejke i hostorie ze starszej (0.4.x) wersji.

    \n" " Zostana one zignorowane i moga zostac utracone!

    \n" " Mozesz zatrzymac SABnzbd i dokonczyc kolejke ze starsza wersja " "programu.

    \n" " Kliknij OK aby konynuowac z SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd wykryl brak pliku sqlite3.dll.

    \n" " Niektóre zle dzialajace programy antywirusowe usuwaja ten plik.
    \n" " Sprawdz swój skaner antywirusowy, spróbuj przeinstalowac SABnzbd i zglos " "problem dostawcy antywirusa.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Nacisnij Klawisz start+R i wpisz linie (przyklad):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Otwórz okno terminala i wpisz linie (przyklad):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Wyglada na to, ze uzywasz ZoneAlarm na systemie Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Program sie nie uruchomil!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Nie masz uprawnien do uzywania portu %s." #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Blad krytyczny" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "" "Nie mozna uruchomic przegladarki, prawdopodobnie nie zostala znaleziona" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Brak dostepu" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Blad %s: nalezy podac prawidlowa nazwe uzytkownika i haslo." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Nie udalo sie wczytac kolejki przetwarzania koncowego: Zla wersja " "(wymagana:%s, znaleziona:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Nie udalo sie usunac nzo z kolejki przetwarzania (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "Pobieranie moze sie nie udac, dostepne %s z wymaganych %s" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "" "Pobieranie nie powiodlo sie - Poza okresem przechowywania twojego serwera?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Nie mozna utworzyc koncowego katalogu %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Brak przetwarzania koncowego z powodu nieudanej weryfikacji" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Przenoszenie" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Wyslano %s do kolejki" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Blad zmiany nazwy \"%s\" na \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Nie udalo sie przeniesc plików" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Uruchamianie skryptu" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Uruchamianie skryptu uzytkownika %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Uruchomiono %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Wiecej" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Zobacz komunikaty wyjscia skryptu" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Zakonczono pobieranie" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Pobieranie nie powiodlo sie" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Przetwarzanie koncowe nie powiodlo sie dla %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "sprawdz plik dziennika" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Przetwarzanie zostalo przerwane (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Czyszczenie %s nie powiodlo sie" #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Blad usuwania katalogu roboczego (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Przetwarzanie koncowe" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s} Brak zestawów par2" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Próba weryfikacji SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Weryfikacja niektórych plików wzgledem \"%s\" nie powiodla sie" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Poprawnie zweryfikowano z uzyciem plików SFV" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Usuwanie %s nie powiodlo sie" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Hibernacja systemu nie powiodla sie" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Wstrzymanie systemu nie powiodlo sie" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Wylaczenie systemu nie powiodlo sie" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Nieprawiodlowy opis kanalu RSS \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Nie udalo sie pobrac RSS z %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Brak poprawnego uwierzytelnienia dla kanalu %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "Kanal RSS %s byl pusty" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Niekompatybilny kanal" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Znaleziono pusty wpis RSS (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Pokaz interfejs" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Otwórz katalog z pobranymi plikami" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Zakoncz" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Pozostalo" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Zly harmonogram %s w %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Nieznana akcja: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Harmonogram dla nieistniejacego serwera %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Pobierz" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Zlacz pliki" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Rozpakuj" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Skrypt" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Zródlo" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Niepowodzenie" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Ukonczone" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Nieudane" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Oczekuje" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Naprawianie..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Rozpakowywanie..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Przenoszenie..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Wykonywanie skryptu..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Pobieranie dodatkowych bloków..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Szybkie sprawdzanie..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Weryfikowanie..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Pobieranie" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Pobieranie NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Sprawdzanie" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Czestotliwosc" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Akcja" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argumenty" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Zadanie" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "wylacz serwer" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "wlacz serwer" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Limit predkosci" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Zatrzymaj wszystkie" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Zatrzymaj przetwarzanie koncowe" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Wznów przetwarzanie koncowe" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Czytaj kanaly RSS" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Usun nieudane zadania" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "godzina" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "godziny" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "minuta" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minut" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sek" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "sekund" #: sabnzbd/skintext.py:79 msgid "day" msgstr "dzien" #: sabnzbd/skintext.py:80 msgid "days" msgstr "dni" #: sabnzbd/skintext.py:81 msgid "week" msgstr "tydzien" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Miesiac" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "Rok" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Dzien miesiaca" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Ten tydzien" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Ten miesiac" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Dzisiaj" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Razem" #: sabnzbd/skintext.py:97 msgid "on" msgstr "Wl." #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametry" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "wersja Python" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Strona projektu" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "lub" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Host" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Automatyczne narzedzie pobieranie dla usenetu" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Zapisz" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "W kolejce" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Czy na pewno?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Usunac wszystkie pobrane pliki?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Start" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Konfiguracja" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Status" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Pomoc" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Ogólne" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Katalogi" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Przelaczniki" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Serwery" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Harmonogram" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Powiadomienia" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Email" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Indeksy" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Kategorie" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortowanie" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Specjalne" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Katalog pobierania" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Katalog na pobrane" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Szybkosc pobierania" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "ZATRZYMANE" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "Przechowano %s artykulów (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Obciazenie" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "OSTRZEZENIA" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Dostepne nowe wydanie %s na" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Dodaj nowe pliki" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Na pewno wylaczyc SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Dodaj" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Kod raportu" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Dodaj plik" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Kategoria" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Przetwarzanie" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Priorytet" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Napraw" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Rozpakuj" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Usun" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "N" #: sabnzbd/skintext.py:176 msgid "U" msgstr "R" #: sabnzbd/skintext.py:177 msgid "D" msgstr "U" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Wymus" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normalny" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Wysoki" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Niski" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stop" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Wprowadz URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " lub ID raportu" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Sortuj po nazwie" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Sortuj po wieku" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Sortuj po rozmiarze" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Ukryj pliki" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Pokaz pliki" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Po zakonczeniu kolejki" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Wylacz komputer" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Uspij komputer" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Hibernuj komputer" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "WYlacz SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Limit predkosci" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Zatrzymaj na" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Kolejnosc" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nazwa" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Pozostalo/Razem" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "ETA" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "WIEK" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Usun" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Ponów" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Akcje" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Skrypty" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Usunac wszystkie obiekty z kolejki?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Wyczysc NZB" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Wyczysc NZB i usun pliki" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Usun NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Usun NZB i pliki" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "z" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Brakujace artykuly" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Pozostalo limitu" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "recznie" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Resetuj limit" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Wyczysc historie bledów" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Usunac z historii wszystkie ukonczone pliki?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Usunac z historii wszystkie bledne pliki?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Ukryj szczególy" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Pokaz szczególy" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Rozmiar historii" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Pokaz nieudane" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Pokaz wszystko" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Rozmiar" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Wyczysc nieudane NZB" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Wyczysc nieudane NZB i usun pliki" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Wyczysc ukonczone NZB" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Opcjonalne dodatkowe NZB" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Sciezka" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Wymus rozlaczenie" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "NastaLi wyslanie testowej wiadomosci na twoje konto." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Pokaz logowanie" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Pokaz logowanie web" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Testuj Email" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Logowanie" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Bledy/Ostrzezenia" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Informacje" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Debugowanie" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Polaczenia" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Watek" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Wynik testu email" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Ostatnie ostrzezenia" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "wyczysc" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Odblokuj" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Identyfikator artykulu" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Zestaw plików" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Kiedy" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Typ" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Ostrzezenie" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Wlaczone" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Plik konfiguracyjny" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Uzyta pamiec podreczna" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "SPowoduje to restart SABnzbd.
    Uzyj tego jesli wydaje ci sie, ze " "program ma problemy ze stabilnoscia.
    Pobieranie zostanie zatrzymane " "przez restartem i wznowione po ponownym uruchomieniu." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "W katalogu pobieranie istnieja opuszczone zadania.
    Mozesz je usunac " "(razem z plikami) lub wyslac spowrotem do kolejki." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "Przycisk \"Napraw\" ponownie uruchomi SABnzbd i spowoduje kompletne
    odtworzenie zawartosci kolejki, zachowujac juz pobrane pliki
    ZMieni " "to kolejnosc kolejki." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Wersja" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Czas dzialania" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Zapasowy" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Ogólna konfiguracja" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Zmiany wymagaja restartu SABnzbd" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Serwer www SABnzbd" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Adres hosta SABnzbd" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Host na którym SABnzbd bedzie uruchomiony" #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Posrt na którym SABnzbd bedzie uruchomiony" #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Interfejs WWW" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Wybierz skórke." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Dodatkowy interfejs WWW" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Wlacz alternatywna skórke." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Uwierzytelnienie serwera www" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Uzywkownik SABnzbd" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Opcjonalna nazwa uzytkownika" #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Haslo SABnzbd" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Opcjonanle haslo" #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "Wsparcie dla HTTPS" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Wlacz HTTPS" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "nie zainstalowane" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Wlacz dostep do interfejsu przez adres HTTPS" #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Jesli nie podano obsluga HTTPS bedzie na standardowym porcie" #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "Certyfikat HTTPS" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Nazwa pliku lub sciezka do certyfikatu HTTPS" #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "Klucz HTTPS" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Nazwa pliku lub sciezka do klucza HTTPS" #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Dostrajanie" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Interwal automatycznego odswiezania kolejki" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Interwal autmatycznego odswiezania strony kolejki w interfejsie WWW " "(sekundy, 0=brak)" #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "Interwal sprawdzania RSS" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Interwal sprawdzania (w minutach, co najmniej 15). Nieuzywany podczas " "korzystania z harmonogramu" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Limit pobierania danych" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Limit pobierania danych (w KB/s - kilobajtach na sekunde)" #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Limit pamieci podrecznej artykulów" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Umieszcza artykuly w pamieci podreczne aby ograniczyc korzystanie z " "dysku.
    w bajtach, opcjonalnie z dodatkiem K,M,G. Na przyklad: " "\"64M\" lub \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Lista czyszczenia" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista rozszerzen które powinny zostac usuniete po sciagnieciu.
    Na " "przyklad:.nfo lub .nfo,.sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Zapisz zmiany" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Jezyk" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Wybierz jezyk interfejsu WWW." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "Klucz API" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Klucz umozliwi dostep innych programów do SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "Klucz NZB" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "Klucz umozliwi innym programom dodawanie plików NZB do SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Utwórz nowy klucz" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Wylacz klucz API" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Nie wymagaj klucza API" #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "UZYWAJ NA SWOJA ODPOWIEDZIALNOS" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "Kod QR" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "Kod QR klucza API" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Konfiguracja katalogów" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "UWAGA: Katalogi zostana automatycznie utworzone po zapisaniu. Mozna " "uzywac sciezek absolutnych aby wskazac katalogi poza domyslnym katalogim." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Uzywaj katalogów" #: sabnzbd/skintext.py:345 msgid "In" msgstr "w" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Tymczasowy katalog pobierania" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Miejsce przechowywania nieprzetworzonych plików.
    Mozna zmienic tylko " "kiedy kolejka jest pusta." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimalna ilosc wolnego miejsca w tymczasowym katalogu pobierania" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Zatrzymaj automatycznie jesli pozostanie mniej miejsca niz ta wartosc.
    w bajtach, opcjonalnie z K,M,G,T. Na przyklad: \"800M\" lub \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Katalog dla ukonczonych plików" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Miejsce przechowywania ukonczoncyh, przetworzonych plików.
    Mozna " "nadpisac przez kategorie." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Uprawnienia dla ukonczonych plików" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Ustawienia wzorca uprawnien dla pobranych plików/katalogów.
    notacja " "ósemkowa. Na przyklad: \"775\" lub \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Obserwowany katalog" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Katalog monitorowany na obecnosc plików .nzb.
    Skanuje równiez pliki " ".zip, .rar oraz .ta.gz." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Szybkosc skanowania katalogu obserwowanego" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Ilosc sekund miedzy skanami plików .nzb" #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Katalog skryptów przetwarzania koncowego" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Katalog zawierajacy skrypty przetwarzania koncowego" #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Katalog szablonów email" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Katalog zawierajacy szablony uzytkownika dla powiadomien email" #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Plik hasel" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Plik zawierajace wszystkie hasla do wykorzystania dla zaszyfrowanych plików " "RAR." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Katalogi systemowe" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Katalog administracyjny" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Polozenie admina kolejki oraz bazy danych historycznych.
    Mozna " "zmienic tylko kiedy kolejka jest pusta." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Dane nie zostana przeniesione. Wymaga restartu SABnzbd!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Katalog dzienników zdarzen" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Polozenieplików dziennika SABnzbd.
    Wymaga restartu SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Katalog backupów .nzb" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Miejsce przechowywania plików .nzb" #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Domyslny katalog bazowy" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Konfiguracja przelaczników" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Przetwarzanie przelaczników" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Wlacz szybkie sprawdzanie" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Pomin sprawdzanie par2 dla 100% prawidlowych plików." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Wlacz unran" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Wlacz wbudowana funkcjonalnosc unrar" #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Wlacz unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Wlacz wbudowana funkcjonalnosc unzip." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Wlacz laczenie plików" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Lacz pliki konczace sie na .001, .002 itd. w jeden plik" #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Wlacz laczenie TS" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "Lacz pliki konczace sie na .001.ts, 002.ts itd. w jeden plik" #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Wlacz czyszczenie par" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Czysc pliki par (jesli weryfikacja/naprawa byla udana)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Przerywaj po bledach CRC yEnc" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "Próbuj pobierac artykuly z bledami CRC z innych serwerów" #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Pobieraj artykuly tylko z góry kolejki" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Oszczedza pamiec. Nalezy wylaczyc jesli wolne zadania blokuja kolejke." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Przetwarzanie koncowe tylko dla zweryfikowanych zadan." #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Uruchamiaj przetwarzanie koncowe tylko dla zadan, które przeszly sprawdzanie " "PAR2" #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Wykrywaj zduplikowane pliki" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Wykrywaj identycznie nazwane pliki NZB (wymaga opcji backupu NZB) oraz " "zduplikowane tytuly w kanalach RSS." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Wylaczone" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Porzuc" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Wlacz sprawdzania bazujace na SFV" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Wykonuj dodatkowa weryfikacje na podstawie plików SFV." #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Sprawdzaj wyniki rozpakowywania" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Sprawdzaj wyniki rozpakowywania (nalezy wylaczyc dla niektórych systemów " "plików)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Wlacz zmiane nazwy katalogów" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Uzywaj tymczasowych nazw plików podczas przetwarzania koncowego. Nalezy " "wylaczyc, jesli system nie obsluguje tej opcji prawidlowo." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Domyslne przetwarzanie koncowe" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Uzywane, kiedy brak definicji w kategorii." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Domyslny skrypt uzytkownika" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Uzywane, kiedy brak definicji w kategorii." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Skrypt uzytkownika przed kolejka" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Uzywany, zanim plik NZB trafi do kolejki" #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Domyslny priorytet" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Uzywane, kiedy brak definicji w kategorii" #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Wlacz wielordzeniowy Par2" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Przeczytaj na ten temat w Wikii Pomocy!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Dodatkowe parametry PAR2" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Parametry nice" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "Parametry IONice" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Inne przelaczniki" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Rozlacz przy pustej kolejce" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Rozlacz serwer(y) Usenet kiedy kolejka jest pusta lub zatrzymana." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Wyslij group" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Wyslij polecenie group przed zadaniem artykulu" #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sortuj wedlug wieku" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Automatycznie sortuj pozycje wedlug (sredniego) wieku" #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Sprawdzaj aktualizacje" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Sprawdzaj co tydzien w poszukiwaniu nowych wydan SABnzbd." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Zastap spacje w nazwach katalogów" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Zastap spacje w nazwach katalogów podkresleniami." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Zastap kropki w nazwach katalogów" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Zastap kropki w nazwach katalogów spacjami." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Zastap niedopuszczalne znaki w nazwach katalogów" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Zastap niedopuszczalne znaki w nazwach katalogów ich odpowiednikami (w " "przeciwnym wypadku usun)" #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Uruchom przegladarke na starcie" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Uruchom domyslna przegladarka podczas startowania SABnzbd." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Zatrzymaj pobieranie podczas przetwarzania koncowego" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Zatrzymuje pobieranie na poczatku przetwarzania koncowego i przywraca po " "zakonczeniu." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignoruj próbki" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Odfiltrowuj pliki próbek (np. próbki wideo)" #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Usun po pobraniu" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Nie pobieraj" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "Typ SSL" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Uzyj V23 chyba, ze dostawca wymaga innego!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Uzywaj 12sto godzinnego zegara (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Pokazuj czas w notacji AM/PM (nie dotyczy harmonogramu)" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Serwer" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Przetwarzanie koncowe" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Nazewnictwo" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Limit pobierania" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Ile danych mozna pobrac w miesiacu (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Dzien resetu" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "W którym dniu miesiaca lub tygodnia (1=poniedzialek) twój dostawca resetuje " "limit pobierania (opcjonalnie z gg:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Automatyczne przywracanie" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "Czy pobieranie powinno sie automtycznie przywrócic w dniu resetu" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Okres limitu" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Czy limit jest kasowany dziennie, tygodniowo czy miesiecznie?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Sprawdz przed pobraniem" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Spróbuj przewidziec, czy pobieranie bedzie udane przed jego rozpoczeciem " "(wolne!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Maksymalna ilosc prób" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Maksymalna ilosc prób per serwer" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Tylko dla dodatkowych serwerów" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Zastosuj maksymalna ilosc prób tylko dla serwerów dodatkowych." #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Konfiguracja serwera" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Definicja serwera" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Dodaj serwer" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Nazwa uzytkownika" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Haslo" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Limit czasu odpowiedzi" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Czas przechowywanie" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Serwer zapasowy" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Opcjonalny" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Wlacz" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Usun serwer" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Testuj serwer" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Wyczysc liczniki" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testuje szczególy serwera..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Nacisnij ponizej, aby przetestowac." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Przepustowosc" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Konfiguracja harmonogramów" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Dodaj harmonogram" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Usun" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Obecne harmonogramy" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "Konfiguracja RSS" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Nowy URL kanalu" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Pole wyboru obok nazwy kanalu musi byc zaznaczone, aby kanal byl wlaczony do " "automatycznego sprawdzania nowych wpisów.
    Dla nowych kanalów pobrane " "zostana tylko nowe wpisy, bez wpisów juz istniejacych, chyba ze zostanie " "wybrane \"Wymuszenie pobrania\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Dodaj kanal" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Usun kanal" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Pobierz kanal" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Wymus pobranie" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filtr" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Pomin" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Akceptuj" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Odrzuc" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Wymaga" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "WymagaKat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Nie dopasowano" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Kanaly" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Czytaj teraz wszystkie kanaly" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Ustawienia" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtry" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Opcje email" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Powiadomienia email po zakonczeniu zadan" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Nigdy" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Zawsze" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Tylko bledy" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Powiadomienie o pelnym dysku" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Powiadom kiedy dysk jest pelen a SABnzbd zatrzymany" #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Powiadomienia RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Powiadom, kiedy kanal RSS dodaje zadanie do kolejki" #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Ustawienia konta email" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "Serwer SMTP" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Ustaw serwer twojego dostawcy dla powiadomien" #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Odbiorca emaili" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Adres email na który wysylac powiadomienia" #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Nadawca email" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Kto powinien byc nadawca emaila?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "OPCJONALNA nazwa konta" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Nazwa konta dla kont z uwierzytelnieniem." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "OPCJONALNE haslo do konta" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Haslo dla kont z uwierzytelnieniem." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Wlacz Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Wysylaj powiadomienia Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Adres serwera" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Tylko dla zdalnych serwerów Growl (host:port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Haslo serwera" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Opcjonalne haslo dla serwera Growl" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Wlacz NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Wysylaj powiadomienia do NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Jesli posiadasz konto na www.newzbin2.es, mozesz tutaj " "podac jego dane.
    Spowoduje to wlaczenie dodatkowych funkcji." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Informacje o koncie" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Nazwa uzytkownika Newzbin" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Podaj nazwe twojego uzytkownika." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Haslo Newzbin" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Podaj swoje haslo" #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Przetwarzanie zakladek" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Automatycznei pobieraj zakladki" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Automatycznei pobieraj zadania z twoich zakladek." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Pobierz teraz zakladki" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Ukryj zakladki" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Pokaz zakladki" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Usun zakladke po pobraniu" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Usun z listy zakladek po zakonczeniu pobierania." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Interwal sprawdzania" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "W minutach (co najmniej 15)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Przetworzone zakladki" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Jesli posiadasz konto w www.nzbmatrix.com, mozesz tutaj " "podac jego dane.
    Jest to wymagane do uzywania kanalów RSS z tej strony." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Nazwa uzytkownika NzbMatrix" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "Klucz NzbMatrix" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Tutaj ustaw klucz API NzbMatrix." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Kategorie uzytkownika" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Definiuje przetwarzanie koncowe i przechowywanie." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Uzyj kolumny \"Grupy / Etykiety indeksera\" to zmapowania grup i etykiet do " "twoich kategorii.
    Znaki wieloznaczne sa dopuszczalne. Uzyj przecinków " "do rozdzielenia terminów." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Zakonczenie sciezki znakiem asterisk * zapobiegnie tworzeniu katalogów dla " "zadan." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Wzgledne katalogi sa bazowane na" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Katalog/Sciezka" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Grupy / Etykiety indeksera" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Konfiguracja sortowania" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Sortowanie seryjne" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Wlacz sortowanie TV" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Wlacz sortowanie i zmiane nazw odcinków" #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Klucz wzorca" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Wyczysc" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Predefiniowane" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Przyklad" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Sortowanie standardowe" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Wlacz sortowanie filmów" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Wlacz standardowe sortowanie i zmiane nazw plików." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Trzymaj niesklasyfikowane zadania w dodatkowych katalogach" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Wlacz, jesli zadania nie sa umieszczane we wlasnych katalogach." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Dotkniete kategorie" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Znaczenie" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Wzorzec" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Wynik" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "Katalog sezonu 1x05" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "Katalog sezonu S01E05" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "Katalog odcinka 1x05" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "Katalog odcinka S01E05" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Tytul" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Nazwa filmu" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Nazwa.Filmu" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Nazwa_Filmu" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Nazwa serialu" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Nazwa.Serialu" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Nazwa_Serialu" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Numer Sezonu" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Numer Odcinka" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Nazwa Odcinka" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Nazwa.Odcinka" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Nazwa_Odcinka" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Rozszerzenie pliku" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Rozszerzenie" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Numer fragmentu" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Dekada" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Oryginalna nazwa pliku" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Oryginalna nazwa katalogu" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Male litery" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py:667 msgid "text" msgstr "text" #: sabnzbd/skintext.py:668 msgid "file" msgstr "plik" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "katalog" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Lancuch sortowania" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "WIeloczesciowa etykieta" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "W katalogach" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Brak katalogów" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Sortowanie po dacie" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Wlacz sortowanie wedlug daty" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Wlacz sortowanie i zmiane nazwy wedlug dacie." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Pokaz katalog nazwy" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Katalogi Rok-Miesiac" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Katalogi dzienne" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "z dostosowaniem wielkosci" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Przetworzone wyniki" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Rzadko uzywane opcje. Jesli chcesz sie dowiedzic co oznaczaja, klikniej " "przycisk Pomoc i przeczytaj strony Wiki.
    Nie zmieniaj tych opcji bez " "uprzedniego przeczytania Wiki, poniewaz niektóre maja skutki " "uboczne.
    Domyslne wartosci sa umieszczone w nawiasach." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Wartosci" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Edytuj szczególy NZB" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Usun" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Na góre" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Wyzej" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Nizej" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Na dól" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Wszystko" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Odwróc" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Nazwa pliku" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Temat" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Wiek" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Zaznaczenie" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Czy na pewno usunac?" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Odswiez" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Opcje" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Strona" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Poprzednia" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Nastepna" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Pierwsza" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Ostatnia" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Zamknij" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Ustaw interwal wstrzymywania" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sortuj" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Wyczyscic kolejke?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Interwal wstrzymywania" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Wstrzymaj na 5 minut" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Wstrzymaj na 15 minut" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Wstrzymaj na 30 minut" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Wstrzymaj na 1 godzine" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Wstrzymaj na 2 godziny" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Wstrzymaj na 6 godzin" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Wstrzymaj na 12 godzin" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Wstrzymaj na 24 godziny" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sortuj po wieku Najstarsze→Najnowsze" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sortuj po wieku Najnowsze→Najstarsze" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sortuj po nazwie A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sortuj po nazwie Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sortuj po rozmiarze Najmniejsze→Najwieksze" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sortuj po rozmiarze Najwieksze→Najmniejsze" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Zmien nazwe" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Pozostalo" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Wyczyscic historie?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Niezachowano zmian, zostana one utracone." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Otwórz URL zródlowy" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Otwórz URL informacyjny" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Miejsce" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Zobacz dziennik skryptu" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Plush wymaga wlaczenia oblsugi JavaScript" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Dodaj NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Opcje Plush" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Dostepna aktualizacja" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Na ile minut wstrzymac?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Wstrzymaj na..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Wielokrotne operacje" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Górne menu" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Po zakonczeniu" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sortuj po wieku (Najstarsze→Najnowsze)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sortuj po wieku (Najnowsze→Najstarsze)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sortuj po nazwie (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sortuj po nazwie (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sortuj po rozmiarze (Najmniejsze→Najwieksze)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sortuj po rozmiarze (Najwieksze→Najmniejsze)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Wyczysc" #: sabnzbd/skintext.py:781 msgid "left" msgstr "pozostalo" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Max szybkosc" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Zakres" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Reset" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Zastosuj do zaznaczonych" #: sabnzbd/skintext.py:786 msgid "page" msgstr "strona" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Wszystko" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Wylaczone" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Czest. odswiezania" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Szerokosc kontenera" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Potwierdzaj usuwanie z kolejki" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Potwierdzaj usuwanie historii" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "Zablokuje odswiezanie zawartosci po najechaniu kursorem" #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Zablokuj odswiezanie podczas wskazywania" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Pobierz" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Wczytaj" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Wczytaj: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Opcjonalnie podaj nazwe pliku" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Postep" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Brak miejsca na dysku na dokonczenie pobierania" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Wolne miejsce" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Wolne (Temp)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "BEZCZYNNY" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Pobieranie" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Naprawa kolejki" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Czytaj kanal pobierze aktualna zawartosc kanalu. " "Wymus pobranie pobierze teraz wszystkie pasujace pliki NZB." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Godziny:Minuty" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Usuwanie zakonczone" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Usunac wszystkie nieudane z hostorii?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Usuwanie nie powiodlo sie" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Odnosniki" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Pokazywanie %s do %s z %s wyników" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Brak wyników" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Pokazuje jeden wynik" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Wyslano email!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Wyslano powiadomienie!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Zapisywanie..." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Zapisano" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Szybkosc" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Przelacz dodanie NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "DualView1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "DualView2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Wlasny" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Pobierz zakladki" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Czy na pewno zrestartowac SABnzbd" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Czestotliwosc odswiezania" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Usun wszystko" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Usun opcje edycji" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Pokaz opcje edycji" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Edytuj" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Pozostalo" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "Szybki kreator konfiguracji SABnzbd" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "Wersja SABnzbd" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Poprzednia" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Dostep" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "Chce, aby kazdy komputer w mojej sieci mial dostep do SABnzbd" #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Chce, abym mial dostep do SABnzbd tylko z mojego komputera" #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Zabezpiecz dostep do SABnzbd haslem (rekomendowane)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Wlacz dostep HTTPS do SABnzbd" #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Pozostale" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Uruchom strone SABnzbd w przegladarce kiedy program startuje" #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Szczególy serwera" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Podaj szczególy twojego podstawowego dostawcy usenet" #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Pobieranie z usenet wymaga dostepu do dostawcy. Twój ISP moze umozliwiac " "dostep, aczkolwiek zalecany jest dostawca klasy premium." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Nie posiadasz dostawcy usenet? Polecamy spróbowac %s" #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Ilosc polaczen dopuszczanych przez twojego dostawce" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "Np. 8 lub 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Zaznaczy tylko jesli twój dostawca zezwala na SSL." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Kliknij aby przetestowac wprowadzone dane." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "To pole jest wymagane." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Wprowadz liczbe calkowita" #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Jesli jestes czlonkiem newzbin lub nzbmatrix, mozesz tutaj podac swoja nazwe " "uzytkownik i haslo aby umozliwic pobieranie NZB stamtad. Ten etam mozna " "pominac jesli nie uzywasz tych serwisów." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Automatycznie pobieraj posty dodane do zakladek" #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Np." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "REstarowanie SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Konfiguracja zostala zakonczona!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd bedzie uruchomiony w tle." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Zamkniecie okna przegladarki lub karty NIE zamknie SABnzbd" #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Po zakonczeniu ponownego uruchamiania bedziesz mial dostep do niego pod: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Zalecamy dodanie tej strony do zakladek i uzywanie tej zakladki do " "pózniejszego dostepu do SABnzbd uruchomionego w tle." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Dalsza pomoc mozna uzyskac na naszej" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Idz do SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Krok pierwszy" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Krok drugi" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Krok trzeci" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Krok czwarty" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Krok piaty" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "Np. 119 lub 563 dla SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Wyjscie SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Uruchom Asystenta" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd nie posiada ABSOLUTNIE ZADNEJ GWARANCJI.\n" "Program jest wolnym oprogramowaniem i zachecamy do jego rozpowszechniania z " "zachowaniem odpowiednich warunków.\n" "Program jest wydany na licencji GNU GENERAL PUBLIC LICENSE wersja 2 lub (dla " "twojego wyboru) kazda pózniejsza wersja.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Blad pobieranie informacji TV (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Nie udalo sie zmienic nazwy: %s na %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Nie udalo sie zmienic nazwy podobnego pliku: %s na %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Nieprawidlowy numer raportu nzbmatrix %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Dostep do API wymaga konta VIP nzbmatrix" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Nieprawidlowe dane uwierzytelniajace nzbmatrix." #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Problem z dostepem do serwera nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Nazwa hosta nie zostala ustawiona." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Nie ma polaczenia z zadnym serwerem. Nalezy ustanowic przynajmniej jedno " "polaczenie." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Haslo ukryte za ******, prosze wprowadzic ponownie" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Niewlasciwe dane serwera" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Uplynal limit czasu odpowiedzi: Spróbuj wlaczyc SSL lub polacz sie z innym " "portem." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Uplynal limit czasu odpowiedzi" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Nieprawidlowy adres serwera." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Serwer przerwal komunikacje w trakcie logowania" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Serwer wymaga podania nazwy uzytkownika i hasla." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Polaczenie udane!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Blad polaczenia, sprawdz nazwe uzytkownika i haslo." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Zbyt wiele polaczen, prosze wstrzymac pobieranie lub spróbowac ponownie " "pózniej" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Nie mozna okreslic rezultatu polaczenia (%s)" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Blad pobierania msgid %s z www.newzbin.com - Prosze upewnic sie, ze Login i " #~ "Haslo sa ustawione" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "pobieram msgid %s z www.newzbin.com" #~ msgid "Could not compile regex: %s" #~ msgstr "Nie udalo sie skompilowac wyrazenia regularnego: %s" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Nalezy podac haslo i wznowic zadanie" #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Zatrzymaj zadanie podczas pobierania zaszygrowanego pliku RAR" SABnzbd-0.7.20/po/main/pl.px0000644000000000000000000036740312433712556015600 0ustar00usergroup00000000000000# Polish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2014-07-02 18:04+0000\n" "Last-Translator: shypike \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:54+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Nie udało się uruchomić interfejsu www" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Nie ma szablonu: %s, użyto standardowego szablonu" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "moduł _yens... NIE znaleziono!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "program par2 ... NIE znaleziono!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "program unrar ... NIE znaleziono!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "program unzip ... NIE znaleziono!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "Nazwa hosta 0.0.0.0 wymaga adresu IPv6 do dostępu z zewnątrz" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Wyłączono HTTPS z powodu braku plików CERT oraz KEY" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnabd został wyłączony" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Odebrano sygnał %s. Zapisywanie i i zamykanie programu..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "pobieranie wiadomości %s z www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Błąd pobierania %s z www.newzbin2.es - Upewnij się, że ustawiłeś nazwę " "użytkownika i hasło" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Próba pobrania NZB z %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Nie można utworzyć tymczasowego pliku dla %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Próba ustawienia statusu nieistniejącego serwera %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Zbyt mało miejsca, wymuszanie WSTRZYMANIA" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Błąd w tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Nie udało się zapisać %s" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Nie udało się wczytać %s" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Powiadomienie testowe" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Brak" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Domyślny" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "UWAGA:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "BŁĄD:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "nieznany" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Błąd kompilacji wyrażenia regularnego dla wyszukiwania: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "g" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Dysk pełny! wstrzymuję pobieranie" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Błąd dysku podczas tworzenia pliku %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "UWAGA: wstrzymane zadanie \"%s\" z powodu zaszyfrowanego pliku RAR" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "UWAGA: Przerwano zadanie \"%s\" z powodu zaszyfrowanego pliku RAR" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Przerwano, wykryto szyfrowanie" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "brakuje %s" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Przekroczono limit, zatrzymywanie pobierania" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s nie jest prawidłowym adresem mail" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Wymagane jest podanie adresu serwera" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Nie mogę utworzyć %s katalog %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Nie mogę zapisać pliki INI %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Nie mogę utworzyć kopii zapasowej %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Nieprawidłowo zakodowane hasło %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s jest nieprawidłową wartością w systemie ósemkowym" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "Ścieźka UNC %s niedozwolona" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Błąd: Kolejka nie jest pusta, nie można zmienić katalogu" #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Folder \"%s\" nie istnieje" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "Błąd polecenia SQL, sprawdź logi" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "Błąd wykonania polecenia SQL, sprawdź logi" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Błąd zamykania bazy danych, sprawdź logi" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Nieprawidłowy zapis dziennika etapu w historii dla %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Błąd dekodowania %s" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "Błąd CRC w %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Źle zbudowny artykuł yEnc w %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Nieznany błąd podczas dekodowania %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => nie znaleziono na żadnym serwerze, porzucam zadanie" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Błąd podczas usuwania %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Nie można odczytać %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Nie można przeczytać Obserwowanego Katalogu %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Wstrzymano" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Serwer %s będzie ignorowany przez %s minut" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Błąd inicjowania %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Zbyt wiele połączeń z serwerem %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Prawdopodobny sharing konta" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Błąd logowania do serwera %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Nie można połączyć się z serwerem %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Połączenie z %s@%s:%s nieudane, odpowiedź serwera=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Serwer %s wymagania podania nazwy użytkownika i hasła" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Wyłączanie" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Błąd połącenia z serwerem pocztowym" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Błąd połączenia TLS" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Błąd autoryzacji z serwerem pocztowym" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Błąd wysyłania maila" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Nie udało się zamknąć połączenia z serwerem pocztowym" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Wiadomość wysłana" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Brak szablonów maili w %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Brak odbiorców, nie wysłano wiadomości" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Nieprawidłowe kodowanie szablonu maila %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Nie znaleziono szablonów maili" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd raportuje przekroczenie zajętości dysku\n" "\n" "Cześć,\n" "\n" "SABnzbd przestał pobierać pliki, ponieważ dysk jest prawie pełen.\n" "Opróżnij trochę miejsca i wznów SABnzbd ręcznie.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Uruchomienie/Wyłączenie" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "Dodano NZB" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Uruchomiono przetwarzanie końcowe" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Zadanie ukończone" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Inne komunikaty" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Ostrzeżenie: LOCALHOST jest wieloznaczny, użyj adresu IP." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Nieprawidłowy adres serwera \"%s:%s\"" #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Brak klucza sesji" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Błąd: wymagany klucz sesji" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Błąd: nieparwidłowy klucz sesji" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "Brak klucza API, należy wprowadzić klucz API z Konfiguracja->Ogólne do " "innego programu:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Klucz API jest nieprawidłowy, użyj klucza API z Konfiguracja->Ogólne w twoim " "drugim programie:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Brak danych uwierzytelniających, wprowadź nazwę użytkownika/hasło z " "Konfiguracja->Ogólne do twojego zewnętrznego programu:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Błąd: nie zdefiniowano drugiego interfejsu." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Twoja wersja programu UNRAR jest niezalecana, pobierz nową z " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Nie znaleziono programu UNRAR, wypakowanie flików nie jest możliwe
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Nie znaleziono programu PAR2, naprawa nie jest możliwa
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Inicjuję restart...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd został wyłączony.
    Zaczekaj około 5 sekund i kliknij " "guzik poniżej.

    Odśwież
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Kanał" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Codziennie" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Poniedziałek" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Wtorek" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Środa" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Czwartek" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Piątek" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Sobota" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Niedziela" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "wyłączone" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Rozwiązywanie odresu" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Błędny parametr" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Powrót" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Zadanie \"%s\" zostało dodane ponownie do kolejki" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Zadanie oznaczone jako '*' nie zostanie automatycznie pobrane." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Dopasowano" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Nie dopasowano" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Pobrane" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Dotychczas pobrano" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Nieprawidłowa wartość %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Nie można stworzyć katalogu %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s katalog: %s: błąd dostępu" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Nie można się połączyć do gałęzi rejestru HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Nie można otworzyć klucza rejestru \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Nie udało się odczytac kluczy rejestru dla katalogów specjalnych" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Nie udało się utworzyć (%s)" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Nie udało się przenieść %s do %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Nieprzydatny plik NZB" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Spróbuj ponownie" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Pobieranie URL nie powiodło się; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "brak modułu pyopenssl, należy go zainstalować w celu dostępu https" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Błąd tworzenie certyfikatu i klucza SSL" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Nie można zmienić uprawnień %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Łączenie" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Niekompletna sekwencja plików do łączenia" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Łaczeni pliku %s nie powiodło się" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Błąd %s podczas łączenia plików" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Błąd \"%s\" podczas uruchamiania file_join na %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Połączono %s plików" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Rozpakowywanie nie powiodło się, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Bład \"%s\" podczas rozpakowywania plików RAR" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Błąd \"%s\" podczas uruchamiania rar_unpack na %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Usuwanie %s nie powiodło się!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Próba rozpakowania rar z hasłem %s" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Rozpakowywanie nie powiodło się, archiwum wymaga podania hasła" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Rozpakowywanie" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Rozpakowywanie nie powiodło się, nie można znaleźć %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "BŁĄD: nie można znaleźć \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Rozpakowywanie nie powiodło się, bład sumy kontrolnej CRC" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "BŁAD: nieprawidłowa suma kontrolna CRC w \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Rozpakowywanie nie powiodło się, być może dysk jest zapełniony." #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "BŁĄD: błąd zapisu (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Rozpakowywanie nie powiodło się, za długa ścieżka" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "BŁĄD: za długa ścieżka (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Rozpakowywanie nie powiodło się, srpawdź dziennik zdarzeń" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "BŁĄD: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "Nieużywalny plik RAR" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Brak oczekiwanego pliku: %s =>błąd unrar?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "" "Rozpakowywanie nie powiodło się, oczekiwany plik nie został wypakowany" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Rozpakowywanie nie powiodło się, brak następujących plików:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Rozpakowano %s plików/katalogów w %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s plików w %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Błąd \"%s\" podczas uruchamiania unzip() na %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Szybkie sprawdzanie" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Naprawa" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s} Szybkie sprawdzenie OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Rozpoczynanie naprawiania" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Naprawa nie powiodła się, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Błąd %s podczas uruchamiania par2_repair na zbiorze %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Błąd \"%s\" podczas wykonywania par2_rapair na zestawie %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s} PAR2 otrzymał nieprawidłowe opcje, sprawdź ustawienia w Konfiguracja-" ">Przełączniki" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Zweryfikowano w %s, wszystkie pliki prawidłowe" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Zweryfikowano w %s, wymagana naprawa" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Główna paczka nieznaleziona..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Nieprawidłowe pliki par2, nie można zweryfikować lub naprawić" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Naprawa nie powiodła się, brak wystarczającej ilości bloków naprawczych " "(brakuje %s)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Pobieranie %s bloków..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Pobieranie" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Naprawianie" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Naprawiono w %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Sprawdzanie" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Błąd importu modułu OpenSSL. Łaczenie bez SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Nie udało się zaktualizować zadania newzbin %s" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB dodany do kolejki" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Serwer Newzbin zmienił protokół" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Brak kredytów na koncie Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Nie uwierzytelniono, sprawdź nazwę użytkownika/hasło do Newzbin" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Raport Newzbin %s nie został znaleziony" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin zwrócił nieudokumentowany kod błędu (%s,%s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Serwer Newzbin nie zwrócił informacji dla %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Nie można usunąć zzakłądki Newzbin dla %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin zwrócił nieudokumentowany kod błędu (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Znaleziono niekompatybilny plik kolejki, nie można kontynuować" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Błąd ładowania %s, wykryto uszkodzony plik" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Bład podczas dodawania %s, usuwanie" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Nieznane kodowanie" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Plik %s jest pusty," #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Nie udało się zaimportować %s plików z %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Niekompletny plik NZB %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Nieprawidłowy plik NZB %s, pomijam (powód=%s, linia=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Pusty plik NZB %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignoruję zduplikowany NZB \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Zatrzymuję zduplikowany NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Przerwano, nie można ukończyć" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "ZDUPLIKOWANY" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "ZASZYFROWANY" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "ZA DUŻY" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "NIEKOMPLETNY" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "CZEKAM %s sek" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Pobrano w %s ze średnią %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artykułów było uszkodzonych" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "Brakowało %s artykułów" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artykułów posiada niepasujące duplikaty" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "Usunięto %s artykułów" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Błąd importu %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Ostrzeżenia" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Bezczynny" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Konfiguracja" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Kolejka" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Czyszczenie kolejki" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historia" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "usunięcie historii" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Ograniczenie prędkości" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pauza" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Wznów" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Pobierz zakładki z Newzbin" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Przeszukaj obserwowany katalog" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Folder zakończonych" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Folder niezakończonych" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Rozwiąż problem" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Uruchom ponownie" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Restart bez logowania" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Zakończ" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Zakolejkuj 10 pierwszych" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Brak" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Historia ostatnich 10" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Dostępne jest nowe wydanie" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Uruchom kreatora" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Zatrzymywanie..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problem z" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nie jest zgodny z niektórymi programai typu firewall.
    \n" " %s
    \n" " Przepraszamy, ale nie możemy obecnie rozwiązać tego problemu.
    \n" " Zgłoś problem u dostawcy swojego programu.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd wymaga wolnego portu tcp/ip dla wewnętrznego serwera www.
    \n" " Próbowano portu %s na %s, ale nie jest dostępny.
    \n" " Inny program używa tego portu lub SABnzbd jest już uruchomiony.
    \n" "
    \n" " Uruchom ponownie SABnzbd na innym porcie." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "Jeśli ponownie otrzymasz ten sam błąd, spróbuj zmienić port.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd wymaga wolnego portu tcp/ip dla wewnętrznego serwera WWW.
    \n" " Próbowano portu %s na %s, lecz użytkownik dla SABnzbd nie ma uprawnień " "do jego użycia.
    \n" " W systemach OSX oraz Linux normalny użytkownik musi używać portów " "poniżej 1023.
    \n" "
    \n" " Zrestartuj SABnzbd na innym porcie." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd wymaga prawidłowego adresu hosta dla wewnętrznego serwera " "WWW.
    \n" " Podano nieprawidłowy adres.
    \n" " Bezpieczne wartości to localhost i 0.0.0.0
    \n" "
    \n" " Zrestartuje SABnzbd z prawidłowym adresem." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd wykrył dane zapisane w innej wersji SABnzbd
    \n" " lecz nie może ponownie użyć tych danych.

    \n" " Powinieneś najpierw zakońćzyć kolejkę w innym programie.

    \n" " Następnie należy uruchomić program z opcją \"--clean\".
    \n" " SPowoduje to wymazanie aktualnej kolejki i histori!
    \n" " SABnzbd czyta plik \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nie może znaleźć plików interfejsu WWW w %s.
    \n" " Należy zainstalowac program ponownie.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd wykrył krytyczny błąd:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd wykrył kolejkę i hostorię ze starszej (0.4.x) wersji.

    \n" " Zostaną one zignorowane i moga zostac utracone!

    \n" " Możesz zatrzymać SABnzbd i dokończyć kolejkę ze starszą wersją " "programu.

    \n" " Kliknij OK aby konynuować z SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd wykrył brak pliku sqlite3.dll.

    \n" " Niektóre źle działające programy antywirusowe usuwają ten plik.
    \n" " Sprawdź swój skaner antywirusowy, spróbuj przeinstalowac SABnzbd i zgłoś " "problem dostawcy antywirusa.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Naciśnij Klawisz start+R i wpisz linię (przykład):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Otwórz okno terminala i wpisz linię (przykład):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Wygląda na to, że używasz ZoneAlarm na systemie Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Program się nie uruchomił!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Nie masz uprawnień do używania portu %s." #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Błąd krytyczny" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "" "Nie można uruchomić przeglądarki, prawdopodobnie nie została znaleziona" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Brak dostępu" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Błąd %s: należy podać prawidłową nazwę użytkownika i hasło." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Nie udało się wczytać kolejki przetwarzania końcowego: Zła wersja " "(wymagana:%s, znaleziona:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Nie udało sie usunąć nzo z kolejki przetwarzania (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "Pobieranie może się nie udać, dostępne %s z wymaganych %s" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "" "Pobieranie nie powiodło się - Poza okresem przechowywania twojego serwera?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Nie można utworzyć końcowego katalogu %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Brak przetwarzania końcowego z powodu nieudanej weryfikacji" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Przenoszenie" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Wysłano %s do kolejki" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Błąd zmiany nazwy \"%s\" na \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Nie udało się przenieść plików" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Uruchamianie skryptu" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Uruchamianie skryptu użytkownika %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Uruchomiono %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Więcej" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Zobacz komunikaty wyjścia skryptu" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Zakończono pobieranie" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Pobieranie nie powiodło się" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Przetwarzanie końcowe nie powiodło się dla %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "sprawdź plik dziennika" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Przetwarzanie zostało przerwane (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Czyszczenie %s nie powiodło się" #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Błąd usuwania katalogu roboczego (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Przetwarzanie końcowe" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s} Brak zestawów par2" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Próba weryfikacji SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Weryfikacja niektórych plików względem \"%s\" nie powiodła się" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Poprawnie zweryfikowano z użyciem plików SFV" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Usuwanie %s nie powiodło się" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Hibernacja systemu nie powiodła się" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Wstrzymanie systemu nie powiodło się" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Wyłączenie systemu nie powiodło się" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Nieprawiodłowy opis kanału RSS \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Nie udało sie pobrać RSS z %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Brak poprawnego uwierzytelnienia dla kanału %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "Kanał RSS %s był pusty" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Niekompatybilny kanał" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Znaleziono pusty wpis RSS (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Pokaż interfejs" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Otwórz katalog z pobranymi plikami" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Zakończ" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Pozostało" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Zły harmonogram %s w %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Nieznana akcja: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Harmonogram dla nieistniejącego serwera %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Pobierz" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Złącz pliki" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Rozpakuj" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Skrypt" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Źródło" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Niepowodzenie" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Ukończone" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Nieudane" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Oczekuje" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Naprawianie..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Rozpakowywanie..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Przenoszenie..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Wykonywanie skryptu..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Pobieranie dodatkowych bloków..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Szybkie sprawdzanie..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Weryfikowanie..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Pobieranie" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Pobieranie NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Sprawdzanie" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Częstotliwość" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Akcja" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argumenty" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Zadanie" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "wyłącz serwer" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "włącz serwer" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Limit prędkości" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Zatrzymaj wszystkie" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Zatrzymaj przetwarzanie końcowe" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Wznów przetwarzanie końcowe" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Czytaj kanały RSS" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Usuń nieudane zadania" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "godzina" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "godziny" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "minuta" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minut" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sek" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "sekund" #: sabnzbd/skintext.py:79 msgid "day" msgstr "dzień" #: sabnzbd/skintext.py:80 msgid "days" msgstr "dni" #: sabnzbd/skintext.py:81 msgid "week" msgstr "tydzień" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Miesiąc" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "Rok" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Dzień miesiąca" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Ten tydzień" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Ten miesiąc" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Dzisiaj" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Razem" #: sabnzbd/skintext.py:97 msgid "on" msgstr "Wł." #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametry" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "wersja Python" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Strona projektu" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "lub" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Host" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Automatyczne narzędzie pobieranie dla usenetu" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Zapisz" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "W kolejce" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Czy na pewno?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Usunąć wszystkie pobrane pliki?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Start" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Konfiguracja" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Status" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Pomoc" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Ogólne" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Katalogi" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Przełączniki" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Serwery" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Harmonogram" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Powiadomienia" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Email" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Indeksy" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Kategorie" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortowanie" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Specjalne" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Katalog pobierania" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Katalog na pobrane" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Szybkość pobierania" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "ZATRZYMANE" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "Przechowano %s artykułów (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Obciążenie" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "OSTRZEŻENIA" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Dostępne nowe wydanie %s na" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Dodaj nowe pliki" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Na pewno wyłączyć SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Dodaj" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Kod raportu" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Dodaj plik" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Kategoria" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Przetwarzanie" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Priorytet" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Napraw" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Rozpakuj" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Usuń" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "N" #: sabnzbd/skintext.py:176 msgid "U" msgstr "R" #: sabnzbd/skintext.py:177 msgid "D" msgstr "U" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Wymuś" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normalny" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Wysoki" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Niski" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stop" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Wprowadź URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " lub ID raportu" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Sortuj po nazwie" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Sortuj po wieku" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Sortuj po rozmiarze" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Ukryj pliki" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Pokaż pliki" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Po zakończeniu kolejki" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Wyłącz komputer" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Uśpij komputer" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Hibernuj komputer" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "WYłącz SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Limit prędkości" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Zatrzymaj na" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Kolejność" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nazwa" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Pozostało/Razem" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "ETA" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "WIEK" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Usuń" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Ponów" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Akcje" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Skrypty" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Usunąć wszystkie obiekty z kolejki?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Wyczyść NZB" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Wyczyść NZB i usuń pliki" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Usuń NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Usuń NZB i pliki" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "z" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Brakujące artykuły" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Pozostało limitu" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "ręcznie" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Resetuj limit" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Wyczyść historię błędów" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Usunąć z historii wszystkie ukończone pliki?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Usunąć z historii wszystkie błędne pliki?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Ukryj szczegóły" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Pokaż szczegóły" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Rozmiar historii" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Pokaż nieudane" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Pokaż wszystko" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Rozmiar" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Wyczyść nieudane NZB" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Wyczyść nieudane NZB i usuń pliki" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Wyczyść ukończone NZB" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Opcjonalne dodatkowe NZB" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Ścieżka" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Wymuś rozłączenie" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "NastąĻi wysłanie testowej wiadomości na twoje konto." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Pokaż logowanie" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Pokaż logowanie web" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Testuj Email" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Logowanie" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Błędy/Ostrzeżenia" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Informacje" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Debugowanie" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Połączenia" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Wątek" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Wynik testu email" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Ostatnie ostrzeżenia" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "wyczyść" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Odblokuj" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Identyfikator artykułu" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Zestaw plików" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Kiedy" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Typ" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Ostrzeżenie" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Włączone" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Plik konfiguracyjny" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Użyta pamięć podręczna" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "SPowoduje to restart SABnzbd.
    Użyj tego jeśli wydaje ci się, że " "program ma problemy ze stabilnością.
    Pobieranie zostanie zatrzymane " "przez restartem i wznowione po ponownym uruchomieniu." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "W katalogu pobieranie istnieją opuszczone zadania.
    Możesz je usunąć " "(razem z plikami) lub wysłąć spowrotem do kolejki." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "Przycisk \"Napraw\" ponownie uruchomi SABnzbd i spowoduje kompletne
    odtworzenie zawartości kolejki, zachowując już pobrane pliki
    ZMieni " "to kolejnośc kolejki." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Wersja" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Czas działania" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Zapasowy" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Ogólna konfiguracja" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Zmiany wymagają restartu SABnzbd" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Serwer www SABnzbd" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Adres hosta SABnzbd" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Host na którym SABnzbd będzie uruchomiony" #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Posrt na którym SABnzbd będzie uruchomiony" #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Interfejs WWW" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Wybierz skórkę." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Dodatkowy interfejs WWW" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Włącz alternatywną skórkę." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Uwierzytelnienie serwera www" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Używkownik SABnzbd" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Opcjonalna nazwa użytkownika" #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Hasło SABnzbd" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Opcjonanle hasło" #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "Wsparcie dla HTTPS" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Włącz HTTPS" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "nie zainstalowane" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Włącz dostęp do interfejsu przez adres HTTPS" #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Jeśli nie podano obsługa HTTPS będzie na standardowym porcie" #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "Certyfikat HTTPS" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Nazwa pliku lub ścieżka do certyfikatu HTTPS" #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "Klucz HTTPS" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Nazwa pliku lub ścieżka do klucza HTTPS" #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Dostrajanie" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Interwał automatycznego odświeżania kolejki" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Interwał autmatycznego odświeżania strony kolejki w interfejsie WWW " "(sekundy, 0=brak)" #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "Interwał sprawdzania RSS" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Interwał sprawdzania (w minutach, co najmniej 15). Nieużywany podczas " "korzystania z harmonogramu" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Limit pobierania danych" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Limit pobierania danych (w KB/s - kilobajtach na sekundę)" #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Limit pamięci podręcznej artykułów" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Umieszcza artykuły w pamięci podręczne aby ograniczyć korzystanie z " "dysku.
    w bajtach, opcjonalnie z dodatkiem K,M,G. Na przykład: " "\"64M\" lub \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Lista czyszczenia" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista rozszerzeń które powinny zostać usunięte po ściągnięciu.
    Na " "przykład:.nfo lub .nfo,.sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Zapisz zmiany" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Język" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Wybierz język interfejsu WWW." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "Klucz API" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Klucz umożliwi dostęp innych programów do SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "Klucz NZB" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "Klucz umożliwi innym programom dodawanie plików NZB do SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Utwórz nowy klucz" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Wyłącz klucz API" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Nie wymagaj klucza API" #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "UŻYWAJ NA SWOJĄ ODPOWIEDZIALNOŚ" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "Kod QR" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "Kod QR klucza API" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Konfiguracja katalogów" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "UWAGA: Katalogi zostaną automatycznie utworzone po zapisaniu. Można " "używać ścieżek absolutnych aby wskazać katalogi poza domyślnym katalogim." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Używaj katalogów" #: sabnzbd/skintext.py:345 msgid "In" msgstr "w" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Tymczasowy katalog pobierania" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Miejsce przechowywania nieprzetworzonych plików.
    Można zmienić tylko " "kiedy kolejka jest pusta." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimalna ilośc wolnego miejsca w tymczasowym katalogu pobierania" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Zatrzymaj automatycznie jeśli pozostanie mniej miejsca niż ta wartość.
    w bajtach, opcjonalnie z K,M,G,T. Na przykład: \"800M\" lub \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Katalog dla ukończonych plików" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Miejsce przechowywania ukończoncyh, przetworzonych plików.
    Można " "nadpisać przez kategorie." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Uprawnienia dla ukończonych plików" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Ustawienia wzorca uprawnień dla pobranych plików/katalogów.
    notacja " "ósemkowa. Na przykład: \"775\" lub \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Obserwowany katalog" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Katalog monitorowany na obecnośc plików .nzb.
    Skanuje również pliki " ".zip, .rar oraz .ta.gz." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Szybkośc skanowania katalogu obserwowanego" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Ilość sekund między skanami plików .nzb" #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Katalog skryptów przetwarzania końcowego" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Katalog zawierający skrypty przetwarzania końcowego" #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Katalog szablonów email" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Katalog zawierający szablony użytkownika dla powiadomień email" #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Plik haseł" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Plik zawierające wszystkie hasła do wykorzystania dla zaszyfrowanych plików " "RAR." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Katalogi systemowe" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Katalog administracyjny" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Położenie admina kolejki oraz bazy danych historycznych.
    Można " "zmienić tylko kiedy kolejka jest pusta." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Dane nie zostaną przeniesione. Wymaga restartu SABnzbd!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Katalog dzienników zdarzeń" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Położenieplików dziennika SABnzbd.
    Wymaga restartu SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Katalog backupów .nzb" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Miejsce przechowywania plików .nzb" #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Domyślny katalog bazowy" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Konfiguracja przełączników" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Przetwarzanie przełączników" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Włącz szybkie sprawdzanie" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Pomiń sprawdzanie par2 dla 100% prawidłowych plików." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Włącz unran" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Włącz wbudowaną funkcjonalność unrar" #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Włącz unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Włącz wbudowaną funkcjonalność unzip." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Włącz łączenie plików" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Łacz pliki kończące się na .001, .002 itd. w jeden plik" #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Włącz łączenie TS" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "Łacz pliki kończące się na .001.ts, 002.ts itd. w jeden plik" #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Włącz czyszczenie par" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Czyśc pliki par (jeśli weryfikacja/naprawa była udana)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Przerywaj po błędach CRC yEnc" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "Próbuj pobierać artykuły z błędami CRC z innych serwerów" #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Pobieraj artykuły tylko z góry kolejki" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Oszczędza pamięć. Należy wyłączyć jeśli wolne zadania blokują kolejkę." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Przetwarzanie końcowe tylko dla zweryfikowanych zadań." #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Uruchamiaj przetwarzanie końcowe tylko dla zadań, które przeszły sprawdzanie " "PAR2" #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Wykrywaj zduplikowane pliki" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Wykrywaj identycznie nazwane pliki NZB (wymaga opcji backupu NZB) oraz " "zduplikowane tytuły w kanałach RSS." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Wyłączone" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Porzuć" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Włącz sprawdzania bazujące na SFV" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Wykonuj dodatkową weryfikację na podstawie plików SFV." #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Sprawdzaj wyniki rozpakowywania" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Sprawdzaj wyniki rozpakowywania (należy wyłączyć dla niektórych systemów " "plików)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Włącz zmianę nazwy katalogów" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Używaj tymczasowych nazw plików podczas przetwarzania końcowego. Należy " "wyłączyć, jeśli system nie obsługuje tej opcji prawidłowo." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Domyślne przetwarzanie końcowe" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Używane, kiedy brak definicji w kategorii." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Domyślny skrypt użytkownika" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Używane, kiedy brak definicji w kategorii." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Skrypt użytkownika przed kolejką" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Używany, zanim plik NZB trafi do kolejki" #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Domyślny priorytet" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Używane, kiedy brak definicji w kategorii" #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Włącz wielordzeniowy Par2" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Przeczytaj na ten temat w Wikii Pomocy!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Dodatkowe parametry PAR2" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Parametry nice" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "Parametry IONice" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Inne przełączniki" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Rozłącz przy pustej kolejce" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Rozłącz serwer(y) Usenet kiedy kolejka jest pusta lub zatrzymana." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Wyslij group" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Wyślij polecenie group przed żądaniem artykułu" #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sortuj według wieku" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Automatycznie sortuj pozycje według (średniego) wieku" #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Sprawdzaj aktualizacje" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Sprawdzaj co tydzień w poszukiwaniu nowych wydań SABnzbd." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Zastąp spacje w nazwach katalogów" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Zastąp spacje w nazwach katalogów podkreśleniami." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Zastąp kropki w nazwach katalogów" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Zastąp kropki w nazwach katalogów spacjami." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Zastąp niedopuszczalne znaki w nazwach katalogów" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Zastąp niedopuszczalne znaki w nazwach katalogów ich odpowiednikami (w " "przeciwnym wypadku usuń)" #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Uruchom przeglądarkę na starcie" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Uruchom domyślną przeglądarką podczas startowania SABnzbd." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Zatrzymaj pobieranie podczas przetwarzania końcowego" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Zatrzymuje pobieranie na początku przetwarzania końcowego i przywraca po " "zakończeniu." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignoruj próbki" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Odfiltrowuj pliki próbek (np. próbki wideo)" #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Usuń po pobraniu" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Nie pobieraj" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "Typ SSL" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Użyj V23 chyba, że dostawca wymaga innego!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Używaj 12sto godzinnego zegara (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Pokazuj czas w notacji AM/PM (nie dotyczy harmonogramu)" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Serwer" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Przetwarzanie końcowe" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Nazewnictwo" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Limit pobierania" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Ile danych można pobrac w miesiącu (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Dzień resetu" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "W którym dniu miesiąca lub tygodnia (1=poniedziałek) twój dostawca resetuje " "limit pobierania (opcjonalnie z gg:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Automatyczne przywracanie" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "Czy pobieranie powinno się automtycznie przywrócić w dniu resetu" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Okres limitu" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Czy limit jest kasowany dziennie, tygodniowo czy miesięcznie?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Sprawdź przed pobraniem" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Spróbuj przewidzieć, czy pobieranie będzie udane przed jego rozpoczęciem " "(wolne!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Maksymalna ilość prób" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Maksymalna ilość prób per serwer" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Tylko dla dodatkowych serwerów" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Zastosuj maksymalną ilośc prób tylko dla serwerów dodatkowych." #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Konfiguracja serwera" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Definicja serwera" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Dodaj serwer" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Nazwa użytkownika" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Hasło" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Limit czasu odpowiedzi" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Czas przechowywanie" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Serwer zapasowy" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Opcjonalny" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Włącz" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Usuń serwer" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Testuj serwer" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Wyczyść liczniki" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testuję szczegóły serwera..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Naciśnij poniżej, aby przetestować." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Przepustowość" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Konfiguracja harmonogramów" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Dodaj harmonogram" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Usuń" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Obecne harmonogramy" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "Konfiguracja RSS" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Nowy URL kanału" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Pole wyboru obok nazwy kanału musi byc zaznaczone, aby kanał był włączony do " "automatycznego sprawdzania nowych wpisów.
    Dla nowych kanałów pobrane " "zostaną tylko nowe wpisy, bez wpisów już istniejących, chyba że zostanie " "wybrane \"Wymuszenie pobrania\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Dodaj kanał" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Usuń kanał" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Pobierz kanał" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Wymuś pobranie" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filtr" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Pomiń" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Akceptuj" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Odrzuć" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Wymaga" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "WymagaKat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Nie dopasowano" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Kanały" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Czytaj teraz wszystkie kanały" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Ustawienia" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtry" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Opcje email" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Powiadomienia email po zakończeniu zadań" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Nigdy" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Zawsze" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Tylko błędy" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Powiadomienie o pełnym dysku" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Powiadom kiedy dysk jest pełen a SABnzbd zatrzymany" #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Powiadomienia RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Powiadom, kiedy kanał RSS dodaje zadanie do kolejki" #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Ustawienia konta email" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "Serwer SMTP" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Ustaw serwer twojego dostawcy dla powiadomień" #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Odbiorca emaili" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Adres email na który wysyłać powiadomienia" #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Nadawca email" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Kto powinien być nadawcą emaila?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "OPCJONALNA nazwa konta" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Nazwa konta dla kont z uwierzytelnieniem." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "OPCJONALNE hasło do konta" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Hasło dla kont z uwierzytelnieniem." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Włącz Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Wysyłaj powiadomienia Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Adres serwera" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Tylko dla zdalnych serwerów Growl (host:port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Hasło serwera" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Opcjonalne hasło dla serwera Growl" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Włącz NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Wysyłaj powiadomienia do NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Jeśli posiadasz konto na www.newzbin2.es, możesz tutaj " "podać jego dane.
    Spowoduje to włączenie dodatkowych funkcji." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Informacje o koncie" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Nazwa użytkownika Newzbin" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Podaj nazwę twojego użytkownika." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Hasło Newzbin" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Podaj swoje hasło" #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Przetwarzanie zakładek" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Automatycznei pobieraj zakładki" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Automatycznei pobieraj zadania z twoich zakładek." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Pobierz teraz zakładki" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Ukryj zakładki" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Pokaż zakładki" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Usuń zakładkę po pobraniu" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Usuń z listy zakładek po zakończeniu pobierania." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Interwał sprawdzania" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "W minutach (co najmniej 15)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Przetworzone zakładki" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Jeśłi posiadasz konto w www.nzbmatrix.com, możesz tutaj " "podać jego dane.
    Jest to wymagane do używania kanałów RSS z tej strony." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Nazwa użytkownika NzbMatrix" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "Klucz NzbMatrix" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Tutaj ustaw klucz API NzbMatrix." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Kategorie użytkownika" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Definiuje przetwarzanie końcowe i przechowywanie." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Użyj kolumny \"Grupy / Etykiety indeksera\" to zmapowania grup i etykiet do " "twoich kategorii.
    Znaki wieloznaczne są dopuszczalne. Użyj przecinków " "do rozdzielenia terminów." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Zakończenie ścieżki znakiem asterisk * zapobiegnie tworzeniu katalogów dla " "zadań." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Względne katalogi są bazowane na" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Katalog/Ścieżka" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Grupy / Etykiety indeksera" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Konfiguracja sortowania" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Sortowanie seryjne" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Włącz sortowanie TV" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Włącz sortowanie i zmianę nazw odcinków" #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Klucz wzorca" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Wyczyść" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Predefiniowane" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Przykład" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Sortowanie standardowe" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Włącz sortowanie filmów" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Włącz standardowe sortowanie i zmiane nazw plików." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Trzymaj niesklasyfikowane zadania w dodatkowych katalogach" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Włącz, jeśli zadania nie sa umieszczane we własnych katalogach." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Dotknięte kategorie" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Znaczenie" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Wzorzec" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Wynik" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "Katalog sezonu 1x05" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "Katalog sezonu S01E05" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "Katalog odcinka 1x05" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "Katalog odcinka S01E05" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Tytuł" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Nazwa filmu" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Nazwa.Filmu" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Nazwa_Filmu" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Nazwa serialu" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Nazwa.Serialu" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Nazwa_Serialu" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Numer Sezonu" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Numer Odcinka" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Nazwa Odcinka" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Nazwa.Odcinka" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Nazwa_Odcinka" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Rozszerzenie pliku" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Rozszerzenie" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Numer fragmentu" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Dekada" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Oryginalna nazwa pliku" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Oryginalna nazwa katalogu" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Małe litery" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEKST" #: sabnzbd/skintext.py:667 msgid "text" msgstr "text" #: sabnzbd/skintext.py:668 msgid "file" msgstr "plik" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "katalog" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Łańcuch sortowania" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "WIeloczęściowa etykieta" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "W katalogach" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Brak katalogów" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Sortowanie po dacie" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Włącz sortowanie według daty" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Włącz sortowanie i zmianę nazwy według dacie." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Pokaż katalog nazwy" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Katalogi Rok-Miesiąc" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Katalogi dzienne" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "z dostosowaniem wielkości" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Przetworzone wyniki" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Rzadko używane opcje. Jeśli chcesz się dowiedzić co oznaczają, klikniej " "przycisk Pomoc i przeczytaj strony Wiki.
    Nie zmieniaj tych opcji bez " "uprzedniego przeczytania Wiki, ponieważ niektóre mają skutki " "uboczne.
    Domyślne wartości są umieszczone w nawiasach." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Wartości" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Edytuj szczegóły NZB" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Usuń" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Na górę" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Wyżej" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Niżej" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Na dół" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Wszystko" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Odwróć" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Nazwa pliku" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Temat" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Wiek" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Zaznaczenie" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Czy na pewno usunąć?" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Odśwież" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Opcje" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Strona" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Poprzednia" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Następna" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Pierwsza" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Ostatnia" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Zamknij" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Ustaw interwał wstrzymywania" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sortuj" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Wyczyścić kolejkę?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Interwał wstrzymywania" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Wstrzymaj na 5 minut" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Wstrzymaj na 15 minut" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Wstrzymaj na 30 minut" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Wstrzymaj na 1 godzinę" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Wstrzymaj na 2 godziny" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Wstrzymaj na 6 godzin" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Wstrzymaj na 12 godzin" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Wstrzymaj na 24 godziny" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sortuj po wieku Najstarsze→Najnowsze" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sortuj po wieku Najnowsze→Najstarsze" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sortuj po nazwie A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sortuj po nazwie Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sortuj po rozmiarze Najmniejsze→Największe" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sortuj po rozmiarze Największe→Najmniejsze" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Zmień nazwę" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Pozostało" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Wyczyścić historię?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Niezachowano zmian, zostaną one utracone." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Otwórz URL źródłowy" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Otwórz URL informacyjny" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Miejsce" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Zobacz dziennik skryptu" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Plush wymaga włączenia obłsugi JavaScript" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Dodaj NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Opcje Plush" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Dostępna aktualizacja" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Na ile minut wstrzymać?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Wstrzymaj na..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Wielokrotne operacje" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Górne menu" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Po zakończeniu" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sortuj po wieku (Najstarsze→Najnowsze)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sortuj po wieku (Najnowsze→Najstarsze)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sortuj po nazwie (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sortuj po nazwie (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sortuj po rozmiarze (Najmniejsze→Największe)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sortuj po rozmiarze (Największe→Najmniejsze)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Wyczyść" #: sabnzbd/skintext.py:781 msgid "left" msgstr "pozostało" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Max szybkość" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Zakres" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Reset" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Zastosuj do zaznaczonych" #: sabnzbd/skintext.py:786 msgid "page" msgstr "strona" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Wszystko" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Wyłączone" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Częst. odświeżania" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Szerokośc kontenera" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Potwierdzaj usuwanie z kolejki" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Potwierdzaj usuwanie historii" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "Zablokuje odświeżanie zawartości po najechaniu kursorem" #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Zablokuj odświeżanie podczas wskazywania" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Pobierz" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Wczytaj" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Wczytaj: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Opcjonalnie podaj nazwę pliku" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Postęp" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Brak miejsca na dysku na dokończenie pobierania" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Wolne miejsce" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Wolne (Temp)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "BEZCZYNNY" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Pobieranie" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Naprawa kolejki" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Czytaj kanał pobierze aktualną zawartość kanału. " "Wymuś pobranie pobierze teraz wszystkie pasujące pliki NZB." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Godziny:Minuty" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Usuwanie zakończone" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Usunąć wszystkie nieudane z hostorii?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Usuwanie nie powiodło się" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Odnośniki" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Pokazywanie %s do %s z %s wyników" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Brak wyników" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Pokazuję jeden wynik" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Wysłano email!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Wysłano powiadomienie!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Zapisywanie..." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Zapisano" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Szybkość" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Przełącz dodanie NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "DualView1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "DualView2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Własny" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Pobierz zakładki" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Czy na pewno zrestartować SABnzbd" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Częstotliwość odświeżania" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Usuń wszystko" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Usuń opcje edycji" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Pokaż opcje edycji" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Edytuj" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Pozostało" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "Szybki kreator konfiguracji SABnzbd" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "Wersja SABnzbd" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Poprzednia" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Dostęp" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "Chcę, aby każdy komputer w mojej sieci miał dostęp do SABnzbd" #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Chcę, abym miał dostęp do SABnzbd tylko z mojego komputera" #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Zabezpiecz dostęp do SABnzbd hasłem (rekomendowane)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Włącz dostęp HTTPS do SABnzbd" #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Pozostałe" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Uruchom stronę SABnzbd w przeglądarce kiedy program startuje" #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Szczegóły serwera" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Podaj szczegóły twojego podstawowego dostawcy usenet" #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Pobieranie z usenet wymaga dostępu do dostawcy. Twój ISP może umożliwiać " "dostęp, aczkolwiek zalecany jest dostawca klasy premium." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Nie posiadasz dostawcy usenet? Polecamy spróbować %s" #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Ilość połączeń dopuszczanych przez twojego dostawcę" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "Np. 8 lub 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Zaznaczy tylko jeśli twój dostawca zezwala na SSL." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Kliknij aby przetestować wprowadzone dane." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "To pole jest wymagane." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Wprowadź liczbę całkowitą" #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Jeśli jesteś członkiem newzbin lub nzbmatrix, możesz tutaj podać swoją nazwę " "użytkownik i hasło aby umożliwić pobieranie NZB stamtąd. Ten etam można " "pominąć jeśli nie używasz tych serwisów." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Automatycznie pobieraj posty dodane do zakłądek" #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Np." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "REstarowanie SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Konfiguracja została zakończona!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd będzie uruchomiony w tle." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Zamknięcie okna przeglądarki lub karty NIE zamknie SABnzbd" #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Po zakończeniu ponownego uruchamiania będziesz miał dostęp do niego pod: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Zalecamy dodanie tej strony do zakładek i używanie tej zakładki do " "późniejszego dostępu do SABnzbd uruchomionego w tle." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Dalszą pomoc można uzyskać na naszej" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Idź do SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Krok pierwszy" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Krok drugi" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Krok trzeci" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Krok czwarty" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Krok piąty" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "Np. 119 lub 563 dla SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Wyjście SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Uruchom Asystenta" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd nie posiada ABSOLUTNIE ŻADNEJ GWARANCJI.\n" "Program jest wolnym oprogramowaniem i zachęcamy do jego rozpowszechniania z " "zachowaniem odpowiednich warunków.\n" "Program jest wydany na licencji GNU GENERAL PUBLIC LICENSE wersja 2 lub (dla " "twojego wyboru) każda późniejsza wersja.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Błąd pobieranie informacji TV (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Nie udało się zmienić nazwy: %s na %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Nie udało się zmienić nazwy podobnego pliku: %s na %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Nieprawidłowy numer raportu nzbmatrix %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Dostęp do API wymaga konta VIP nzbmatrix" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Nieprawidłowe dane uwierzytelniające nzbmatrix." #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Problem z dostępem do serwera nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Nazwa hosta nie została ustawiona." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Nie ma połączenia z żadnym serwerem. Należy ustanowić przynajmniej jedno " "połączenie." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Hasło ukryte za ******, proszę wprowadzić ponownie" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Niewłaściwe dane serwera" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Upłynął limit czasu odpowiedzi: Spróbuj włączyć SSL lub połącz się z innym " "portem." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Upłynął limit czasu odpowiedzi" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Nieprawidłowy adres serwera." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Serwer przerwał komunikację w trakcie logowania" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Serwer wymaga podania nazwy użytkownika i hasła." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Połączenie udane!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Błąd połączenia, sprawdź nazwę użytkownika i hasło." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Zbyt wiele połączeń, proszę wstrzymać pobieranie lub spróbować ponownie " "później" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Nie można określić rezultatu połączenia (%s)" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Błąd pobierania msgid %s z www.newzbin.com - Proszę upewnić się, że Login i " #~ "Hasło są ustawione" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "pobieram msgid %s z www.newzbin.com" #~ msgid "Could not compile regex: %s" #~ msgstr "Nie udało się skompilować wyrażęnia regularnego: %s" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Należy podać hasło i wznowić zadanie" #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Zatrzymaj zadanie podczas pobierania zaszygrowanego pliku RAR" SABnzbd-0.7.20/po/main/pt_BR.po0000644000000000000000000037165012433712556016161 0ustar00usergroup00000000000000# Brazilian Portuguese translation for sabnzbd # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2013-02-11 19:34+0000\n" "Last-Translator: lrrosa \n" "Language-Team: Brazilian Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:55+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Falha ao iniciar a interface web" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "" "Não foi possível encontrar o template web: %s. Tentando o template padrão" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "módulo _yenc... NÃO encontrado!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "aplicativo par2... NÃO encontrado!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "aplicativo unrar... NÃO encontrado!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "aplicativo unzip... NÃO encontrado!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Esteja ciente de que o nome de host 0.0.0.0 vai precisar de um endereço IPv6 " "para acesso externo" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "HTTPS desabilitado pela falta de arquivos CERT e KEY" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s iniciado" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "Encerramento do SABnzbd concluído" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Sinal %s encontrado. Salvando e saindo..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "obtendo msgid %s de www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Erro ao obter msgid %s de www.newzbin2.es - Por favor, tenha certeza que seu " "usuário e senha estão corretos." #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Tentando obter NZB de %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Não é possível criar um arquivo temporário para %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Tentando definir o status do servidor inexistente %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Muito pouco espaço em disco. Forçando PAUSE" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Falha em tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Falha ao salvar %s" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Falha ao carregar %s" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Notificação de teste" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Nenhum" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Padrão" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "AVISO:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "ERRO:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "desconhecido" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Falha ao compilar a expressão para o termo pesquisado: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disco cheio! Forçando Pausa" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Erro de disco na criação do arquivo %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "" "ATENÇÃO: Tarefa \"%s\" em pausa por causa de arquivo RAR criptografado" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "" "ATENÇÃO: Tarefa \"%s\" cancelada por causa de arquivo RAR criptografado" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Cancelado, criptografia detectada" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "faltando %s" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Quota esgotada, pausando o download" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s não é um endereço de e-mail válido" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Endereço do servidor necessário" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Não foi possível criar %s pasta %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Não é possível gravar no arquivo INI %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Não é possível criar um arquivo de backup para %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Senha %s codificada incorretamente" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s não é um valor octal correto" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "O caminho UNC \"%s\" não é permitido aqui" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Erro: A fila não está vazia. Não será possível mudar de pasta." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "A pasta \"%s\" não existe" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "O comando SQL falhou. Consulte o log" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "O commit do SQL falhou. Consulte o log" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Falha ao fechar o banco de dados. Consulte o log" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Registro inválido de etapa no histórico para %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Falha ao decodificar %s" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "Erro de CRC em %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Artigo yEnc mal formado em %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Erro desconhecido ao decodificar %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => faltando em todos os servidores. Descartando" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Erro ao remover %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Não é possível ler %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Não é possível ler a Pasta de Assistidos %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Pausado" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "O servidor %s será ignorado por %s minutos" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Falha ao iniciar %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Excesso de conexões ao servidor %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Provável compartilhamento de conta" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Falha de logon ao servidor %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Não é possível conectar ao servidor %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "A conexão a %s@%s:%s falhou. Mensagem=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Servidor %s requer usuário/senha" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Encerrando" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Falha ao conectar ao servidor de e-mail" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Falha ao iniciar a conexão TLS" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Falha ao autenticar com o servidor de e-mail" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Falha ao enviar o e-mail" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Falha ao fechar a conexão de email" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "E-mail enviado com sucesso" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Não é possível encontrar templates de email em %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Nenhum destinatário fornecido. E-mail não enviado" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Codificação inválida do template de e-mail %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Nenhum template de e-mail encontrado" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd informa Disco Cheio\n" "\n" "Olá,\n" "\n" "SABnzbd parou de baixar, porque o disco está quase cheio.\n" "Por favor, arranje mais espaço e retome SABnzbd manualmente.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Inicialização/Encerramento" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "NZB Adicionado" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Pós-processamento iniciado" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Tarefa concluída" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Outras Mensagens" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Atenção: LOCALHOST é ambíguo, use endereço IP numérico." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Endereço de servidor \"%s:%s\" não é válido." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Faltando chave de sessão" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Erro: chave de sessão obrigatória" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Erro: chave de sessão incorreta" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "Chave de API faltando. Por favor insira a chave de API de Configuração-" ">Geral em seu programa de terceiros:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Chave de API incorreta. Use a chave de API de Configuração->Geral em seu " "programa de terceiros:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Autenticação faltando. Por favor insira usuário/senha de Configuração->Geral " "em seu programa de terceiros:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Erro: Nenhuma interface secundária definida." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Sua versão do UNRAR não é recomendada. Pegue-a de " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Nenhum programa UNRAR foi encontrado. Não será possível descompactar " "arquivos RAR
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "" "Nenhum programa PAR2 foi encontrado. Reparos não serão possíveis
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "B" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Fazendo o reinício...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    Encerramento do SABnzbd concluído.
    Espere cerca de 5 " "segundos e, em seguida, clique no botão abaixo.

    Atualizar
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Feed" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Diariamente" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "segunda-feira" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "terça-feira" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "quarta-feira" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "quinta-feira" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "sexta-feira" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "sábado" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "domingo" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "desligado" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Resolvendo endereço" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Parâmetro incorreto" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Voltar" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "A tarefa \"%s\" foi adicionada novamente à fila" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "As tarefas marcadas com um '*' não serão baixadas automaticamente." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Correspondido" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Não correspondido" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Baixados" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Baixados até agora" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Valor incorreto para %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Não é possível criar a pasta %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "pasta %s: %s erro de acesso" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Não é possível conectar à seção de registro HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Não é possível abrir a chave de registro \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Falha ao ler chaves de registro para pastas especiais" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Falha ao criar (%s)" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Falha ao mover %s para %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Arquivo NZB inutilizável" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Tente novamente" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "A busca da URL falhou; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "Módulo pyOpenSSL ausente. Instale-o para obter acesso https" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Erro ao criar chave SSL e certificado" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Não é possível alterar permissões de %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Unindo" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Sequência de arquivos multiparte incompleta" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "A união de arquivos de %s falhou" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Erro \"%s\" na união de arquivos" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Erro \"%s\" ao executar file_join em %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Unidos %s arquivos" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "A descompactação falhou. %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Erro \"%s\" ao descompactar os arquivos RAR" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Erro \"%s\" ao executar rar_unpack em %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "A exclusão de %s falhou!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Tentando descompactar com a senha \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "A descompactação falhou. O arquivo exige uma senha" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Descompactando" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "A descompactação falhou. Não foi possível encontrar %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "ERRO: Não foi possível encontrar \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "A descompactação falhou. Erro de CRC" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "ERRO: CRC falhou em \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "A descompactação falhou. Erro de escrita ou disco cheio?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "ERRO: erro de escrita (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Descompactação falhou, o caminho é muito extenso" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "ERRO: caminho muito extenso (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "A descompactação falhou. Veja o log" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "ERRO: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Faltando arquivo esperado: %s => erro no unrar?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "A descompactação falhou. Um arquivo esperado não foi descompactado" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "A descompactação falhou. Este(s) arquivo(s) estão faltando:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Descompactados %s arquivos/pastas em %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s arquivos em %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Erro \"%s\" ao executar unzip() em %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Verificação Rápida" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Reparar" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Verificação Rápida OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Iniciando reparação" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparação falhou, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Erro %s ao executar par2_repair no conjunto %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Erro \"%s\" ao executar par2_repair no conjunto %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 recebeu opções incorretas. Verifique em Configuração->Opções" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificado em %s. Todos os arquivos corretos" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificado em %s. É necessário reparar" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Pacote principal não encontrado..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Arquivos PAR2 inválidos. Não é possível verificar ou reparar" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparação falhou. Blocos de reparação insuficientes (faltam %s)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Obtendo %s blocos..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Obtendo" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Reparando" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Reparado em %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Verificando" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Erro ao importar o módulo OpenSSL. Conectando-se sem SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Falha ao atualizar a tarefa newzbin %s" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB adicionado à fila" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "O servidor Newzbin mudou seu protocolo" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Você não tem créditos na sua conta Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Não autorizado. Verifique o seu nome de usuário e senha Newzbin" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin informou %s não encontrado" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin enviou código de erro não documentado (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Servidor Newzbin falhou ao enviar informações de %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Não foi possível excluir o favorito newzbin %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin enviou código de erro não documentado (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Encontrado arquivo de fila incompatível. Não é possível continuar" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Erro ao carregar %s. Arquivo corrupto detectado" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Erro ao adicionar %s. Removendo" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Codificação desconhecida" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Arquivo %s está vazio. Pulando" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Falha ao importar %s arquivos de %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Arquivo NZB incompleto %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Arquivo NZB %s inválido. Pulando (razão=%s, linha=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Arquivo NZB %s vazio" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorando NZB duplicado \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Pausando NZB duplicado \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Cancelado, não é possível concluir" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLICADO" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "CRIPTOGRAFADO" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "MUITO GRANDE" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "INCOMPLETO" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "Espere %s segundo(s)" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Baixado em %s a uma média de %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artigos estavam malformados" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s artigos estavam faltando" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artigos tinham duplicatas não-correspondentes" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s artigos foram removidos" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Erro ao importar %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Alertas" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Inativo" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Configuração" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Fila" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Limpar Fila" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Histórico" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Limpar Histórico" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Limitar Velocidade" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pausar" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Continuar" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Obter Favoritos Newzbin" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Varrer pasta de assistidos" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Pasta de Finalizados" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Pasta de Não-Finalizados" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Resolução de problemas" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Reiniciar" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Reinicie sem login" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Sair" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Fila dos primeiros 10 items" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Esvaziar" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Histórico dos últimos 10 items" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Nova versão disponível" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Ir para o assistente" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Parando..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problema com" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd não é compatível com alguns softwares de firewall.
    \n" " %s
    \n" " Lamentamos, mas não podemos resolver esta incompatibilidade no " "momento.
    \n" " Por favor, registre uma reclamação com seu fornecedor de firewall.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd precisa de uma porta tcp/ip livre para seu servidor web " "interno.
    \n" " A porta %s em %s foi tentada, mas não está disponível.
    \n" " Algum outro software usa a porta ou o SABnzbd já está rodando.
    \n" "
    \n" " Por favor reinicie o SABnzbd com um número de porta diferente." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "" "Se você receber esta mensagem de erro outra vez, tente um número " "diferente.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd precisa de uma porta tcp/ip livre para seu servidor web " "interno.
    \n" " A porta %s em %s foi tentada, mas a conta usada para o SABnzbd não tem " "permissão para usá-la.
    \n" " Nos sistemas OSX e Linux, usuários normais devem usar portas acima de " "1023.
    \n" "
    \n" " Por favor reinicie o SABnzbd com um número de porta diferente." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd precisa de um endereço de host válido para seu servidor web " "interno.
    \n" " Você especificou um endereço inválido.
    \n" " Valores seguros são localhost e 0.0.0.0
    \n" "
    \n" " Por favor reinicie o SABnzbd com um endereço de host correto." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd detectou dados salvos de outra versão do SABnzbd
    \n" " mas não pode reutilizar os dados do outro programa.

    \n" " Você pode querer terminar sua fila antes com o outro programa.

    \n" " Após isso inicie este programa com a opção \"--clean\".
    \n" " Isto irá apagar a fila atual e histórico!
    \n" " SABnzbd leu o arquivo \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd não pode encontrar seus arquivos da interface web em %s.
    \n" " Por favor instale o programa novamente.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd detectou um erro fatal:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd detectou uma Fila e Histórico de uma versão antiga " "(0.4.x).

    \n" " Tanto a fila quanto o histórico serão ignorados e podem se " "perder!

    \n" " Você pode optar por parar o SABnzbd e terminar a fila com o programa " "mais antigo.

    \n" " Clique em OK para prosseguir ao SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd detectou que o arquivo sqlite3.dll está faltando.

    \n" " Alguns anti-vírus mal projetados removem este arquivo.
    \n" " Por favor, verifique o seu anti-vírus, tente reinstalar o SABnzbd e " "reclame com o seu fornecedor de anti-vírus.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Aperte a tecla Windows+R e digite a linha (exemplo):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Abra uma janela de terminal e digite a linha (exemplo):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "É provável que você esteja usando o ZoneAlarm no Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "O programa não iniciou!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Você não tem permissão para usar a porta %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Erro fatal" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Não é possível iniciar o navegador. Provavelmente não foi encontrado" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Acesso negado" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Erro %s: Você precisa fornecer um nome de usuário e senha válidos." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Falha ao carregar fila de pós-processamento: Versão incorreta (requerido:%s, " "encontrado:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Falha ao remover nzb da fila de pós-processamento (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "" "O download pode falhar. Somente %s de %s necessários estão disponíveis" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "O download falhou - Fora da retenção do seu servidor?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Não é possível criar a pasta final %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Sem pós-processamento por causa de falha na verificação" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Movendo" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Enviados %s para a fila" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Erro ao renomear \"%s\" para \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Falha ao mover arquivos" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Executando script" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Executando script de usuário %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "%s executado" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Mais" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Ver saída do script" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Download concluído" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "O download falhou" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "O pós-processamento falhou para %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "veja o arquivo de log" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "O pós-processamento foi cancelado (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "A limpeza de %s falhou." #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Erro ao remover a pasta de trabalho (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Pós-processamento" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Nenhum conjunto par2" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Tentando verificação SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Alguns arquivos falharam na verificação de \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Verificado com sucesso. Usando arquivos SFV." #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "A remoção de %s falhou" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Falha ao hibernar o sistema" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Falha ao colocar o sistema em espera" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Erro ao desligar o sistema" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Descrição de feed RSS incorreta \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Falha ao obter RSS de %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Não há autenticação válida para o feed %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "O feed RSS %s estava vazio" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Feed incompatível" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Entrada RSS vazia encontrada (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Exibir interface" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Abrir pasta de finalizados" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Encerrar" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Restante" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Agendamento %s incorreto em %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Ação desconhecida: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Agendamento para um servidor inexistente %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Download" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Unir arquivos" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Descompactar" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Script" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Código fonte" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Falha" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Concluído" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Falhou" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Aguardando" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparando..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Extraindo..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Movendo..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Executando script..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Obtendo blocos extras..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Verificação Rápida..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Verificando..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Baixando" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Obter NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Verificando" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Frequência" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Ação" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Parâmetros" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Tarefa" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "desativar o servidor" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "ativar o servidor" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Limite de velocidade" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Pausar Todos" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pausar o pós-processamento" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Continuar o pós-processamento" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Ler feeds RSS" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Remover tarefas com falha" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "hora" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "horas" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "min" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "min" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "seg" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "segundos" #: sabnzbd/skintext.py:79 msgid "day" msgstr "dia" #: sabnzbd/skintext.py:80 msgid "days" msgstr "dias" #: sabnzbd/skintext.py:81 msgid "week" msgstr "semana" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Mês" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "Ano" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Dia do mês" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Esta semana" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Este mês" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Hoje" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Total" #: sabnzbd/skintext.py:97 msgid "on" msgstr "ligado" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parâmetros:" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Versão do Python" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Página inicial" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "ou" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Host" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "A ferramenta de download automático da usenet" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Gravar" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Na fila" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Você tem certeza?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Excluir todos os arquivos baixados?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Início" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Configuração" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Situação" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Ajuda" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Fórum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Gerais" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Pastas" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Opções" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Servidores" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Agendamento" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Notificações" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "E-mail" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Sites de Indexação" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Categorias" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Ordenação" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Especial" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Pasta de Download" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Pasta Completados" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Velocidade de download" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "EM PAUSA" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "%s artigos em cache (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Carga do sistema" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "AVISOS" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Nova versão %s disponível em" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Adicionar novos downloads" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Tem certeza de que quer encerrar o SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Adicionar" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Report-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Adicionar Arquivo" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Categoria" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Processamento" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioridade" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparar" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Descompactar" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Excluir" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "U" #: sabnzbd/skintext.py:177 msgid "D" msgstr "D" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Forçar" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Alta" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Baixa" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Parar" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Digite a URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " ou Report ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Ordenar pelo nome" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Ordenar por idade" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Ordenar por tamanho" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Ocultar arquivos" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Exibir arquivos" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "Ao terminar a fila" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Desligar o PC" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "PC em espera" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Hibernar o PC" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Encerrar o SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Limite de velocidade" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pausa de" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Ordem" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nome" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Restante/Total" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Estimado" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "IDADE" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Apagar" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Repetir" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Ações" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Scripts" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Eliminar todos os itens da fila?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Limpar NZBs" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Limpar NZBs & Excluir Arquivos" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Remover NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Remover NZB & Excluir Arquivos" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "de" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Artigos faltando" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Quota restante" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "manual" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Redefinir Quota agora" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Limpar Histórico de Falhas" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Eliminar do histórico todos os itens concluídos?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Eliminar do histórico todos os itens falhados?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Ocultar detalhes" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Mostrar detalhes" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Tamanho do histórico" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Mostrar Falhados" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Mostrar Todos" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Tamanho" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Limpar NZBs Falhados" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Limpar NZBs Falhados & Excluir Arquivos" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Limpar NZBs Terminados" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "NZB Suplementar Opcional" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Caminho" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Forçar Desconexão" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Isto irá enviar um e-mail de teste para sua conta." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Mostrar Logs" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Mostrar Logs da Web" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Testar E-mail" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Logs" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Erros/Avisos" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Debug" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Conexões" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Tópico" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Resultado do Teste de E-mail" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Últimos Alertas" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "limpar" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Desbloquear" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Identificador de artigo" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Conjunto de arquivos" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Quando" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Tipo" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Alerta" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Ativo" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Arquivo de Configuração" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Cache utilizado" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Isto irá reiniciar o SABnzbd.
    Use-o quando você achar que o programa " "tem um problema de estabilidade.
    Os downloads serão pausados antes de " "reiniciar e retomados depois." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Existem tarefas órfãs na pasta de downloads.
    Você pode optar por excluí-" "las (incluindo arquivos) ou enviá-las de volta para a fila." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "O botão \"Reparar\" irá reiniciar o SABnzbd e fazer uma reconstrução
    completa do conteúdo da fila, preservando arquivos já baixados.
    Isto " "modificará a ordem da fila." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Versão" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Tempo ativo" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Backup" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Configuração geral" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Mudanças exigirão um reinício do SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Servidor Web do SABnzbd" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Host do SABnzbd" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Computador onde o SABnzbd ficará ativo." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Porta do SABnzbd" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Porta onde o SABnzbd será ativado." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Interface Web" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Escolha uma skin." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Interface Web Secundária" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Ativar uma skin alternativa." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Autenticação do servidor web" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Usuário do SABnzbd" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Usuário de autenticação opcional." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Senha do SABnzbd" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Senha de autenticação opcional." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "Suporte HTTPS" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Habilitar HTTPS" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "não instalado" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Ativar acesso à interface por um endereço HTTPS." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "Porta HTTPS" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Se estiver vazio, a porta padrão só irá funcionar com HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "Certificado HTTPS" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Nome do arquivo ou caminho para o certificado HTTPS." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "Chave HTTPS" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Nome do arquivo ou caminho para a chave HTTPS." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "Cadeia de Certificados HTTPS" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Nome de arquivo ou caminho da Cadeia HTTPS." #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Ajustes finos" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Intervalo de atualização da fila:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Intervalo de atualização da página da interface web da fila (em segundos, 0 " "= nenhum)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "Intervalo de verificação de RSS" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Intervalo de verificação (em minutos, ao menos 15). Inativo quando você usar " "o Agendador!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Limite de Velocidade de Download" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Limite da taxa de download (em KB/s - quilobytes por segundo)." #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Limite de Cache de Artigos" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Manter artigos em memória para reduzir o acesso a disco.
    Em bytes, " "opcionalmente seguido de K,M,G. Por exemplo: \"64M\" ou \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Lista de Limpeza" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista de extensões dos arquivos que devem ser excluídos após o download.
    Por exemplo: .nfo ou então .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Salvar Alterações" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Idioma" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Selecione um idioma para a interface web." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "Chave API" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Esta chave dará a programas de terceiros pleno acesso ao SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "Chave NZB" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Esta chave permitirá que programas de terceiros adicionem NZBs ao SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Gerar Nova Chave" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Desabilitar Chave API" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Não requer a chave API." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "USE POR SUA CONTA E RISCO!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "QR Code" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "API Key QR Code" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Configuração de pasta" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTA: Pastas serão criadas automaticamente ao salvar. Você pode " "usar caminhos absolutos para salvar fora das pastas padrão." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Usar Pastas" #: sabnzbd/skintext.py:345 msgid "In" msgstr "Em" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Pasta Temporária de Downloads" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Local para armazenar downloads não processados.
    Só pode ser alterado " "quando a fila estiver vazia." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Espaço livre mínimo para a pasta temporária de downloads" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Pausar automaticamente quando o espaço livre estiver abaixo deste valor.
    Em bytes, opcionalmente seguido de K,M,G,T. Por exemplo: \"800M\" ou " "\"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Pasta de Downloads Concluídos" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Local para armazenar downloads concluídos, totalmente processados​​.
    Pode ser anulado por categorias definidas pelo usuário." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Permissões para downloads concluídos" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Definir padrão de permissões para arquivos/pastas concluídos.
    Em " "notação octal. Por exemplo: \"755\" ou \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Pasta de Assistidos" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Pasta para monitorar por arquivos .nzb.
    Também procura arquivos .nzb " "em arquivos .zip, .rar e .tar.gz." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Velocidade de Varredura na Pasta de Assistidos" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Quantidade de segundos entre as varreduras de arquivos .nzb." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Pasta de Arquivos de Pós-Processamento" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Pasta contendo scripts de usuário para pós-processamento" #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Pasta de Modelos de E-mail" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Pasta contendo modelos de e-mail definidos pelo usuário" #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Arquivo de senhas" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Arquivo contendo todas as senhas que serão testadas em arquivos RAR " "criptografados." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Pastas de Sistema" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Pasta Administrativa" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Localização do banco de dados de histórico e administrador de fila.
    Só pode ser alterado quando a fila estiver vazia." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Dados não serão movidos. Será necessário reiniciar o SABnzbd!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Pasta de Log" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Local dos arquivos de log do SABnzbd.
    Será necessário reiniciar o " "SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Pasta de Backup de .nzb" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Local onde os arquivos .nzb serão armazenados." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Pasta Inicial Padrão" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Configuração de opções" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Opções de Processamento" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Habilitar Verificação Rápida" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Pular verificação par2 quando os arquivos forem 100% válidos." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Habilitar Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Habilitar funcionalidade unrar interna" #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Habilitar Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Habilitar funcionalidade unzip interna" #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Habilitar Filejoin" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Unir arquivos terminando em .001, .002, etc. em um arquivo." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Habilitar União TS" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "Unir arquivos terminando em .001.ts, .002.ts, etc. em um arquivo." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Habilitar Limpeza de Par" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Limpar arquivos par (se a verificação/reparo for bem sucedida)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Falhar em erros CRC yEnc" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "" "Quando o artigo possuir um erro de CRC, tentar obtê-lo de outro servidor." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Apenas Obter Artigos para o Topo da Fila" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Ative para menor uso de memória. Desative para impedir que trabalhos lentos " "bloqueiem a fila." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Pós-processar apenas os trabalhos verificados" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Realizar pós-processamento apenas em trabalhos que passaram todas as " "verificações PAR2." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "Ação quando RAR criptografado é baixado" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" "Em caso de \"Pausa\", você precisa definir uma senha e retomar a tarefa." #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Detectar Downloads Duplicados" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Detectar arquivos NZB com nomes idênticos (requer opção de backup de NZB) e " "duplicar títulos através de feeds RSS." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Desligado" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Descartar" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "Cancelar" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Habilitar verificações baseadas em SFV" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Fazer uma verificação extra baseada em arquivos SFV." #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Verificar o resultado da descompactação" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Verificar o resultado da descompactação (precisa ficar desativado em alguns " "sistemas de arquivos)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Habilitar renomeação de pasta" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Usar nomes temporários durante o pós-processamento. Desative quando seu " "sistema não lidar com isso corretamente." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Pós-processamento Padrão" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "" "Usado quando nenhum pós-processamento estiver definido pela categoria." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Script de usuário padrão" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Usado quando nenhum script de usuário é definido pela categoria." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Script de usuário de pré-fila" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Utilizado antes de um NZB entrar na fila." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Prioridade Padrão" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Utilizado quando nenhuma prioridade é definida pela categoria." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Habilitar MultiCore Par2" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Leia a sessão ajuda no Wiki sobre isso!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Parâmetros Extras PAR2" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Parâmetros Nice" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "Parâmetros IONice" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Outras Opções" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Desconecte quando fila vazia" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Desconecte do(s) servidor(es) Usenet quando a fila estiver vazia ou pausada." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Enviar Grupo" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Enviar comando do grupo antes de solicitar artigos." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Ordernar por Idade" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Classificar automaticamente os itens por (média de) idade." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Procurar por nova versão" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Checar semanalmente por nova versão do SABnzbd." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Também versões de testes" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Substituir espaços no nome da pasta" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Substituir espaços por sublinhado no nome das pastas." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Substituir pontos no nome da pasta" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Substituir pontos por espaços no nome da pasta." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Substituir caracteres inválidos em nomes de pastas" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Substituir caracteres inválidos em nomes de pastas por equivalentes (caso " "contrário, removê-los)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Abrir navegador ao iniciar" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Abrir o navegador padrão ao iniciar o SABnzbd." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Pausar o download durante o pós-processamento." #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Pausar o download no início do pós-processamento e retomar quando concluído." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignorar amostras" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Exclui arquivos de amostra. Exemplo: amostras de vídeo." #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Excluir após download" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Não baixar" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "Tipo SSL" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Utilize V23 a não ser que o seu provedor exija outro!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Utilizar relógio com 12 horas (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Exibir horas na notação AM/PM (não afeta o agendador)." #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Servidor" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Pós-processamento" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Nomeando" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Quota" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Quanto pode ser baixado neste mês (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Primeiro dia do ciclo" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "Em que dia do mês ou da semana (1 = segunda-feira) seu provedor de Internet " "redefine sua quota? (Opcionalmente com hh: mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Retomar automaticamente" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "O download deve retomar quando a quota for restabelecida?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Período da quota" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "A quota é restabelecida a cada dia, semana ou mês?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Verifique antes de baixar" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Tentar prever a conclusão bem sucedida de um futuro download? (lento!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Máximo de tentativas" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Número máximo de tentativas por servidor." #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Apenas para servidores opcionais" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Aplicar o máximo de tentativas somente com servidores opcionais" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "Cancela tarefas que não podem ser concluídas" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" "Quando durante o download ficar claro que muitos dados estão faltando, " "cancela a tarefa" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Configurações do servidor" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Definições do servidor" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Adicionar Servidor" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Porta" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Usuário" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Senha" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Tempo limite" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Tempo de retenção" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Servidor backup" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Opcional" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Habilitar" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Remover servidor" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Testar Servidor" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Limpar Contadores" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testando detalhes do servidor..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Clique abaixo para testar." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Largura de banda" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Configuração de agendamentos" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Adicionar Agendamento" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Remover" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Agendamentos Atuais" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "Configuração de RSS" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Nova URL de Feed" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "A caixa de seleção ao lado do nome do feed deve ser assinalada para que o " "feed seja ativado e automaticamente verificado por novos itens.
    Quando " "um feed é adicionado, ele só vai pegar novos itens e não algo que já esteja " "no feed RSS a menos que você pressione \"Forçar Download\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Adicionar Feed" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Remover Feed" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Ler Feed" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Forçar Download" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filtro" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Pular" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Aceitar" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Recusar" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Requer" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "RequiresCat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Não Encontrado" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Feeds" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Ler Todos os Feeds Agora" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Configurações" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtros" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Opções de e-mail" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Notificar por e-mail na conclusão da tarefa" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Nunca" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Sempre" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Somente para erros" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Notificações de Disco Cheio" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "" "Enviar e-mail quando o disco estiver cheio e SABnzbd estiver pausado." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Enviar notificações RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Enviar e-mail quando um feed RSS adicionar tarefas à fila." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Configurações da Conta de E-mail" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "Servidor SMTP" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Define o servidor para envio de e-mails." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Destinatário do E-mail" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Endereço de e-mail para receber os e-mails." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "E-mail do Remetente" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Quem devemos dizer que enviou o e-mail?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "Nome de usuário OPCIONAL da conta" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Nome da conta, para e-mails com autenticação." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "Senha OPCIONAL da conta" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Senha, para e-mails com autenticação." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Habilitar Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Enviar notificações ao Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Endereço do servidor" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Utilize apenas para servidor remoto Growl (host: porta)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Senha do servidor" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Senha opcional para o servidor Growl" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Habilitar NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Enviar as notificações a NotifyOSD." #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Centro de Notificações" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Envia notificações para o Centro de Notificações" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Classes de notificação" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Habilita classes de mensagens a serem relatadas (nenhuma, uma, ou múltiplas)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Se você já possui uma conta em www.newzbin2.es, introduza " "as informações necessárias.
    Isto permitirá o uso de funcionalidades " "adicionais." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Informações da conta" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Usuário Newzbin" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Digite seu nome de usuário aqui." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Senha Newzbin" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Digite sua senha aqui." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Processamento dos favoritos" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Obtenção automática dos favoritos" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Download automático dos favoritos." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Recuperar os favoritos agora" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Ocultar Favoritos" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Mostrar favoritos" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Eliminar o favorito se o download estiver concluido" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Eliminar da lista de favoritos quando o download estiver concluido." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Intervalo entre as verificações" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "Em minutos (pelo menos 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Favoritos processados" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Se você já possui uma conta em www.nzbmatrix.com, introduza " "as informações necessárias.
    Isso é necessário se você quiser usar os " "feeds RSS deste site." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Usuário NzbMatrix" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "Chave API do NzbMatrix" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Digite a chave API do NzbMatrix aqui." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Categorias do usuário" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Define os métodos de pós-processamento e de armazenamento." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Use a coluna “Indexador Grupos/Etiquetas” para classificar os grupos e as " "etiquetas em funçao de suas categorias
    Os caracteres curinga são " "permitidos. Separe os termos por vírgulas." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Para evitar a criação de pastas de trabalho, adicione um asterisco (*) " "depois do caminho." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Caminho base das pastas relativas" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Pasta/Caminho" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Indexador Grupos/Etiquetas" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Configuração de classificação" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Ordenação de Séries" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Ativar a ordenação de TV" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Ativa a ordenação e renomeação de episódios." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Modelo do padrão" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Limpar" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Predefinições" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Exemplo" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Ordenação genérica" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Ativar a ordenação de filmes" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Ativar a ordenação e a renomeação genérica dos Filmes" #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Manter em pastas separadas os downloads soltos" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Ativar se os downloads não são colocados em suas próprias pastas." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Categorias Afetadas" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Significado" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Modelo" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Resultado" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Pasta Da Temporada" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Pasta Da Temporada" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Pasta Do Episódio" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Pasta Do Episódio" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Tí­tulo" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Nome Filme" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Nome.Filme" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Nome_Filme" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Nome do Show" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Nome.do.Show" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Nome_do_Show" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Número da Temporada" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Número do Episódio" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Nome do Episódio" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Nome.Episódio" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Nome_Episódio" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Extensão do arquivo" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Extensão" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Número do Episódio" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Década" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Nome do arquivo original" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Nome da pasta original" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Minúsculas" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEXTO" #: sabnzbd/skintext.py:667 msgid "text" msgstr "texto" #: sabnzbd/skintext.py:668 msgid "file" msgstr "arquivo" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "pasta" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "String de ordenação" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Rótulo multi-parte" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "Em pastas" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Sem pastas" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Ordenação por data" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Ativar a ordenação por data" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Ativar classificação e renomeação de arquivos nomeados com datas." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Pasta do Nome do Show" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Pastas Ano-Mês" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Pastas Diárias" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "ajuste de maiúsculas" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Resultado Processado" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Opções raramente utilizadas. Para seu significado e explicação, clique no " "botão Ajuda para ir para a página Wiki.
    Não altere estas sem checar o " "Wiki em primeiro lugar, já que algumas têm sérios efeitos colaterais.
    Os " "valores padrão estão entre parênteses." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Valores" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Editar Detalhes do NZB" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Eliminar" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Topo" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Para cima" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Para baixo" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Base" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Todos" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Inverter" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Nome do arquivo" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Assunto" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Idade" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Seleção" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Você tem certeza que quer apagar?" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Atualizar" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Opções" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Página" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Ant" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Próx" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Primeira" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Última" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Fechar" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Definir Intervalo de Pausa" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Ordenar" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Limpar a fila?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Intervalo de Pausa" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pausar por 5 minutos" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pausar por 15 minutos" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pausar por 30 minutos" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pausar por 1 hora" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pausar por 3 horas" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pausar por 6 horas" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pausar por 12 horas" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pausar por 24 horas" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Ordenar por Idade Mais antigo→Mais novo" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Ordenar por Idade Mais novo→Mais antigo" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Ordenar por Nome A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Ordenar por Nome Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Ordenar por Tamanho Menor→Maior" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Ordenar por Tamanho Maior→Menor" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Renomear" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Restantes" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Limpar o Histórico?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "As alterações não foram salvas e serão perdidas." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Abrir URL de Origem" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Abrir URL Informativa" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Armazenamento" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Exibir Log do Script" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Você deve habilitar o JavaScript para Plush funcionar!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Adicionar NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Opções Plush" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Atualização Disponível!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Pausar por quantos minutos?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pausar por..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Multi-Operações" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Menu Superior" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Ao Concluir" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Ordenar por Idade (Mais antigo→Mais novo)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Ordenar por Idade (Mais novo→Mais antigo)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Ordenar por Nome (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Ordenar por Nome (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Ordenar por Tamanho (Menor→Maior)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Ordenar por Tamanho (Maior→Menor)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Eliminar" #: sabnzbd/skintext.py:781 msgid "left" msgstr "restantes" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Velocidade Máx" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Intervalo" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Reiniciar" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Aplicar aos Selecionados" #: sabnzbd/skintext.py:786 msgid "page" msgstr "página" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Tudo" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Desativado" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Taxa de Atualização" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Largura do Contêiner" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Confirmar Exclusões da Fila" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Confirmar Exclusões do Histórico" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Isso irá impedir que o conteúdo seja atualizado quando o cursor do mouse " "estiver sobre a fila." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Impedir Atualizações no Foco" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Obter" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Enviar" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Enviar: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Opcionalmente, especifique um nome de arquivo" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Progresso" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Não há espaço em disco suficiente para completar os downloads!" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Espaço Disponível" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Disponível (Temporário)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "OCIOSO" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Downloads" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Reparação da fila" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Ler Feed vai pegar o conteúdo do feed atual. Forçar " "Download irá baixar todos os NZBs correspondentes agora." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Hora:Min" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Exclusão Concluída" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Excluir do histórico todos os itens com falha?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Falha na Exclusão" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Atalhos" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Mostrando %s a %s de %s resultados" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Sem resultados" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Mostrando um resultado" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Email Enviado!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Notificação Enviada!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Salvando..." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Salvo" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Velocidade" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Alternar Adição de NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "DualView1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "DualView2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Personalizado" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Obter Favoritos" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Tem certeza que deseja reiniciar o SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Taxa de atualização" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Excluir Todos" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Ocultar Opções de Edição" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Mostrar Opções de Edição" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Editar" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Tempo restante" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "Assistente de Início Rápido do SABnzbd" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "Versão do SABnzbd" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Anterior" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Acesso" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Quero que o SABnzbd seja acessado de qualquer computador em minha rede." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Quero que o SABnzbd seja acessado somente pelo meu computador." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Proteger o acesso ao SABnzbd com senha (recomendado)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Habilitar acesso HTTPS ao SABnzbd." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Diversos" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "" "Abrir meu navegador de internet com a página do SABnzbd quando o programa " "for iniciado." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Detalhes do Servidor" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Por favor insira os detalhes de seu provedor de usenet primário." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Para baixar a partir da usenet você precisa ter acesso a um provedor. Seu " "provedor de Internet pode fornecer-lhe acesso, no entanto, um provedor " "exclusivo é recomendado." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Não tem um provedor usenet? Recomendamos testar %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "O número de conexões permitidas por seu provedor" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "Ex: 8 ou 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Selecione somente se seu provedor permitir conexões SSL." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Clique para testar os detalhes informados." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Este campo é necessário." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Por favor insira um número inteiro." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Se você é um membro de newzbin ou nzbmatrix, você pode digitar seu nome de " "usuário e senha aqui para que possamos buscar nzbs deles. Esta etapa pode " "ser pulada se você não usar nenhum desses serviços." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Fazer download automaticamente de mensagens favoritas." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Ex." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Reiniciando SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "A configuração está completa!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd agora será executado em segundo plano." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Fechar qualquer janela/aba do navegador NÃO vai fechar o SABnzbd." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Após o SABnzbd ter reiniciado você será capaz de acessá-lo no seguinte " "local: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Recomenda-se que você adicione este local como favorito para acessar o " "SABnzbd quando ele estiver sendo executado em segundo plano." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Mais ajuda pode ser encontrada em nosso" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Ir para o SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Primeiro Passo" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Segundo Passo" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Terceiro Passo" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Quarto Passo" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Quinto Passo" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "Ex. 119 ou 563 para SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Sair do SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Iniciar o Assistente" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd não possui QUALQUER GARANTIA.\n" "É software livre, e você está convidado a redistribuí-lo sob certas " "condições.\n" "Está licenciado sob a LICENÇA PÚBLICA GERAL GNU Versão 2 ou (a seu critério) " "qualquer versão posterior.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Erro ao obter informações de TV (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Falha ao renomear: %s para %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Falha ao renomear arquivo similar: %s para %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Número de registro nzbmatrix %s inválido" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Você precisa de uma conta VIP nzbmatrix para usar a API" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Credenciais nzbmatrix inválidas" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Problema ao acessar o servidor nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "O nome do host não foi definido." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "Não há conexões definidas. Por favor, defina pelo menos uma conexão." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Senha mascarada em ******, digite novamente" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Detalhes inválidos do servidor" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "Tempo esgotado: Tente habilitar o SSL ou conectar em uma porta diferente." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Tempo esgotado" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Endereço do servidor inválido." #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Servidor parou durante a sequência de login." #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Servidor requer usuário e senha." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Conexão com Sucesso!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Falha de autenticação, verifique usuário / senha." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Excesso de conexões, por favor pause o download ou tente novamente mais tarde" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Não foi possível determinar o resultado da conexão (%s)" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Erro ao obter msgid %s de www.newzbin.com - Verifique se o seu nome de " #~ "usuário e senha estão definidos" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "obtendo msgid %s de www.newzbin.com" #~ msgid "Expected size did not equal actual size" #~ msgstr "O tamanho esperado não é igual ao tamanho real" #~ msgid "Could not compile regex: %s" #~ msgstr "Não foi possível compilar a expressão regular: %s" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Você precisa definir uma senha e retomar a tarefa." #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "" #~ "Interromper tarefa quando arquivos RAR criptografados forem baixados" SABnzbd-0.7.20/po/main/ro.po0000644000000000000000000037133612433712564015573 0ustar00usergroup00000000000000# Romanian translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2012-10-13 17:23+0000\n" "Last-Translator: nicusor \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:54+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Pornirea interfetei-web nereusitã" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Nu se poate gãsi sablon web:%s, se încearcã sablon standard" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "modulul _yenc ... Negãsit!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "binar par2 ... Negãsit!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "binar unrar... Negãsit!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "binar unzip... Negãsit!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Vã rugãm sã fiti constienti cã numele gazdei 0.0.0.0 va avea nevoie de o " "adresa IPv6 pentru acces extern" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Dezactiveazã HTTPS din cauza lipsei fisierelor CERT si KEY" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s pornit" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "Închidere SABnzbd terminatã" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Semnal %s prins, salvez si ies..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "descarc msgid %s from www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Eroare descãrcare msgid %s de la www.newzbin2.es - Vã rugãm asigurati-vã cã " "Nume de Utilizator si Parolã sunt setate" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Încerc sã descarc NZB de la %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Nu pot crea fisier temporar pentru %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Încerc sã setez starea unui server nexistent %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Prea putin spatiu disc fortez PAUZÃ" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Eroare în tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Salvarea %s nereusitã" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Încãrcarea %s nereusitã" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Notificãri Test" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Niciunul" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Implicit" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "ATENTIE:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "EROARE:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "necunoscut" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Compilarea unei cãutãri regex nereusitã: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disc plin! Pauzã Fortatã" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Eroare disc la crearea fisierului %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "" "ATENTIE: Sarcina \"%s\" întreruptã din cauza fisierelor RAR encriptate" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "" "ATENTIE: Sarcinã \"%s\" abandonatã deoarce contine un fisier RAR ecriptat" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Terminat, encriptare detectatã" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s lipsã" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Cotã epuizatã, întrerupem descãrcarea" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s nu este o adresã email validã" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Adresã server necesarã" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Nu pot crea %s dosar %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Nu pot scrie în fisierul INI %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Nu pot crea copie de rezervã pentru %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Parolã %s codificatã gresit" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s nu este o valoare octalã corectã" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "cale UNC \"%s\" nu este premisã aici" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Eroare: Coada nu este goalã, nu pot schimba dosar." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Dosarul \"%s\" nu existã" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "Comandã SQL Nereusitã, vedeti jurnal" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "Modificare SQL Nereusitã, vedeti jurnal" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Închidere bazã de date nereusitã, vedeti jurnal" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Jurnal istoric stagii invalid pentru %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Decodarea %s nereusitã" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "Eroare CRC în %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Articoul yEnc invalid în %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Eroare Necunoscutã în timpul decodãrii %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => lipsã de pe toate serverele, ignorare" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Eroare stergere %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Nu pot citi %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Nu pot citi Dosar Urnãrire %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Întrerupt" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Serverul %s va fi ignorat pentru %s minute" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Initializare nereusitã %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Prea multe conexiuni cãtre serverul %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Partajare cont probabilã" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Autentificare nereusitã la serverul %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Nu mã pot conecta la serverul %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Conectarea %s@%s:%s nereusitã, mesajul=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Serverul %s necesitã utilizator/parolã" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Închidere" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Conectare server mail nereusitã" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Initializare conexiune TLS nereusitã" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Autentificare server mail nereusitã" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Trimitere email nereusiã" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Închidere conexiune mail nereusitã" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Email reusit" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Nu pot gasi sabloane email în %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Destinatar necunoscut, niciun email trimis" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Codificare invalidã a sablonului email %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Sabloane email negãsite" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "From: %s\n" "To: %s\n" "Date: %s\n" "Subject: SABnzbd raporteaza Disc Plin\n" "\n" "Salut,\n" "\n" "SABnzbd sa oprit din descarcare, deoarece discul este aproape plin.\n" "Va rugam sa faceti loc si reluati SABnzbd manual.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Pornire/Închidere" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "NZB-uri Adãugate" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Post-procesare pornitã" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Sarcinã terminatã" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Alte Mesaje" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Atentie:LOCALHOST este ambiguu, folositi o adresã IP numericã" #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Adresa server \"%s:%s\" nu este validã" #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Cheie Sesiune lipsã" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Eroare: Cheie Sesiune Necesarã" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Eroare: Cheie Sesiune Incorectã" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "Cheie API lipsã, vã rugãm sã introduceti cheia api de la Configurare-" ">General în programul dumneavoastrã tert" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Cheie API incorectã, Folositi cheia api din Configurare->General în " "programul dumneavoastrã tert:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Autentificare lipsã, vã rugãm sã introduceti numele de utilizator/parola de " "la Configurare->General în programul dumneavoastrã tert:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Eroare: Nici o interfatã secundarã definitã." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Versiunea dvs. UNRAR nu este recomandatã, luati-o de la " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Nici un program UNRAR gãsit, dezarhivarea fisierelor RAR imposibilã
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Nici un program PAR2 gãsit, repararea imposibilã
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Initializare repornire...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    Închidere SABnzbd terminatã.
    Asteptati timp de aproximativ 5 " "secunde si apoi faceti clic pe butonul de mai jos.

    Reîmprospãteazã
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Flux" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Zilnic" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Luni" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Marti" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Miercuri" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Joi" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Vineri" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Sâmbãtã" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Duminicã" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "dezactivat" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Reolvare adresã" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Parametru Incorect" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Înapoi" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Sarcina \"%s\" a fost re-adãugatã în coadã" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Sarcinile selectate cu '*' vor fi descãrcate automat" #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Potrivite" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Nepotrivite" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Descãrcate" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Decãrcat pânã acum" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Valoare incorectã pentru %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Nu pot crea dosarul %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "dosarul %s: eroare accesare %s" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Nu mã pot conecta la registru HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Nu pot deschide cheie registru \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Citire valoare registru pentru dosare speciale nereusitã" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Facere nereusitã (%s)" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Mutare %s în %s nereusitã" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Fisier NZB Inutilizabil" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Încercati din nou" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Descãrcare URL nereusitã; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "modul pyopenssl lipsã, instalati-l pentru acces https" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Eroare la crearea cheiei si certificatlui SSL" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Nu pot schimba permisiunile lui %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Unim" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Secventã incompletã de unire fisiere" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Unirea fisierului %s nereusitã" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Eroare \"%s\" în timpul unirii fisierelor" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Eroare \"%s\" în timpul file_join a %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Unit %s fisierele" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Dezarhivare nereusitã, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Eroare \"%s\" în timpul dezarhivãrii fisierelor RAR" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Eroare \"%s\" în timpul rar_unpack a %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Stergere %s nereusitã!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Încerc unrar cu parola \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Dezarhivare nereusitã, arhiva necesitã o parolã" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Dezarhivare" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Dezarhivare nereusitã, nu pot gãsi %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "EROARE: nu pot gãsi \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Dezarhivare nereusitã, eroare CRC" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "EROARE: CRC nereusit în \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Dezarhivare nereusitã, eroare scriere sau disc plin?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "EROARE: eroare scriere (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Dezarhivare nereusitã, vezi jurnal" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "EROARE: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Fisiere asteptate lipsã: %s => eroare unrar?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Dezarhivare nereusitã, un fisier asteptat nu a fost dezarhivat" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Dezarhivare nereusitã, acest(e) fisier(e) sunt lipsã:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Dezarhivat %s fisierele/dosarele în %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s fisiere în %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Eroare \"%s\" în timpul rulãrii unzip() pe %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Verificare Rapidã" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Reparã" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Verficare Rapidã OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Pornire Reparare" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparare nereusitã, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Eroare %s în timpul rulãrii par2_repair pe setul %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Eroare \"%s\" în timpul rulãrii par2_repair pe setul %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 a primit optiuni incorecte, verificã setãrile Configurare-" ">Comutatoare" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificat în %s, toate fisierele sunt corecte" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificat în %s, reparare necesarã" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Pachet principal negãsit..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Fisier par2 invalid, nu pot verifica sau repara" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparare nereusitã, blocuri reparare insuficiente (%s mai putin)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Descãrcare %s blocuri..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Descãrcare" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Se reparã" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Reparat în %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Se verificã" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Eroare importare modul OpenSSL . Se conecteazã folosind NON-SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Actualizare sarcinã %s nereusitã" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB adãugat în coadã" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Serverul Newzbin si-a schimbat protocolul" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Nu aveti credit în contul dvs. Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "" "Neautorizat, verificati numele de utilizator/parola dvs. de la newzbin" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin raporteazã ca nu a fost gãsit %s" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin a dat o eroare nedocumentatã (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Serverul Newzbin nu poate da informatii pentru %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Nu am putut sterge semnul de carte newzbin %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin a dat o eroare nedocumentatã (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Fisier coadã gãsit incompatibil, nu pot înainta" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Eroare încãrcare %s, fisier corupt detectat" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Eroare adãugare %s, stergem" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Codificare Necunoscutã" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Fisierul %s este gol , ignorãm" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Importare %s a fisierelor de la %s nereusitã" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Fisier NZB incomplet %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Fisier NZB invalid %s, ignorãm (motiv=%s, line=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Fisier NZB gol %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorãm duplicat NZB \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Întrerupem duplicat NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLICAT" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "ENCRIPTAT" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "PREA MARE" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "INCOMPLET" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "ASTEAPTÃ %s sec" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Descãrcat în %s cu o medie de %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s articolele au fost incorecte" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s articolele au fost lipsã" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s articolele au avut duplicate diferite" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Eroare importare %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Atentionãri" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Inactiv" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Configurare" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Coadã" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Goleste Coadã" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Istoric" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Sterge Istoricul" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Limitare de Vitezã" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pauzã" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Reia" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Descarcã Semne de Carte Newzbin" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Scaneazã dosar urmãrire" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Dosar Complet" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Dosar Incomplet" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Depanare" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Reporneste" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Reporneste fãrã autorizare" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Iesire" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Pune la Coadã Primele 10 Obiecte" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Gol" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Istoric Ultimele 10 Obiecte" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Versiune nouã disponibilã" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Dute la vrãjitor" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Se opreste..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problemã cu" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nu este compatibil cu unele programe firewall
    \n" " %s
    \n" " Ne pare rãu, dar noi nu putem rezolva aceastã incompatibilitate " "acum.
    \n" " Vã rugãm sã vã plângeti producãtorului dvs. de firewall.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd are nevoie de un tcp/ip port liber pentru serverul sãu " "intern.
    \n" " Portul %s de pe %s a fost încercat , dar nu este disponibil.
    \n" " Alt program foloseste portul sau SABnzbd este deja pornit.
    \n" "
    \n" " Vã rugãm sã reporniti SABnzbd cu un numãr de port diferit." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "" "Dacã primiti acest mesaj de eroare din nou, vã rugãm sã încercati un alt " "numãr.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd are nevoie de un port tcp/ip liber pentru serverul sãu " "intern.
    \n" " Portul %s de pe %s a fost încercat , dar contul folosit de SABnzbd nu " "are permisiunea de a-l folosi.
    \n" " În sisteme OSX si Linux , utilizatori normali trebuie sã foloseascã " "porturi peste 1023.
    \n" "
    \n" " Vã rugãm sã reporniti SABnzbd cu un numãr de port diferit." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd are nevoie de o adresã gazdã validã pentru serverul sãu " "intern.
    \n" " Dvs. a-ti specificat o adresã invalidã.
    \n" " Valori sigure sunt localhost si 0.0.0.0
    \n" "
    \n" " Vã rugãm sã reporniti SABnzbd cu o adresã gazdã bunã." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd a detectat informatii salvate de la o altã versiune SABnzbd
    \n" " dar nu poate sã refoloseascã informatiile de la cealaltã versiune de " "program.

    \n" " Ar fi bine sã terminati coada mai întâi cu cealaltã versiune de " "program.

    \n" " Dupã aceia , porniti programul cu optiunea \"--clean\".
    \n" " Aceasta va sterge coada curentã si istoricul!
    \n" " SABnzbd citeste fisierul \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nu poate gãsi fisierele de la interfata-web %s.
    \n" " Vã rugãm sã reinstalati programul din nou.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd a detectat o eroare fatalã:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd a detectat o Coadã si Istoric de la o versiune veche " "(0.4.x).

    \n" " Atât coada si istoricul vor fi ignorate si s-ar putea pierde!

    \n" " Puteti sã opriti SABnzbd si sã terminati coada cu cealaltã versiune de " "program.

    \n" " Clic OK pentru a porni SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd a detectat cã fisierul sqlite3.dll lipseste.

    \n" " Unele antivirusuri sterg acest fisier.
    \n" " Vã rugãm sã verificati antivirusul , încercati sã reinstalati SABnzbd si " "plângetivã autorului antivirusului.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Apasã Start+R si scrie linia (exemplu):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Deschide fereastra Terminal si scrie linia (exemplu):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Este posibil cã folositi ZoneAlarm în Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Aplicatia nu a pornit!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Nu ai permisiunea sã folosesti acest port %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Eroare fatalã" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Nu pot porni navigatorul web, probabil nu a fost gãsit" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Acces interzis" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Eroare %s: Trebuie sã furnizati un nume utilizator si parolã valid" #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Încãrcare coadã post-procesare nereusitã : Versiune gresitã (am nevoie " "de:%s, gãsit:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Stergere nzo din coadã post-procesare nereusitã (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "Descãrcarea ar putea esua, doar %s din %s disponibil" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Descãrcare nereusitã - Retentie server depãsitã ?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Nu pot crea dosar final %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Nici o post-procesare din cauza verificãrii nereusite" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Mutare" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Trimis %s în coadã" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Eroare redenumire \"%s\" în \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Nu am putu muta fisier" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Rulare script" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Rulare script utilizator %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Duratã %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Mai mult" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Vezi rezultat script" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Descãrcare terminatã" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Descãrcarea a esuat" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Post Procesare Nereusitã pentru %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "vezi fisier jurnal" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Post-Procesarea a fost abandonatã (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Stergerea lui %s nereusitã." #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Eroare stergere dosar curent (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Post-procesare" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Niciun set par2" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Încerc verificare SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Unele fisiere nu au fost verificate corect cu \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Verificare reusitã cu fisierele SFV" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Stergerea %s nereusitã" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Punere sistem în hibernare nereusitã" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Punere sistem în asteptare nereusitã" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Eroare la oprirea sistemului" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Descriere flux RSS incorectã \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Descãrcare %s: %s din RSS nereusitã" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Autentificare invalida pentru flux %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "Fluxul RSS %s a fost gol" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Fulx RSS incompatibil" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Valoare RSS gasitã a fost goalã (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Aratã interfata" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Deschide dosar descãrcãri complete" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Închidere" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Rãmas" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Programator Gresit %s la %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Actiune necunoscutã: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Planificare pentru un server inexistent %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Descarcã" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Uneste fisierele" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Dezarhiveazã" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Script" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Sursã" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Nereusit" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Finalizat" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Nereusit" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Se asteaptã" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparare..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Dezarhivare..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Mutare..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Rulare script..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Descãrcare blocuri extra..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Verificare Rapidã..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Verificare..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Descãrcare" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Descarcã NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Se verificã" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Frecventã" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Actiune" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argumente" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Sarcinã" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "dezactiveazã server" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "activeazã server" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Limitare de Vitezã" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Pauzã Toate" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pauzã post-procesare" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Reia post-procesare" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Citeste fluxuri RSS" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Eliminã sarcini nereusite" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "orã" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "ore" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "min" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minute" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sec" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "secunde" #: sabnzbd/skintext.py:79 msgid "day" msgstr "zi" #: sabnzbd/skintext.py:80 msgid "days" msgstr "zile" #: sabnzbd/skintext.py:81 msgid "week" msgstr "sãptãmânã" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Lunã" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "An" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Zi din lunã" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Sãptãmâna aceasta" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Luna aceasta" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Azi" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Total" #: sabnzbd/skintext.py:97 msgid "on" msgstr "activat" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametrii" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Versiune Python" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Paginã de pornire" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "sau" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Gazdã" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Instrumentul de descãrcare automatã usenet" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Salveazã" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Pus în coadã" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Sunteti sigur?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Stergeti toate fisierele descãrcate?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Pagina de pornire" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Configurare" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Stare" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Ajutor" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "General" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Directoare" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Comutatoare" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Servere" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Planificare" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Notificãri" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Email" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Situri Index" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Categorii" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortare" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Special" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Dosar Descãrcare" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Dosar Complete" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Vitezã de descãrcare" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "ÎNTRERUPT" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "Articole %s în cache (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Încãrcare sistem" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "AVERTIZÃRI" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Versiune nouã %s disponibilã la" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Adaugã descãrcãri noi" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Sunteti sigur cã doriti sã inchideti SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Adaugã" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Report-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Adaugã fisier" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Categorie" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "În curs de procesare" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioritate" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparare" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Dezarhivare" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Stergere" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "U" #: sabnzbd/skintext.py:177 msgid "D" msgstr "D" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Forteazã" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Ridicatã" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Scãzutã" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stop" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Introdu URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " sau Report ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Sorteazã dupã nume" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Sorteazã dupã vârstã" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Sorteazã dupã mãrime" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Ascunde fisiere" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Aratã fisiere" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "La terminarea coadei de descãrcare" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Închide PC" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Repaus PC" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Hibernare PC" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Închide SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Limitã de Vitezã" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pauzã timp de" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Ordine" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nume" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Rãmas/Total" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Timp Estimat" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "Vârstã" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Sterge" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Reîncearcã" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Actiuni" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Script-uri" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Stergeti toate obiectele din coadã?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Sterge NZB-uri" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Sterge NZB-uri & Fisiere Sterse" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Sterge NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Sterge NZB & Fisiere Sterse" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "din" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Articole lipsã" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Cotã rãmasã" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "manual" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Reseteazã Cota acum" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Goleste Istoric Descãrcãri Nereusite" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Stergeti toate obiectele complete din Istoric?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Stergeti toate obiectele nereusite din Istoric?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Ascunde detaliile" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Aratã detalii" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Mãrime Istoric" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Aratã Nereusite" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Aratã toate" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Mãrime" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Sterge NZB-uri nereusite" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Sterge NZB-uri Nereusite & Fisiere Sterse" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Sterge NZB-uri Complete" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "NZB Suplimentar Optional" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Cale" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Forteazã Deconectarea" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Acesta va trimite un email test cãtre contul dvs." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Aratã Jurnalizarea" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Aratã Jurnal Web" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Email Test" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Jurnalizare" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Erori/Avertismente" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Depanare" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Conexiuni" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Proces" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Rezultat Test Email" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Ultimele Avertizãri" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "Sterge" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Deblocheazã" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Identificator Articol" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Set fisiere" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Când" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Tip" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Avertisment" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Activat" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Fisier Configurare" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Cache Folosit" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Acest lucru va reporni SABnzbd.
    Folositi-l atunci când credeti cã " "programul are o problemã de stabilitate.
    Descãrcarea va fi opritã " "înainte de repornire si reluatã ulterior." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Sunt sarcini orfane în dosarul de descãrcare.
    Puteti alege în a le " "sterge (inclusiv fisierele) sau a le trimite înapoi în coadã." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "Butonul \"Reparare\" va reporni SABnzbd si face o reconstructie completã
    a continutului coadei de descãrcare , mentinând fisierele deja " "descãrcate.
    Acest lucru va modifica ordinea în coada de descãrcare." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Versiune" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Durata Functionãrii" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Server Secundar" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Configuratie Generalã" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Modificãrile vor necesita repornirea SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Server Web SABnzbd" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Gazdã SABnzbd" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Nume Gazdã unde SABnzbd va asculta." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Portul pe care SABnzbd îl va asculta." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Interfatã Web" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Alege o temã." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Interfatã Web Secundarã" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Activeazã o temã alternativã." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Autentificare server web" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Nume Utilizator SABnzbd" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Nume Utilizator autentificare optional" #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Parolã SABnzbd" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Parolã autentificare optionalã" #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "Suport HTTPS" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Activeazã HTTPS" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "neinstalat" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Permite acesarea interfetei de la o adresã HTTPS." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Dacã e gol, portul standard va asculta doar în HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "Certificat HTTPS" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Nume fisier sau cale Certificat HTTPS." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "Cheie HTTPS" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Nume fisier sau cale Cheie HTTPS." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "Certificate Cheie HTTPS" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Nume fisier sau cale cheie HTTPS." #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Optimizãri" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Interval reîmprospãtare automatã coadã:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Interval reîmprospãtare a coadei din pagina interfetei web(sec, 0= niciunul)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "Interval Verficare RSS" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Interval verificare (în minute, cel putin 15). Inactiv când se foloseste " "Planificatorul!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Limitã de Vitezã Descãrcare" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Limitã Ratã de Descãrcare ( în KB/s - kilo-octeti pe secundã)" #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Limitã Cache Articole" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Stocheazã articolele în memorie pentru a reduce acesul disc.
    În " "octeti, optional urmati de K,M,G. De exemplu : \"64M\" sau\"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Listã Curãtenie" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista de extensii de fisiere care ar trebui sã fie sterse dupã " "descãrcare.
    De exemplu: .nfo sau .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Salveazã Modificãrile" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Limbã" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Alegeti o limbã interfatã web." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "Cheie API" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Aceastã cheie va oferi programelor terte acces deplin la SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "Cheie NZB" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Aceastã cheie va permite programelor terte sã adauge NZB-uri în SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Genereazã o Cheie Nouã" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Dezactiveazã cheie-API" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Nu necesitã cheie API." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "UTILIZATI PE RISCUL DVS. !" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "Cod QR" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "Cheie API sau Cod QR" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Configurare Dosare" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTÃ:Dosarele vor fi create automat când se Salveazã. Puteti " "utiliza cãi absolute pentru a salva în afara dosarelor implicite." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Dosare Utilizator" #: sabnzbd/skintext.py:345 msgid "In" msgstr "În" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Dosar Descãrcare Temporar" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Locatie de stocare a descãrcãrilor neprelucrate.
    Poate fi schimbatã " "doar atunci când coada este goalã." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minim de Spatiu Liber pentru Dosar Descãrcare Temporar" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pauzã când spatiul liber este sub aceastã valoare.
    În octeti, " "urmati optional de K, M, G, T. De exemplu: \"800M\" sau \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Dosar Descãrcãri Finalizate" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Locatie pentru stocare , a descãrcãrilor procesate complet.
    Poate fi " "suprascris de categoriile definite de utilizator." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Permisiuni pentru descãrcãri finalizate" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Seteazã permisiunile pentru fisierele/directoarele finalizate.
    În " "valori octale. De exemplu: \"755\" sau \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Dosar Monitorizat" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Dosar pentru supraveghere fisiere .nzb.
    Scaneazã de asemenea si " "arhivele .zip .rar .tar.gz de fisiere .nzb." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Vitezã Scanare Dosar Monitorizat" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Numãrul de secunde între scanarea de fisiere .nzb." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Director Script-uri Post-Procesare" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Dosar ce contine script-uri de post-procesare." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Dosar Sabloane Email" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Dosar ce contine sabloane email utilizator." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Fisier parole" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "Fisier ce contine parole pentru fisiere RAR encriptate." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Dosare Sistem" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Dosar Administrativ" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Locatia coadei admin si istoricul bazei de date.
    Poate fi folosit " "doar când coada e goalã." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Informatiile vor nu vor fi mutate. Necesitã repornire SABnzbd!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Dosar Jurnal" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Locatie a fisierelor jurnal ale SABnzbd.
    Necesitã repornire " "SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Dosar Copie de Sigurantã .nzb" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Locatie unde fisierele .nzb vor fi stocate." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Dosar de Bazã Implicit" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Configurare Comutatoare" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Comutatoare Procesare" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Activeazã Verificare Rapidã" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Ignorã verificarea par2 când fisierele sunt complete 100%%." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Activeazã Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Activeazã functionalitatea inclusã unrar." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Activeazã Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Activeazã functionalitatea inclusã unzip ." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Activeazã Unire Fisiere" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "" "Uneste fisierele care se terminã în .001, .002 etc. într-un singur fisier." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Activeazã Unire TS" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "" "Uneste fisierele care se terminã în .001.ts, .002.ts etc. într-un singur " "fisier." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Activeazã Sterge Par" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Sterge fisierele par (dacã verificarea/repararea este cu succes)" #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Nereusit din cauza Erorilor CRC yEnc" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "" "Când un articol are o eroare CRC , încearcã sã-l iei de pe un alt server." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Ia Articole doar din Vârful Coadei" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Activeazã pentru folosire de memorie mai putinã. Dezactivati pentru a " "preveni ca sarcinile lente sã blocheze coada." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Post-Proceseazã Doar Sarcinile Verificate" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Executã post-procesarea doar dacã sarcina a trecut toate verificãrile PAR2." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Detecteazã Descãrcãri Duplicate" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Detecteazã fisierele NZB denumite la fel (necesitã optiunea copie de rezervã " "NZB) si titluri duplicat în fluxuri RSS." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Oprit" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Ignorã" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Activeazã verficãri SFV" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Fã o verificare extra bazatã pe fisiere SFV" #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Verificã rezultatul dezarhivãrii" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Verificã rezultatul dezarhivãrii ( trebuie sã fie dezactivat pentru unele " "sisteme de fisiere )" #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Activeazã redenumire dosar" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Foloseste nume temporare în timpul post procesãrii. Dezactivati când " "sistemul dvs. nu gestioneazã aceasta corect." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Post-Procesare Implicitã" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Folosit când nu este definit nici o post-procesare de categorie." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Script Utilizator Implicit" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Folosit când nu este definit nici un script de categorie." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Script utilizator Pre-Coadã" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Folosit înainte ca un NZB sã intre în coadã." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Prioritate Implicitã" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Folosit când nu este definit nici o prioritate de categorie." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Activeazã Par2 MultiCore" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Citeste Ajutorul Wiki despre asta !" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Parametri Extra PAR2" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Parametri Nice" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "Parametri IONice" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Alte Comutatoare" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Deconecteazã când Coada e Goalã" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Deconecteazã de la serverul(ele) Usenet când coada e goalã sau în pauzã." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Trimite Grup" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Trimite comanda group înainte de a cere articole." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sorteazã dupã Vârstã" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Sorteazã automat obiectele dupa vârstã (medie)." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Verificã Versiuni Noi" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Verificare sãptãmânalã versiuni noi SABnzbd." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Testeaza si versiuni de încercare" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Înlocuieste Spatiile din Numele Dosarelor" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Înlocuieste spatiile cu _ în numele dosarelor." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Înlocuieste punctele din Numele Dosarelor" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Înlocuieste puntele cu spatii în numele dosarelor." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Înlocuieste Caracterle Ilegale din Numele Dosarelor" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Înlocuieste caracterele ilegale din numele dosarelor cu echivalente (altfel " "sterge)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Porneste Navigator Web la Pornire" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Porneste navigatorul web implicit când se porneste SABnzbd." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Întrerupe Descãrcarea în Timpul Post-Procesare" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Întrerupe descãrcare la începerea post procesãrii si reporneste când e " "terminatã." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignorã Monstre" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Ignorã fisiere monstrã (de ex. monstre video)" #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Sterge dupã descãrcare" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Nu descãrca" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "Tip SSL" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Folositi V23 doar dacã furnizorul dumneavoastrã necesitã altfel!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Folositi sitemul 12 ore (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Afisati timpii în notatia AM/PM (nu afecteazã planificatorul)" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Server" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Post procesare" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Redenumire" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Cotã" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Cât de mult poate fi descãrcat în acestã lunã (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Zi resetare" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "În ce zi a lunii sau sãptãmânã (1=Luni) ISP dumneavoastrã reseteazã cota? " "(Optional cu hh:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Auto repornire" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "Se reia descãrcarea dupã resetarea cotei?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Perioadã Cotã" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Cota se reseteazã în fiecare zi, sãptãmânã sau lunã ?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Verificã înainte de descãrcare" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Încearcã sã prezici decãrcarea cu succes înaintea descãrcãrii reale (mai " "lent!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Numãr Maxim reîncercãri" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Numãr Maxim reîncercãri pe server" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Doar pentru servere optionale" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Aplicã numãrul maxim de reîncercãri la serverele optionale" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Configurare Server" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Definitie Server" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Adaugã Server" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Nume de Utilizator" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Parolã" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Timp Expirare" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Timp Retentie" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Server Secundar" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Optional" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Activeazã" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Sterge Server" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Test Server" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Reseteazã Statistici" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testez detalii server..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Clic mai jos pentru a testa." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Descãrcat" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Configurare Planificator" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Adaugã Planificare" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Sterge" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Planificãri Curente" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "Configurare RSS" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Flux URL Nou" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Caseta de lângã numele fluxului trebuie sã fie selectatã pentru ca fluxul sã " "fie verificat de obiecte noi automat.
    Când un flux este adãugat , el va " "lua doar obiectele noi si nu cele deja existente, cu exceptia când apãsati " "\"Descãrcare Fortatã\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Adaugã flux" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Sterge flux" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Citeste Flux" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Descãrcare Fortatã" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filtru" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Omite" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Acceptã" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Respinge" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Necesitã" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "NecesitãCategoria" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Nepotrivit" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Fluxuri" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Citeste Toate Fluxurile Acum" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Setãri" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtre" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Optiuni Email" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Notificãri Email Sarcinã Terminatã" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Niciodatã" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Întotdeauna" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Doar-erori" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Notificãri Disc Plin" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Trimite email când discul este plin si SABnzbd este întrerupt." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Trimite notificãri RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Trimite email când un flux RSS adaugã sarcini în coadã." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Setãri Cont Email" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "Server SMTP" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Seteazã serverul dvs. ISP pentru trimitere email." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Destinatar Email" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Adresã de email cãtre care se trimite email." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Expeditor Email" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Cine ar trebui sã spunem cã a trimis email?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "Nume Cont OPTIONAL" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Pentru email autentificat, nume cont." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "Parolã Cont OPTIONAL" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Pentru email autentificat, parola." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Activeazã Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Trimite notificãri Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Adresã server" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Foloseste doar pentru server Growl de la distantã (gazdã:port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Parolã server" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Parolã optionalã server Growl" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Activeazã NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Trimite notificãri cãtre NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Centru Notificãri" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Trimite notificãri la Centru Notificãri" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Clase notificãri" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Activeazã clasã mesaje ce vor fi raportate (niciunul, unul sau mai multe)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Dacã aveti un cont la www.newzbin2.es, puteti introduce " "informatiile contului aici.
    Aceasta va debloca functionalitate extra." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Info Cont" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Nume de Utilizator Newzbin" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Setati numele de utilizator de cont aici." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Parolã Newzbin" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Setati parola contului dvs. aici." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Procesare Semne de Carte" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Descãrcare-Automatã Semne de Carte" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Descarcã automat semnele dvs. de carte" #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Ia Semne de Carte Acum" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Ascunde Semnele de Carte" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Afiseazã Semnele de Carte" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Sterge Semn Carte dupã Descãrcare Finalizatã" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Sterge din lista dvs. de semne de carte dupã o descãrcare finalizatã" #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Interval Verificare" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "În minute (cel putin 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Semne de Carte Procesate" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Dacã aveti un cont la www.nzbmatrix.com, puteti introduce " "informatiile contului dvs. aici .
    Acest lucru este necesar dacã doriti " "sã utilizati fluxurile RSS de pe acest site." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Nume de Utilizator NzbMatrix" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "Cheia API NzbMatrix" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Setati cheia API NzbMatrix aici." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Categorii definite de utilizator" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Defineste post-procesarea si stocarea." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Utilizati coloana \"Grupuri /Taguri Indexer\" pentru a desemna taguri " "categoriilor dvs. .
    Metacaracterele sunt acceptate. Utilizati virgule " "pentru a separa termeni." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Finalizarea unei cãi cu un asterix * va preveni crearea de dosare sarcini." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Dosarele relative se bazeazã pe" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Dosar/Cale" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Grupuri / Taguri Indexer" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Configurare Sortare" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Sortare Seriale" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Activeazã Sortare TV" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Permite sortarea si redenumirea de episoade." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Model Cheie" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Sterge" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Presetãri" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Exemplu" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Sortare Genericã" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Activeazã Sortare Filme" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Activeazã sortarea si redenumirea genericã a fisierelor." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Pãstreazã descãrcãrile suplimentare în dosare extra" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Activeazã dacã descãrcãrile nu sunt puse în dosarele lor." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Categorii Afectate" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Semnificatie" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Sablon" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Rezultat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Dosar Sezon" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Dosar Sezon" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Dosar Episod" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Dosar Episod" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Titlu" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Nume Film" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Nume.Film" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Nume_Film" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Nume Serial" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Nume.Serial" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Nume_Serial" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Numãr Sezon" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Numãr Episod" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Nume Episod" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Nume.Episod" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Nume_Episod" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Extensie fisier" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Extensie" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Numãr Parte" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Deceniu" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Nume de Fisier Original" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Nume de Dosar Original" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Litere Mici" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py:667 msgid "text" msgstr "text" #: sabnzbd/skintext.py:668 msgid "file" msgstr "fisier" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "dosar" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Sir Caractere Sortare" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Etichetã Multi-pãrti" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "În dosare" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Fãrã dosare" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Sortare Datã" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Activeazã Sortare Datã" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Activeazã sortarea si redenumirea fisierelor denumite dupã datã." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Aratã Nume dosar" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Dosar An-Lunã" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Dosare Zilnice" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "ajustare nume fisier" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Rezultat Procesat" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Optiuni folosite rar. Pentru explicatiile si semnificatia lor, click pe " "meniul Ajutor si viziteazã pagina Wiki.
    Nu modificati aceste setãri fãrã " "a verifica mai întâi pagina Wiki , pentru cã unele pot cauza probleme " "serioase .
    Valorile originale sunt în paranteze ." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Valori" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Editeazã Detalii NZB" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Sterge" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Vârf" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Sus" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Jos" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Coadã" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Toate" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Inverseazã" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Nume de fisier" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Subiect" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Vârsta" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Selectie" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Sigur doriti sã stergeti" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Reîmprospãteazã" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Optiuni" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Paginã" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Precedent" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Urmãtorul" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Primul" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Ultimul" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Închide" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Seteazã Interval Pauzã" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sorteazã" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Goliti Coada?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Interval Pauzã" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pauzã timp de 5 minute" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pauzã timp de 15 minute" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pauzã timp de 30 minute" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pauzã timp de o orã" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pauzã timp de 3 ore" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pauzã timp de 6 ore" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pauzã timp de 12 ore" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pauzã timp de 24 ore" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sorteazã dupã Vârstã Cel mai Vechi→Cel mai Nou" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sorteazã dupã Vârstã Cel mai Nou→Cel mai Vechi" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sorteazã dupã Nume A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sorteazã dupã Nume Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sorteazã dupã Mãrime Cel mai Mic→Cel mai Mare" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sorteazã dupã Mãrime Cel mai Mare→Cel mai Mic" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Redenumeste" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Stânga" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Goliti Istoricul?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Modificãrile nu au fost salvate, si vor fi pierdute." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Deschide URL Sursã" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Dechide URL Informatii" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Stocare" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Vezi Jurnal Script" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Trebuie sã activati JavaScript pentru ca Plush sã functioneze!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Adaugã NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Optiuni Plush" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Actualizare Disponibilã!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Pauzã pentru câte minute?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pauzã timp de..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Operatii-Multiple" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Meniu Top" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "La Terminare" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sorteazã dupã Vârstã (Cel mai Vechi→Cel mai Nou)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sorteazã dupã Vârstã (Cel mai Nou→Cel mai Vechi)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sorteazã dupã Nume (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sorteazã dupã Nume (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sorteazã dupã Mãrime (Cel mai Mic→Cel mai Mare)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sorteazã dupã Mãrime (Cel mai Mare→Cel mai Mic)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Sterge" #: sabnzbd/skintext.py:781 msgid "left" msgstr "rãmas" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Vitezã Maximã" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Interval" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Reseteazã" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Aplicã la Selectie" #: sabnzbd/skintext.py:786 msgid "page" msgstr "paginã" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Tot" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Dezactivat" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Rata de Reîmprospãtare" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Lãtime Container" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Confirmã Stergere Coadã" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Confirmã Stergere Istoric" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Acest lucru va preveni reîmprospãtarea când cursorul mouse-ului este " "deasupra coadei." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Blocheazã Reîmprospãtarea Hover" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Descarcã" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Încarcã" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Încarcã: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Optional specificã un nume de fisier" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Progres" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Spatiul liber insuficient pe disc pentru finalizarea descãrcãrilor !" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Spatiu liber" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Gol (Temp)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "INACTIV" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Descãrcãri" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Coadã reparare" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Citeste Flux va descãrca continutul fluxului curent. " "Descãrcare Fortatã va descãrca toate NZB-urile " "corespunzãtoare acum." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Ore:Min" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Stergere Finalizatã" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Stergeti toate fisierele nereusite din istoric?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Sterge Nereusite" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Legãturi" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Afisare %s pânã la %s din totalul %s rezultate" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Fãrã rezultate" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Afisãm un rezultat" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Email Trimis!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Notificare Trimisã!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Salvãm.." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Salvat" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Vitezã" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Comutã Adaugã NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "VedereDualã1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "VedereDualã2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Personalizat" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Descarcã Semne de Carte" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Sunteti sigur cã doriti sã reporniti SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Ratã actualizare" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Sterge tot" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Ascunde Optiuni Editare" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Aratã Optiuni Editare" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Editeazã" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Timp rãmas" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "Vrãjitor Pornire-Rapidã SABnzbd" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "Versiune SABnzbd" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Precedent" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Acces" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Vreau SABnzbd sã fie vizibil de cãtre orice calculator din reteaua mea." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Vreau SABnzbd sã fie vizibilã numai de pe PC-ul meu." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Acces SABnzbd protejat cu parolã (recomandat)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Permite acces HTTPS la SABnzbd." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Diverse" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Lanseazã navigatorul meu web la pornirea SABnzbd ." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Detalii Server" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "" "Vã rugãm sã introduceti detaliile furnizorului dvs principal de usenet." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Pentru a descãrca de pe usenet veti avea nevoie de un furnizor. ISP-ul dvs. " "vã poate oferi acces, totusi un furnizor premium e recomandat." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Nu aveti un furnizor usenet? Vã recomandãm sã încercati %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Numãrul de conexiuni permis de furnizor" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "De ex. 8 sau 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Selecteazã doar dacã furnizorul dvs. permite conexiuni SSL." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Clic pentru a testa detaliile introduse." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Acest câmp este obligatoriu." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Vã rugãm sã introduceti un numãr întreg." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Dacã sunteti un membru al newzbin sau nzbmatrix, puteti introduce numele de " "utilizator si parola aici, astfel încât sã putem descãrca nzb-uri de la ei. " "Aceastã etapã poate fi omisã dacã nu folositi serviciile lor." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Descãrcare automatã a semnelor de carte" #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "De ex." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Repornim SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Instalarea este acum completã!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd va rula acum în fundal." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Închidere a oricãrei ferestrele browser/file NU va închide SABnzbd." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "Dupã repornire SABnzbd ,îl veti putea acesa la urmãtoarea locatie: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Este recomandat sã faceti clic dreapta si sã faceti o scurtaturã , pe care " "sã o folositi pentru a accesa SABnzbd când ruleazã în fundal." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Ajutor suplimentar poate fi gãsit pe pagina noastrã" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Du-te la SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Pasul Unu" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Pasul Doi" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Pasul Trei" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Pasul Patru" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Pasul Cinci" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "De ex. 119 sau 563 pentru SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Închide SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Porneste Vrãjitor" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd vine cu ABSOLUT NICI O GARANTIE.\n" "Acesta este software gratis, si sunteti binevenit sã-l redistribuiti în " "anumite conditii.\n" "Este licentiat sub GNU General Public License versiunea 2 sau (la optiunea " "dumneavoastrã) orice versiune ulterioarã.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Eroare obtinere info TV (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Redenumire:%s în %s nereusitã" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Redenumire fisiere similare : %s în %s nereusitã" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Numãr report invalid nzbmatrix %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Aveti nevoie de un cont VIP la nzbmatrix pentru a utiliza API" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Credentiale invalide nzbmatrix" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Probleme la accesarea server nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Numele gazdei nu este setat." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Nu sunt conexiuni stabilite. Vã rugãm sã stabiliti cel putin o conexiune." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Parolã ascunsã în ******, Vã rugãm sã re-introduceti" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Detalii server invalide" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "A depãsit timpul alocat : Încercati sã activati SSL sau conectarea pe un " "port diferit." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "A depãsit timpul alocat" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Adresã server invalidã" #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Serverul a renuntat în timpul logãrii." #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Serverul necesitã nume utilizator si parolã" #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Conexiune Reusitã!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Autentificare nereusitã, verificã nume utilizator/parolã." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Prea multe conexiuni, vã rugãm sã întrerupeti descãrcarea sau sã încercati " "din nou mai târziu" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Nu pot determina reultatul conexiunii (%s)" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Eroare Descãrcare msgid %s de la www.newzbin.com - Vã rugãm asigurati-vã cã " #~ "Numele de Utilizator si Parola sunt stabilite" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "descarc msgid %s de la www.newzbin.com" #~ msgid "Expected size did not equal actual size" #~ msgstr "Mãrimea asteptatã nu este egalã cu cea realã" #~ msgid "Could not compile regex: %s" #~ msgstr "Nu am putut compila regex: %s" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Veti avea nevoie sã setati o parolã si sã reluati sarcina." #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Întrerupe o sarcinã când sunt descãrcate fisiere RAR encriptate" #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Dacã aveti un cont la www.newzbin.com, puteti introduce " #~ "informatiile contului dvs. aici.
    Aceasta va debloca functionalitate " #~ "extra." #~ msgid "Email Notifications" #~ msgstr "Notificãri Email" #~ msgid "Quotum period" #~ msgstr "Perioadã cotã" #~ msgid "Should downloading resume after the quotum is reset?" #~ msgstr "Reia descãrcarea dupã resetarea cotei ?" #~ msgid "Does the quotum get reset each day, week or month?" #~ msgstr "Cota se reseteazã în fiecare zi, sãptãmânã sau lunã ?" #~ msgid "" #~ "On which day of the month or week (1=Monday) does your ISP reset the quotum? " #~ "(Optionally with hh:mm)" #~ msgstr "" #~ "În ce zi a lunii sau sãptãmânã (1=Luni) ISP dvs. reseteazã cota ? (Optional " #~ "cu hh:mm)" #~ msgid "Quotum" #~ msgstr "Cotã" #~ msgid "Quotum left" #~ msgstr "Cotã rãmasã" SABnzbd-0.7.20/po/main/ro.px0000644000000000000000000037235712433712556015611 0ustar00usergroup00000000000000# Romanian translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2012-10-13 17:23+0000\n" "Last-Translator: nicusor \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:54+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Pornirea interfeţei-web nereuşită" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Nu se poate găsi şablon web:%s, se încearcă şablon standard" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "modulul _yenc ... Negăsit!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "binar par2 ... Negăsit!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "binar unrar... Negăsit!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "binar unzip... Negăsit!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Vă rugăm să fiţi conştienţi că numele gazdei 0.0.0.0 va avea nevoie de o " "adresa IPv6 pentru acces extern" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Dezactivează HTTPS din cauza lipsei fişierelor CERT şi KEY" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "SABnzbd %s pornit" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "Închidere SABnzbd terminată" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Semnal %s prins, salvez şi ies..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "descarc msgid %s from www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Eroare descărcare msgid %s de la www.newzbin2.es - Vă rugăm asiguraţi-vă că " "Nume de Utilizator şi Parolă sunt setate" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Încerc să descarc NZB de la %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Nu pot crea fişier temporar pentru %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Încerc să setez starea unui server nexistent %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "Prea puţin spaţiu disc forţez PAUZĂ" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Eroare în tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Salvarea %s nereuşită" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Încărcarea %s nereuşită" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Notificări Test" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Niciunul" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Implicit" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "ATENŢIE:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "EROARE:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "necunoscut" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Compilarea unei căutări regex nereuşită: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disc plin! Pauză Forţată" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Eroare disc la crearea fişierului %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "" "ATENŢIE: Sarcina \"%s\" întreruptă din cauza fişierelor RAR encriptate" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "" "ATENŢIE: Sarcină \"%s\" abandonată deoarce conţine un fişier RAR ecriptat" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "Terminat, encriptare detectată" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s lipsă" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Cotă epuizată, întrerupem descărcarea" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s nu este o adresă email validă" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Adresă server necesară" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Nu pot crea %s dosar %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Nu pot scrie în fişierul INI %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Nu pot crea copie de rezervă pentru %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Parolă %s codificată greşit" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s nu este o valoare octală corectă" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "cale UNC \"%s\" nu este premisă aici" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Eroare: Coada nu este goală, nu pot schimba dosar." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Dosarul \"%s\" nu există" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "Comandă SQL Nereuşită, vedeţi jurnal" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "Modificare SQL Nereuşită, vedeţi jurnal" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Închidere bază de date nereuşită, vedeţi jurnal" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Jurnal istoric stagii invalid pentru %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Decodarea %s nereuşită" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "Eroare CRC în %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Articoul yEnc invalid în %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Eroare Necunoscută în timpul decodării %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => lipsă de pe toate serverele, ignorare" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Eroare ştergere %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Nu pot citi %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Nu pot citi Dosar Urnărire %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Întrerupt" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Serverul %s va fi ignorat pentru %s minute" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Iniţializare nereuşită %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "Prea multe conexiuni către serverul %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Partajare cont probabilă" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Autentificare nereuşită la serverul %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Nu mă pot conecta la serverul %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Conectarea %s@%s:%s nereuşită, mesajul=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Serverul %s necesită utilizator/parolă" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Închidere" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Conectare server mail nereuşită" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Iniţializare conexiune TLS nereuşită" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Autentificare server mail nereuşită" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Trimitere email nereuşiă" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Închidere conexiune mail nereuşită" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "Email reuşit" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Nu pot gasi şabloane email în %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Destinatar necunoscut, niciun email trimis" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Codificare invalidă a şablonului email %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Şabloane email negăsite" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "From: %s\n" "To: %s\n" "Date: %s\n" "Subject: SABnzbd raporteaza Disc Plin\n" "\n" "Salut,\n" "\n" "SABnzbd sa oprit din descarcare, deoarece discul este aproape plin.\n" "Va rugam sa faceti loc si reluati SABnzbd manual.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Pornire/Închidere" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "NZB-uri Adăugate" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Post-procesare pornită" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Sarcină terminată" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Alte Mesaje" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Atenţie:LOCALHOST este ambiguu, folosiţi o adresă IP numerică" #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Adresa server \"%s:%s\" nu este validă" #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Cheie Sesiune lipsă" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Eroare: Cheie Sesiune Necesară" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Eroare: Cheie Sesiune Incorectă" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "Cheie API lipsă, vă rugăm să introduceţi cheia api de la Configurare-" ">General în programul dumneavoastră terţ" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "Cheie API incorectă, Folosiţi cheia api din Configurare->General în " "programul dumneavoastră terţ:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Autentificare lipsă, vă rugăm să introduceţi numele de utilizator/parola de " "la Configurare->General în programul dumneavoastră terţ:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Eroare: Nici o interfaţă secundară definită." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Versiunea dvs. UNRAR nu este recomandată, luaţi-o de la " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" "Nici un program UNRAR găsit, dezarhivarea fişierelor RAR imposibilă
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Nici un program PAR2 găsit, repararea imposibilă
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Iniţializare repornire...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    Închidere SABnzbd terminată.
    Aşteptaţi timp de aproximativ 5 " "secunde şi apoi faceţi clic pe butonul de mai jos.

    Reîmprospătează
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Flux" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Zilnic" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Luni" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Marţi" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Miercuri" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Joi" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Vineri" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Sâmbătă" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Duminică" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "dezactivat" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Reolvare adresă" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Parametru Incorect" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Înapoi" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Sarcina \"%s\" a fost re-adăugată în coadă" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Sarcinile selectate cu '*' vor fi descărcate automat" #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Potrivite" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Nepotrivite" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Descărcate" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Decărcat până acum" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Valoare incorectă pentru %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Nu pot crea dosarul %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "dosarul %s: eroare accesare %s" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Nu mă pot conecta la registru HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Nu pot deschide cheie registru \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Citire valoare registru pentru dosare speciale nereuşită" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Facere nereuşită (%s)" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Mutare %s în %s nereuşită" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Fişier NZB Inutilizabil" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Încercați din nou" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "Descărcare URL nereuşită; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "modul pyopenssl lipsă, instalaţi-l pentru acces https" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Eroare la crearea cheiei şi certificatlui SSL" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Nu pot schimba permisiunile lui %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Unim" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Secvenţă incompletă de unire fişiere" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Unirea fişierului %s nereuşită" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Eroare \"%s\" în timpul unirii fişierelor" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Eroare \"%s\" în timpul file_join a %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Unit %s fişierele" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Dezarhivare nereuşită, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Eroare \"%s\" în timpul dezarhivării fişierelor RAR" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Eroare \"%s\" în timpul rar_unpack a %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Ştergere %s nereuşită!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Încerc unrar cu parola \"%s\"" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Dezarhivare nereuşită, arhiva necesită o parolă" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Dezarhivare" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Dezarhivare nereuşită, nu pot găsi %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "EROARE: nu pot găsi \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Dezarhivare nereuşită, eroare CRC" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "EROARE: CRC nereuşit în \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Dezarhivare nereuşită, eroare scriere sau disc plin?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "EROARE: eroare scriere (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Dezarhivare nereuşită, vezi jurnal" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "EROARE: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Fişiere aşteptate lipsă: %s => eroare unrar?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Dezarhivare nereuşită, un fişier aşteptat nu a fost dezarhivat" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Dezarhivare nereuşită, acest(e) fişier(e) sunt lipsă:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Dezarhivat %s fişierele/dosarele în %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s fişiere în %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Eroare \"%s\" în timpul rulării unzip() pe %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Verificare Rapidă" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Repară" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Verficare Rapidă OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Pornire Reparare" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparare nereuşită, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Eroare %s în timpul rulării par2_repair pe setul %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Eroare \"%s\" în timpul rulării par2_repair pe setul %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 a primit opţiuni incorecte, verifică setările Configurare-" ">Comutatoare" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verificat în %s, toate fişierele sunt corecte" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verificat în %s, reparare necesară" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Pachet principal negăsit..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Fișier par2 invalid, nu pot verifica sau repara" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "Reparare nereuşită, blocuri reparare insuficiente (%s mai puţin)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Descărcare %s blocuri..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Descărcare" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Se repară" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Reparat în %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Se verifică" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Eroare importare modul OpenSSL . Se conectează folosind NON-SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Actualizare sarcină %s nereuşită" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB adăugat în coadă" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Serverul Newzbin şi-a schimbat protocolul" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Nu aveţi credit în contul dvs. Newzbin" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "" "Neautorizat, verificaţi numele de utilizator/parola dvs. de la newzbin" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin raportează ca nu a fost găsit %s" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin a dat o eroare nedocumentată (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Serverul Newzbin nu poate da informaţii pentru %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Nu am putut şterge semnul de carte newzbin %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin a dat o eroare nedocumentată (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Fişier coadă găsit incompatibil, nu pot înainta" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Eroare încărcare %s, fişier corupt detectat" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Eroare adăugare %s, ştergem" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Codificare Necunoscută" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Fişierul %s este gol , ignorăm" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Importare %s a fişierelor de la %s nereuşită" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "Fişier NZB incomplet %s" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Fişier NZB invalid %s, ignorăm (motiv=%s, line=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "Fişier NZB gol %s" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorăm duplicat NZB \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Întrerupem duplicat NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUPLICAT" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "ENCRIPTAT" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "PREA MARE" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "INCOMPLET" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "AŞTEAPTĂ %s sec" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Descărcat în %s cu o medie de %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s articolele au fost incorecte" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s articolele au fost lipsă" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s articolele au avut duplicate diferite" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Eroare importare %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Atenționări" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Inactiv" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Configurare" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Coadă" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Goleşte Coadă" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Istoric" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Şterge Istoricul" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Limitare de Viteză" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pauză" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Reia" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Descarcă Semne de Carte Newzbin" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Scanează dosar urmărire" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Dosar Complet" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Dosar Incomplet" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Depanare" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Repornește" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Reporneşte fără autorizare" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Ieșire" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Pune la Coadă Primele 10 Obiecte" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Gol" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Istoric Ultimele 10 Obiecte" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Versiune nouă disponibilă" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Dute la vrăjitor" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Se oprește..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problemă cu" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nu este compatibil cu unele programe firewall
    \n" " %s
    \n" " Ne pare rău, dar noi nu putem rezolva această incompatibilitate " "acum.
    \n" " Vă rugăm să vă plângeţi producătorului dvs. de firewall.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd are nevoie de un tcp/ip port liber pentru serverul său " "intern.
    \n" " Portul %s de pe %s a fost încercat , dar nu este disponibil.
    \n" " Alt program foloseşte portul sau SABnzbd este deja pornit.
    \n" "
    \n" " Vă rugăm să reporniţi SABnzbd cu un număr de port diferit." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "" "Dacă primiţi acest mesaj de eroare din nou, vă rugăm să încercaţi un alt " "număr.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd are nevoie de un port tcp/ip liber pentru serverul său " "intern.
    \n" " Portul %s de pe %s a fost încercat , dar contul folosit de SABnzbd nu " "are permisiunea de a-l folosi.
    \n" " În sisteme OSX şi Linux , utilizatori normali trebuie să folosească " "porturi peste 1023.
    \n" "
    \n" " Vă rugăm să reporniţi SABnzbd cu un număr de port diferit." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd are nevoie de o adresă gazdă validă pentru serverul său " "intern.
    \n" " Dvs. a-ţi specificat o adresă invalidă.
    \n" " Valori sigure sunt localhost şi 0.0.0.0
    \n" "
    \n" " Vă rugăm să reporniţi SABnzbd cu o adresă gazdă bună." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd a detectat informaţii salvate de la o altă versiune SABnzbd
    \n" " dar nu poate să refolosească informaţiile de la cealaltă versiune de " "program.

    \n" " Ar fi bine să terminaţi coada mai întâi cu cealaltă versiune de " "program.

    \n" " După aceia , porniţi programul cu opţiunea \"--clean\".
    \n" " Aceasta va şterge coada curentă şi istoricul!
    \n" " SABnzbd citeşte fişierul \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd nu poate găsi fişierele de la interfaţa-web %s.
    \n" " Vă rugăm să reinstalaţi programul din nou.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd a detectat o eroare fatală:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd a detectat o Coadă şi Istoric de la o versiune veche " "(0.4.x).

    \n" " Atât coada şi istoricul vor fi ignorate şi s-ar putea pierde!

    \n" " Puteţi să opriţi SABnzbd şi să terminaţi coada cu cealaltă versiune de " "program.

    \n" " Clic OK pentru a porni SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd a detectat că fişierul sqlite3.dll lipseşte.

    \n" " Unele antivirusuri şterg acest fişier.
    \n" " Vă rugăm să verificaţi antivirusul , încercaţi să reinstalaţi SABnzbd şi " "plângeţivă autorului antivirusului.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Apasă Start+R şi scrie linia (exemplu):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Deschide fereastra Terminal şi scrie linia (exemplu):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Este posibil că folosiţi ZoneAlarm în Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Aplicaţia nu a pornit!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Nu ai permisiunea să foloseşti acest port %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Eroare fatală" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Nu pot porni navigatorul web, probabil nu a fost găsit" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Acces interzis" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Eroare %s: Trebuie să furnizaţi un nume utilizator şi parolă valid" #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Încărcare coadă post-procesare nereuşită : Versiune greşită (am nevoie " "de:%s, găsit:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Ştergere nzo din coadă post-procesare nereuşită (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "Descărcarea ar putea eşua, doar %s din %s disponibil" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Descărcare nereuşită - Retenţie server depăşită ?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Nu pot crea dosar final %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Nici o post-procesare din cauza verificării nereuşite" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Mutare" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Trimis %s în coadă" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Eroare redenumire \"%s\" în \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Nu am putu muta fişier" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Rulare script" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Rulare script utilizator %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Durată %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Mai mult" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Vezi rezultat script" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Descărcare terminată" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Descărcarea a eșuat" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Post Procesare Nereuşită pentru %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "vezi fişier jurnal" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Post-Procesarea a fost abandonată (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Ştergerea lui %s nereuşită." #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Eroare ştergere dosar curent (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Post-procesare" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Niciun set par2" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Încerc verificare SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Unele fişiere nu au fost verificate corect cu \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Verificare reuşită cu fişierele SFV" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Ştergerea %s nereuşită" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Punere sistem în hibernare nereuşită" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Punere sistem în aşteptare nereuşită" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Eroare la oprirea sistemului" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Descriere flux RSS incorectă \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Descărcare %s: %s din RSS nereuşită" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Autentificare invalida pentru flux %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "Fluxul RSS %s a fost gol" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Fulx RSS incompatibil" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Valoare RSS gasită a fost goală (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Arată interfața" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Deschide dosar descărcări complete" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Închidere" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Rămas" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Programator Greşit %s la %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Acţiune necunoscută: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Planificare pentru un server inexistent %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Descarcă" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Uneşte fişierele" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Dezarhivează" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Script" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Sursă" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Nereuşit" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Finalizat" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Nereuşit" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Se așteaptă" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparare..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Dezarhivare..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Mutare..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Rulare script..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Descărcare blocuri extra..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Verificare Rapidă..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Verificare..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Descărcare" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Descarcă NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Se verifică" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Frecvenţă" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Acțiune" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argumente" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Sarcină" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "dezactivează server" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "activează server" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Limitare de Viteză" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Pauză Toate" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pauză post-procesare" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Reia post-procesare" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Citeşte fluxuri RSS" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Elimină sarcini nereuşite" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "oră" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "ore" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "min" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minute" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sec" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "secunde" #: sabnzbd/skintext.py:79 msgid "day" msgstr "zi" #: sabnzbd/skintext.py:80 msgid "days" msgstr "zile" #: sabnzbd/skintext.py:81 msgid "week" msgstr "săptămână" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Lună" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "An" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Zi din lună" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Săptămâna aceasta" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Luna aceasta" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "Azi" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Total" #: sabnzbd/skintext.py:97 msgid "on" msgstr "activat" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametrii" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Versiune Python" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Pagină de pornire" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "sau" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Gazdă" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Instrumentul de descărcare automată usenet" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Salvează" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Pus în coadă" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Sunteţi sigur?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Ştergeţi toate fişierele descărcate?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Pagina de pornire" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Configurare" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Stare" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Ajutor" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "General" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Directoare" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Comutatoare" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Servere" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Planificare" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Notificări" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "Email" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Situri Index" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Categorii" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortare" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Special" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Dosar Descărcare" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Dosar Complete" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Viteză de descărcare" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "ÎNTRERUPT" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "Articole %s în cache (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Încărcare sistem" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "AVERTIZĂRI" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Versiune nouă %s disponibilă la" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Adaugă descărcări noi" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Sunteţi sigur că doriţi să inchideţi SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Adaugă" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Report-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Adaugă fişier" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Categorie" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "În curs de procesare" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioritate" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparare" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Dezarhivare" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Ştergere" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "U" #: sabnzbd/skintext.py:177 msgid "D" msgstr "D" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Forțează" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Ridicată" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Scăzută" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stop" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "Introdu URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " sau Report ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Sortează după nume" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Sortează după vârstă" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Sortează după mărime" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Ascunde fişiere" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Arată fişiere" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "La terminarea coadei de descărcare" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Închide PC" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Repaus PC" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Hibernare PC" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Închide SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Limită de Viteză" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pauză timp de" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Ordine" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Nume" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Rămas/Total" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Timp Estimat" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "Vârstă" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Şterge" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Reîncearcă" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Acțiuni" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Script-uri" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Ştergeţi toate obiectele din coadă?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Şterge NZB-uri" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Şterge NZB-uri & Fişiere Şterse" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Şterge NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Şterge NZB & Fişiere Şterse" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "din" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Articole lipsă" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Cotă rămasă" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "manual" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Resetează Cota acum" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Goleşte Istoric Descărcări Nereuşite" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Ştergeţi toate obiectele complete din Istoric?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Ştergeţi toate obiectele nereuşite din Istoric?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Ascunde detaliile" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Arată detalii" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Mărime Istoric" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Arată Nereuşite" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Arată toate" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Mărime" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Şterge NZB-uri nereuşite" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Şterge NZB-uri Nereuşite & Fişiere Şterse" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Şterge NZB-uri Complete" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "NZB Suplimentar Opţional" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Cale" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Forţează Deconectarea" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Acesta va trimite un email test către contul dvs." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Arată Jurnalizarea" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Arată Jurnal Web" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Email Test" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Jurnalizare" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Erori/Avertismente" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Depanare" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Conexiuni" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Proces" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "Rezultat Test Email" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Ultimele Avertizări" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "Şterge" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Deblochează" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Identificator Articol" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Set fişiere" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "Când" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Tip" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Avertisment" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Activat" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Fişier Configurare" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Cache Folosit" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Acest lucru va reporni SABnzbd.
    Folosiţi-l atunci când credeţi că " "programul are o problemă de stabilitate.
    Descărcarea va fi oprită " "înainte de repornire şi reluată ulterior." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Sunt sarcini orfane în dosarul de descărcare.
    Puteţi alege în a le " "şterge (inclusiv fişierele) sau a le trimite înapoi în coadă." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "Butonul \"Reparare\" va reporni SABnzbd şi face o reconstrucţie completă
    a conţinutului coadei de descărcare , menţinând fişierele deja " "descărcate.
    Acest lucru va modifica ordinea în coada de descărcare." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Versiune" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Durata Funcţionării" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Server Secundar" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Configuraţie Generală" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Modificările vor necesita repornirea SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "Server Web SABnzbd" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "Gazdă SABnzbd" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Nume Gazdă unde SABnzbd va asculta." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "Port SABnzbd" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Portul pe care SABnzbd îl va asculta." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Interfață Web" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Alege o temă." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Interfaţă Web Secundară" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Activează o temă alternativă." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Autentificare server web" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "Nume Utilizator SABnzbd" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Nume Utilizator autentificare opţional" #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "Parolă SABnzbd" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Parolă autentificare opţională" #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "Suport HTTPS" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "Activează HTTPS" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "neinstalat" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Permite acesarea interfeţei de la o adresă HTTPS." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "Port HTTPS" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Dacă e gol, portul standard va asculta doar în HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "Certificat HTTPS" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Nume fişier sau cale Certificat HTTPS." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "Cheie HTTPS" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Nume fişier sau cale Cheie HTTPS." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "Certificate Cheie HTTPS" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "Nume fişier sau cale cheie HTTPS." #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Optimizări" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Interval reîmprospătare automată coadă:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" "Interval reîmprospătare a coadei din pagina interfeţei web(sec, 0= niciunul)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "Interval Verficare RSS" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Interval verificare (în minute, cel puţin 15). Inactiv când se foloseşte " "Planificatorul!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Limită de Viteză Descărcare" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "Limită Rată de Descărcare ( în KB/s - kilo-octeţi pe secundă)" #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Limită Cache Articole" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Stochează articolele în memorie pentru a reduce acesul disc.
    În " "octeţi, opţional urmaţi de K,M,G. De exemplu : \"64M\" sau\"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Listă Curăţenie" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista de extensii de fişiere care ar trebui să fie şterse după " "descărcare.
    De exemplu: .nfo sau .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Salvează Modificările" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Limbă" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Alegeţi o limbă interfaţă web." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "Cheie API" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Această cheie va oferi programelor terţe acces deplin la SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "Cheie NZB" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Această cheie va permite programelor terţe să adauge NZB-uri în SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Generează o Cheie Nouă" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Dezactivează cheie-API" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Nu necesită cheie API." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "UTILIZAŢI PE RISCUL DVS. !" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "Cod QR" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "Cheie API sau Cod QR" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Configurare Dosare" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "NOTĂ:Dosarele vor fi create automat când se Salvează. Puteţi " "utiliza căi absolute pentru a salva în afara dosarelor implicite." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Dosare Utilizator" #: sabnzbd/skintext.py:345 msgid "In" msgstr "În" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Dosar Descărcare Temporar" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Locaţie de stocare a descărcărilor neprelucrate.
    Poate fi schimbată " "doar atunci când coada este goală." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minim de Spaţiu Liber pentru Dosar Descărcare Temporar" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pauză când spaţiul liber este sub această valoare.
    În octeţi, " "urmaţi opţional de K, M, G, T. De exemplu: \"800M\" sau \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Dosar Descărcări Finalizate" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Locație pentru stocare , a descărcărilor procesate complet.
    Poate fi " "suprascris de categoriile definite de utilizator." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Permisiuni pentru descărcări finalizate" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Setează permisiunile pentru fişierele/directoarele finalizate.
    În " "valori octale. De exemplu: \"755\" sau \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Dosar Monitorizat" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Dosar pentru supraveghere fişiere .nzb.
    Scanează de asemenea şi " "arhivele .zip .rar .tar.gz de fişiere .nzb." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Viteză Scanare Dosar Monitorizat" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Numărul de secunde între scanarea de fişiere .nzb." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Director Script-uri Post-Procesare" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Dosar ce conţine script-uri de post-procesare." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Dosar Şabloane Email" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Dosar ce conţine şabloane email utilizator." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Fișier parole" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "Fişier ce conţine parole pentru fişiere RAR encriptate." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Dosare Sistem" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Dosar Administrativ" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Locaţia coadei admin şi istoricul bazei de date.
    Poate fi folosit " "doar când coada e goală." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" "Informaţiile vor nu vor fi mutate. Necesită repornire SABnzbd!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Dosar Jurnal" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Locaţie a fişierelor jurnal ale SABnzbd.
    Necesită repornire " "SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "Dosar Copie de Siguranţă .nzb" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Locaţie unde fişierele .nzb vor fi stocate." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Dosar de Bază Implicit" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Configurare Comutatoare" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Comutatoare Procesare" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Activează Verificare Rapidă" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Ignoră verificarea par2 când fişierele sunt complete 100%%." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Activează Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Activează funcţionalitatea inclusă unrar." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Activează Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Activează funcţionalitatea inclusă unzip ." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Activează Unire Fişiere" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "" "Uneşte fişierele care se termină în .001, .002 etc. într-un singur fişier." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Activează Unire TS" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "" "Uneşte fişierele care se termină în .001.ts, .002.ts etc. într-un singur " "fişier." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Activează Şterge Par" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Şterge fişierele par (dacă verificarea/repararea este cu succes)" #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Nereuşit din cauza Erorilor CRC yEnc" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "" "Când un articol are o eroare CRC , încearcă să-l iei de pe un alt server." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Ia Articole doar din Vârful Coadei" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Activează pentru folosire de memorie mai puţină. Dezactivaţi pentru a " "preveni ca sarcinile lente să blocheze coada." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Post-Procesează Doar Sarcinile Verificate" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" "Execută post-procesarea doar dacă sarcina a trecut toate verificările PAR2." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Detectează Descărcări Duplicate" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Detectează fişierele NZB denumite la fel (necesită opţiunea copie de rezervă " "NZB) şi titluri duplicat în fluxuri RSS." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Oprit" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Ignoră" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Activează verficări SFV" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Fă o verificare extra bazată pe fişiere SFV" #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Verifică rezultatul dezarhivării" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Verifică rezultatul dezarhivării ( trebuie să fie dezactivat pentru unele " "sisteme de fișiere )" #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Activează redenumire dosar" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Foloseşte nume temporare în timpul post procesării. Dezactivaţi când " "sistemul dvs. nu gestionează aceasta corect." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Post-Procesare Implicită" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Folosit când nu este definit nici o post-procesare de categorie." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Script Utilizator Implicit" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Folosit când nu este definit nici un script de categorie." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Script utilizator Pre-Coadă" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Folosit înainte ca un NZB să intre în coadă." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Prioritate Implicită" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Folosit când nu este definit nici o prioritate de categorie." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Activează Par2 MultiCore" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Citeşte Ajutorul Wiki despre asta !" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Parametri Extra PAR2" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Parametri Nice" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "Parametri IONice" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Alte Comutatoare" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Deconectează când Coada e Goală" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" "Deconectează de la serverul(ele) Usenet când coada e goală sau în pauză." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Trimite Grup" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Trimite comanda group înainte de a cere articole." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sortează după Vârstă" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Sortează automat obiectele dupa vârstă (medie)." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Verifică Versiuni Noi" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Verificare săptămânală versiuni noi SABnzbd." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "Testeaza şi versiuni de încercare" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Înlocuieşte Spaţiile din Numele Dosarelor" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Înlocuieşte spaţiile cu _ în numele dosarelor." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Înlocuieşte punctele din Numele Dosarelor" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Înlocuieşte puntele cu spaţii în numele dosarelor." #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Înlocuieşte Caracterle Ilegale din Numele Dosarelor" #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Înlocuieşte caracterele ilegale din numele dosarelor cu echivalente (altfel " "şterge)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Porneşte Navigator Web la Pornire" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Porneşte navigatorul web implicit când se porneşte SABnzbd." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Întrerupe Descărcarea în Timpul Post-Procesare" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Întrerupe descărcare la începerea post procesării şi reporneşte când e " "terminată." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignoră Monstre" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Ignoră fişiere monstră (de ex. monstre video)" #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Şterge după descărcare" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Nu descărca" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "Tip SSL" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Folosiţi V23 doar dacă furnizorul dumneavoastră necesită altfel!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "Folosiţi sitemul 12 ore (AM/PM)" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "Afişaţi timpii în notaţia AM/PM (nu afectează planificatorul)" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "Server" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "Post procesare" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "Redenumire" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "Cotă" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "Cât de mult poate fi descărcat în acestă lună (K/M/G)" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "Zi resetare" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" "În ce zi a lunii sau săptămână (1=Luni) ISP dumneavoastră resetează cota? " "(Opțional cu hh:mm)" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "Auto repornire" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "Se reia descărcarea după resetarea cotei?" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "Perioadă Cotă" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "Cota se resetează în fiecare zi, săptămână sau lună ?" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "Verifică înainte de descărcare" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" "Încearcă să prezici decărcarea cu succes înaintea descărcării reale (mai " "lent!)" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "Număr Maxim reîncercări" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "Număr Maxim reîncercări pe server" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "Doar pentru servere opționale" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "Aplică numărul maxim de reîncercări la serverele opționale" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Configurare Server" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "Definiţie Server" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Adaugă Server" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "Port" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Nume de Utilizator" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Parolă" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "Timp Expirare" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "Timp Retenţie" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "SSL" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Server Secundar" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Opţional" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Activează" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Şterge Server" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Test Server" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "Resetează Statistici" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testez detalii server..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Clic mai jos pentru a testa." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "Descărcat" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Configurare Planificator" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Adaugă Planificare" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Șterge" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Planificări Curente" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "Configurare RSS" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Flux URL Nou" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Caseta de lângă numele fluxului trebuie să fie selectată pentru ca fluxul să " "fie verificat de obiecte noi automat.
    Când un flux este adăugat , el va " "lua doar obiectele noi şi nu cele deja existente, cu excepţia când apăsaţi " "\"Descărcare Forţată\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "Adaugă flux" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Șterge flux" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "Citeşte Flux" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Descărcare Forţată" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "Filtru" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "Omite" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Acceptă" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Respinge" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Necesită" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "NecesităCategoria" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "Nepotrivit" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "Fluxuri" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "Citeşte Toate Fluxurile Acum" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "Setări" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "Filtre" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "Opţiuni Email" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "Notificări Email Sarcină Terminată" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Niciodată" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Întotdeauna" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Doar-erori" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Notificări Disc Plin" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Trimite email când discul este plin şi SABnzbd este întrerupt." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "Trimite notificări RSS" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "Trimite email când un flux RSS adaugă sarcini în coadă." #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "Setări Cont Email" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "Server SMTP" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Setează serverul dvs. ISP pentru trimitere email." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "Destinatar Email" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "Adresă de email către care se trimite email." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "Expeditor Email" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Cine ar trebui să spunem că a trimis email?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "Nume Cont OPŢIONAL" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Pentru email autentificat, nume cont." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "Parolă Cont OPŢIONAL" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Pentru email autentificat, parola." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "Activează Growl" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "Trimite notificări Growl" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "Adresă server" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "Foloseşte doar pentru server Growl de la distanţă (gazdă:port)" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "Parolă server" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "Parolă opţională server Growl" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "Activează NotifyOSD" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "Trimite notificări către NotifyOSD" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "Centru Notificări" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "Trimite notificări la Centru Notificări" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "Clase notificări" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" "Activează clasă mesaje ce vor fi raportate (niciunul, unul sau mai multe)" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" "Dacă aveţi un cont la www.newzbin2.es, puteţi introduce " "informaţiile contului aici.
    Aceasta va debloca funcţionalitate extra." #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Info Cont" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Nume de Utilizator Newzbin" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Setaţi numele de utilizator de cont aici." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Parolă Newzbin" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Setaţi parola contului dvs. aici." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Procesare Semne de Carte" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Descărcare-Automată Semne de Carte" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Descarcă automat semnele dvs. de carte" #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Ia Semne de Carte Acum" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "Ascunde Semnele de Carte" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "Afișează Semnele de Carte" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Şterge Semn Carte după Descărcare Finalizată" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Şterge din lista dvs. de semne de carte după o descărcare finalizată" #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Interval Verificare" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "În minute (cel puţin 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Semne de Carte Procesate" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Dacă aveţi un cont la www.nzbmatrix.com, puteţi introduce " "informatiile contului dvs. aici .
    Acest lucru este necesar dacă doriţi " "să utilizaţi fluxurile RSS de pe acest site." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "Nume de Utilizator NzbMatrix" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "Cheia API NzbMatrix" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Setaţi cheia API NzbMatrix aici." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Categorii definite de utilizator" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Defineşte post-procesarea şi stocarea." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" "Utilizaţi coloana \"Grupuri /Taguri Indexer\" pentru a desemna taguri " "categoriilor dvs. .
    Metacaracterele sunt acceptate. Utilizaţi virgule " "pentru a separa termeni." #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" "Finalizarea unei căi cu un asterix * va preveni crearea de dosare sarcini." #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Dosarele relative se bazează pe" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Dosar/Cale" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "Grupuri / Taguri Indexer" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Configurare Sortare" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Sortare Seriale" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Activează Sortare TV" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Permite sortarea şi redenumirea de episoade." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Model Cheie" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Şterge" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Presetări" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Exemplu" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Sortare Generică" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Activează Sortare Filme" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Activează sortarea şi redenumirea generică a fişierelor." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Păstrează descărcările suplimentare în dosare extra" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Activează dacă descărcările nu sunt puse în dosarele lor." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Categorii Afectate" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Semnificaţie" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Șablon" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Rezultat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Dosar Sezon" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Dosar Sezon" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Dosar Episod" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Dosar Episod" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Titlu" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Nume Film" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Nume.Film" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Nume_Film" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Nume Serial" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Nume.Serial" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Nume_Serial" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Număr Sezon" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Număr Episod" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Nume Episod" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Nume.Episod" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Nume_Episod" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Extensie fișier" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "Extensie" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Număr Parte" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Deceniu" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Nume de Fişier Original" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "Nume de Dosar Original" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Litere Mici" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "TEXT" #: sabnzbd/skintext.py:667 msgid "text" msgstr "text" #: sabnzbd/skintext.py:668 msgid "file" msgstr "fișier" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "dosar" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Şir Caractere Sortare" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Etichetă Multi-părţi" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "În dosare" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Fără dosare" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Sortare Dată" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Activează Sortare Dată" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Activează sortarea şi redenumirea fişierelor denumite după dată." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Arată Nume dosar" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "Dosar An-Lună" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Dosare Zilnice" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "ajustare nume fişier" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "Rezultat Procesat" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" "Opţiuni folosite rar. Pentru explicaţiile şi semnificaţia lor, click pe " "meniul Ajutor şi vizitează pagina Wiki.
    Nu modificaţi aceste setări fără " "a verifica mai întâi pagina Wiki , pentru că unele pot cauza probleme " "serioase .
    Valorile originale sunt în paranteze ." #: sabnzbd/skintext.py:688 msgid "Values" msgstr "Valori" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Editează Detalii NZB" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Şterge" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Vârf" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Sus" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Jos" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Coadă" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Toate" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Inversează" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Nume de fișier" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Subiect" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Vârsta" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Selecţie" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Sigur doriți să ștergeți" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Reîmprospătează" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Opțiuni" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Pagină" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Precedent" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Următorul" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Primul" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Ultimul" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Închide" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Setează Interval Pauză" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sortează" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Goliţi Coada?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Interval Pauză" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pauză timp de 5 minute" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pauză timp de 15 minute" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pauză timp de 30 minute" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pauză timp de o oră" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pauză timp de 3 ore" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pauză timp de 6 ore" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pauză timp de 12 ore" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pauză timp de 24 ore" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sortează după Vârstă Cel mai Vechi→Cel mai Nou" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sortează după Vârstă Cel mai Nou→Cel mai Vechi" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sortează după Nume A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sortează după Nume Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sortează după Mărime Cel mai Mic→Cel mai Mare" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sortează după Mărime Cel mai Mare→Cel mai Mic" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "Redenumește" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Stânga" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Goliţi Istoricul?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Modificările nu au fost salvate, şi vor fi pierdute." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Deschide URL Sursă" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Dechide URL Informaţii" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Stocare" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Vezi Jurnal Script" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "Trebuie să activaţi JavaScript pentru ca Plush să funcţioneze!" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Adaugă NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Opţiuni Plush" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Actualizare Disponibilă!" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Pauză pentru câte minute?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pauză timp de..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "Operaţii-Multiple" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "Meniu Top" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "La Terminare" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sortează după Vârstă (Cel mai Vechi→Cel mai Nou)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sortează după Vârstă (Cel mai Nou→Cel mai Vechi)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sortează după Nume (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sortează după Nume (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sortează după Mărime (Cel mai Mic→Cel mai Mare)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sortează după Mărime (Cel mai Mare→Cel mai Mic)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Șterge" #: sabnzbd/skintext.py:781 msgid "left" msgstr "rămas" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Viteză Maximă" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Interval" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "Resetează" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "Aplică la Selecţie" #: sabnzbd/skintext.py:786 msgid "page" msgstr "pagină" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Tot" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Dezactivat" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Rata de Reîmprospătare" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "Lăţime Container" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Confirmă Ştergere Coadă" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Confirmă Ştergere Istoric" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" "Acest lucru va preveni reîmprospătarea când cursorul mouse-ului este " "deasupra coadei." #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "Blochează Reîmprospătarea Hover" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Descarcă" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "Încarcă" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Încarcă: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "Opţional specifică un nume de fişier" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Progres" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Spaţiul liber insuficient pe disc pentru finalizarea descărcărilor !" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Spațiu liber" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Gol (Temp)" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "INACTIV" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "Descărcări" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "Coadă reparare" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" "Citeşte Flux va descărca conţinutul fluxului curent. " "Descărcare Forţată va descărca toate NZB-urile " "corespunzătoare acum." #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Ore:Min" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "Ştergere Finalizată" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Ştergeţi toate fişierele nereuşite din istoric?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "Şterge Nereuşite" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Legături" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Afişare %s până la %s din totalul %s rezultate" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "Fără rezultate" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "Afişăm un rezultat" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Email Trimis!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "Notificare Trimisă!" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Salvăm.." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Salvat" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Viteză" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Comută Adaugă NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "VedereDuală1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "VedereDuală2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Personalizat" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Descarcă Semne de Carte" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Sunteţi sigur că doriţi să reporniţi SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Rată actualizare" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Șterge tot" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Ascunde Opţiuni Editare" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Arată Opţiuni Editare" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Editează" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Timp rămas" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "Vrăjitor Pornire-Rapidă SABnzbd" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "Versiune SABnzbd" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Precedent" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Acces" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Vreau SABnzbd să fie vizibil de către orice calculator din reţeaua mea." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Vreau SABnzbd să fie vizibilă numai de pe PC-ul meu." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Acces SABnzbd protejat cu parolă (recomandat)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Permite acces HTTPS la SABnzbd." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Diverse" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Lansează navigatorul meu web la pornirea SABnzbd ." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Detalii Server" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "" "Vă rugăm să introduceţi detaliile furnizorului dvs principal de usenet." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "Pentru a descărca de pe usenet veţi avea nevoie de un furnizor. ISP-ul dvs. " "vă poate oferi acces, totuşi un furnizor premium e recomandat." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Nu aveţi un furnizor usenet? Vă recomandăm să încercaţi %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Numărul de conexiuni permis de furnizor" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "De ex. 8 sau 20" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Selectează doar dacă furnizorul dvs. permite conexiuni SSL." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Clic pentru a testa detaliile introduse." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Acest câmp este obligatoriu." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Vă rugăm să introduceţi un număr întreg." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Dacă sunteţi un membru al newzbin sau nzbmatrix, puteţi introduce numele de " "utilizator şi parola aici, astfel încât să putem descărca nzb-uri de la ei. " "Această etapă poate fi omisă dacă nu folosiţi serviciile lor." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Descărcare automată a semnelor de carte" #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "De ex." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Repornim SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Instalarea este acum completă!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd va rula acum în fundal." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "Închidere a oricărei ferestrele browser/file NU va închide SABnzbd." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" "După repornire SABnzbd ,îl veţi putea acesa la următoarea locaţie: %s" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Este recomandat să faceţi clic dreapta şi să faceţi o scurtatură , pe care " "să o folosiţi pentru a accesa SABnzbd când rulează în fundal." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Ajutor suplimentar poate fi găsit pe pagina noastră" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Du-te la SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Pasul Unu" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Pasul Doi" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Pasul Trei" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Pasul Patru" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Pasul Cinci" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "De ex. 119 sau 563 pentru SSL" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "Închide SABnzbd" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "Porneşte Vrăjitor" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" "\n" "SABnzbd vine cu ABSOLUT NICI O GARANŢIE.\n" "Acesta este software gratis, şi sunteţi binevenit să-l redistribuiţi în " "anumite condiţii.\n" "Este licenţiat sub GNU General Public License versiunea 2 sau (la opţiunea " "dumneavoastră) orice versiune ulterioară.\n" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Eroare obţinere info TV (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Redenumire:%s în %s nereuşită" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Redenumire fişiere similare : %s în %s nereuşită" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Număr report invalid nzbmatrix %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Aveţi nevoie de un cont VIP la nzbmatrix pentru a utiliza API" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "Credenţiale invalide nzbmatrix" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Probleme la accesarea server nzbmatrix (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Numele gazdei nu este setat." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Nu sunt conexiuni stabilite. Vă rugăm să stabiliţi cel puţin o conexiune." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Parolă ascunsă în ******, Vă rugăm să re-introduceţi" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Detalii server invalide" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" "A depăşit timpul alocat : Încercaţi să activaţi SSL sau conectarea pe un " "port diferit." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "A depăşit timpul alocat" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Adresă server invalidă" #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Serverul a renunţat în timpul logării." #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Serverul necesită nume utilizator şi parolă" #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Conexiune Reuşită!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Autentificare nereuşită, verifică nume utilizator/parolă." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "Prea multe conexiuni, vă rugăm să întrerupeţi descărcarea sau să încercaţi " "din nou mai târziu" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Nu pot determina reultatul conexiunii (%s)" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Eroare Descărcare msgid %s de la www.newzbin.com - Vă rugăm asiguraţi-vă că " #~ "Numele de Utilizator şi Parola sunt stabilite" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "descarc msgid %s de la www.newzbin.com" #~ msgid "Expected size did not equal actual size" #~ msgstr "Mărimea aşteptată nu este egală cu cea reală" #~ msgid "Could not compile regex: %s" #~ msgstr "Nu am putut compila regex: %s" #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Veţi avea nevoie să setaţi o parolă şi să reluaţi sarcina." #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Întrerupe o sarcină când sunt descărcate fişiere RAR encriptate" #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Dacă aveţi un cont la www.newzbin.com, puteţi introduce " #~ "informatiile contului dvs. aici.
    Aceasta va debloca funcţionalitate " #~ "extra." #~ msgid "Email Notifications" #~ msgstr "Notificări Email" #~ msgid "Quotum period" #~ msgstr "Perioadă cotă" #~ msgid "Should downloading resume after the quotum is reset?" #~ msgstr "Reia descărcarea după resetarea cotei ?" #~ msgid "Does the quotum get reset each day, week or month?" #~ msgstr "Cota se resetează în fiecare zi, săptămână sau lună ?" #~ msgid "" #~ "On which day of the month or week (1=Monday) does your ISP reset the quotum? " #~ "(Optionally with hh:mm)" #~ msgstr "" #~ "În ce zi a lunii sau săptămână (1=Luni) ISP dvs. resetează cota ? (Opțional " #~ "cu hh:mm)" #~ msgid "Quotum" #~ msgstr "Cotă" #~ msgid "Quotum left" #~ msgstr "Cotă rămasă" SABnzbd-0.7.20/po/main/SABnzbd.pot0000644000000000000000000026606012433712555016617 0ustar00usergroup00000000000000# # SABnzbd Translation Template file MAIN # Copyright (C) 2011-2012 by the SABnzbd Team # team@sabnzbd.org # msgid "" msgstr "" "Project-Id-Version: SABnzbd-0.7.x\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: shypike@sabnzbd.org\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 7bit\n" "POT-Creation-Date: 2014-07-01 21:29+CEST\n" "Generated-By: pygettext.py 1.5\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "" #: SABnzbd.py:640 [Warning message] msgid "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external access" msgstr "" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "" #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "" #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "" #: sabnzbd/__init__.py:500 [Error message] msgid "Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are set" msgstr "" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "" #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "" #: sabnzbd/assembler.py:127 [Warning message] msgid "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "" #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "" #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "" #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "" #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "" #: sabnzbd/interface.py:212 msgid "API Key missing, please enter the api key from Config->General into your 3rd party program:" msgstr "" #: sabnzbd/interface.py:219 msgid "API Key incorrect, Use the api key from Config->General in your 3rd party program:" msgstr "" #: sabnzbd/interface.py:228 msgid "Authentication missing, please enter username/password from Config->General into your 3rd party program:" msgstr "" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "" #: sabnzbd/interface.py:292 msgid "Your UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    " msgstr "" #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "" #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "" #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "" #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    " msgstr "" #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr "" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "" #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "" #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "" #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "" #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "" #: sabnzbd/newsunpack.py:1042 msgid "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "" #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "" #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "" #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "" #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "If you get this error message again, please try a different number.
    " msgstr "" #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" #: sabnzbd/panic.py:140 msgid "OK" msgstr "" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.
    \n" "
    \n" msgstr "" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "" #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "" #: sabnzbd/postproc.py:98 [Warning message] msgid "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "" #: sabnzbd/postproc.py:470 msgid "More" msgstr "" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "" #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "" #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "" #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "" #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "" #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "" #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "" #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "" #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "" #: sabnzbd/skintext.py:79 msgid "day" msgstr "" #: sabnzbd/skintext.py:80 msgid "days" msgstr "" #: sabnzbd/skintext.py:81 msgid "week" msgstr "" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "" #: sabnzbd/skintext.py:97 msgid "on" msgstr "" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "" #: sabnzbd/skintext.py:174 msgid " " msgstr "" #: sabnzbd/skintext.py:175 msgid "R" msgstr "" #: sabnzbd/skintext.py:176 msgid "U" msgstr "" #: sabnzbd/skintext.py:177 msgid "D" msgstr "" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "" #: sabnzbd/skintext.py:181 msgid "High" msgstr "" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr "" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "" #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "" #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "" #: sabnzbd/skintext.py:276 msgid "This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards." msgstr "" #: sabnzbd/skintext.py:278 msgid "There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue." msgstr "" #: sabnzbd/skintext.py:280 msgid "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order." msgstr "" #: sabnzbd/skintext.py:282 msgid "Version" msgstr "" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "" #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "" #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "" #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "" #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "" #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "" #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "" #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "" #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "" #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "" #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "" #: sabnzbd/skintext.py:320 msgid "Checking interval (in minutes, at least 15). Not active when you use the Scheduler!" msgstr "" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "" #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "" #: sabnzbd/skintext.py:324 msgid "Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "" #: sabnzbd/skintext.py:326 msgid "List of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfv" msgstr "" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "" #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "" #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "" #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "" #: sabnzbd/skintext.py:343 msgid "NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders." msgstr "" #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "" #: sabnzbd/skintext.py:345 msgid "In" msgstr "" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py:347 msgid "Location to store unprocessed downloads.
    Can only be changed when queue is empty." msgstr "" #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "" #: sabnzbd/skintext.py:349 msgid "Auto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "" #: sabnzbd/skintext.py:351 msgid "Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories." msgstr "" #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "" #: sabnzbd/skintext.py:353 msgid "Set permissions pattern for completed files/folders.
    In octal notation. For example: \"755\" or \"777\"" msgstr "" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "" #: sabnzbd/skintext.py:355 msgid "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files." msgstr "" #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "" #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "" #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "" #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "" #: sabnzbd/skintext.py:366 msgid "Location for queue admin and history database.
    Can only be changed when queue is empty." msgstr "" #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "" #: sabnzbd/skintext.py:369 msgid "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr "" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "" #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "" #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "" #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "" #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "" #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "" #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "" #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "" #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "" #: sabnzbd/skintext.py:392 msgid "Enable for less memory usage. Disable to prevent slow jobs from blocking the queue." msgstr "" #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "" #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py:396 msgid "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "" #: sabnzbd/skintext.py:398 msgid "Detect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds." msgstr "" #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "" #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "" #: sabnzbd/skintext.py:412 msgid "Use temporary names during post processing. Disable when your system doesn't handle that properly." msgstr "" #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "" #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "" #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "" #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "" #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "" #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "" #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "" #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "" #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "" #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "" #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "" #: sabnzbd/skintext.py:444 msgid "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "" #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "" #: sabnzbd/skintext.py:448 msgid "Pauses downloading at the start of post processing and resumes when finished." msgstr "" #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "" #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "" #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "" #: sabnzbd/skintext.py:468 msgid "On which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)" msgstr "" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py:480 msgid "When during download it becomes clear that too much data is missing, abort the job" msgstr "" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "Enhanced functionality including ratings and extra status information is available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "This key provides identity to indexer. Refer to https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "" #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "" #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "" #: sabnzbd/skintext.py:529 msgid "The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press \"Force Download\"." msgstr "" #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "" #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "" #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "" #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "" #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "" #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" #: sabnzbd/skintext.py:590 msgid "If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality." msgstr "" #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "" #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "" #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "" #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "" #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "" #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "" #: sabnzbd/skintext.py:607 msgid "If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site." msgstr "" #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "" #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "" #: sabnzbd/skintext.py:616 msgid "Use the \"Groups / Indexer tags\" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" #: sabnzbd/skintext.py:617 msgid "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "" #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "" #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "" #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "" #: sabnzbd/skintext.py:667 msgid "text" msgstr "" #: sabnzbd/skintext.py:668 msgid "file" msgstr "" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "" #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "" #: sabnzbd/skintext.py:684 msgid "Rarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    Don't change these without checking the Wiki first, as some have serious side-effects.
    The default values are between parentheses." msgstr "" #: sabnzbd/skintext.py:688 msgid "Values" msgstr "" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "" #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "" #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "" #: sabnzbd/skintext.py:781 msgid "left" msgstr "" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "" #: sabnzbd/skintext.py:786 msgid "page" msgstr "" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "" #: sabnzbd/skintext.py:793 msgid "This will prevent refreshing content when your mouse cursor is hovering over the queue." msgstr "" #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "" #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "" #: sabnzbd/skintext.py:809 msgid "Read Feed will get the current feed content. Force Download will download all matching NZBs now." msgstr "" #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "" #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "" #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "" #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "" #: sabnzbd/skintext.py:864 msgid "Launch my internet browser with the SABnzbd page when the program starts." msgstr "" #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "" #: sabnzbd/skintext.py:868 msgid "In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended." msgstr "" #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "" #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "" #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "" #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "" #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "" #: sabnzbd/skintext.py:876 msgid "If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb's. This stage can be skipped if you don't use either services." msgstr "" #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "" #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "" #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "" #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "" #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" #: sabnzbd/skintext.py:885 [Wizard tip] msgid "After SABnzbd has finished restarting you will be able to access it at the following location: %s" msgstr "" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background." msgstr "" #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version.\n" msgstr "" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "" #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "" #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "" #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "" #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "" #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "" SABnzbd-0.7.20/po/main/sv.po0000644000000000000000000035724012433712556015602 0ustar00usergroup00000000000000# Swedish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-07-02 18:06+0000\n" "PO-Revision-Date: 2013-03-17 20:50+0000\n" "Last-Translator: Kristofer Norén \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2014-07-03 05:55+0000\n" "X-Generator: Launchpad (build 17082)\n" #: SABnzbd.py:304 [Error message] msgid "Failed to start web-interface" msgstr "Det gick inte att starta webbgränssnittet" #: SABnzbd.py:342 [Warning message] msgid "Cannot find web template: %s, trying standard template" msgstr "Hittar inte webbmall: %s, försöker med standardmall" #: SABnzbd.py:467 [Error message] msgid "_yenc module... NOT found!" msgstr "_yenc modul... EJ funnen!" #: SABnzbd.py:474 [Error message] msgid "par2 binary... NOT found!" msgstr "par2 binär... EJ funnen!" #: SABnzbd.py:482 [Warning message] msgid "unrar binary... NOT found" msgstr "unrar binär... EJ funnen!" #: SABnzbd.py:487 [Warning message] msgid "unzip binary... NOT found!" msgstr "unzip binär... EJ funnen!" #: SABnzbd.py:640 [Warning message] msgid "" "Please be aware the 0.0.0.0 hostname will need an IPv6 address for external " "access" msgstr "" "Tänk på att värdnamnet 0.0.0.0 behöver en IPv6-adress för extern åtkomst" #: SABnzbd.py:1389 [Warning message] msgid "Disabled HTTPS because of missing CERT and KEY files" msgstr "Avaktiverade HTTPS då CERT och KEY -filer saknas" #: SABnzbd.py:1550 msgid "SABnzbd %s started" msgstr "" #: SABnzbd.py:1701 # sabnzbd/osxmenu.py:771 msgid "SABnzbd shutdown finished" msgstr "SABnzbd nedstängning utförd." #: sabnzbd/__init__.py:170 [Warning message] msgid "Signal %s caught, saving and exiting..." msgstr "Signal %s mottagen, sparar och stänger..." #: sabnzbd/__init__.py:494 msgid "fetching msgid %s from www.newzbin2.es" msgstr "Hämtar msgid %s från www.newzbin2.es" #: sabnzbd/__init__.py:500 [Error message] msgid "" "Error Fetching msgid %s from www.newzbin2.es - Please make sure your " "Username and Password are set" msgstr "" "Fel vid hämtning av msgid %s från www.newzbin2.es - Kontrollera att " "användarnamn och lösenord är angivna" #: sabnzbd/__init__.py:512 msgid "Trying to fetch NZB from %s" msgstr "Försöker att hämta NZB från %s" #: sabnzbd/__init__.py:636 [Error message] msgid "Cannot create temp file for %s" msgstr "Kan inte skapa temp -fil för %s" #: sabnzbd/__init__.py:653 [Warning message] # sabnzbd/__init__.py:665 [Warning message] msgid "Trying to set status of non-existing server %s" msgstr "Försöker att sätta status på icke existerande server %s" #: sabnzbd/__init__.py:806 [Warning message] msgid "Too little diskspace forcing PAUSE" msgstr "För lite diskutrymme pausar systemet" #: sabnzbd/__init__.py:832 [Error message] msgid "Failure in tempfile.mkstemp" msgstr "Fel i tempfile.mkstemp" #: sabnzbd/__init__.py:862 [Error message] # sabnzbd/__init__.py:933 [Error message] msgid "Saving %s failed" msgstr "Sparar %s misslyckades" #: sabnzbd/__init__.py:892 [Error message] # sabnzbd/__init__.py:962 [Error message] msgid "Loading %s failed" msgstr "Laddning av %s misslyckades" #: sabnzbd/api.py:694 # sabnzbd/skintext.py:587 msgid "Test Notification" msgstr "Testa notifikation" #: sabnzbd/api.py:1562 # sabnzbd/osxmenu.py:193 # sabnzbd/skintext.py:69 [No value, used in dropdown menus] #: sabnzbd/skintext.py:699 [Job details page, select no files] msgid "None" msgstr "Ingen" #: sabnzbd/api.py:1564 # sabnzbd/interface.py:99 # sabnzbd/skintext.py:68 [Default value, used in dropdown menus] msgid "Default" msgstr "Standard" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 msgid "WARNING:" msgstr "VARNING:" #: sabnzbd/api.py:1624 # sabnzbd/interface.py:2402 # sabnzbd/interface.py:2502 msgid "ERROR:" msgstr "FEL:" #: sabnzbd/api.py:1690 msgid "unknown" msgstr "okänd" #: sabnzbd/api.py:1713 [Error message] msgid "Failed to compile regex for search term: %s" msgstr "Det gick inte att kompilera regex för sök-sträng: %s" #: sabnzbd/api.py:1919 [Single letter abbreviation of day] msgid "d" msgstr "d" #: sabnzbd/api.py:1920 [Single letter abbreviation of hour] msgid "h" msgstr "h" #: sabnzbd/api.py:1921 [Single letter abbreviation of minute] msgid "m" msgstr "m" #: sabnzbd/assembler.py:98 [Error message] msgid "Disk full! Forcing Pause" msgstr "Disken är full! Pausar..." #: sabnzbd/assembler.py:100 [Error message] msgid "Disk error on creating file %s" msgstr "Diskfel vid skapande av fil %s" #: sabnzbd/assembler.py:117 [Warning message] msgid "WARNING: Paused job \"%s\" because of encrypted RAR file" msgstr "WARNING: Paused job \"%s\" because of encrypted RAR file" #: sabnzbd/assembler.py:120 [Warning message] msgid "WARNING: Aborted job \"%s\" because of encrypted RAR file" msgstr "Varning: avbröt jobbet %s på grund av att RAR-filen är krypterad" #: sabnzbd/assembler.py:121 msgid "Aborted, encryption detected" msgstr "" #: sabnzbd/assembler.py:127 [Warning message] msgid "" "WARNING: In \"%s\" unwanted extension in RAR file. Unwanted file is %s " msgstr "" #: sabnzbd/assembler.py:128 msgid "Unwanted extension is in rar file %s" msgstr "" #: sabnzbd/assembler.py:135 msgid "Aborted, unwanted extension detected" msgstr "" #: sabnzbd/assembler.py:171 msgid "%s missing" msgstr "%s saknas" #: sabnzbd/bpsmeter.py:233 [Warning message] msgid "Quota spent, pausing downloading" msgstr "Din kvot är uppnådd, pausar nerladdning" #: sabnzbd/cfg.py:46 msgid "%s is not a valid email address" msgstr "%s är inte en godkänd e-mail adress" #: sabnzbd/cfg.py:54 # sabnzbd/interface.py:1637 msgid "Server address required" msgstr "Kräver serveradress" #: sabnzbd/config.py:216 msgid "Cannot create %s folder %s" msgstr "Kan inte skapa %s mapp %s" #: sabnzbd/config.py:774 [Error message] # sabnzbd/config.py:791 [Error message] msgid "Cannot write to INI file %s" msgstr "Kan inte skriva till INI filen %s" #: sabnzbd/config.py:782 [Warning message] msgid "Cannot create backup file for %s" msgstr "Kan inte skapa backup-fil för %s" #: sabnzbd/config.py:914 [Error message] msgid "Incorrectly encoded password %s" msgstr "Felaktigt kodat lösenord %s" #: sabnzbd/config.py:938 msgid "%s is not a correct octal value" msgstr "%s är inte rätt siffervärde" #: sabnzbd/config.py:947 msgid "UNC path \"%s\" not allowed here" msgstr "UNC sökväg \"%s\" är inte tillåten här" #: sabnzbd/config.py:955 msgid "Error: Queue not empty, cannot change folder." msgstr "Fel: Kön är inte tom, kan inte byta mapp." #: sabnzbd/config.py:964 msgid "Folder \"%s\" does not exist" msgstr "Mappen \"%s\" finns inte" #: sabnzbd/database.py:111 [Error message] msgid "SQL Command Failed, see log" msgstr "SQL Kommando misslyckades, se logg" #: sabnzbd/database.py:154 [Error message] msgid "SQL Commit Failed, see log" msgstr "SQL Commit misslyckades, se logg" #: sabnzbd/database.py:162 [Error message] msgid "Failed to close database, see log" msgstr "Det gick inte att stänga databasen, se logg" #: sabnzbd/database.py:393 [Error message] # sabnzbd/database.py:410 [Error message] msgid "Invalid stage logging in history for %s" msgstr "Felaktig loggning i historiken av %s" #: sabnzbd/decoder.py:107 msgid "Decoding %s failed" msgstr "Avkodning av %s misslyckades" #: sabnzbd/decoder.py:120 msgid "CRC Error in %s (%s -> %s)" msgstr "CRC Fel i %s (%s -> %s)" #: sabnzbd/decoder.py:157 msgid "Badly formed yEnc article in %s" msgstr "Felaktigt utformad yEnc artikel i %s" #: sabnzbd/decoder.py:167 msgid "Unknown Error while decoding %s" msgstr "Okänt fel under avkodning av %s" #: sabnzbd/decoder.py:229 msgid "%s => missing from all servers, discarding" msgstr "%s => saknas från alla servrar, kastar" #: sabnzbd/dirscanner.py:127 [Error message] # sabnzbd/dirscanner.py:200 [Error message] msgid "Error removing %s" msgstr "Fel vid borttagning av %s" #: sabnzbd/dirscanner.py:165 [Warning message] msgid "Cannot read %s" msgstr "Kan ej läsa %s" #: sabnzbd/dirscanner.py:300 [Error message] # sabnzbd/dirscanner.py:383 [Error message] msgid "Cannot read Watched Folder %s" msgstr "Kan ej läsa övervakad mapp %s" #: sabnzbd/downloader.py:221 # sabnzbd/osxmenu.py:445 # sabnzbd/sabtray.py:81 #: sabnzbd/skintext.py:37 [PP status] # sabnzbd/skintext.py:183 # sabnzbd/skintext.py:828 msgid "Paused" msgstr "Pausad" #: sabnzbd/downloader.py:290 # sabnzbd/downloader.py:291 [Warning message] msgid "Server %s will be ignored for %s minutes" msgstr "Server %s kommer att ignoreras i %s minuter" #: sabnzbd/downloader.py:384 [Error message] msgid "Failed to initialize %s@%s:%s" msgstr "Det gick inte att initialisera %s@%s:%s" #: sabnzbd/downloader.py:515 # sabnzbd/downloader.py:516 [Error message] msgid "Too many connections to server %s:%s" msgstr "För många anslutningar till server %s:%s" #: sabnzbd/downloader.py:523 # sabnzbd/downloader.py:525 [Error message] msgid "Probable account sharing" msgstr "Misstänkt kontodelning" #: sabnzbd/downloader.py:530 # sabnzbd/downloader.py:531 [Error message] msgid "Failed login for server %s" msgstr "Det gick inte att logga in på server %s" #: sabnzbd/downloader.py:537 # sabnzbd/downloader.py:538 [Warning message] #: sabnzbd/downloader.py:553 # sabnzbd/downloader.py:554 [Error message] msgid "Cannot connect to server %s [%s]" msgstr "Kan ej ansluta till server %s [%s]" #: sabnzbd/downloader.py:568 [Error message] msgid "Connecting %s@%s:%s failed, message=%s" msgstr "Anslutning av %s@%s:%s misslyckades, meddelande=%s" #: sabnzbd/downloader.py:607 # sabnzbd/downloader.py:610 msgid "Server %s requires user/password" msgstr "Server %s kräver användarnamn/lösenord" #: sabnzbd/downloader.py:803 msgid "Shutting down" msgstr "Påbörjar nedstängning av SABnzbd.." #: sabnzbd/emailer.py:96 # sabnzbd/emailer.py:98 msgid "Failed to connect to mail server" msgstr "Det gick inte att ansluta till mailserver" #: sabnzbd/emailer.py:110 msgid "Failed to initiate TLS connection" msgstr "Det gick inte att initialisera TLS anslutning" #: sabnzbd/emailer.py:117 msgid "Failed to authenticate to mail server" msgstr "Autentisering till mailserver misslyckades" #: sabnzbd/emailer.py:131 msgid "Failed to send e-mail" msgstr "Det gick inte att skicka e-mail" #: sabnzbd/emailer.py:136 msgid "Failed to close mail connection" msgstr "Det gick inte att stänga e-mail anslutning" #: sabnzbd/emailer.py:142 msgid "Email succeeded" msgstr "E-mail sändning lyckades" #: sabnzbd/emailer.py:172 [Error message] msgid "Cannot find email templates in %s" msgstr "Kan ej finna e-mail mallar i %s" #: sabnzbd/emailer.py:203 msgid "No recipients given, no email sent" msgstr "Ingen mottager angiven, ingen email har skickats" #: sabnzbd/emailer.py:205 msgid "Invalid encoding of email template %s" msgstr "Ogiltig avkodning av email mallen %s" #: sabnzbd/emailer.py:208 msgid "No email templates found" msgstr "Inga email mallar funna" #: sabnzbd/emailer.py:271 msgid "" "To: %s\n" "From: %s\n" "Date: %s\n" "Subject: SABnzbd reports Disk Full\n" "\n" "Hi,\n" "\n" "SABnzbd has stopped downloading, because the disk is almost full.\n" "Please make room and resume SABnzbd manually.\n" "\n" msgstr "" "Till: %s\n" "Från: %s\n" "Datum: %s\n" "Ämne: SABnzbd rapporterar att disk är full\n" "\n" "Hej,\n" "\n" "SABnzbd har stoppat nerladdningen på grund av att din disk inte har " "tillräckligt med utrymme kvar.\n" "Frigör utrymme och återuppta nerladdningen manuellt.\n" "\n" #: sabnzbd/growler.py:57 [Message class for Growl server] msgid "Startup/Shutdown" msgstr "Starta/Stäng" #: sabnzbd/growler.py:58 [Message class for Growl server] msgid "Added NZB" msgstr "NZB tillagd" #: sabnzbd/growler.py:59 [Message class for Growl server] msgid "Post-processing started" msgstr "Efterbehandling påbörjad" #: sabnzbd/growler.py:60 [Message class for Growl server] msgid "Job finished" msgstr "Arbetet utförd" #: sabnzbd/growler.py:61 [Message class for Growl server] msgid "Other Messages" msgstr "Andra meddelanden" #: sabnzbd/interface.py:80 msgid "Warning: LOCALHOST is ambiguous, use numerical IP-address." msgstr "Varning: LOCALHOST är tvetydigt, använda numerisk IP-adress ." #: sabnzbd/interface.py:85 msgid "Server address \"%s:%s\" is not valid." msgstr "Serveradressen \"%s:%s\" är ej giltig." #: sabnzbd/interface.py:175 [Warning message] msgid "Missing Session key" msgstr "Saknar sessionsnyckel" #: sabnzbd/interface.py:176 msgid "Error: Session Key Required" msgstr "Fel: Kräver sessionsnyckel" #: sabnzbd/interface.py:178 [Warning message] # sabnzbd/interface.py:179 msgid "Error: Session Key Incorrect" msgstr "Fel: Fel sessionsnyckel" #: sabnzbd/interface.py:212 msgid "" "API Key missing, please enter the api key from Config->General into your 3rd " "party program:" msgstr "" "API-nyckel saknas, skriv in api-nyckeln från Konfiguration-> Allmänt i ditt " "tredjepartsprogram:" #: sabnzbd/interface.py:219 msgid "" "API Key incorrect, Use the api key from Config->General in your 3rd party " "program:" msgstr "" "API-nyckel felaktig, använd api-nyckeln från Konfiguration-> Allmänt i ditt " "tredjepartsprogram:" #: sabnzbd/interface.py:228 msgid "" "Authentication missing, please enter username/password from Config->General " "into your 3rd party program:" msgstr "" "Autentisering saknas, ange användarnamn / lösenord från Konfiguration-> " "Allmänt i ditt tredjepartsprogram:" #: sabnzbd/interface.py:240 msgid "Error: No secondary interface defined." msgstr "Fel: Inget andrainterface definierat." #: sabnzbd/interface.py:292 msgid "" "Your UNRAR version is not recommended, get it from " "http://www.rarlab.com/rar_add.htm
    " msgstr "" "Din version av UNRAR rekommenderas inte, få UNRAR från " "http://www.rarlab.com/rar_add.htm
    " #: sabnzbd/interface.py:294 msgid "No UNRAR program found, unpacking RAR files is not possible
    " msgstr "Inget UNRAR program funnet, uppackning ej möjlig
    " #: sabnzbd/interface.py:296 msgid "No PAR2 program found, repairs not possible
    " msgstr "Inget PAR2 program funnet, reparation ej möjlig
    " #: sabnzbd/interface.py:909 [Abbreviation for bytes, as in GB] msgid "B" msgstr "" #: sabnzbd/interface.py:1109 # sabnzbd/interface.py:1121 msgid "Initiating restart...
    " msgstr "Förbereder omstart...
    " #: sabnzbd/interface.py:1111 # sabnzbd/interface.py:1123 msgid "" " 
    SABnzbd shutdown finished.
    Wait for about 5 second and then " "click the button below.

    Refresh
    " msgstr "" " 
    SABnzbd nedstängning färdig.
    Vänta ungefär 5 sekunder och " "klicka sedan på knappen under..

    Ladda " "om
    " #: sabnzbd/interface.py:1754 [Used as default Feed name in Config->RSS] # sabnzbd/skintext.py:530 [Config->RSS, tab header] msgid "Feed" msgstr "Flöde" #: sabnzbd/interface.py:1992 # sabnzbd/skintext.py:84 msgid "Daily" msgstr "Dagligen" #: sabnzbd/interface.py:1993 # sabnzbd/skintext.py:85 msgid "Monday" msgstr "Måndag" #: sabnzbd/interface.py:1994 # sabnzbd/skintext.py:86 msgid "Tuesday" msgstr "Tisdag" #: sabnzbd/interface.py:1995 # sabnzbd/skintext.py:87 msgid "Wednesday" msgstr "Onsdag" #: sabnzbd/interface.py:1996 # sabnzbd/skintext.py:88 msgid "Thursday" msgstr "Torsdag" #: sabnzbd/interface.py:1997 # sabnzbd/skintext.py:89 msgid "Friday" msgstr "Fredag" #: sabnzbd/interface.py:1998 # sabnzbd/skintext.py:90 msgid "Saturday" msgstr "Lördag" #: sabnzbd/interface.py:1999 # sabnzbd/skintext.py:91 msgid "Sunday" msgstr "Söndag" #: sabnzbd/interface.py:2027 ["Off" value for speedlimit in scheduler] # sabnzbd/skintext.py:98 msgid "off" msgstr "av" #: sabnzbd/interface.py:2394 msgid " Resolving address" msgstr " Lösa adress" #: sabnzbd/interface.py:2502 msgid "Incorrect parameter" msgstr "Fel parameter" #: sabnzbd/interface.py:2502 # sabnzbd/interface.py:2528 #: sabnzbd/interface.py:2552 # sabnzbd/interface.py:2569 #: sabnzbd/interface.py:2659 # sabnzbd/interface.py:2678 # sabnzbd/skintext.py:117 [Generic "Back" button] msgid "Back" msgstr "Bakåt" #: sabnzbd/interface.py:2569 msgid "Job \"%s\" was re-added to the queue" msgstr "Jobb \"%s\" är återinlagt i kön" #: sabnzbd/interface.py:2659 msgid "Jobs marked with a '*' will not be automatically downloaded." msgstr "Jobb markerade med '*' kommer ej att laddas ned automatiskt." #: sabnzbd/interface.py:2659 # sabnzbd/skintext.py:544 [Config->RSS section header] msgid "Matched" msgstr "Matchade" #: sabnzbd/interface.py:2660 msgid "Not matched" msgstr "Matchade inte" #: sabnzbd/interface.py:2660 # sabnzbd/skintext.py:546 [Config->RSS section header] msgid "Downloaded" msgstr "Nedladdae" #: sabnzbd/interface.py:2678 msgid "Downloaded so far" msgstr "Nedladdade än så länge" #: sabnzbd/interface.py:2730 # sabnzbd/interface.py:2734 msgid "Incorrect value for %s: %s" msgstr "Fel värde för %s: %s" #: sabnzbd/misc.py:372 [Error message] # sabnzbd/tvsort.py:176 [Error message] msgid "Cannot create directory %s" msgstr "Kan ej skapa mapp %s" #: sabnzbd/misc.py:378 [Error message] msgid "%s directory: %s error accessing" msgstr "%s mapp: %s åtkomst misslyckad" #: sabnzbd/misc.py:400 [Error message] msgid "Cannot connect to registry hive HKEY_CURRENT_USER." msgstr "Kan ej ansluta till registret HKEY_CURRENT_USER." #: sabnzbd/misc.py:407 [Error message] msgid "Cannot open registry key \"%s\"." msgstr "Kan ej öppna registernyckel \"%s\"." #: sabnzbd/misc.py:434 [Error message] msgid "Failed to read registry keys for special folders" msgstr "Det gick inte att läsa registernyckel för specialmappar" #: sabnzbd/misc.py:791 [Error message] msgid "Failed making (%s)" msgstr "Skapande av (%s) misslyckades" #: sabnzbd/misc.py:826 [Error message] # sabnzbd/postproc.py:370 msgid "Failed moving %s to %s" msgstr "Det gick inte att flyta %s till %s" #: sabnzbd/misc.py:950 msgid "Unusable NZB file" msgstr "Oanvändbar NZB fil" #: sabnzbd/misc.py:961 msgid "Try again" msgstr "Försök igen" #: sabnzbd/misc.py:961 # sabnzbd/misc.py:969 msgid "URL Fetching failed; %s" msgstr "URL hämtning misslyckades; %s" #: sabnzbd/misc.py:1154 [Warning message] msgid "pyopenssl module missing, please install for https access" msgstr "pyopenssl modul saknas, var vändlig installera för https åtkomst" #: sabnzbd/misc.py:1172 [Error message] msgid "Error creating SSL key and certificate" msgstr "Det gick inte att skapa SSL-nyckel eller certifikat." #: sabnzbd/misc.py:1359 [Error message] msgid "Cannot change permissions of %s" msgstr "Det gick inte att ändra rättigheter på %s" #: sabnzbd/newsunpack.py:355 msgid "Joining" msgstr "Slår ihop" #: sabnzbd/newsunpack.py:373 msgid "Incomplete sequence of joinable files" msgstr "Ej komplett sekvens av filer för ihopläggning" #: sabnzbd/newsunpack.py:374 # sabnzbd/newsunpack.py:382 msgid "File join of %s failed" msgstr "Filsammanslagning av %s misslyckades" #: sabnzbd/newsunpack.py:375 # sabnzbd/newsunpack.py:383 msgid "[%s] Error \"%s\" while joining files" msgstr "[%s] Fel \"%s\" under filsammanslagning" #: sabnzbd/newsunpack.py:376 [Error message] # sabnzbd/newsunpack.py:384 [Error message] msgid "Error \"%s\" while running file_join on %s" msgstr "Fel \"%s\" när du kör file_join på %s" #: sabnzbd/newsunpack.py:378 msgid "[%s] Joined %s files" msgstr "[%s] Slår ihop %s filer" #: sabnzbd/newsunpack.py:434 # sabnzbd/newsunpack.py:788 msgid "Unpacking failed, %s" msgstr "Uppackning misslyckades, %s" #: sabnzbd/newsunpack.py:436 msgid "[%s] Error \"%s\" while unpacking RAR files" msgstr "[%s] Fel \"%s\" under uppackning av RAR fil(er)" #: sabnzbd/newsunpack.py:438 [Error message] msgid "Error \"%s\" while running rar_unpack on %s" msgstr "Fel \"%s\" när du kör rar_unpack på %s" #: sabnzbd/newsunpack.py:453 [Warning message] # sabnzbd/newsunpack.py:462 [Warning message] #: sabnzbd/newsunpack.py:773 [Warning message] # sabnzbd/newsunpack.py:783 [Warning message] #: sabnzbd/newsunpack.py:890 [Warning message] # sabnzbd/newsunpack.py:900 [Warning message] #: sabnzbd/newsunpack.py:907 [Warning message] # sabnzbd/newsunpack.py:914 [Warning message] #: sabnzbd/newsunpack.py:930 [Warning message] msgid "Deleting %s failed!" msgstr "Borttagning av %s misslyckades!" #: sabnzbd/newsunpack.py:509 msgid "Trying unrar with password \"%s\"" msgstr "Försöker att packa upp med lösenord %s" #: sabnzbd/newsunpack.py:517 [Error message] # sabnzbd/newsunpack.py:661 #: sabnzbd/newsunpack.py:662 msgid "Unpacking failed, archive requires a password" msgstr "Uppackning misslyckades, arkivet kräver lösenord" #: sabnzbd/newsunpack.py:582 # sabnzbd/newsunpack.py:602 #: sabnzbd/newsunpack.py:748 msgid "Unpacking" msgstr "Packar upp" #: sabnzbd/newsunpack.py:606 # sabnzbd/newsunpack.py:607 msgid "Unpacking failed, unable to find %s" msgstr "Uppackning misslyckades, gick inte att hitta %s" #: sabnzbd/newsunpack.py:609 [Warning message] msgid "ERROR: unable to find \"%s\"" msgstr "FEL: gick inte att hitta \"%s\"" #: sabnzbd/newsunpack.py:614 msgid "Unpacking failed, CRC error" msgstr "Uppackning misslyckades, CRC-fel" #: sabnzbd/newsunpack.py:615 # sabnzbd/newsunpack.py:617 [Warning message] msgid "ERROR: CRC failed in \"%s\"" msgstr "FEL: CRC misslyckades i \"%s\"" #: sabnzbd/newsunpack.py:621 # sabnzbd/newsunpack.py:622 #: sabnzbd/newsunpack.py:634 # sabnzbd/newsunpack.py:635 msgid "Unpacking failed, write error or disk is full?" msgstr "Uppackning misslyckades, skrivfel eller disken full?" #: sabnzbd/newsunpack.py:624 [Error message] # sabnzbd/newsunpack.py:636 [Error message] msgid "ERROR: write error (%s)" msgstr "FEL: skrivningsfel (%s)" #: sabnzbd/newsunpack.py:630 # sabnzbd/newsunpack.py:631 msgid "Unpacking failed, path is too long" msgstr "Uppackning misslyckades, sökvägen är för lång" #: sabnzbd/newsunpack.py:632 [Error message] msgid "ERROR: path too long (%s)" msgstr "FEL: sökvägen är för lång (%s)" #: sabnzbd/newsunpack.py:641 msgid "Unpacking failed, see log" msgstr "Uppackning misslyckades, se logg" #: sabnzbd/newsunpack.py:642 [Warning message] # sabnzbd/newsunpack.py:643 msgid "ERROR: %s" msgstr "FEL: %s" #: sabnzbd/newsunpack.py:673 # sabnzbd/newsunpack.py:674 msgid "Unusable RAR file" msgstr "" #: sabnzbd/newsunpack.py:714 msgid "Missing expected file: %s => unrar error?" msgstr "Saknade förväntad fil: %s => unrar fel?" #: sabnzbd/newsunpack.py:717 msgid "Unpacking failed, an expected file was not unpacked" msgstr "Uppackning misslyckades, en väntad fil är inte uppackad" #: sabnzbd/newsunpack.py:719 msgid "Unpacking failed, these file(s) are missing:" msgstr "Uppackning misslyckades, dessa filer saknas:" #: sabnzbd/newsunpack.py:726 msgid "Unpacked %s files/folders in %s" msgstr "Uppackad %s filer/mappar i %s" #: sabnzbd/newsunpack.py:760 msgid "%s files in %s" msgstr "%s filer i %s" #: sabnzbd/newsunpack.py:789 [Error message] msgid "Error \"%s\" while running unzip() on %s" msgstr "Fel \"%s\" när du kör unzip() på %s" #: sabnzbd/newsunpack.py:832 msgid "Quick Checking" msgstr "Snabbkontrollerar" #: sabnzbd/newsunpack.py:832 # sabnzbd/newsunpack.py:846 # sabnzbd/skintext.py:27 [PP phase "repair"] #: sabnzbd/skintext.py:179 # sabnzbd/skintext.py:279 msgid "Repair" msgstr "Reparerar" #: sabnzbd/newsunpack.py:836 msgid "[%s] Quick Check OK" msgstr "[%s] Snabbkontroll OK" #: sabnzbd/newsunpack.py:846 msgid "Starting Repair" msgstr "Startar reparation" #: sabnzbd/newsunpack.py:873 # sabnzbd/newsunpack.py:933 msgid "Repairing failed, %s" msgstr "Reparation misslyckades, %s" #: sabnzbd/newsunpack.py:874 [Error message] msgid "Error %s while running par2_repair on set %s" msgstr "Fel %s när du kör par2_repair på %s" #: sabnzbd/newsunpack.py:934 [Error message] msgid "Error \"%s\" while running par2_repair on set %s" msgstr "Fel \"%s\" medans par2_repair kördes på %s" #: sabnzbd/newsunpack.py:1042 msgid "" "[%s] PAR2 received incorrect options, check your Config->Switches settings" msgstr "" "[%s] PAR2 har fått felaktiga alternativ, ändra dessa via Config->Switches " "inställningarna" #: sabnzbd/newsunpack.py:1047 msgid "[%s] Verified in %s, all files correct" msgstr "[%s] Verifierad i %s, alla filer är ok" #: sabnzbd/newsunpack.py:1054 msgid "[%s] Verified in %s, repair is required" msgstr "[%s] Verifiering i %s, kräver reparation" #: sabnzbd/newsunpack.py:1069 msgid "Main packet not found..." msgstr "Huvudarkiv saknas..." #: sabnzbd/newsunpack.py:1096 msgid "Invalid par2 files, cannot verify or repair" msgstr "Korrupta par2 filer, kan inte verifiera eller reparera" #: sabnzbd/newsunpack.py:1137 # sabnzbd/newsunpack.py:1171 msgid "Repair failed, not enough repair blocks (%s short)" msgstr "" "Misslyckad reparation, finns ej tillräckligt med reparationsblock (%s saknas)" #: sabnzbd/newsunpack.py:1166 msgid "Fetching %s blocks..." msgstr "Hämtar %s block..." #: sabnzbd/newsunpack.py:1168 msgid "Fetching" msgstr "Hämtar" #: sabnzbd/newsunpack.py:1180 # sabnzbd/newsunpack.py:1185 msgid "Repairing" msgstr "Reparerar" #: sabnzbd/newsunpack.py:1189 msgid "[%s] Repaired in %s" msgstr "[%s] Reparerad i %s" #: sabnzbd/newsunpack.py:1240 # sabnzbd/newsunpack.py:1258 msgid "Verifying" msgstr "Verifierar" #: sabnzbd/newswrapper.py:181 [Error message] msgid "Error importing OpenSSL module. Connecting with NON-SSL" msgstr "Misslyckades med importering av OpenSSL modul. Ansluter utan SSL" #: sabnzbd/newzbin.py:126 [Error message] msgid "Failed to update newzbin job %s" msgstr "Det gick inte att uppdatera newzbin jobb %s" #: sabnzbd/newzbin.py:140 # sabnzbd/nzbqueue.py:380 msgid "NZB added to queue" msgstr "NZB tillagd i kön" #: sabnzbd/newzbin.py:189 [Error message] msgid "Newzbin server changed its protocol" msgstr "Newzbin server ändrade sitt protokoll" #: sabnzbd/newzbin.py:223 # sabnzbd/newzbin.py:333 [Warning message] msgid "You have no credit on your Newzbin account" msgstr "Du har ingen kredit på ditt Newzbin konto" #: sabnzbd/newzbin.py:227 # sabnzbd/newzbin.py:331 [Warning message] msgid "Unauthorised, check your newzbin username/password" msgstr "Obehörig, kontrollera ditt newzbin användarnamn/lösenord" #: sabnzbd/newzbin.py:231 msgid "Newzbin report %s not found" msgstr "Newzbin rapporterade %s ej funnen" #: sabnzbd/newzbin.py:235 msgid "Newzbin gives undocumented error code (%s, %s)" msgstr "Newzbin ger odokumenterad felkod (%s, %s)" #: sabnzbd/newzbin.py:242 msgid "Newzbin server fails to give info for %s" msgstr "Newzbin servern misslyckades ge info för %s" #: sabnzbd/newzbin.py:344 [Warning message] msgid "Could not delete newzbin bookmark %s" msgstr "Det gick inte att ta bort newzbin bokmärke %s" #: sabnzbd/newzbin.py:356 [Error message] msgid "Newzbin gives undocumented error code (%s)" msgstr "Newzbin ger odokumenterad felkod (%s)" #: sabnzbd/nzbqueue.py:79 [Error message] msgid "Incompatible queuefile found, cannot proceed" msgstr "Felaktig köfil funnen, kan ej fortsätta" #: sabnzbd/nzbqueue.py:85 [Error message] msgid "Error loading %s, corrupt file detected" msgstr "Laddningsfel %s, felaktig fil detekterad" #: sabnzbd/nzbqueue.py:285 [Error message] msgid "Error while adding %s, removing" msgstr "Det gick inte att lägga till %s, tar bort" #: sabnzbd/nzbqueue.py:745 [Warning message] msgid "%s -> Unknown encoding" msgstr "%s -> Okänd kodning" #: sabnzbd/nzbstuff.py:435 [Warning message] msgid "File %s is empty, skipping" msgstr "Fil %s är tom, hoppar över" #: sabnzbd/nzbstuff.py:479 [Warning message] msgid "Failed to import %s files from %s" msgstr "Det gick inte att importera %s filer från %s" #: sabnzbd/nzbstuff.py:717 [Warning message] msgid "Incomplete NZB file %s" msgstr "NZB filen %s är inte komplett" #: sabnzbd/nzbstuff.py:719 [Warning message] # sabnzbd/nzbstuff.py:723 [Warning message] msgid "Invalid NZB file %s, skipping (reason=%s, line=%s)" msgstr "Felaktig NZB fil %s, hoppar över (orsak=%s, linje=%s)" #: sabnzbd/nzbstuff.py:742 # sabnzbd/nzbstuff.py:744 msgid "Empty NZB file %s" msgstr "NZB filen %s är tom" #: sabnzbd/nzbstuff.py:810 [Warning message] msgid "Ignoring duplicate NZB \"%s\"" msgstr "Ignorerar dubblett för NZB \"%s\"" #: sabnzbd/nzbstuff.py:815 [Warning message] msgid "Pausing duplicate NZB \"%s\"" msgstr "Pausar dubblett för NZB \"%s\"" #: sabnzbd/nzbstuff.py:947 msgid "Aborted, cannot be completed" msgstr "Avbrutet, kan inte slutföras" #: sabnzbd/nzbstuff.py:1037 [Queue indicator for duplicate job] msgid "DUPLICATE" msgstr "DUBLETT" #: sabnzbd/nzbstuff.py:1039 [Queue indicator for encrypted job] msgid "ENCRYPTED" msgstr "KRYPTERAT" #: sabnzbd/nzbstuff.py:1041 [Queue indicator for oversized job] msgid "TOO LARGE" msgstr "FÖR STOR" #: sabnzbd/nzbstuff.py:1043 [Queue indicator for incomplete NZB] msgid "INCOMPLETE" msgstr "INKOMPLETT" #: sabnzbd/nzbstuff.py:1045 [Queue indicator for unwanted extensions] msgid "UNWANTED" msgstr "" #: sabnzbd/nzbstuff.py:1049 [Queue indicator for waiting URL fetch] msgid "WAIT %s sec" msgstr "VÄNTA %s SEKUNDER" #: sabnzbd/nzbstuff.py:1141 msgid "Downloaded in %s at an average of %sB/s" msgstr "Hämtade i %s vid ett genomsnitt på %sB/s" #: sabnzbd/nzbstuff.py:1148 msgid "%s articles were malformed" msgstr "%s artiklar var felaktiga" #: sabnzbd/nzbstuff.py:1150 msgid "%s articles were missing" msgstr "%s artiklar saknades" #: sabnzbd/nzbstuff.py:1152 msgid "%s articles had non-matching duplicates" msgstr "%s artiklar hade icke-matchande dubletter" #: sabnzbd/nzbstuff.py:1154 msgid "%s articles were removed" msgstr "%s artiklar borttagna" #: sabnzbd/nzbstuff.py:1186 [Error message] msgid "Error importing %s" msgstr "Det gick inte att importera %s" #: sabnzbd/osxmenu.py:127 # sabnzbd/osxmenu.py:424 # sabnzbd/osxmenu.py:432 #: sabnzbd/skintext.py:269 [Footer: indicator of warnings] # sabnzbd/skintext.py:711 # sabnzbd/skintext.py:840 msgid "Warnings" msgstr "Varningar" #: sabnzbd/osxmenu.py:138 # sabnzbd/osxmenu.py:468 # sabnzbd/sabtray.py:87 #: sabnzbd/skintext.py:830 msgid "Idle" msgstr "Sysslolös" #: sabnzbd/osxmenu.py:145 # sabnzbd/skintext.py:273 msgid "Configuration" msgstr "Konfiguration" #: sabnzbd/osxmenu.py:154 # sabnzbd/skintext.py:124 [Main menu item] # sabnzbd/skintext.py:460 msgid "Queue" msgstr "Kö" #: sabnzbd/osxmenu.py:161 # sabnzbd/skintext.py:213 [Queue page button] # sabnzbd/skintext.py:722 msgid "Purge Queue" msgstr "Rensa kö" #: sabnzbd/osxmenu.py:170 # sabnzbd/skintext.py:125 [Main menu item] msgid "History" msgstr "Historik" #: sabnzbd/osxmenu.py:177 # sabnzbd/skintext.py:226 [History page button] # sabnzbd/skintext.py:741 msgid "Purge History" msgstr "Töm historik" #: sabnzbd/osxmenu.py:189 msgid "Limit Speed" msgstr "Hastighetsbegränsning" #: sabnzbd/osxmenu.py:209 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:56 [#: Config->Scheduler] #: sabnzbd/skintext.py:160 # sabnzbd/skintext.py:209 [Queue page button] # sabnzbd/skintext.py:405 [Three way switch for duplicates] #: sabnzbd/skintext.py:522 msgid "Pause" msgstr "Pausa" #: sabnzbd/osxmenu.py:215 msgid "min." msgstr "min." #: sabnzbd/osxmenu.py:225 # sabnzbd/sabtray.py:64 # sabnzbd/skintext.py:55 [#: Config->Scheduler] #: sabnzbd/skintext.py:161 # sabnzbd/skintext.py:208 [Queue page button] # sabnzbd/skintext.py:521 msgid "Resume" msgstr "Återuppta" #: sabnzbd/osxmenu.py:235 msgid "Get Newzbin Bookmarks" msgstr "Hämta Newzbin bokmärken" #: sabnzbd/osxmenu.py:245 # sabnzbd/skintext.py:63 [#: Config->Scheduler] msgid "Scan watched folder" msgstr "Scanna bevakad mapp" #: sabnzbd/osxmenu.py:258 # sabnzbd/osxmenu.py:616 msgid "Complete Folder" msgstr "Färdig mapp" #: sabnzbd/osxmenu.py:263 # sabnzbd/osxmenu.py:617 msgid "Incomplete Folder" msgstr "Ofullständig mapp" #: sabnzbd/osxmenu.py:276 # sabnzbd/sabtray.py:61 msgid "Troubleshoot" msgstr "Felsök" #: sabnzbd/osxmenu.py:278 # sabnzbd/osxmenu.py:279 # sabnzbd/sabtray.py:61 #: sabnzbd/sabtray.py:63 # sabnzbd/sabtray.py:115 # sabnzbd/sabtray.py:124 #: sabnzbd/sabtray.py:133 # sabnzbd/skintext.py:58 [#: Config->Scheduler] # sabnzbd/skintext.py:277 #: sabnzbd/skintext.py:524 msgid "Restart" msgstr "Starta om" #: sabnzbd/osxmenu.py:280 # sabnzbd/sabtray.py:62 msgid "Restart without login" msgstr "Starta om utan login" #: sabnzbd/osxmenu.py:293 msgid "Quit" msgstr "Avsluta" #: sabnzbd/osxmenu.py:346 msgid "Queue First 10 Items" msgstr "Kö (10 första sakerna)" #: sabnzbd/osxmenu.py:366 # sabnzbd/osxmenu.py:408 msgid "Empty" msgstr "Tom" #: sabnzbd/osxmenu.py:384 msgid "History Last 10 Items" msgstr "Historik (10 senaste sakerna)" #: sabnzbd/osxmenu.py:529 msgid "New release available" msgstr "Ny utgåva tillgänglig" #: sabnzbd/osxmenu.py:568 msgid "Go to wizard" msgstr "Gå till guiden" #: sabnzbd/osxmenu.py:719 # sabnzbd/osxmenu.py:722 # sabnzbd/osxmenu.py:730 #: sabnzbd/osxmenu.py:733 # sabnzbd/osxmenu.py:739 # sabnzbd/osxmenu.py:742 #: sabnzbd/osxmenu.py:763 msgid "Stopping..." msgstr "Stänger..." #: sabnzbd/panic.py:44 msgid "Problem with" msgstr "Problem med" #: sabnzbd/panic.py:59 msgid "" "\n" " SABnzbd is not compatible with some software firewalls.
    \n" " %s
    \n" " Sorry, but we cannot solve this incompatibility right now.
    \n" " Please file a complaint at your firewall supplier.
    \n" "
    \n" msgstr "" "\n" " SABnzbd är inte kompatibelt med vissa mjukvarubaserade brandväggar.
    \n" " %s
    \n" " Tyvärr kan vi inte lösa denna inkompatibilitet just nu.
    \n" " Vänligen registrera ett klagomål hos brandväggens tillverkare.
    \n" "
    \n" #: sabnzbd/panic.py:68 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but it is not available.
    \n" " Some other software uses the port or SABnzbd is already running.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd behöver en ledig tcp/ip -port för sin interna webbserver.
    \n" " Port %s på %s testades , men den är inte tillgänglig.
    \n" " Någon annan applikation använder porten eller så körs redan " "SABnzbd.
    \n" "
    \n" " Vänligen starta om SABnzbd med ett annat portnummer." #: sabnzbd/panic.py:79 # sabnzbd/panic.py:93 msgid "" "If you get this error message again, please try a different number.
    " msgstr "" "Om du får detta felmeddelande igen, var vänlig försök med en annan " "siffra.
    " #: sabnzbd/panic.py:82 msgid "" "\n" " SABnzbd needs a free tcp/ip port for its internal web server.
    \n" " Port %s on %s was tried , but the account used for SABnzbd has no " "permission to use it.
    \n" " On OSX and Linux systems, normal users must use ports above 1023.
    \n" "
    \n" " Please restart SABnzbd with a different port number." msgstr "" "\n" " SABnzbd behöver en tillgänglig tcp/ip port för dess interna web " "server.
    \n" " Port %s på %s testades, men kontot som används för SABnzbd har inte " "tillåtelse att använda den.
    \n" " På OSX och Linux-system måste normala användare använda portnummer 1023 " "eller högre.
    \n" "
    \n" " Var vänlig starta om SABnzbd med ett annat portnummer." #: sabnzbd/panic.py:96 msgid "" "\n" " SABnzbd needs a valid host address for its internal web server.
    \n" " You have specified an invalid address.
    \n" " Safe values are localhost and 0.0.0.0
    \n" "
    \n" " Please restart SABnzbd with a proper host address." msgstr "" "\n" " SABnzbd behöver en giltig värdadress för dess interna webbserver.
    \n" " Du har specifierat en ogiltig adress.
    \n" " Säkra värdadresser är localhost och 0.0.0.0
    \n" "
    \n" " Var vänlig starta om SABnzbd med en giltig värdadress." #: sabnzbd/panic.py:110 msgid "" "\n" " SABnzbd detected saved data from an other SABnzbd version
    \n" " but cannot re-use the data of the other program.

    \n" " You may want to finish your queue first with the other program.

    \n" " After that, start this program with the \"--clean\" option.
    \n" " This will erase the current queue and history!
    \n" " SABnzbd read the file \"%s\"." msgstr "" "\n" " SABnzbd har upptäckt sparad data från en annan version av SABnzbd
    \n" " men kan inte återanvända datan från det andra programmet.

    \n" " Färdigställ dina nedladdningar med det andra programmet först.

    \n" " Därefter kan du starta det här programmet med alternativet \"--" "clean\".
    \n" " Detta kommando kommer att ta bort din nuvarande kö och historik!
    \n" " SABnzbd read the file \"%s\"." #: sabnzbd/panic.py:125 msgid "" "\n" " SABnzbd cannot find its web interface files in %s.
    \n" " Please install the program again.
    \n" "
    \n" msgstr "" "\n" " SABnzbd kan inte hitta webbgränssnittets filer i %s.
    \n" " Var vänlig installera om programmet.
    \n" "
    \n" #: sabnzbd/panic.py:132 msgid "SABnzbd detected a fatal error:" msgstr "SABnzbd upptäckte ett allvarligt fel:" #: sabnzbd/panic.py:135 msgid "" "\n" " SABnzbd detected a Queue and History from an older (0.4.x) " "release.

    \n" " Both queue and history will be ignored and may get lost!

    \n" " You may choose to stop SABnzbd and finish the queue with the older " "program.

    \n" " Click OK to proceed to SABnzbd" msgstr "" "\n" " SABnzbd upptäckte Kö and Historik från en äldre (0.4.x) " "version.

    \n" " Både kö och historik kommer att ignoreras och kan försvinna!

    \n" " Du kan välja att stoppa SABnzbd och färdigställa nedladdningskön med den " "äldre versionen.

    \n" " Klicka OK för att gå vidare till SABnzbd" #: sabnzbd/panic.py:140 msgid "OK" msgstr "OK" #: sabnzbd/panic.py:143 msgid "" "\n" " SABnzbd detected that the file sqlite3.dll is missing.

    \n" " Some poorly designed virus-scanners remove this file.
    \n" " Please check your virus-scanner, try to re-install SABnzbd and complain " "to your virus-scanner vendor.
    \n" "
    \n" msgstr "" "\n" " SABnzbd upptäckte att filen sqlite3.dll saknas.

    \n" " Det händer att bristfälligt designade virusprogram tar bort denna " "fil.
    \n" " Var vänlig kontrollera ditt virusprogram, försök installera om SABnzbd " "och klaga till din återförsäljare.
    \n" "
    \n" #: sabnzbd/panic.py:154 msgid "Press Startkey+R and type the line (example):" msgstr "Tryck på Startknappen+R och skriv raden (exempel):" #: sabnzbd/panic.py:157 msgid "Open a Terminal window and type the line (example):" msgstr "Öppna ett Terminal-fönster och skriv raden (exempel):" #: sabnzbd/panic.py:177 msgid "It is likely that you are using ZoneAlarm on Vista.
    " msgstr "Det är troligt att du använder ZoneAlarm på Vista.
    " #: sabnzbd/panic.py:188 msgid "Program did not start!" msgstr "Programmet startade inte!" #: sabnzbd/panic.py:213 [Error message] msgid "You have no permisson to use port %s" msgstr "Du har ingen behörighet för att använda port %s" #: sabnzbd/panic.py:229 msgid "Fatal error" msgstr "Allvarligt fel" #: sabnzbd/panic.py:253 [Warning message] msgid "Cannot launch the browser, probably not found" msgstr "Kan inte starta webbläsaren, hittades troligtvis inte" #: sabnzbd/panic.py:259 msgid "Access denied" msgstr "Åtkomst nekades" #: sabnzbd/panic.py:260 msgid "Error %s: You need to provide a valid username and password." msgstr "Error %s: Du måste ange ett giltigt användarnamn och lösenord." #: sabnzbd/postproc.py:98 [Warning message] msgid "" "Failed to load postprocessing queue: Wrong version (need:%s, found:%s)" msgstr "" "Det gick inte att ladda efterbehandlings kön: Fel version (kräver:%s, " "hittade:%s)" #: sabnzbd/postproc.py:128 [Error message] msgid "Failed to remove nzo from postproc queue (id)" msgstr "Det gick inte att ta bort nzo från efterbehandlings kön (id)" #: sabnzbd/postproc.py:265 msgid "Download might fail, only %s of required %s available" msgstr "" "Nerladdningen kan misslyckas, bara %s av krävda %s finns tillgängligt" #: sabnzbd/postproc.py:267 msgid "Download failed - Out of your server's retention?" msgstr "Hämtning misslyclades - Out of your server's retention?" #: sabnzbd/postproc.py:331 msgid "Cannot create final folder %s" msgstr "Kan inte skapa slutgiltig mapp %s" #: sabnzbd/postproc.py:353 msgid "No post-processing because of failed verification" msgstr "Ingen efterbehandling på grund av misslyckad verifiering" #: sabnzbd/postproc.py:361 msgid "Moving" msgstr "Flyttar" #: sabnzbd/postproc.py:392 msgid "Sent %s to queue" msgstr "Skickat %s till kö" #: sabnzbd/postproc.py:406 [Error message] msgid "Error renaming \"%s\" to \"%s\"" msgstr "Det gick inte att döpa om \"%s\" till \"%s\"" #: sabnzbd/postproc.py:430 msgid "Failed to move files" msgstr "Misslyckades med att flytta filer" #: sabnzbd/postproc.py:438 msgid "Running script" msgstr "Kör skript" #: sabnzbd/postproc.py:439 msgid "Running user script %s" msgstr "Kör användarskript %s" #: sabnzbd/postproc.py:449 msgid "Ran %s" msgstr "Körde %s" #: sabnzbd/postproc.py:470 msgid "More" msgstr "Mer" #: sabnzbd/postproc.py:474 msgid "View script output" msgstr "Visa skriptutmatning" #: sabnzbd/postproc.py:500 msgid "Download Completed" msgstr "Hämtningen slutfördes" #: sabnzbd/postproc.py:503 # sabnzbd/postproc.py:512 msgid "Download Failed" msgstr "Hämtning misslyckades" #: sabnzbd/postproc.py:507 [Error message] msgid "Post Processing Failed for %s (%s)" msgstr "Efterbehandling misslyckades för %s (%s)" #: sabnzbd/postproc.py:510 msgid "see logfile" msgstr "se loggfil" #: sabnzbd/postproc.py:511 msgid "PostProcessing was aborted (%s)" msgstr "Efterbehandling avbröts (%s)" #: sabnzbd/postproc.py:543 [Error message] msgid "Cleanup of %s failed." msgstr "Rensning av %s misslyckades." #: sabnzbd/postproc.py:553 [Error message] msgid "Error removing workdir (%s)" msgstr "Det gick inte att ta bort arbetsmapp (%s)" #: sabnzbd/postproc.py:570 msgid "Post-processing" msgstr "Efterbehandling" #: sabnzbd/postproc.py:605 msgid "[%s] No par2 sets" msgstr "[%s] Ingen par2 sats" #: sabnzbd/postproc.py:637 msgid "Trying SFV verification" msgstr "Försöker verifiera SFV" #: sabnzbd/postproc.py:640 msgid "Some files failed to verify against \"%s\"" msgstr "Some files failed to verify against \"%s\"" #: sabnzbd/postproc.py:646 msgid "Verified successfully using SFV files" msgstr "Verifieringen lyckades med SFV-filer" #: sabnzbd/postproc.py:701 [Error message] # sabnzbd/postproc.py:776 [Error message] msgid "Removing %s failed" msgstr "Borttagning av %s misslyckades" #: sabnzbd/powersup.py:39 [Error message] msgid "Failed to hibernate system" msgstr "Kunde inte sätta systemet i vänteläge" #: sabnzbd/powersup.py:50 [Error message] # sabnzbd/powersup.py:93 [Error message] msgid "Failed to standby system" msgstr "Det gick inte att sätta systemet i viloläge" #: sabnzbd/powersup.py:81 [Error message] msgid "Error while shutting down system" msgstr "Fel uppstod då systemet skulle stängas" #: sabnzbd/rss.py:278 [Error message] # sabnzbd/rss.py:280 msgid "Incorrect RSS feed description \"%s\"" msgstr "Felaktigt RSS-flödesbeskrivning \"%s\"" #: sabnzbd/rss.py:336 # sabnzbd/rss.py:352 msgid "Failed to retrieve RSS from %s: %s" msgstr "Det gick inte att hämta RSS flödet från %s: %s" #: sabnzbd/rss.py:342 msgid "Do not have valid authentication for feed %s" msgstr "Har inte giltig autentisering för flöde %s" #: sabnzbd/rss.py:346 msgid "Server side error (server code %s); could not get %s on %s" msgstr "" #: sabnzbd/rss.py:356 msgid "RSS Feed %s was empty" msgstr "RSS-flödet %s var tomt" #: sabnzbd/rss.py:382 # sabnzbd/rss.py:384 msgid "Incompatible feed" msgstr "Inkompatibel feed" #: sabnzbd/rss.py:674 [Warning message] msgid "Empty RSS entry found (%s)" msgstr "Tom RSS post hittades (%s)" #: sabnzbd/sabtray.py:59 msgid "Show interface" msgstr "Visa gränssnitt" #: sabnzbd/sabtray.py:60 msgid "Open complete folder" msgstr "Öppna färdig mapp" #: sabnzbd/sabtray.py:65 # sabnzbd/sabtray.py:139 # sabnzbd/skintext.py:57 [#: Config->Scheduler] #: sabnzbd/skintext.py:159 # sabnzbd/skintext.py:523 msgid "Shutdown" msgstr "Stäng Av" #: sabnzbd/sabtray.py:84 # sabnzbd/skintext.py:800 msgid "Remaining" msgstr "Återstår" #: sabnzbd/scheduler.py:83 [Warning message] msgid "Bad schedule %s at %s:%s" msgstr "Fel schema %s vid %s:%s" #: sabnzbd/scheduler.py:124 [Warning message] msgid "Unknown action: %s" msgstr "Okänd åtgärd: %s" #: sabnzbd/scheduler.py:315 [Warning message] # sabnzbd/scheduler.py:320 [Warning message] msgid "Schedule for non-existing server %s" msgstr "Schema för icke existerande server %s" #: sabnzbd/skintext.py:26 [Queue status "download"] # sabnzbd/skintext.py:170 # sabnzbd/skintext.py:547 [Config->RSS button "download item"] msgid "Download" msgstr "Nedladdning" #: sabnzbd/skintext.py:28 [PP phase "filejoin"] msgid "Join files" msgstr "Slår ihop filer" #: sabnzbd/skintext.py:29 [PP phase "unpack"] msgid "Unpack" msgstr "Packa upp" #: sabnzbd/skintext.py:30 [PP phase "script"] # sabnzbd/skintext.py:168 msgid "Script" msgstr "Skript" #: sabnzbd/skintext.py:31 [PP Source of the NZB (path or URL)] # sabnzbd/skintext.py:102 [Where to find the SABnzbd sourcecode] msgid "Source" msgstr "Källa" #: sabnzbd/skintext.py:32 [PP Failure message] msgid "Failure" msgstr "Misslyckades" #: sabnzbd/skintext.py:34 [PP status] # sabnzbd/skintext.py:235 [History: job status] msgid "Completed" msgstr "Färdig" #: sabnzbd/skintext.py:35 [PP status] # sabnzbd/skintext.py:835 msgid "Failed" msgstr "Misslyckades" #: sabnzbd/skintext.py:36 [Queue and PP status] msgid "Waiting" msgstr "Väntar" #: sabnzbd/skintext.py:38 [PP status] msgid "Repairing..." msgstr "Reparerar..." #: sabnzbd/skintext.py:39 [PP status] msgid "Extracting..." msgstr "Extraherar..." #: sabnzbd/skintext.py:40 [PP status] msgid "Moving..." msgstr "Flyttar..." #: sabnzbd/skintext.py:41 [PP status] msgid "Running script..." msgstr "Kör skript..." #: sabnzbd/skintext.py:42 [PP status] msgid "Fetching extra blocks..." msgstr "Hämtar extra block..." #: sabnzbd/skintext.py:43 [PP status] msgid "Quick Check..." msgstr "Snabbkontroll..." #: sabnzbd/skintext.py:44 [PP status] msgid "Verifying..." msgstr "Verifierar..." #: sabnzbd/skintext.py:45 [Pseudo-PP status, in reality used for Queue-status] # sabnzbd/skintext.py:829 msgid "Downloading" msgstr "Laddar ner" #: sabnzbd/skintext.py:46 [Pseudo-PP status, in reality used for Grabbing status] msgid "Get NZB" msgstr "Lägg till NZB" #: sabnzbd/skintext.py:47 [PP status] msgid "Checking" msgstr "Kontrollerar" #: sabnzbd/skintext.py:49 [#: Config->Scheduler] # sabnzbd/skintext.py:515 msgid "Frequency" msgstr "Förekomst" #: sabnzbd/skintext.py:50 [#: Config->Scheduler] # sabnzbd/skintext.py:516 # sabnzbd/skintext.py:705 [Job details page, section header] msgid "Action" msgstr "Åtgärd" #: sabnzbd/skintext.py:51 [#: Config->Scheduler] # sabnzbd/skintext.py:517 msgid "Arguments" msgstr "Argument" #: sabnzbd/skintext.py:52 [#: Config->Scheduler] msgid "Task" msgstr "Uppgift" #: sabnzbd/skintext.py:53 [#: Config->Scheduler] msgid "disable server" msgstr "avaktivera server" #: sabnzbd/skintext.py:54 [#: Config->Scheduler] msgid "enable server" msgstr "aktivera server" #: sabnzbd/skintext.py:59 [#: Config->Scheduler] msgid "Speedlimit" msgstr "Hastighetsgräns" #: sabnzbd/skintext.py:60 [#: Config->Scheduler] msgid "Pause All" msgstr "Pausa Allt" #: sabnzbd/skintext.py:61 [#: Config->Scheduler] msgid "Pause post-processing" msgstr "Pausa efterbehandla" #: sabnzbd/skintext.py:62 [#: Config->Scheduler] msgid "Resume post-processing" msgstr "Återuppta efterbehandla" #: sabnzbd/skintext.py:64 [#: Config->Scheduler] msgid "Read RSS feeds" msgstr "Läs RSS-flöden" #: sabnzbd/skintext.py:65 [Config->Scheduler] msgid "Remove failed jobs" msgstr "Ta bort misslyckade jobb" #: sabnzbd/skintext.py:70 [Speed indicator kilobytes/sec] msgid "KB/s" msgstr "KB/s" #: sabnzbd/skintext.py:71 [Megabytes] msgid "MB" msgstr "MB" #: sabnzbd/skintext.py:72 [Gigabytes] msgid "GB" msgstr "GB" #: sabnzbd/skintext.py:73 [One hour] msgid "hour" msgstr "timme" #: sabnzbd/skintext.py:74 [Multiple hours] msgid "hours" msgstr "timmar" #: sabnzbd/skintext.py:75 [One minute] msgid "min" msgstr "minut" #: sabnzbd/skintext.py:76 [Multiple minutes] msgid "mins" msgstr "minuter" #: sabnzbd/skintext.py:77 [One second] msgid "sec" msgstr "sekund" #: sabnzbd/skintext.py:78 [Multiple seconds] msgid "seconds" msgstr "sekunder" #: sabnzbd/skintext.py:79 msgid "day" msgstr "dag" #: sabnzbd/skintext.py:80 msgid "days" msgstr "dagar" #: sabnzbd/skintext.py:81 msgid "week" msgstr "vecka" #: sabnzbd/skintext.py:82 msgid "Month" msgstr "Månad" #: sabnzbd/skintext.py:83 msgid "Year" msgstr "År" #: sabnzbd/skintext.py:92 msgid "Day of month" msgstr "Månadsdag" #: sabnzbd/skintext.py:93 msgid "This week" msgstr "Denna vecka" #: sabnzbd/skintext.py:94 msgid "This month" msgstr "Denna månad" #: sabnzbd/skintext.py:95 msgid "Today" msgstr "I dag" #: sabnzbd/skintext.py:96 msgid "Total" msgstr "Totalt" #: sabnzbd/skintext.py:97 msgid "on" msgstr "den" #: sabnzbd/skintext.py:99 [Config: startup parameters of SABnzbd] msgid "Parameters" msgstr "Parametrar" #: sabnzbd/skintext.py:100 msgid "Python Version" msgstr "Python-version" #: sabnzbd/skintext.py:101 [Home page of the SABnzbd project] msgid "Home page" msgstr "Webbplats" #: sabnzbd/skintext.py:103 [Used in "IRC or IRC-Webaccess"] msgid "or" msgstr "eller" #: sabnzbd/skintext.py:104 # sabnzbd/skintext.py:493 [Server hostname or IP] msgid "Host" msgstr "Adress" #: sabnzbd/skintext.py:105 msgid "Comment" msgstr "" #: sabnzbd/skintext.py:106 msgid "Send" msgstr "" #: sabnzbd/skintext.py:107 msgid "Cancel" msgstr "" #: sabnzbd/skintext.py:108 msgid "Other" msgstr "" #: sabnzbd/skintext.py:109 msgid "Report" msgstr "" #: sabnzbd/skintext.py:110 msgid "Video" msgstr "" #: sabnzbd/skintext.py:111 msgid "Audio" msgstr "" #: sabnzbd/skintext.py:114 [SABnzbd's theme line] msgid "The automatic usenet download tool" msgstr "Det automatiska usenet nedladdningsverktyget" #: sabnzbd/skintext.py:115 ["Save" button] msgid "Save" msgstr "Spara" #: sabnzbd/skintext.py:116 ["Queued" used to show amount of jobs] # sabnzbd/skintext.py:149 msgid "Queued" msgstr "Köad" #: sabnzbd/skintext.py:118 [Generic "Delete" button, short form] # sabnzbd/skintext.py:543 [Config->RSS button "Delete filter"] # sabnzbd/skintext.py:621 msgid "X" msgstr "X" #: sabnzbd/skintext.py:119 [Used in confirmation popups] # sabnzbd/skintext.py:746 msgid "Are you sure?" msgstr "Är du säker?" #: sabnzbd/skintext.py:120 [Used in confirmation popups] msgid "Delete all downloaded files?" msgstr "Ta bort alla nedladdade filer?" #: sabnzbd/skintext.py:123 [Main menu item] msgid "Home" msgstr "Hem" #: sabnzbd/skintext.py:126 [Main menu item] msgid "Config" msgstr "Konfiguration" #: sabnzbd/skintext.py:127 [Main menu item] # sabnzbd/skintext.py:237 [History table header] msgid "Status" msgstr "Status" #: sabnzbd/skintext.py:128 [Main menu item] # sabnzbd/skintext.py:867 [Wizard help link] msgid "Help" msgstr "Hjälp" #: sabnzbd/skintext.py:129 [Main menu item] msgid "Wiki" msgstr "Wiki" #: sabnzbd/skintext.py:130 [Main menu item] msgid "Forum" msgstr "Forum" #: sabnzbd/skintext.py:131 [Main menu item] msgid "IRC" msgstr "IRC" #: sabnzbd/skintext.py:132 [Main menu item] # sabnzbd/skintext.py:458 msgid "General" msgstr "Allmänt" #: sabnzbd/skintext.py:133 [Main menu item] msgid "Folders" msgstr "Mappar" #: sabnzbd/skintext.py:134 [Main menu item] # sabnzbd/skintext.py:687 msgid "Switches" msgstr "Switchar" #: sabnzbd/skintext.py:135 [Main menu item] msgid "Servers" msgstr "Servrar" #: sabnzbd/skintext.py:136 [Main menu item] # sabnzbd/skintext.py:745 msgid "Scheduling" msgstr "Schemaläggare" #: sabnzbd/skintext.py:137 [Main menu item] msgid "RSS" msgstr "RSS" #: sabnzbd/skintext.py:138 [Main menu item] # sabnzbd/skintext.py:553 [Main Config page] # sabnzbd/skintext.py:574 [Section header] msgid "Notifications" msgstr "Meddelanden" #: sabnzbd/skintext.py:139 [Main menu item] msgid "Email" msgstr "E-mail" #: sabnzbd/skintext.py:140 [Main menu item] msgid "Index Sites" msgstr "Index-sidor" #: sabnzbd/skintext.py:141 [Main menu item] msgid "Categories" msgstr "Kategorier" #: sabnzbd/skintext.py:142 [Main menu item] msgid "Sorting" msgstr "Sortering" #: sabnzbd/skintext.py:143 [Main menu item] msgid "Special" msgstr "Speciell" #: sabnzbd/skintext.py:146 msgid "Download Dir" msgstr "Temporär nedladdningmapp" #: sabnzbd/skintext.py:147 msgid "Complete Dir" msgstr "Färdig nedladdningsmapp" #: sabnzbd/skintext.py:148 msgid "Download speed" msgstr "Nedladdningshastighet" #: sabnzbd/skintext.py:150 msgid "PAUSED" msgstr "PAUSAD" #: sabnzbd/skintext.py:151 msgid "Cached %s articles (%s)" msgstr "Sparat %s artiklar (%s)" #: sabnzbd/skintext.py:152 msgid "Sysload" msgstr "Systembelastning" #: sabnzbd/skintext.py:153 msgid "WARNINGS" msgstr "VARNINGAR" #: sabnzbd/skintext.py:154 msgid "New release %s available at" msgstr "Ny utgåva %s tillgänglig" #: sabnzbd/skintext.py:157 msgid "Add new downloads" msgstr "Lägg till ny nedladdning" #: sabnzbd/skintext.py:158 msgid "Are you sure you want to shutdown SABnzbd?" msgstr "Är du säker på att du vill stänga av SABnzbd?" #: sabnzbd/skintext.py:162 # sabnzbd/skintext.py:163 msgid "Add" msgstr "Lägg till" #: sabnzbd/skintext.py:164 msgid "Report-id" msgstr "Rapport-id" #: sabnzbd/skintext.py:165 msgid "Add File" msgstr "Lägg till fil" #: sabnzbd/skintext.py:166 msgid "Category" msgstr "Kategori" #: sabnzbd/skintext.py:167 # sabnzbd/skintext.py:201 [Queue page table column header] msgid "Processing" msgstr "Bearbetar" #: sabnzbd/skintext.py:169 msgid "Priority" msgstr "Prioritet" #: sabnzbd/skintext.py:171 msgid "+Repair" msgstr "+Reparera" #: sabnzbd/skintext.py:172 msgid "+Unpack" msgstr "+Packar upp" #: sabnzbd/skintext.py:173 msgid "+Delete" msgstr "+Ta bort" #: sabnzbd/skintext.py:174 msgid " " msgstr " " #: sabnzbd/skintext.py:175 msgid "R" msgstr "R" #: sabnzbd/skintext.py:176 msgid "U" msgstr "P" #: sabnzbd/skintext.py:177 msgid "D" msgstr "T" #: sabnzbd/skintext.py:178 msgid "Force" msgstr "Tvinga" #: sabnzbd/skintext.py:180 msgid "Normal" msgstr "Normal" #: sabnzbd/skintext.py:181 msgid "High" msgstr "Hög" #: sabnzbd/skintext.py:182 msgid "Low" msgstr "Låg" #: sabnzbd/skintext.py:184 msgid "Stop" msgstr "Stopp" #: sabnzbd/skintext.py:185 msgid "Enter URL" msgstr "URL" #: sabnzbd/skintext.py:186 msgid " or Report ID" msgstr " eller Report ID" #: sabnzbd/skintext.py:189 [Queue page button] msgid "Sort by name" msgstr "Sortera efter namn" #: sabnzbd/skintext.py:190 [Queue page button] msgid "Sort by age" msgstr "Sortera efter ålder" #: sabnzbd/skintext.py:191 [Queue page button] msgid "Sort by size" msgstr "Sortera efter storlek" #: sabnzbd/skintext.py:192 [Queue page button] msgid "Hide files" msgstr "Göm filer" #: sabnzbd/skintext.py:193 [Queue page button] msgid "Show files" msgstr "Visa filer" #: sabnzbd/skintext.py:194 [Queue page selection menu] msgid "On queue finish" msgstr "När kön är färdig" #: sabnzbd/skintext.py:195 [Queue page end-of-queue action] msgid "Shutdown PC" msgstr "Stäng av PC" #: sabnzbd/skintext.py:196 [Queue page end-of-queue action] msgid "Standby PC" msgstr "Sparläge PC" #: sabnzbd/skintext.py:197 [Queue page end-of-queue action] msgid "Hibernate PC" msgstr "Viloläge PC" #: sabnzbd/skintext.py:198 [Queue page end-of-queue action] msgid "Shutdown SABnzbd" msgstr "Stäng av SABnzbd" #: sabnzbd/skintext.py:199 [Queue page selection menu or entry box] msgid "Speed Limit" msgstr "Hastighetsgräns" #: sabnzbd/skintext.py:200 [Queue page button or entry box] msgid "Pause for" msgstr "Pausa för" #: sabnzbd/skintext.py:202 [Queue page table column header] # sabnzbd/skintext.py:535 [Config->RSS table column header] msgid "Order" msgstr "Ordning" #: sabnzbd/skintext.py:203 [Queue page table column header] # sabnzbd/skintext.py:692 [Job details page] msgid "Name" msgstr "Namn" #: sabnzbd/skintext.py:204 [Queue page table column header] msgid "Remain/Total" msgstr "Återstår/Totalt" #: sabnzbd/skintext.py:205 [Queue page table column header, "estimated time of arrival"] msgid "ETA" msgstr "Tid kvar" #: sabnzbd/skintext.py:206 [Queue page table column header, "age of the NZB"] msgid "AGE" msgstr "År" #: sabnzbd/skintext.py:207 [Queue page table, "Delete" button] msgid "Del" msgstr "Ta bort" #: sabnzbd/skintext.py:210 [Queue page button] msgid "Retry" msgstr "Försök igen" #: sabnzbd/skintext.py:211 [Queue end-of-queue selection box] # sabnzbd/skintext.py:808 msgid "Actions" msgstr "Åtgärder" #: sabnzbd/skintext.py:212 [Queue page table, script selection menu] msgid "Scripts" msgstr "Skript" #: sabnzbd/skintext.py:214 [Confirmation popup] msgid "Delete all items from the queue?" msgstr "Ta bort alla saker från kön?" #: sabnzbd/skintext.py:215 [Queue page button] msgid "Purge NZBs" msgstr "Rensa NZB:er" #: sabnzbd/skintext.py:216 [Queue page button] msgid "Purge NZBs & Delete Files" msgstr "Rensa NZB:er och ta bort filer" #: sabnzbd/skintext.py:217 [Queue page button] msgid "Remove NZB" msgstr "Ta bort NZB" #: sabnzbd/skintext.py:218 [Queue page button] msgid "Remove NZB & Delete Files" msgstr "Ta bort NZB och filer" #: sabnzbd/skintext.py:219 [Queue page, as in "4G *of* 10G"] msgid "of" msgstr "av" #: sabnzbd/skintext.py:220 [Caption for missing articles in Queue] msgid "Missing articles" msgstr "Saknade artiklar" #: sabnzbd/skintext.py:221 [Remaining quota (displayed in Queue)] msgid "Quota left" msgstr "Kvot kvar" #: sabnzbd/skintext.py:222 [Manual reset of quota] msgid "manual" msgstr "handbok" #: sabnzbd/skintext.py:223 msgid "Reset Quota now" msgstr "Återställ Kvot nu" #: sabnzbd/skintext.py:227 [History page button] msgid "Purge Failed History" msgstr "Rensa Misslyckad Historik" #: sabnzbd/skintext.py:228 [Confirmation popup] msgid "Delete all completed items from History?" msgstr "Ta bort alla slutförda objekt från Historik?" #: sabnzbd/skintext.py:229 [Confirmation popup] msgid "Delete all failed items from History?" msgstr "Ta bort alla misslyckade objekt från Historik?" #: sabnzbd/skintext.py:230 [Button/link hiding History job details] msgid "Hide details" msgstr "Göm detaljer" #: sabnzbd/skintext.py:231 [Button/link showing History job details] msgid "Show details" msgstr "Visa detaljer" #: sabnzbd/skintext.py:232 [History: amount of downloaded data] msgid "History Size" msgstr "Historikstorlek" #: sabnzbd/skintext.py:233 [Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG!] msgid "Show Failed" msgstr "Visa Misslyckade" #: sabnzbd/skintext.py:234 [Button or link showing all History jobs] msgid "Show All" msgstr "Visa alla" #: sabnzbd/skintext.py:236 [History table header] # sabnzbd/skintext.py:465 [Size of the download quota] # sabnzbd/skintext.py:818 msgid "Size" msgstr "Storlek" #: sabnzbd/skintext.py:238 [Button to delete all failed jobs in History] msgid "Purge Failed NZBs" msgstr "Rensa Misslyckade NZB:er." #: sabnzbd/skintext.py:239 [Button to delete all failed jobs in History, including files] msgid "Purge Failed NZBs & Delete Files" msgstr "Rensa Misslyckade NZB:er och ta bort filer" #: sabnzbd/skintext.py:240 [Button to delete all completed jobs in History] msgid "Purge Completed NZBs" msgstr "Rensa färdiga NZB:er" #: sabnzbd/skintext.py:241 [Button to add NZB to failed job in History] msgid "Optional Supplemental NZB" msgstr "Valfri Kompletterande NZB" #: sabnzbd/skintext.py:242 [Path as displayed in History details] # sabnzbd/skintext.py:749 # sabnzbd/skintext.py:819 msgid "Path" msgstr "Genväg" #: sabnzbd/skintext.py:243 msgid "Virus/spam" msgstr "" #: sabnzbd/skintext.py:244 msgid "Passworded" msgstr "" #: sabnzbd/skintext.py:245 msgid "Out of retention" msgstr "" #: sabnzbd/skintext.py:246 msgid "Other problem" msgstr "" #: sabnzbd/skintext.py:249 [Status page button] msgid "Force Disconnect" msgstr "Tvinga frånkoppling" #: sabnzbd/skintext.py:250 msgid "This will send a test email to your account." msgstr "Detta kommer att skicka ett test e-mail till ditt konto." #: sabnzbd/skintext.py:251 [Status page button] msgid "Show Logging" msgstr "Visa logg" #: sabnzbd/skintext.py:252 [Status page button] msgid "Show Weblogging" msgstr "Visa webblogg" #: sabnzbd/skintext.py:253 [Status page button] msgid "Test Email" msgstr "Testa E-mail" #: sabnzbd/skintext.py:254 [Status page selection menu] msgid "Logging" msgstr "Loggning" #: sabnzbd/skintext.py:255 [Status page table header] msgid "Errors/Warning" msgstr "Fel/Varning" #: sabnzbd/skintext.py:256 [Status page logging selection value] msgid "+ Info" msgstr "+ Info" #: sabnzbd/skintext.py:257 [Status page logging selection value] msgid "+ Debug" msgstr "+ Debug" #: sabnzbd/skintext.py:258 [Status page tab header] # sabnzbd/skintext.py:498 [Server: amount of connections] msgid "Connections" msgstr "Anslutningar" #: sabnzbd/skintext.py:259 [Status page, server threads] msgid "Thread" msgstr "Tråd" #: sabnzbd/skintext.py:260 [Status page, title for email test result] msgid "Email Test Result" msgstr "E-mail testresultat" #: sabnzbd/skintext.py:261 [Status page, table header] msgid "Latest Warnings" msgstr "Senaste Varningar" #: sabnzbd/skintext.py:262 [Status page button] msgid "clear" msgstr "rensa" #: sabnzbd/skintext.py:263 [Status page button] msgid "Unblock" msgstr "Ta bort blockering" #: sabnzbd/skintext.py:264 [Status page, article identifier] msgid "Article identifier" msgstr "Artikel-ID" #: sabnzbd/skintext.py:265 [Status page, par-set that article belongs to] msgid "File set" msgstr "Filuppsättning" #: sabnzbd/skintext.py:266 [Status page, table column header, when error occured] msgid "When" msgstr "När" #: sabnzbd/skintext.py:267 [Status page, table column header, type of message] # sabnzbd/skintext.py:536 [Config->RSS table column header] msgid "Type" msgstr "Typ" #: sabnzbd/skintext.py:268 [Status page, table column header, actual message] msgid "Warning" msgstr "Varning" #: sabnzbd/skintext.py:270 [Status page, indicator that server is enabled] msgid "Enabled" msgstr "Aktiverad" #: sabnzbd/skintext.py:274 msgid "Config File" msgstr "Konfig fil" #: sabnzbd/skintext.py:275 [Main config page, how much cache is in use] msgid "Used cache" msgstr "Använt cache" #: sabnzbd/skintext.py:276 msgid "" "This will restart SABnzbd.
    Use it when you think the program has a " "stability problem.
    Downloading will be paused before the restart and " "resume afterwards." msgstr "" "Detta kommer att starta om SABnzbd.
    Använd det när du tror att " "programmet har stabilitetsproblem.
    Nerladdningar kommer att pusas innan " "omstarten och återupptas efteråt." #: sabnzbd/skintext.py:278 msgid "" "There are orphaned jobs in the download folder.
    You can choose to " "delete them (including files) or send them back to the queue." msgstr "" "Det finns övergivna jobb i nedladdningsmappen.
    Du kan välja mellan att " "radera dem (inklusive filer) eller skicka tillbaka dem i kön." #: sabnzbd/skintext.py:280 msgid "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." msgstr "" "The \"Repair\" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded " "files.
    This will modify the queue order." #: sabnzbd/skintext.py:282 msgid "Version" msgstr "Version" #: sabnzbd/skintext.py:283 msgid "Uptime" msgstr "Upptid" #: sabnzbd/skintext.py:284 [Indicates that server is Backup server in Status page] msgid "Backup" msgstr "Säkerhetskopiera" #: sabnzbd/skintext.py:285 msgid "OZnzb" msgstr "" #: sabnzbd/skintext.py:288 msgid "General configuration" msgstr "Allmän konfiguration" #: sabnzbd/skintext.py:289 msgid "Changes will require a SABnzbd restart!" msgstr "Ändringar kräver omstart av SABnzbd!" #: sabnzbd/skintext.py:290 msgid "SABnzbd Web Server" msgstr "SABnzbd Webbserver" #: sabnzbd/skintext.py:291 msgid "SABnzbd Host" msgstr "SABnzbd Adress" #: sabnzbd/skintext.py:292 msgid "Host SABnzbd should listen on." msgstr "Adress som SABnzbd ska lyssna på." #: sabnzbd/skintext.py:293 msgid "SABnzbd Port" msgstr "SABnzbd-port" #: sabnzbd/skintext.py:294 msgid "Port SABnzbd should listen on." msgstr "Port som SABnzbd ska lyssna på." #: sabnzbd/skintext.py:295 msgid "Web Interface" msgstr "Webbkontrollsutseende" #: sabnzbd/skintext.py:296 msgid "Choose a skin." msgstr "Välj ett skin." #: sabnzbd/skintext.py:297 msgid "Secondary Web Interface" msgstr "Andra Webbkontrollsutseende" #: sabnzbd/skintext.py:298 msgid "Activate an alternative skin." msgstr "Aktivera ett alternativt skin." #: sabnzbd/skintext.py:299 msgid "Web server authentication" msgstr "Webbserver autentiserng" #: sabnzbd/skintext.py:300 msgid "SABnzbd Username" msgstr "SABnzbd Användarnamn" #: sabnzbd/skintext.py:301 msgid "Optional authentication username." msgstr "Väljbart autentiserings användarnamn." #: sabnzbd/skintext.py:302 msgid "SABnzbd Password" msgstr "SABnzbd Lösenord" #: sabnzbd/skintext.py:303 msgid "Optional authentication password." msgstr "Väljbart autentiserings lösenord." #: sabnzbd/skintext.py:304 msgid "HTTPS Support" msgstr "HTTPS Stöd" #: sabnzbd/skintext.py:305 msgid "Enable HTTPS" msgstr "HTTPS Aktivera" #: sabnzbd/skintext.py:306 msgid "not installed" msgstr "(ej installerat)" #: sabnzbd/skintext.py:307 msgid "Enable accessing the interface from a HTTPS address." msgstr "Aktivera åtkomst till webbkontrollen med HTTPS adress." #: sabnzbd/skintext.py:308 msgid "HTTPS Port" msgstr "HTTPS-port" #: sabnzbd/skintext.py:309 msgid "If empty, the standard port will only listen to HTTPS." msgstr "Om tom kommer standardporten endast lyssna till HTTPS." #: sabnzbd/skintext.py:310 msgid "HTTPS Certificate" msgstr "HTTPS Certifikat" #: sabnzbd/skintext.py:311 msgid "File name or path to HTTPS Certificate." msgstr "Filnamn eller sökväg till HTTPS Certifikat." #: sabnzbd/skintext.py:312 msgid "HTTPS Key" msgstr "HTTPS Nyckel" #: sabnzbd/skintext.py:313 msgid "File name or path to HTTPS Key." msgstr "Filnamn eller sökväg till HTTPS Nyckel." #: sabnzbd/skintext.py:314 msgid "HTTPS Chain Certifcates" msgstr "" #: sabnzbd/skintext.py:315 msgid "File name or path to HTTPS Chain." msgstr "" #: sabnzbd/skintext.py:316 msgid "Tuning" msgstr "Justeringar" #: sabnzbd/skintext.py:317 msgid "Queue auto refresh interval:" msgstr "Automatisk uppdateringsintervall av kö:" #: sabnzbd/skintext.py:318 msgid "Refresh interval of the queue web-interface page(sec, 0= none)." msgstr "Uppdateringsintervall av kö-sidan (sek, 0= ingen)." #: sabnzbd/skintext.py:319 msgid "RSS Checking Interval" msgstr "RSS Uppdateringsintervall" #: sabnzbd/skintext.py:320 msgid "" "Checking interval (in minutes, at least 15). Not active when you use the " "Scheduler!" msgstr "" "Kontrollintervall (i minuter, minst 15). Ej aktiv om du använder " "Schemaläggaren!" #: sabnzbd/skintext.py:321 msgid "Download Speed Limit" msgstr "Hastighetsbegränsning för Nedladdning" #: sabnzbd/skintext.py:322 msgid "Download rate limit (in KB/s - kilobytes per second)." msgstr "" "Medelhastighetsbegränsning för Nedladdning (i KB/s - kilobyte per sekund)." #: sabnzbd/skintext.py:323 msgid "Article Cache Limit" msgstr "Cachestorlek för artiklar" #: sabnzbd/skintext.py:324 msgid "" "Cache articles in memory to reduce disk access.
    In bytes, optionally " "follow with K,M,G. For example: \"64M\" or \"128M\"" msgstr "" "Sparar artiklar i minnet för att reducera diskåtkomst.
    I bytes, " "följt av K,M,G. Till exempel: \"64M\" eller \"128M\"" #: sabnzbd/skintext.py:325 msgid "Cleanup List" msgstr "Rensa lista" #: sabnzbd/skintext.py:326 msgid "" "List of file extensions that should be deleted after download.
    For " "example: .nfo or .nfo, .sfv" msgstr "" "Lista med filändelser som ska tas bort efter nedladdning.
    Till exempel: " ".nfo or .nfo, .sfv" #: sabnzbd/skintext.py:327 msgid "Save Changes" msgstr "Spara ändringar" #: sabnzbd/skintext.py:328 msgid "Language" msgstr "Språk" #: sabnzbd/skintext.py:329 msgid "Select a web interface language." msgstr "Välj språk till webbkontrollen." #: sabnzbd/skintext.py:330 msgid "API Key" msgstr "API-nyckel" #: sabnzbd/skintext.py:331 msgid "This key will give 3rd party programs full access to SABnzbd." msgstr "Denna nyckel ger tredjepartsprogram full tillgång till SABnzbd." #: sabnzbd/skintext.py:332 msgid "NZB Key" msgstr "NZB-nyckel" #: sabnzbd/skintext.py:333 msgid "This key will allow 3rd party programs to add NZBs to SABnzbd." msgstr "" "Denna nyckel ger tredjepartsprogram möjlighet att lägga till NZB:er i " "SABnzbd." #: sabnzbd/skintext.py:334 msgid "Generate New Key" msgstr "Generera Ny Nyckel" #: sabnzbd/skintext.py:335 msgid "Disable API-key" msgstr "Stäng av API-nyckel" #: sabnzbd/skintext.py:336 msgid "Do not require the API key." msgstr "Kräv ingen API-nyckel." #: sabnzbd/skintext.py:337 msgid "USE AT YOUR OWN RISK!" msgstr "ANVÄND PÅ EGEN RISK!" #: sabnzbd/skintext.py:338 [Button to show QR code of APIKEY] msgid "QR Code" msgstr "QR-kod" #: sabnzbd/skintext.py:339 [Explanation for QR code of APIKEY] msgid "API Key QR Code" msgstr "API- eller QR-kod" #: sabnzbd/skintext.py:342 msgid "Folder configuration" msgstr "Mappkonfiguration" #: sabnzbd/skintext.py:343 msgid "" "NOTE: Folders will be created automatically when Saving. You may " "use absolute paths to save outside of the default folders." msgstr "" "OBS: Mappar kommer att skapas automatiskt när du Sparar. Du måste " "ange exakta sökvägar till dina mappar för att spara utanför standardmapparna." #: sabnzbd/skintext.py:344 msgid "User Folders" msgstr "Användarmappar" #: sabnzbd/skintext.py:345 msgid "In" msgstr "I" #: sabnzbd/skintext.py:346 msgid "Temporary Download Folder" msgstr "Temporär nedladdningsmapp" #: sabnzbd/skintext.py:347 msgid "" "Location to store unprocessed downloads.
    Can only be changed when " "queue is empty." msgstr "" "Plats för att lagra ej bearbetade nedladdningar.
    Kan endast ändras " "när kön är tom." #: sabnzbd/skintext.py:348 msgid "Minimum Free Space for Temporary Download Folder" msgstr "Minimal fri plats för temporär nedladdningsmapp" #: sabnzbd/skintext.py:349 msgid "" "Auto-pause when free space is beneath this value.
    In bytes, " "optionally follow with K,M,G,T. For example: \"800M\" or \"8G\"" msgstr "" "Auto-pausa när fri plats är nära sin gräns.
    I bytes, följt av " "K,M,G,T. Till exempel: \"800M\" or \"8G\"" #: sabnzbd/skintext.py:350 msgid "Completed Download Folder" msgstr "Färdig nedladdningsmapp" #: sabnzbd/skintext.py:351 msgid "" "Location to store finished, fully processed downloads.
    Can be " "overruled by user-defined categories." msgstr "" "Plats för att lagra bearbetade och färdiga nedladdningar.
    Kan " "åsidosättas av användar-definierade kategorier." #: sabnzbd/skintext.py:352 msgid "Permissions for completed downloads" msgstr "Rättigheter för färdiga nedladdningar" #: sabnzbd/skintext.py:353 msgid "" "Set permissions pattern for completed files/folders.
    In octal " "notation. For example: \"755\" or \"777\"" msgstr "" "Sätt rättigheter för färdiga filer och mappar.
    Använd siffror. Till " "exempel: \"755\" or \"777\"" #: sabnzbd/skintext.py:354 msgid "Watched Folder" msgstr "Övervakad Mapp" #: sabnzbd/skintext.py:355 msgid "" "Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz " "archives for .nzb files." msgstr "" "Mapp som igenomsöks automatiskt efter .nzb filer.
    Skannar även " "igenom .zip .rar och .tar.gz arkiv efter .nzb filer." #: sabnzbd/skintext.py:356 msgid "Watched Folder Scan Speed" msgstr "Skanningsintervall för Övervakade mappar" #: sabnzbd/skintext.py:357 msgid "Number of seconds between scans for .nzb files." msgstr "Sekunder mellan skanningar för .nzb filer." #: sabnzbd/skintext.py:358 msgid "Post-Processing Scripts Folder" msgstr "Efterbehandlings skriptmapp" #: sabnzbd/skintext.py:359 msgid "Folder containing user scripts for post-processing." msgstr "Mapp innehållande skript för efterbehandling." #: sabnzbd/skintext.py:360 msgid "Email Templates Folder" msgstr "Mapp för E-mail mallar" #: sabnzbd/skintext.py:361 msgid "Folder containing user-defined email templates." msgstr "Mapp som innehåller användar-definierade e-mail mallar." #: sabnzbd/skintext.py:362 msgid "Password file" msgstr "Lösenordsfil" #: sabnzbd/skintext.py:363 msgid "File containing all passwords to be tried on encrypted RAR files." msgstr "" "Fil som innehåller alla lösenord som ska prövas på krypterade RAR-filer." #: sabnzbd/skintext.py:364 msgid "System Folders" msgstr "Systemmappar" #: sabnzbd/skintext.py:365 msgid "Administrative Folder" msgstr "Administrativ mapp" #: sabnzbd/skintext.py:366 msgid "" "Location for queue admin and history database.
    Can only be changed " "when queue is empty." msgstr "" "Plats för köadministration och historiedatabas.
    Kan bara ändras när " "kön är tom." #: sabnzbd/skintext.py:367 msgid "Data will not be moved. Requires SABnzbd restart!" msgstr "Data kommer inte tas bort. Kräver omstart av SABnzbd!" #: sabnzbd/skintext.py:368 msgid "Log Folder" msgstr "Loggmapp" #: sabnzbd/skintext.py:369 msgid "" "Location of log files for SABnzbd.
    Requires SABnzbd restart!" msgstr "" "Plats för sparade loggfiler från SABnzbd.
    Kräver omstart av " "SABnzbd!" #: sabnzbd/skintext.py:370 msgid ".nzb Backup Folder" msgstr ".nzb Reservmapp" #: sabnzbd/skintext.py:371 msgid "Location where .nzb files will be stored." msgstr "Plats där .nzb filer sparas." #: sabnzbd/skintext.py:372 msgid "Default Base Folder" msgstr "Standard basmapp" #: sabnzbd/skintext.py:375 msgid "Switches configuration" msgstr "Parameterkonfiguration" #: sabnzbd/skintext.py:376 msgid "Processing Switches" msgstr "Bearbetar parametrar" #: sabnzbd/skintext.py:377 msgid "Enable Quick Check" msgstr "Aktivera Snabbkoll" #: sabnzbd/skintext.py:378 msgid "Skip par2 checking when files are 100% valid." msgstr "Strunta i par2 kontroll när filerna är 100% giltiga." #: sabnzbd/skintext.py:379 msgid "Enable Unrar" msgstr "Aktivera Unrar" #: sabnzbd/skintext.py:380 msgid "Enable built-in unrar functionality." msgstr "Aktiverar inbyggda Unrar funktionen." #: sabnzbd/skintext.py:381 msgid "Enable Unzip" msgstr "Aktivera Unzip" #: sabnzbd/skintext.py:382 msgid "Enable built-in unzip functionality." msgstr "Aktiverar inbyggda Unzip funktionen." #: sabnzbd/skintext.py:383 msgid "Enable Filejoin" msgstr "Aktivera Filsammanslagning (Filejoin)" #: sabnzbd/skintext.py:384 msgid "Join files ending in .001, .002 etc. into one file." msgstr "Slår ihop filer med filändelserna .001, .002 etc. till en fil." #: sabnzbd/skintext.py:385 msgid "Enable TS Joining" msgstr "Aktivera TS Sammanslagning (TS Joining)" #: sabnzbd/skintext.py:386 msgid "Join files ending in .001.ts, .002.ts etc. into one file." msgstr "Slår ihop filer med filändelserna .001.ts, .002.ts etc. till en fil." #: sabnzbd/skintext.py:387 msgid "Enable Par Cleanup" msgstr "Aktivera Par rensning (Par Cleanup)" #: sabnzbd/skintext.py:388 msgid "Cleanup par files (if verifiying/repairing succeded)." msgstr "Rensar bort par filer (om verifiering/reparation lyckades)." #: sabnzbd/skintext.py:389 msgid "Fail on yEnc CRC Errors" msgstr "Vid fel på på yEnc CRC" #: sabnzbd/skintext.py:390 msgid "When article has a CRC error, try to get it from another server." msgstr "" "När artiklars CRC-kontrollsumma ger fel, försök att hämta dem från en annan " "server." #: sabnzbd/skintext.py:391 msgid "Only Get Articles for Top of Queue" msgstr "Bara artiklarna för början av kön" #: sabnzbd/skintext.py:392 msgid "" "Enable for less memory usage. Disable to prevent slow jobs from blocking the " "queue." msgstr "" "Aktivera för lägre minnesanvändning. Avaktivera för att förhindra långsamma " "jobb att blockera kön." #: sabnzbd/skintext.py:393 msgid "Post-Process Only Verified Jobs" msgstr "Efterbehandla endast verifierade jobb" #: sabnzbd/skintext.py:394 msgid "Only perform post-processing on jobs that passed all PAR2 checks." msgstr "Efterbehandla enbart jobb som passerat PAR2 kontrollen." #: sabnzbd/skintext.py:395 msgid "Action when encrypted RAR is downloaded" msgstr "" #: sabnzbd/skintext.py:396 msgid "" "In case of \"Pause\", you'll need to set a password and resume the job." msgstr "" #: sabnzbd/skintext.py:397 msgid "Detect Duplicate Downloads" msgstr "Upptäck dubbletter av nedladdningar" #: sabnzbd/skintext.py:398 msgid "" "Detect identically named NZB files (requires NZB backup option) and " "duplicate titles across RSS feeds." msgstr "" "Upptäck NZB:er med samma namn (kräver att NZB säkerhetskopiering är på) och " "dubbletter av titlar över RSS-flöden." #: sabnzbd/skintext.py:399 msgid "Action when unwanted extension detected" msgstr "" #: sabnzbd/skintext.py:400 msgid "Action when an unwanted extension is detected in RAR files" msgstr "" #: sabnzbd/skintext.py:401 msgid "Unwanted extensions" msgstr "" #: sabnzbd/skintext.py:402 msgid "" "List all unwanted extensions. For example: exe or exe, com" msgstr "" #: sabnzbd/skintext.py:403 [Three way switch for duplicates] # sabnzbd/skintext.py:451 msgid "Off" msgstr "Av" #: sabnzbd/skintext.py:404 [Three way switch for duplicates] msgid "Discard" msgstr "Förkasta" #: sabnzbd/skintext.py:406 [Three way switch for encrypted posts] msgid "Abort" msgstr "" #: sabnzbd/skintext.py:407 msgid "Enable SFV-based checks" msgstr "Använd SFV-baserade kontroller" #: sabnzbd/skintext.py:408 msgid "Do an extra verification based on SFV files." msgstr "Gör en extra kontroll med SFV filer" #: sabnzbd/skintext.py:409 msgid "Check result of unpacking" msgstr "Kontrollera resultat av uppackning" #: sabnzbd/skintext.py:410 msgid "Check result of unpacking (needs to be off for some file systems)." msgstr "" "Kontrollera resultat av uppackning (måste slås av på vissa filsystem)." #: sabnzbd/skintext.py:411 msgid "Enable folder rename" msgstr "Döp om mappar" #: sabnzbd/skintext.py:412 msgid "" "Use temporary names during post processing. Disable when your system doesn't " "handle that properly." msgstr "" "Använd temporära namn under efterbehandling. Avslaget när ditt system inte " "stöder det." #: sabnzbd/skintext.py:413 msgid "Default Post-Processing" msgstr "Standard efterbehandling" #: sabnzbd/skintext.py:414 msgid "Used when no post-processing is defined by the category." msgstr "Används när efterbehandlingen är bestämd efter kategori." #: sabnzbd/skintext.py:415 msgid "Default User Script" msgstr "Standard användarskript" #: sabnzbd/skintext.py:416 msgid "Used when no user script is defined by the category." msgstr "Används när användarskript är bestämd efter kategori." #: sabnzbd/skintext.py:417 msgid "Pre-queue user script" msgstr "Kö-specifika användarskript" #: sabnzbd/skintext.py:418 msgid "Used before an NZB enters the queue." msgstr "Används innan en NZB tas in i kön." #: sabnzbd/skintext.py:419 msgid "Default Priority" msgstr "Standard prioritet" #: sabnzbd/skintext.py:420 msgid "Used when no priority is defined by the category." msgstr "Använd när ingen prioritet är bestämd av kategori." #: sabnzbd/skintext.py:421 msgid "Enable MultiCore Par2" msgstr "Aktivera MultiCore Par2" #: sabnzbd/skintext.py:422 # sabnzbd/skintext.py:424 # sabnzbd/skintext.py:426 #: sabnzbd/skintext.py:428 msgid "Read the Wiki Help on this!" msgstr "Läs Wiki Help för detta!" #: sabnzbd/skintext.py:423 msgid "Extra PAR2 Parameters" msgstr "Extra PAR2 parametrar" #: sabnzbd/skintext.py:425 msgid "Nice Parameters" msgstr "Bra parametrar" #: sabnzbd/skintext.py:427 msgid "IONice Parameters" msgstr "IONice parametrar" #: sabnzbd/skintext.py:429 msgid "Other Switches" msgstr "Andra parametrar" #: sabnzbd/skintext.py:430 msgid "Disconnect on Empty Queue" msgstr "Koppla ifrån när kön är tom" #: sabnzbd/skintext.py:431 msgid "Disconnect from Usenet server(s) when queue is empty or paused." msgstr "Koppla ifrån usenet servrarna när kön är tom eller pausad." #: sabnzbd/skintext.py:432 msgid "Send Group" msgstr "Skicka grupp" #: sabnzbd/skintext.py:433 msgid "Send group command before requesting articles." msgstr "Skicka gruppkommando innan du begär artiklar." #: sabnzbd/skintext.py:434 msgid "Sort by Age" msgstr "Sortera efter ålder" #: sabnzbd/skintext.py:435 msgid "Automatically sort items by (average) age." msgstr "Sortera automatiskt efter (medel) ålder." #: sabnzbd/skintext.py:436 msgid "Check for New Release" msgstr "Kolla efter ny utgåva" #: sabnzbd/skintext.py:437 msgid "Weekly check for new SABnzbd release." msgstr "Kolla efter ny utgåva av SABnzbd varje vecka." #: sabnzbd/skintext.py:438 [Pick list for weekly test for new releases] msgid "Also test releases" msgstr "" #: sabnzbd/skintext.py:439 msgid "Replace Spaces in Foldername" msgstr "Ersätt mellanslag i mappnamn" #: sabnzbd/skintext.py:440 msgid "Replace spaces with underscores in folder names." msgstr "Ersätt mellanslag med understreck i mappnamn." #: sabnzbd/skintext.py:441 msgid "Replace dots in Foldername" msgstr "Ersätt punkter i mappnamn" #: sabnzbd/skintext.py:442 msgid "Replace dots with spaces in folder names." msgstr "Ersätt punkter med mellanslag i mappnamn" #: sabnzbd/skintext.py:443 msgid "Replace Illegal Characters in Folder Names" msgstr "Ersätt otillåtna tecken i mappnamn." #: sabnzbd/skintext.py:444 msgid "" "Replace illegal characters in folder names by equivalents (otherwise remove)." msgstr "" "Ersätt otillåtna tecken i mappnamn med motsvarande tecken (annars ta bort)." #: sabnzbd/skintext.py:445 msgid "Launch Browser on Startup" msgstr "Starta webbläsare vid uppstart" #: sabnzbd/skintext.py:446 msgid "Launch the default web browser when starting SABnzbd." msgstr "Startar standard webbläsaren när SABnzbd startar." #: sabnzbd/skintext.py:447 msgid "Pause Downloading During Post-Processing" msgstr "Pausa nedladdning under efterbehandling" #: sabnzbd/skintext.py:448 msgid "" "Pauses downloading at the start of post processing and resumes when finished." msgstr "" "Pausas nedladdning när efterbehandling börjar och återupptar nedladdning när " "efterbehandling är klar." #: sabnzbd/skintext.py:449 msgid "Ignore Samples" msgstr "Ignorera Sample-filer" #: sabnzbd/skintext.py:450 msgid "Filter out sample files (e.g. video samples)." msgstr "Filtrera ut sample-filer (ex. video samplingar)." #: sabnzbd/skintext.py:452 msgid "Delete after download" msgstr "Ta bort efter nedladdning" #: sabnzbd/skintext.py:453 msgid "Do not download" msgstr "Ladda inte ned." #: sabnzbd/skintext.py:454 msgid "SSL type" msgstr "SSL typ" #: sabnzbd/skintext.py:455 msgid "Use V23 unless your provider requires otherwise!" msgstr "Använd V23 om inte din leverantör kräver annat!" #: sabnzbd/skintext.py:456 msgid "Use 12 hour clock (AM/PM)" msgstr "" #: sabnzbd/skintext.py:457 msgid "Show times in AM/PM notation (does not affect scheduler)." msgstr "" #: sabnzbd/skintext.py:459 msgid "Server" msgstr "" #: sabnzbd/skintext.py:461 msgid "Post processing" msgstr "" #: sabnzbd/skintext.py:462 msgid "Naming" msgstr "" #: sabnzbd/skintext.py:463 msgid "Quota" msgstr "" #: sabnzbd/skintext.py:464 msgid "Indexing" msgstr "" #: sabnzbd/skintext.py:466 msgid "How much can be downloaded this month (K/M/G)" msgstr "" #: sabnzbd/skintext.py:467 [Reset day of the download quota] msgid "Reset day" msgstr "" #: sabnzbd/skintext.py:468 msgid "" "On which day of the month or week (1=Monday) does your ISP reset the quota? " "(Optionally with hh:mm)" msgstr "" #: sabnzbd/skintext.py:469 [Auto-resume download on the reset day] msgid "Auto resume" msgstr "" #: sabnzbd/skintext.py:470 msgid "Should downloading resume after the quota is reset?" msgstr "" #: sabnzbd/skintext.py:471 [Does the quota get reset every day, week or month?] msgid "Quota period" msgstr "" #: sabnzbd/skintext.py:472 msgid "Does the quota get reset each day, week or month?" msgstr "" #: sabnzbd/skintext.py:473 msgid "Check before download" msgstr "" #: sabnzbd/skintext.py:474 msgid "Try to predict successful completion before actual download (slower!)" msgstr "" #: sabnzbd/skintext.py:475 msgid "Maximum retries" msgstr "" #: sabnzbd/skintext.py:476 msgid "Maximum number of retries per server" msgstr "" #: sabnzbd/skintext.py:477 msgid "Only for optional servers" msgstr "" #: sabnzbd/skintext.py:478 msgid "Apply maximum retries only to optional servers" msgstr "" #: sabnzbd/skintext.py:479 msgid "Abort jobs that cannot be completed" msgstr "" #: sabnzbd/skintext.py:480 msgid "" "When during download it becomes clear that too much data is missing, abort " "the job" msgstr "" #: sabnzbd/skintext.py:481 msgid "Enable OZnzb Integration" msgstr "" #: sabnzbd/skintext.py:482 msgid "" "Enhanced functionality including ratings and extra status information is " "available when connected to OZnzb indexer." msgstr "" #: sabnzbd/skintext.py:483 msgid "Site API Key" msgstr "" #: sabnzbd/skintext.py:484 msgid "" "This key provides identity to indexer. Refer to " "https://www.oznzb.com/profile." msgstr "" #: sabnzbd/skintext.py:485 msgid "Refer to https://www.oznzb.com/profile" msgstr "" #: sabnzbd/skintext.py:486 msgid "Automatic Feedback" msgstr "" #: sabnzbd/skintext.py:487 msgid "" "Send automatically calculated validation results for downloads to indexer." msgstr "" #: sabnzbd/skintext.py:490 [Caption] msgid "Server configuration" msgstr "Serverkonfiguration" #: sabnzbd/skintext.py:491 msgid "Server definition" msgstr "" #: sabnzbd/skintext.py:492 [Caption] # sabnzbd/skintext.py:504 [Button: Add server] msgid "Add Server" msgstr "Lägg till server" #: sabnzbd/skintext.py:494 [Server port] msgid "Port" msgstr "" #: sabnzbd/skintext.py:495 [Server username] msgid "Username" msgstr "Användarnamn" #: sabnzbd/skintext.py:496 [Server password] msgid "Password" msgstr "Lösenord" #: sabnzbd/skintext.py:497 [Server timeout] msgid "Timeout" msgstr "" #: sabnzbd/skintext.py:499 [Server's retention time in days] msgid "Retention time" msgstr "" #: sabnzbd/skintext.py:500 [Server SSL tickbox] msgid "SSL" msgstr "" #: sabnzbd/skintext.py:501 [Backup server tickbox] msgid "Backup server" msgstr "Reserv server" #: sabnzbd/skintext.py:502 [Server optional tickbox] # sabnzbd/skintext.py:878 [As in "this item is optional"] msgid "Optional" msgstr "Valfri" #: sabnzbd/skintext.py:503 [Enable server tickbox] msgid "Enable" msgstr "Aktivera" #: sabnzbd/skintext.py:505 [Button: Remove server] msgid "Remove Server" msgstr "Ta bort server" #: sabnzbd/skintext.py:506 [Button: Test server] # sabnzbd/skintext.py:880 [Wizard step] msgid "Test Server" msgstr "Testserver" #: sabnzbd/skintext.py:507 [Button: Clear server's byte counters] msgid "Clear Counters" msgstr "" #: sabnzbd/skintext.py:508 msgid "Testing server details..." msgstr "Testar serverdetaljer..." #: sabnzbd/skintext.py:509 msgid "Click below to test." msgstr "Klicka nedan för att testa." #: sabnzbd/skintext.py:510 msgid "Bandwidth" msgstr "" #: sabnzbd/skintext.py:513 msgid "Scheduling configuration" msgstr "Schemakonfiguration" #: sabnzbd/skintext.py:514 # sabnzbd/skintext.py:518 msgid "Add Schedule" msgstr "Lägg till schema" #: sabnzbd/skintext.py:519 msgid "Remove" msgstr "Ta bort" #: sabnzbd/skintext.py:520 msgid "Current Schedules" msgstr "Aktuella scheman" #: sabnzbd/skintext.py:527 msgid "RSS Configuration" msgstr "RSS-konfiguration" #: sabnzbd/skintext.py:528 msgid "New Feed URL" msgstr "Ny flödesadress" #: sabnzbd/skintext.py:529 msgid "" "The checkbox next to the feed name should be ticked for the feed to be " "enabled and be automatically checked for new items.
    When a feed is " "added, it will only pick up new items and not anything already in the RSS " "feed unless you press \"Force Download\"." msgstr "" "Kryssrutan bredvid flödesnamnet ska aktiveras för att flödet automatiskt ska " "kontrolleras för nya objekt.
    När ett flöde läggs till kommer det bara " "att välja nya objekt och inte allt som redan finns i RSS-flöded så länge du " "inte klickar på \"Tvinga nedladdning\"." #: sabnzbd/skintext.py:531 [Config->RSS button] msgid "Add Feed" msgstr "" #: sabnzbd/skintext.py:532 [Config->RSS button] msgid "Delete Feed" msgstr "Ta bort flöde" #: sabnzbd/skintext.py:533 [Config->RSS button] msgid "Read Feed" msgstr "" #: sabnzbd/skintext.py:534 [Config->RSS button] msgid "Force Download" msgstr "Tvinga nedladdning" #: sabnzbd/skintext.py:537 [Config->RSS table column header] msgid "Filter" msgstr "" #: sabnzbd/skintext.py:538 [Config->RSS table column header] msgid "Skip" msgstr "" #: sabnzbd/skintext.py:539 [Config->RSS filter-type selection menu] msgid "Accept" msgstr "Acceptera" #: sabnzbd/skintext.py:540 [Config->RSS filter-type selection menu] msgid "Reject" msgstr "Avvisa" #: sabnzbd/skintext.py:541 [Config->RSS filter-type selection menu] msgid "Requires" msgstr "Kräver" #: sabnzbd/skintext.py:542 [Config->RSS filter-type selection menu] msgid "RequiresCat" msgstr "KräverKat" #: sabnzbd/skintext.py:545 [Config->RSS section header] msgid "Not Matched" msgstr "" #: sabnzbd/skintext.py:548 [Tab title for Config->Feeds] msgid "Feeds" msgstr "" #: sabnzbd/skintext.py:549 [Config->RSS button] msgid "Read All Feeds Now" msgstr "" #: sabnzbd/skintext.py:550 [Tab title for Config->Feeds] msgid "Settings" msgstr "" #: sabnzbd/skintext.py:551 [Tab title for Config->Feeds] msgid "Filters" msgstr "" #: sabnzbd/skintext.py:554 [Section header] msgid "Email Options" msgstr "E-mail alternativ" #: sabnzbd/skintext.py:555 msgid "Email Notification On Job Completion" msgstr "E-mail notifiering när jobb är slutfört" #: sabnzbd/skintext.py:556 [When to send email] msgid "Never" msgstr "Aldrig" #: sabnzbd/skintext.py:557 [When to send email] msgid "Always" msgstr "Alltid" #: sabnzbd/skintext.py:558 [When to send email] msgid "Error-only" msgstr "Bara vid fel" #: sabnzbd/skintext.py:559 msgid "Disk Full Notifications" msgstr "Full hårddisk notifiering" #: sabnzbd/skintext.py:560 msgid "Send email when disk is full and SABnzbd is paused." msgstr "Skicka e-mail när hårddisken är full och SABnzbd har pausat." #: sabnzbd/skintext.py:561 msgid "Send RSS notifications" msgstr "" #: sabnzbd/skintext.py:562 msgid "Send email when an RSS feed adds jobs to the queue." msgstr "" #: sabnzbd/skintext.py:563 msgid "Email Account Settings" msgstr "E-mail kontoinställningar" #: sabnzbd/skintext.py:564 msgid "SMTP Server" msgstr "" #: sabnzbd/skintext.py:565 msgid "Set your ISP's server for outgoing email." msgstr "Ställ in din ISP's server för utgående e-mail." #: sabnzbd/skintext.py:566 msgid "Email Recipient" msgstr "E-mail mottagare" #: sabnzbd/skintext.py:567 msgid "Email address to send the email to." msgstr "E-mail adress att skicka e-mailen till." #: sabnzbd/skintext.py:568 msgid "Email Sender" msgstr "E-mail sändare" #: sabnzbd/skintext.py:569 msgid "Who should we say sent the email?" msgstr "Vem ska vi skicka e-mailet från?" #: sabnzbd/skintext.py:570 msgid "OPTIONAL Account Username" msgstr "VALFRITT Kontoanvändarnamn" #: sabnzbd/skintext.py:571 msgid "For authenticated email, account name." msgstr "Användarnamn för e-mail som kräver autentisering." #: sabnzbd/skintext.py:572 msgid "OPTIONAL Account Password" msgstr "VALFRITT Användarlösenord" #: sabnzbd/skintext.py:573 msgid "For authenticated email, password." msgstr "Lösenord för e-mail som kräver autentisering." #: sabnzbd/skintext.py:575 [Don't translate "Growl"] msgid "Enable Growl" msgstr "" #: sabnzbd/skintext.py:576 [Don't translate "Growl"] msgid "Send notifications to Growl" msgstr "" #: sabnzbd/skintext.py:577 [Address of Growl server] msgid "Server address" msgstr "" #: sabnzbd/skintext.py:578 [Don't translate "Growl"] msgid "Only use for remote Growl server (host:port)" msgstr "" #: sabnzbd/skintext.py:579 [Growl server password] msgid "Server password" msgstr "" #: sabnzbd/skintext.py:580 [Don't translate "Growl"] msgid "Optional password for Growl server" msgstr "" #: sabnzbd/skintext.py:581 [Don't translate "NotifyOSD"] msgid "Enable NotifyOSD" msgstr "" #: sabnzbd/skintext.py:582 [Don't translate "NotifyOSD"] msgid "Send notifications to NotifyOSD" msgstr "" #: sabnzbd/skintext.py:583 msgid "Notification Center" msgstr "" #: sabnzbd/skintext.py:584 msgid "Send notifications to Notification Center" msgstr "" #: sabnzbd/skintext.py:585 msgid "Notification classes" msgstr "" #: sabnzbd/skintext.py:586 msgid "Enable classes of messages to be reported (none, one or multiple)" msgstr "" #: sabnzbd/skintext.py:590 msgid "" "If you have an account at www.newzbin2.es, you can enter " "your account info here.
    This will unlock extra functionality." msgstr "" #: sabnzbd/skintext.py:591 msgid "Account info" msgstr "Användarinfo" #: sabnzbd/skintext.py:592 msgid "Newzbin Username" msgstr "Newzbin Användarnamn" #: sabnzbd/skintext.py:593 # sabnzbd/skintext.py:609 msgid "Set your account username here." msgstr "Ställ in ditt användarnamn här." #: sabnzbd/skintext.py:594 msgid "Newzbin Password" msgstr "Newzbin Lösenord" #: sabnzbd/skintext.py:595 msgid "Set your account password here." msgstr "Ställ in ditt användarlösenord här." #: sabnzbd/skintext.py:596 msgid "Bookmark Processing" msgstr "Bearbetar bokmärken" #: sabnzbd/skintext.py:597 msgid "Auto-Fetch Bookmarks" msgstr "Hämta bokmärken automatiskt" #: sabnzbd/skintext.py:598 msgid "Automatically retrieve jobs from your bookmarks." msgstr "Hämtar jobb från bokmärken automatiskt." #: sabnzbd/skintext.py:599 msgid "Get Bookmarks Now" msgstr "Hämta bokmärken nu" #: sabnzbd/skintext.py:600 msgid "Hide Bookmarks" msgstr "" #: sabnzbd/skintext.py:601 msgid "Show Bookmarks" msgstr "" #: sabnzbd/skintext.py:602 msgid "Un-Bookmark If Download Complete" msgstr "Ta bort bokmärke efter nedladdning" #: sabnzbd/skintext.py:603 msgid "Remove from bookmark list when download is complete." msgstr "Ta bort från bokmärkeslistan när nedladdning är genomförd." #: sabnzbd/skintext.py:604 msgid "Checking Interval" msgstr "Uppdateringsintervall" #: sabnzbd/skintext.py:605 msgid "In minutes (at least 15 min)." msgstr "I minuter (minst 15 min)." #: sabnzbd/skintext.py:606 msgid "Processed Bookmarks" msgstr "Bearbetar bokmärken" #: sabnzbd/skintext.py:607 msgid "" "If you have an account at www.nzbmatrix.com, you can enter " "your account info here.
    This is required if you want to use the RSS " "feeds of this site." msgstr "" "Om du har ett konto på www.nzbmatrix.com, så kan du skriva " "in din användarinformation här.
    Det krävs för att du ska kunna använda " "RSS-flödet från nzbmatrix." #: sabnzbd/skintext.py:608 msgid "NzbMatrix Username" msgstr "NzbMatrix Användarnamn" #: sabnzbd/skintext.py:610 msgid "NzbMatrix API key" msgstr "NzbMatrix API-nyckel" #: sabnzbd/skintext.py:611 msgid "Set the NzbMatrix API key here." msgstr "Ställ in API-nyckel för NzbMatrix här." #: sabnzbd/skintext.py:614 msgid "User-defined categories" msgstr "Användardefinierade kategorier" #: sabnzbd/skintext.py:615 msgid "Defines post-processing and storage." msgstr "Definierar efterbehandling och lagring." #: sabnzbd/skintext.py:616 msgid "" "Use the \"Groups / Indexer tags\" column to map groups and tags to your " "categories.
    Wildcards are supported. Use commas to seperate terms." msgstr "" #: sabnzbd/skintext.py:617 msgid "" "Ending the path with an asterisk * will prevent creation of job folders." msgstr "" #: sabnzbd/skintext.py:618 msgid "Relative folders are based on" msgstr "Relativa mappar är baserade på" #: sabnzbd/skintext.py:619 msgid "Folder/Path" msgstr "Mapp/Sökväg" #: sabnzbd/skintext.py:620 msgid "Groups / Indexer tags" msgstr "" #: sabnzbd/skintext.py:624 msgid "Sorting configuration" msgstr "Sorteringskonfiguration" #: sabnzbd/skintext.py:625 msgid "Series Sorting" msgstr "Seriesortering" #: sabnzbd/skintext.py:626 msgid "Enable TV Sorting" msgstr "Aktivera TV sortering" #: sabnzbd/skintext.py:627 msgid "Enable sorting and renaming of episodes." msgstr "Aktiverar sortering och omdöpning av episoder." #: sabnzbd/skintext.py:628 msgid "Pattern Key" msgstr "Hjälp till Sorteringssträng" #: sabnzbd/skintext.py:629 msgid "Clear" msgstr "Rensa" #: sabnzbd/skintext.py:630 msgid "Presets" msgstr "Förinställningar" #: sabnzbd/skintext.py:631 msgid "Example" msgstr "Exempel" #: sabnzbd/skintext.py:632 msgid "Generic Sorting" msgstr "Allmän sortering" #: sabnzbd/skintext.py:633 msgid "Enable Movie Sorting" msgstr "Aktivera filmsortering" #: sabnzbd/skintext.py:634 msgid "Enable generic sorting and renaming of files." msgstr "Aktiverar sortering och omdöpning av filer." #: sabnzbd/skintext.py:635 msgid "Keep loose downloads in extra folders" msgstr "Låt nedladdning i extramapp vara" #: sabnzbd/skintext.py:636 msgid "Enable if downloads are not put in their own folders." msgstr "Aktivera om nedladdning inte är flyttad till egen mapp." #: sabnzbd/skintext.py:637 msgid "Affected Categories" msgstr "Påverkade kategorier" #: sabnzbd/skintext.py:638 msgid "Meaning" msgstr "Betyder" #: sabnzbd/skintext.py:639 msgid "Pattern" msgstr "Mönster" #: sabnzbd/skintext.py:640 msgid "Result" msgstr "Resultat" #: sabnzbd/skintext.py:641 msgid "1x05 Season Folder" msgstr "1x05 Säsongsmapp" #: sabnzbd/skintext.py:642 msgid "S01E05 Season Folder" msgstr "S01E05 Säsongsmapp" #: sabnzbd/skintext.py:643 msgid "1x05 Episode Folder" msgstr "1x05 Episodmapp" #: sabnzbd/skintext.py:644 msgid "S01E05 Episode Folder" msgstr "S01E05 Episodmapp" #: sabnzbd/skintext.py:645 msgid "Title" msgstr "Titel" #: sabnzbd/skintext.py:646 msgid "Movie Name" msgstr "Film Namn" #: sabnzbd/skintext.py:647 msgid "Movie.Name" msgstr "Film.Namn" #: sabnzbd/skintext.py:648 msgid "Movie_Name" msgstr "Film_Namn" #: sabnzbd/skintext.py:649 # sabnzbd/skintext.py:650 msgid "Show Name" msgstr "Show Namn" #: sabnzbd/skintext.py:651 msgid "Show.Name" msgstr "Show.Namn" #: sabnzbd/skintext.py:652 msgid "Show_Name" msgstr "Show_Namn" #: sabnzbd/skintext.py:653 msgid "Season Number" msgstr "Säsongsnummer" #: sabnzbd/skintext.py:654 msgid "Episode Number" msgstr "Episodnummer" #: sabnzbd/skintext.py:655 # sabnzbd/skintext.py:656 msgid "Episode Name" msgstr "Episodnamn" #: sabnzbd/skintext.py:657 msgid "Episode.Name" msgstr "Episod.Namn" #: sabnzbd/skintext.py:658 msgid "Episode_Name" msgstr "Episod_Namn" #: sabnzbd/skintext.py:659 msgid "File Extension" msgstr "Filändelse" #: sabnzbd/skintext.py:660 msgid "Extension" msgstr "ändelse" #: sabnzbd/skintext.py:661 msgid "Part Number" msgstr "Delnummer" #: sabnzbd/skintext.py:662 msgid "Decade" msgstr "Tiotal" #: sabnzbd/skintext.py:663 msgid "Original Filename" msgstr "Originalfilnamn" #: sabnzbd/skintext.py:664 msgid "Original Foldername" msgstr "" #: sabnzbd/skintext.py:665 msgid "Lower Case" msgstr "Små bokstäver" #: sabnzbd/skintext.py:666 msgid "TEXT" msgstr "" #: sabnzbd/skintext.py:667 msgid "text" msgstr "" #: sabnzbd/skintext.py:668 msgid "file" msgstr "fil" #: sabnzbd/skintext.py:669 msgid "folder" msgstr "" #: sabnzbd/skintext.py:670 msgid "Sort String" msgstr "Sorteringssträng" #: sabnzbd/skintext.py:671 msgid "Multi-part label" msgstr "Multi-del etikett" #: sabnzbd/skintext.py:672 msgid "In folders" msgstr "In mapp" #: sabnzbd/skintext.py:673 msgid "No folders" msgstr "Ingen mapp" #: sabnzbd/skintext.py:674 msgid "Date Sorting" msgstr "Datum sortering" #: sabnzbd/skintext.py:675 msgid "Enable Date Sorting" msgstr "Aktivera datumssortering" #: sabnzbd/skintext.py:676 msgid "Enable sorting and renaming of date named files." msgstr "Aktiverar sortering och omdöpning av datummärkta filer." #: sabnzbd/skintext.py:677 msgid "Show Name folder" msgstr "Visa Namn på mapp" #: sabnzbd/skintext.py:678 msgid "Year-Month Folders" msgstr "År-Månads mappar" #: sabnzbd/skintext.py:679 msgid "Daily Folders" msgstr "Dagliga mappar" #: sabnzbd/skintext.py:680 [Note for title expression in Sorting that does case adjustment] msgid "case-adjusted" msgstr "" #: sabnzbd/skintext.py:681 msgid "Processed Result" msgstr "" #: sabnzbd/skintext.py:684 msgid "" "Rarely used options. For their meaning and explanation, click on the Help " "button to go to the Wiki page.
    Don't change these without checking the " "Wiki first, as some have serious side-effects.
    The default values are " "between parentheses." msgstr "" #: sabnzbd/skintext.py:688 msgid "Values" msgstr "" #: sabnzbd/skintext.py:691 [Job details page] msgid "Edit NZB Details" msgstr "Ändra NZB detaljer" #: sabnzbd/skintext.py:693 [Job details page, delete button] # sabnzbd/skintext.py:807 msgid "Delete" msgstr "Ta bort" #: sabnzbd/skintext.py:694 [Job details page, move file to top] msgid "Top" msgstr "Topp" #: sabnzbd/skintext.py:695 [Job details page, move file one place up] msgid "Up" msgstr "Upp" #: sabnzbd/skintext.py:696 [Job details page, move file one place down] msgid "Down" msgstr "Ner" #: sabnzbd/skintext.py:697 [Job details page, move file to bottom] msgid "Bottom" msgstr "Botten" #: sabnzbd/skintext.py:698 [Job details page, select all files] msgid "All" msgstr "Alla" #: sabnzbd/skintext.py:700 [Job details page, invert file selection] msgid "Invert" msgstr "Invertera" #: sabnzbd/skintext.py:701 [Job details page, filename column header] msgid "Filename" msgstr "Filnamn" #: sabnzbd/skintext.py:702 [Job details page, subject column header] msgid "Subject" msgstr "Ämne" #: sabnzbd/skintext.py:703 [Job details page, file age column header] # sabnzbd/skintext.py:851 msgid "Age" msgstr "Ålder" #: sabnzbd/skintext.py:704 [Job details page, section header] msgid "Selection" msgstr "Urval" #: sabnzbd/skintext.py:709 msgid "Are you sure you want to delete" msgstr "Är du säker på att du vill ta bort" #: sabnzbd/skintext.py:710 # sabnzbd/skintext.py:757 msgid "Refresh" msgstr "Uppdatera" #: sabnzbd/skintext.py:712 # sabnzbd/skintext.py:758 msgid "Options" msgstr "Alternativ" #: sabnzbd/skintext.py:713 msgid "Page" msgstr "Sida" #: sabnzbd/skintext.py:714 # sabnzbd/skintext.py:752 # sabnzbd/skintext.py:824 msgid "Prev" msgstr "Föregående" #: sabnzbd/skintext.py:715 # sabnzbd/skintext.py:753 # sabnzbd/skintext.py:825 #: sabnzbd/skintext.py:857 [Button to go to next Wizard page] msgid "Next" msgstr "Nästa" #: sabnzbd/skintext.py:716 # sabnzbd/skintext.py:823 msgid "First" msgstr "Första" #: sabnzbd/skintext.py:717 # sabnzbd/skintext.py:826 msgid "Last" msgstr "Sista" #: sabnzbd/skintext.py:718 msgid "Close" msgstr "Stäng" #: sabnzbd/skintext.py:719 msgid "Set Pause Interval" msgstr "Sätt pausintervall" #: sabnzbd/skintext.py:720 # sabnzbd/skintext.py:772 msgid "Sort" msgstr "Sortera" #: sabnzbd/skintext.py:721 # sabnzbd/skintext.py:779 msgid "Purge the Queue?" msgstr "Töm kön?" #: sabnzbd/skintext.py:723 msgid "Pause Interval" msgstr "Pausintervall" #: sabnzbd/skintext.py:724 # sabnzbd/skintext.py:761 msgid "Pause for 5 minutes" msgstr "Pausa 5 minuter" #: sabnzbd/skintext.py:725 # sabnzbd/skintext.py:762 msgid "Pause for 15 minutes" msgstr "Pause 15 minuter" #: sabnzbd/skintext.py:726 # sabnzbd/skintext.py:763 msgid "Pause for 30 minutes" msgstr "Pausa 30 minuter" #: sabnzbd/skintext.py:727 # sabnzbd/skintext.py:764 msgid "Pause for 1 hour" msgstr "Pausa 1 timme" #: sabnzbd/skintext.py:728 # sabnzbd/skintext.py:765 msgid "Pause for 3 hours" msgstr "Pausa 3 timmar" #: sabnzbd/skintext.py:729 # sabnzbd/skintext.py:766 msgid "Pause for 6 hours" msgstr "Pausa 6 timmar" #: sabnzbd/skintext.py:730 msgid "Pause for 12 hours" msgstr "Pausa 12 timmar" #: sabnzbd/skintext.py:731 msgid "Pause for 24 hours" msgstr "Pausa 24 timmar" #: sabnzbd/skintext.py:732 msgid "Sort by Age Oldest→Newest" msgstr "Sortera efter ålder Äldst→Nyast" #: sabnzbd/skintext.py:733 msgid "Sort by Age Newest→Oldest" msgstr "Sortera efter ålder Nyast→Äldst" #: sabnzbd/skintext.py:734 msgid "Sort by Name A→Z" msgstr "Sortera efter namn A→Z" #: sabnzbd/skintext.py:735 msgid "Sort by Name Z→A" msgstr "Sortera efter namn Z→A" #: sabnzbd/skintext.py:736 msgid "Sort by Size Smallest→Largest" msgstr "Sortera efter storlek Minst→Störst" #: sabnzbd/skintext.py:737 msgid "Sort by Size Largest→Smallest" msgstr "Sortera efter storlek Störst→Minst" #: sabnzbd/skintext.py:738 msgid "Rename" msgstr "" #: sabnzbd/skintext.py:739 msgid "Left" msgstr "Vänster" #: sabnzbd/skintext.py:740 # sabnzbd/skintext.py:754 msgid "Purge the History?" msgstr "Vill du verkligen tömma historiken?" #: sabnzbd/skintext.py:744 msgid "Changes have not been saved, and will be lost." msgstr "Ändringarna har inte sparats och kommer att försvinna." #: sabnzbd/skintext.py:747 msgid "Open Source URL" msgstr "Öppen källdkod URL" #: sabnzbd/skintext.py:748 msgid "Open Informational URL" msgstr "Öppen informations URL" #: sabnzbd/skintext.py:750 msgid "Storage" msgstr "Lagring" #: sabnzbd/skintext.py:751 msgid "View Script Log" msgstr "Visa skriptlogg" #: sabnzbd/skintext.py:755 msgid "You must enable JavaScript for Plush to function!" msgstr "" #: sabnzbd/skintext.py:756 msgid "Add NZB" msgstr "Lägg till NZB" #: sabnzbd/skintext.py:759 msgid "Plush Options" msgstr "Plush Inställningar" #: sabnzbd/skintext.py:760 msgid "Update Available!" msgstr "Uppdatering tillgänglig" #: sabnzbd/skintext.py:767 # sabnzbd/skintext.py:827 msgid "Pause for how many minutes?" msgstr "Pausa hur många minuter?" #: sabnzbd/skintext.py:768 msgid "Pause for..." msgstr "Pausa i..." #: sabnzbd/skintext.py:769 msgid "Multi-Operations" msgstr "" #: sabnzbd/skintext.py:770 msgid "Top Menu" msgstr "" #: sabnzbd/skintext.py:771 msgid "On Finish" msgstr "Vid slut" #: sabnzbd/skintext.py:773 msgid "Sort by Age (Oldest→Newest)" msgstr "Sortera efter Ålder (Äldst→Nyast)" #: sabnzbd/skintext.py:774 msgid "Sort by Age (Newest→Oldest)" msgstr "Sortera efter Ålder (Nyast→Äldst)" #: sabnzbd/skintext.py:775 msgid "Sort by Name (A→Z)" msgstr "Sortera efter Namn (A→Z)" #: sabnzbd/skintext.py:776 msgid "Sort by Name (Z→A)" msgstr "Sortera efter Namn (Z→A)" #: sabnzbd/skintext.py:777 msgid "Sort by Size (Smallest→Largest)" msgstr "Sortera efter Storlek (Minst→Störst)" #: sabnzbd/skintext.py:778 msgid "Sort by Size (Largest→Smallest)" msgstr "Sortera efter Storlek (Störst→Minst)" #: sabnzbd/skintext.py:780 msgid "Purge" msgstr "Rensa" #: sabnzbd/skintext.py:781 msgid "left" msgstr "kvar" #: sabnzbd/skintext.py:782 [Used in speed menu. Split in two lines if too long.] msgid "Max Speed" msgstr "Max hastighet" #: sabnzbd/skintext.py:783 msgid "Range" msgstr "Omfång" #: sabnzbd/skintext.py:784 msgid "Reset" msgstr "" #: sabnzbd/skintext.py:785 msgid "Apply to Selected" msgstr "" #: sabnzbd/skintext.py:786 msgid "page" msgstr "sida" #: sabnzbd/skintext.py:787 msgid "Everything" msgstr "Allt" #: sabnzbd/skintext.py:788 msgid "Disabled" msgstr "Avaktiverad" #: sabnzbd/skintext.py:789 msgid "Refresh Rate" msgstr "Uppdateringsintervall" #: sabnzbd/skintext.py:790 msgid "Container Width" msgstr "" #: sabnzbd/skintext.py:791 msgid "Confirm Queue Deletions" msgstr "Bekräfta Kö-borttagningar" #: sabnzbd/skintext.py:792 msgid "Confirm History Deletions" msgstr "Bekräfta Historik-borttagningar" #: sabnzbd/skintext.py:793 msgid "" "This will prevent refreshing content when your mouse cursor is hovering over " "the queue." msgstr "" #: sabnzbd/skintext.py:794 msgid "Block Refreshes on Hover" msgstr "" #: sabnzbd/skintext.py:795 [Fetch from URL button in "Add NZB" dialog box] msgid "Fetch" msgstr "Hämta" #: sabnzbd/skintext.py:796 [Upload button in "Add NZB" dialog box] msgid "Upload" msgstr "" #: sabnzbd/skintext.py:797 msgid "Upload: .nzb .rar .zip .gz" msgstr "Ladda upp: .nzb .rar .zip .gz" #: sabnzbd/skintext.py:798 msgid "Optionally specify a filename" msgstr "" #: sabnzbd/skintext.py:799 # sabnzbd/skintext.py:849 msgid "Progress" msgstr "Arbetar" #: sabnzbd/skintext.py:801 msgid "Not enough disk space to complete downloads!" msgstr "Inte tillräckligt med diskutrymme för att kunna fortsätta ladda ned." #: sabnzbd/skintext.py:802 msgid "Free Space" msgstr "Ledigt diskutrymme" #: sabnzbd/skintext.py:803 msgid "Free (Temp)" msgstr "Ledigt temputrymme" #: sabnzbd/skintext.py:804 msgid "IDLE" msgstr "Väntar" #: sabnzbd/skintext.py:805 msgid "Downloads" msgstr "" #: sabnzbd/skintext.py:806 msgid "Queue repair" msgstr "" #: sabnzbd/skintext.py:809 msgid "" "Read Feed will get the current feed content. Force " "Download will download all matching NZBs now." msgstr "" #: sabnzbd/skintext.py:813 msgid "Hour:Min" msgstr "Timme:Minut" #: sabnzbd/skintext.py:814 msgid "Delete Completed" msgstr "" #: sabnzbd/skintext.py:815 msgid "Delete the all failed items from the history?" msgstr "Ta bort alla felaktiga saker från historiken?" #: sabnzbd/skintext.py:816 msgid "Delete Failed" msgstr "" #: sabnzbd/skintext.py:817 msgid "Links" msgstr "Länkar" #: sabnzbd/skintext.py:820 msgid "Showing %s to %s out of %s results" msgstr "Visar %s till %s av %s resultat" #: sabnzbd/skintext.py:821 msgid "No results" msgstr "" #: sabnzbd/skintext.py:822 msgid "Showing one result" msgstr "" #: sabnzbd/skintext.py:831 msgid "Email Sent!" msgstr "Skickat E-mail!" #: sabnzbd/skintext.py:832 msgid "Notification Sent!" msgstr "" #: sabnzbd/skintext.py:833 msgid "Saving.." msgstr "Sparar.." #: sabnzbd/skintext.py:834 msgid "Saved" msgstr "Sparad" #: sabnzbd/skintext.py:836 msgid "Speed" msgstr "Hastighet" #: sabnzbd/skintext.py:837 msgid "Toggle Add NZB" msgstr "Visa/Dölj Lägg till NZB" #: sabnzbd/skintext.py:838 msgid "DualView1" msgstr "Flerskärm1" #: sabnzbd/skintext.py:839 msgid "DualView2" msgstr "Flerskärm2" #: sabnzbd/skintext.py:841 msgid "Custom" msgstr "Anpassa" #: sabnzbd/skintext.py:842 msgid "Get Bookmarks" msgstr "Hämta bokmärken" #: sabnzbd/skintext.py:843 msgid "Are you sure you want to restart SABnzbd?" msgstr "Är du säker på att du vill starta om SABnzbd?" #: sabnzbd/skintext.py:844 msgid "Refresh rate" msgstr "Uppdateringsfrekvens" #: sabnzbd/skintext.py:845 msgid "Delete All" msgstr "Ta bort alla" #: sabnzbd/skintext.py:846 msgid "Hide Edit Options" msgstr "Dölj Redigeringsalternativ" #: sabnzbd/skintext.py:847 msgid "Show Edit Options" msgstr "Visa Redigeringsalternativ" #: sabnzbd/skintext.py:848 msgid "Edit" msgstr "Ändra" #: sabnzbd/skintext.py:850 msgid "Timeleft" msgstr "Återstående tid" #: sabnzbd/skintext.py:854 msgid "SABnzbd Quick-Start Wizard" msgstr "SABnzbd Snabbstart Guide" #: sabnzbd/skintext.py:855 msgid "SABnzbd Version" msgstr "" #: sabnzbd/skintext.py:856 [Button to go to previous Wizard page] msgid "Previous" msgstr "Föregående" #: sabnzbd/skintext.py:858 [Wizard step in which the web server is set] msgid "Access" msgstr "Åtkomst" #: sabnzbd/skintext.py:859 msgid "I want SABnzbd to be viewable by any pc on my network." msgstr "" "Jag vill att SABnzbd ska bli nåbart från vilken dator som helst i mitt " "nätverk." #: sabnzbd/skintext.py:860 msgid "I want SABnzbd to be viewable from my pc only." msgstr "Jag vill att SABnzbd ska bli nåbart enbart från min dator." #: sabnzbd/skintext.py:861 msgid "Password protect access to SABnzbd (recommended)" msgstr "Lösenordsskydda åtkomst till SABnzbd (rekommenderas)" #: sabnzbd/skintext.py:862 msgid "Enable HTTPS access to SABnzbd." msgstr "Aktivera HTTPS åtkomst till SABnzbd." #: sabnzbd/skintext.py:863 [Wizard step] msgid "Misc" msgstr "Diverse" #: sabnzbd/skintext.py:864 msgid "" "Launch my internet browser with the SABnzbd page when the program starts." msgstr "Starta webbläsaren med SABnzbd's sida när programet startas." #: sabnzbd/skintext.py:865 msgid "Server Details" msgstr "Serveruppgifter" #: sabnzbd/skintext.py:866 msgid "Please enter in the details of your primary usenet provider." msgstr "Fyll i uppgifter om din primära usenet leverantör." #: sabnzbd/skintext.py:868 msgid "" "In order to download from usenet you will require access to a provider. Your " "ISP may provide you with access, however a premium provider is recommended." msgstr "" "För att ladda ner från usenet du behöver tillgång till en leverantör. Din " "internetleverantör kan ge dig tillgång, men en premie leverantör " "rekommenderas." #: sabnzbd/skintext.py:869 msgid "Don't have a usenet provider? We recommend trying %s." msgstr "Har du inte någon usenet leverantör? Vi rekommenderar att prova %s." #: sabnzbd/skintext.py:870 msgid "The number of connections allowed by your provider" msgstr "Antalet anslutningar som tillåts av din leverantör" #: sabnzbd/skintext.py:871 [Wizard: examples of amount of connections] msgid "E.g. 8 or 20" msgstr "" #: sabnzbd/skintext.py:872 msgid "Select only if your provider allows SSL connections." msgstr "Välj bara om din leverantör tillåter SSL-anslutningar." #: sabnzbd/skintext.py:873 msgid "Click to test the entered details." msgstr "Klicka här för att testa dina angivna serveruppgifter." #: sabnzbd/skintext.py:874 msgid "This field is required." msgstr "Detta fält krävs." #: sabnzbd/skintext.py:875 msgid "Please enter a whole number." msgstr "Ange ett heltal." #: sabnzbd/skintext.py:876 msgid "" "If you are a member of newzbin or nzbmatrix, you may enter your username and " "password here so we can fetch their nzb's. This stage can be skipped if you " "don't use either services." msgstr "" "Om du är medlem på newzbin eller nzbmatrix kan du ange ditt användarnamn och " "lösenord här så kan vi hämta deras nzb filer. Detta stadium kan hoppas över " "om du inte använder deras tjänster." #: sabnzbd/skintext.py:877 msgid "Automatically download bookmarked posts." msgstr "Ladda automatiskt ned bokmärkta poster." #: sabnzbd/skintext.py:879 [Abbreviation for "for example"] msgid "E.g." msgstr "Ex." #: sabnzbd/skintext.py:881 [Wizard step] msgid "Restarting SABnzbd..." msgstr "Startar om SABnzbd..." #: sabnzbd/skintext.py:882 [Wizard step] msgid "Setup is now complete!" msgstr "Installationen är nu utförd!" #: sabnzbd/skintext.py:883 [Wizard tip] msgid "SABnzbd will now be running in the background." msgstr "SABnzbd kommer nu att köras i bakgrunden." #: sabnzbd/skintext.py:884 [Wizard tip] msgid "Closing any browser windows/tabs will NOT close SABnzbd." msgstr "" "SABnzbd kommer inte att stängas av om du stänger ett fönster eller en tab i " "webbläsaren." #: sabnzbd/skintext.py:885 [Wizard tip] msgid "" "After SABnzbd has finished restarting you will be able to access it at the " "following location: %s" msgstr "" #: sabnzbd/skintext.py:886 [Wizard tip] msgid "" "It is recommended you right click and bookmark this location and use this " "bookmark to access SABnzbd when it is running in the background." msgstr "" "Det är rekommenderat att du sparar denna plats som ett bokmärke för att " "komma åt SABnzbd när det körs i bakgrunden." #: sabnzbd/skintext.py:887 [Will be appended with a wiki-link, adjust word order accordingly] msgid "Further help can be found on our" msgstr "Övrig hjälp kan du hitta på våran" #: sabnzbd/skintext.py:888 [Wizard step] msgid "Go to SABnzbd" msgstr "Gå till SABnzbd" #: sabnzbd/skintext.py:889 [Wizard step] # sabnzbd/wizard.py:86 msgid "Step One" msgstr "Steg ett" #: sabnzbd/skintext.py:890 [Wizard step] # sabnzbd/wizard.py:129 msgid "Step Two" msgstr "Steg två" #: sabnzbd/skintext.py:891 [Wizard step] # sabnzbd/wizard.py:168 msgid "Step Three" msgstr "Steg tre" #: sabnzbd/skintext.py:892 [Wizard step] # sabnzbd/wizard.py:188 msgid "Step Four" msgstr "Steg fyra" #: sabnzbd/skintext.py:893 [Wizard step] msgid "Step Five" msgstr "Steg fem" #: sabnzbd/skintext.py:894 [Wizard port number examples] msgid "E.g. 119 or 563 for SSL" msgstr "" #: sabnzbd/skintext.py:895 [Wizard EXIT button on first page] msgid "Exit SABnzbd" msgstr "" #: sabnzbd/skintext.py:896 [Wizard START button on first page] msgid "Start Wizard" msgstr "" #: sabnzbd/skintext.py:897 msgid "If you do not have an account it can be created at " msgstr "" #: sabnzbd/skintext.py:900 msgid "" "\n" "SABnzbd comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it under certain " "conditions.\n" "It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your " "option) any later version.\n" msgstr "" #: sabnzbd/tvsort.py:327 [Error message] msgid "Error getting TV info (%s)" msgstr "Det gick inte att hämta TV info (%s)" #: sabnzbd/tvsort.py:696 [Error message] # sabnzbd/tvsort.py:720 [Error message] # sabnzbd/tvsort.py:908 [Error message] msgid "Failed to rename: %s to %s" msgstr "Det gick inte att döpa om: %s till %s" #: sabnzbd/tvsort.py:1148 [Error message] msgid "Failed to rename similar file: %s to %s" msgstr "Det gick inte att döpa om liknande fil: %s till %s" #: sabnzbd/urlgrabber.py:326 # sabnzbd/urlgrabber.py:344 msgid "Invalid nzbmatrix report number %s" msgstr "Ogiltigt nzbmatrix rapporteringsnummer %s" #: sabnzbd/urlgrabber.py:332 msgid "You need an nzbmatrix VIP account to use the API" msgstr "Du behöver ett nzbmatrix VIP-konto för att använda API" #: sabnzbd/urlgrabber.py:334 msgid "Invalid nzbmatrix credentials" msgstr "" #: sabnzbd/urlgrabber.py:352 msgid "Problem accessing nzbmatrix server (%s)" msgstr "Anslutningsproblem till nzbmatrix server (%s)" #: sabnzbd/utils/servertests.py:35 msgid "The hostname is not set." msgstr "Adressen är inte angiven." #: sabnzbd/utils/servertests.py:41 msgid "There are no connections set. Please set at least one connection." msgstr "" "Inga anslutningar är aktiverade. Var vänlig aktivera minst en anslutning." #: sabnzbd/utils/servertests.py:74 msgid "Password masked in ******, please re-enter" msgstr "Lösenordet är dolt med ******, försök igen" #: sabnzbd/utils/servertests.py:78 msgid "Invalid server details" msgstr "Ogiltiga serverdetaljer" #: sabnzbd/utils/servertests.py:90 msgid "Timed out: Try enabling SSL or connecting on a different port." msgstr "Timeout: Försök aktivera SSL eller anslut via en annan port." #: sabnzbd/utils/servertests.py:92 msgid "Timed out" msgstr "Timeout" #: sabnzbd/utils/servertests.py:97 msgid "Invalid server address." msgstr "Ogiltig serveradress" #: sabnzbd/utils/servertests.py:101 msgid "Server quit during login sequence." msgstr "Servern avslutades under inloggning" #: sabnzbd/utils/servertests.py:123 msgid "Server requires username and password." msgstr "Servern kräver användarnamn och lösenord." #: sabnzbd/utils/servertests.py:126 msgid "Connection Successful!" msgstr "Anslutning lyckades!" #: sabnzbd/utils/servertests.py:129 msgid "Authentication failed, check username/password." msgstr "Autentisering misslyckades, kontrollera användarnamn och lösenord." #: sabnzbd/utils/servertests.py:132 msgid "Too many connections, please pause downloading or try again later" msgstr "" "För många anslutningar, pausa en nedladdning eller försök igen senare" #: sabnzbd/utils/servertests.py:135 msgid "Could not determine connection result (%s)" msgstr "Det gick inte att ansluta (%s)" #~ msgid "fetching msgid %s from www.newzbin.com" #~ msgstr "hämtar msgid %s från www.newzbin.com" #~ msgid "" #~ "Error Fetching msgid %s from www.newzbin.com - Please make sure your " #~ "Username and Password are set" #~ msgstr "" #~ "Fel vid hämtning av msgid %s från www.newzbin.com - Kolla så att " #~ "användarnamn och lösenord är inställt" #~ msgid "Expected size did not equal actual size" #~ msgstr "Förväntad storlek är inte lika verklig storlek" #~ msgid "Could not compile regex: %s" #~ msgstr "Gick ej att kompilera regex: %s" #~ msgid "" #~ "If you have an account at www.newzbin.com, you can enter " #~ "your account info here.
    This will unlock extra functionality." #~ msgstr "" #~ "Om du har ett konto på www.newzbin.com, så kan du skriva in " #~ "din användarinformation här.
    Detta kommer att tillgängliggöra extra " #~ "funktioner." #~ msgid "You'll need to set a password and resume the job." #~ msgstr "Du måste ange ett lösenord för att återuppta jobbet." #~ msgid "Pause job when encrypted RAR is downloaded" #~ msgstr "Pausa jobb när krypterade RAR-filer laddas ned" SABnzbd-0.7.20/po/nsis/da.po0000644000000000000000000000677212433712556015567 0ustar00usergroup00000000000000# Danish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-12-28 11:02+0000\n" "Last-Translator: Steffen Thomsen \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-12-29 05:12+0000\n" "X-Generator: Launchpad (build 16378)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Gå til SABnzbd Wiki" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Vis udgivelsesbemærkninger" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Støt projektet, donér!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Luk venligst \"SABnzbd.exe\" først" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> ADVARSEL <<<<\\r\\n\\r\\nVenligst, se først " "produktbemærkningerne eller gå til http://wiki.sabnzbd.org/introducing-0-7-0 " "!" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Dette vil afinstallere SABnzbd fra dit system" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Kør ved opstart" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Skrivebordsikon" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "NZB filtilknytning" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Slet program" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Slet indstillinger" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Dette system kræver, at Microsoft runtime biblioteket VC90 skal installeres " "først. Ønsker du at gøre det nu?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Downloader Microsoft runtime installationsfil..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Download fejl, prøv igen?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Kan ikke installere uden runtime bibliotek, prøv igen?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Du kan ikke overskrive en eksisterende installation. \\n\\nKlik `OK` for at " "fjerne den tidligere version eller `Annuller` for at annullere denne " "opgradering." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Dine indstillinger og data vil blive bevaret." #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Start SABnzbd" #~ msgid "Delete Cache" #~ msgstr "Slet hukommelse" #~ msgid "Delete Logs" #~ msgstr "Slet logs" #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nVenligst, kontrollér først " #~ "udgivelsesnoter eller gå til http://wiki.sabnzbd.org/introducing-0-6-0 !" SABnzbd-0.7.20/po/nsis/de.po0000644000000000000000000000727512433712556015572 0ustar00usergroup00000000000000# German translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-05-04 14:06+0000\n" "Last-Translator: shypike \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Gehen Sie auf die SABnzbd Wiki-Seite" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Versionshinweise anzeigen" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Bitte unterstützen Sie das Projekt durch eine Spende!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Schliessen Sie bitte zuerst \"SABnzbd.exe\"." #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> WARNING <<<<\\r\\n\\r\\nBitte lesen Sie zuerst die " "Versionshinweise oder gehen Sie zu http://wiki.sabnzbd.org/introducing-0-7-0 " "!" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Dies entfernt SABnzbd von Ihrem System" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Beim Systemstart ausführen" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Desktop-Symbol" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "Mit NZB-Dateien verknüpfen" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Programm löschen" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Einstellungen löschen" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Dieses System erfordert die Installation der Laufzeitbibliothek VC90 von " "Microsoft. Möchten Sie die Installation jetzt durchführen?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "" "Installationsprogramm für Microsoft-Laufzeitbibliothek wird " "heruntergeladen..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Download-Fehler. Erneut versuchen?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "" "Installation ohne Laufzeitbibliothek nicht möglich. Erneut versuchen?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Eine vorhandene Installation kann nicht überschrieben werden. \\n\\nWählen " "Sie 'OK', um die vorherige Version zu entfernen oder 'Abbrechen' um die " "Aktualisierung abzubrechen." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Ihre Einstellungen und Daten bleiben erhalten." #~ msgid "Start SABnzbd (hidden)" #~ msgstr "SABnzbd starten (unsichtbar)" #~ msgid "Delete Logs" #~ msgstr "Protokoll löschen" #~ msgid "Delete Cache" #~ msgstr "Cache löschen" #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> WARNUNG <<<<\\r\\n\\r\\nBitte zuerst die " #~ "Versionsanmerkungen lesen oder \"http://wiki.sabnzbd.org/introducing-0-6-0 " #~ "besuchen!\"" SABnzbd-0.7.20/po/nsis/es.po0000644000000000000000000000715212433712556015603 0ustar00usergroup00000000000000# Spanish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-07-30 09:38+0000\n" "Last-Translator: Victor Herrero \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Ir al wiki de SABnzbd" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Mostrar notas de la versión" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "¡Apoye el proyecto, haga una donación!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Por favor cierre primero \"SABnzbd.exe\"" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> ATENCION <<<<\\r\\n\\r\\nPor favor, compruebe las " "notas de version o visite http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Esto desinstalará SABnzbd de su sistema" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Ejecutar al inicio" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Icono del escritorio" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "Asociación de archivos NZB" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Eliminar programa" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Eliminar Ajustes" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Este sistema requiere la ejecución de la biblioteca Microsoft runtime VC90 " "que debe ser instalada. ¿Quieres hacerlo ahora?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Descargando el instalador de Microsoft runtime..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Error en la descarga, ¿probamos de nuevo?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "" "No se puede instalar sin la biblioteca runtime, ¿Lo volvemos a intentar?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "No es posible sobrescribir una instalación existente. \\n\\nPresione `OK' " "para quitar la versión anterior o 'Cancelar' para cancelar la actualización." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Tus ajustes y datos se mantendrán intactos." #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> ADVERTENCIA <<<<\\ r \\ n \\ r \\ nPor favor, " #~ "compruebe primero las notas de lanzamiento o ir a " #~ "http://wiki.sabnzbd.org/introducing-0-6-0!" #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Inicio SABnzbd (oculto)" #~ msgid "Delete Cache" #~ msgstr "Eliminar cache" #~ msgid "Delete Logs" #~ msgstr "Eliminar Registros" SABnzbd-0.7.20/po/nsis/fi.po0000644000000000000000000000702512433712556015571 0ustar00usergroup00000000000000# Finnish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2013-02-19 15:24+0000\n" "Last-Translator: Matti Ylönen \n" "Language-Team: Finnish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-02-20 05:14+0000\n" "X-Generator: Launchpad (build 16491)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Siirry SABnzbd wikiin" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Näytä julkaisutiedot" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Tue projektia, lahjoita!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Ole hyvä ja sulje \"SABnzbd.exe\" ensin" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> VAROITUS <<<<\\r\\n\\r\\nOle hyvä ja tarkista " "julkaisutiedot tai käy osoitteessa http://wiki.sabnzbd.org/introducing-0-7-0 " "!" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Tämä poistaa SABnzbd:n tietokoneestasi" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Suorita käynnistyksen yhteydessä" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Työpöydän kuvake" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "NZB tiedostosidos" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Poista sovellus" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Poista asetukset" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Tämä järjestelmä vaatii, että Microsoft runtime kirjasto VC90 täytyy asentaa " "ensin. Haluatko asentaa sen nyt?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Ladataan Microsoft runtime asennusta..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Latausvirhe, yritä uudelleen?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Ei voida asentaa ilman runtime kirjastoa, yritä uudelleen?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Et voi asentaa tätä vanhan asennuksen päälle. \\n\\nPaina `OK` poistaaksesi " "edellisen version tai paina `Peruuta` peruuttaaksesi tämän päivityksen." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Asetuksiasi ja tietojasi ei poisteta." #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> VAROITUS <<<<\\r\\n\\r\\nOle hyvä ja tarkista " #~ "julkaisutiedot tai mene osoitteeseen http://wiki.sabnzbd.org/introducing-0-6-" #~ "0 !" #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Aloita SABnzbd (piilotettuna)" #~ msgid "Delete Cache" #~ msgstr "Poista välimuisti" #~ msgid "Delete Logs" #~ msgstr "Poista lokit" SABnzbd-0.7.20/po/nsis/fr.po0000644000000000000000000000725312433712556015605 0ustar00usergroup00000000000000# French translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-05-02 15:56+0000\n" "Last-Translator: Fox Ace \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Aller sur le Wiki de SABnzbd" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Afficher les notes de version" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Supportez le projet, faites un don !" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Quittez \"SABnzbd.exe\" avant l'installation, SVP" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> AVERTISSEMENT <<<<\\r\\n\\r\\nS'il vous plaît, " "vérifiez d'abord les notes de version ou consultez " "http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Ceci désinstallera SABnzbd de votre système" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Lancer au démarrage" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Icône sur le Bureau" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "Association des fichiers NZB" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Supprimer le programme" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Supprimer les Paramètres" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Ce système nécessite que la bibliothèque d'exécution Microsoft vc90 soit " "installée en premier. Voulez-vous le faire maintenant?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Téléchargement de Microsoft runtime installateur ..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Erreur téléchargement, réessayer?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Impossible d'installer sans bibliothèque d'exécution, réessayer?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Vous ne pouvez pas remplacer une installation existante. \\n\\nCliquez `OK` " "pour supprimer la version précédente ou `Annuler` pour annuler cette mise à " "niveau." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Vos paramètres et les données seront conservées." #~ msgid "Delete Logs" #~ msgstr "Supprimer les logs" #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Démarrer SABnzbd (caché)" #~ msgid "Delete Cache" #~ msgstr "Supprimer le Cache" #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> AVERTISSEMENT<<<<\\r\\n\\r\\nS'il vous plaît, " #~ "vérifiez d'abord les notes de version ou visiter " #~ "http://wiki.sabnzbd.org/introducing-0-6-0 !" SABnzbd-0.7.20/po/nsis/nb.po0000644000000000000000000000606112433712556015571 0ustar00usergroup00000000000000# Norwegian Bokmal translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2013-12-04 12:09+0000\n" "Last-Translator: Daniel Sebastian \n" "Language-Team: Norwegian Bokmal \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-12-05 05:57+0000\n" "X-Generator: Launchpad (build 16863)\n" #: NSIS_Installer.nsi:416 msgid "Go to the SABnzbd Wiki" msgstr "Gå til SABnzbd Wiki" #: NSIS_Installer.nsi:418 msgid "Show Release Notes" msgstr "Vis versjonsmerknader" #: NSIS_Installer.nsi:420 msgid "Support the project, Donate!" msgstr "Støtt prosjektet, donèr!" #: NSIS_Installer.nsi:422 msgid "Please close \"SABnzbd.exe\" first" msgstr "Vennligst lukk \"SABnzbd.exe\" først" #: NSIS_Installer.nsi:424 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> ADVARSEL <<<<\\r\\n\\r\\nVennligst sjekk " "versjonsmerknadene først, eller gå til http://wiki.sabnzbd.org/introducing-0-" "7-0 !" #: NSIS_Installer.nsi:426 msgid "This will uninstall SABnzbd from your system" msgstr "Dette vil avinstallere SABnzbd fra ditt system" #: NSIS_Installer.nsi:428 msgid "Run at startup" msgstr "Kjør ved oppstart" #: NSIS_Installer.nsi:430 msgid "Desktop Icon" msgstr "Skrivebordsikon" #: NSIS_Installer.nsi:432 msgid "NZB File association" msgstr "NZB-filassosiering" #: NSIS_Installer.nsi:434 msgid "Delete Program" msgstr "Fjern program" #: NSIS_Installer.nsi:436 msgid "Delete Settings" msgstr "Slett innstillinger" #: NSIS_Installer.nsi:438 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Dette sytemet krever at Microsoft runtime library VC90 er installert først. " "Ønsker du å gjøre dette nå?" #: NSIS_Installer.nsi:440 msgid "Downloading Microsoft runtime installer..." msgstr "Laster ned Microsoft runtime installer..." #: NSIS_Installer.nsi:442 msgid "Download error, retry?" msgstr "Nedlasting feilet, prøve på nytt?" #: NSIS_Installer.nsi:444 msgid "Cannot install without runtime library, retry?" msgstr "Kan ikke installere uten runtime library, prøve på nytt?" #: NSIS_Installer.nsi:446 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Du kan ikke overskrive en eksisterende installasjon. \\n\\nTrykk 'OK' for å " "fjerne tidligere installasjon, eller 'Avbryt' for å avbryte denne " "oppgraderingen." #: NSIS_Installer.nsi:448 msgid "Your settings and data will be preserved." msgstr "Dine innstillinger og data vil bli tatt vare på." SABnzbd-0.7.20/po/nsis/nl.po0000644000000000000000000000701612433712556015604 0ustar00usergroup00000000000000# Dutch translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2013-11-03 22:38+0000\n" "Last-Translator: markheloking \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2013-11-04 05:55+0000\n" "X-Generator: Launchpad (build 16820)\n" #: NSIS_Installer.nsi:416 msgid "Go to the SABnzbd Wiki" msgstr "Ga naar de SABnzbd Wiki" #: NSIS_Installer.nsi:418 msgid "Show Release Notes" msgstr "Toon vrijgave bericht" #: NSIS_Installer.nsi:420 msgid "Support the project, Donate!" msgstr "Steun het project, Doneer!" #: NSIS_Installer.nsi:422 msgid "Please close \"SABnzbd.exe\" first" msgstr "Sluit \"SABnzbd.exe\" eerst af" #: NSIS_Installer.nsi:424 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> WAARSCHUWING <<<<\\\\r\\\\n\\\\r\\\\nLees eerst het " "vrijgave bericht of ga naar http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:426 msgid "This will uninstall SABnzbd from your system" msgstr "Dit verwijdert SABnzbd van je systeem" #: NSIS_Installer.nsi:428 msgid "Run at startup" msgstr "Opstarten bij systeem start" #: NSIS_Installer.nsi:430 msgid "Desktop Icon" msgstr "Bureaubladpictogram" #: NSIS_Installer.nsi:432 msgid "NZB File association" msgstr "NZB bestanden koppelen aan SABnzbd" #: NSIS_Installer.nsi:434 msgid "Delete Program" msgstr "Programma verwijderen" #: NSIS_Installer.nsi:436 msgid "Delete Settings" msgstr "Verwijder instellingen" #: NSIS_Installer.nsi:438 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Op dit systeem moeten eerst de Microsoft runtime bibliotheek VC90 " "geïnstalleerd worden. Wilt u dat nu doen?" #: NSIS_Installer.nsi:440 msgid "Downloading Microsoft runtime installer..." msgstr "Downloaden van de Microsoft bibliotheek" #: NSIS_Installer.nsi:442 msgid "Download error, retry?" msgstr "Download mislukt, opnieuw proberen?" #: NSIS_Installer.nsi:444 msgid "Cannot install without runtime library, retry?" msgstr "Installeren heeft geen zin zonder de bibliotheek, opnieuw proberen?" #: NSIS_Installer.nsi:446 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "U kunt geen bestaande installatie overschrijven.\\n\\nKlik op `OK` om de " "vorige versie te verwijderen of op `Annuleren` om te stoppen." #: NSIS_Installer.nsi:448 msgid "Your settings and data will be preserved." msgstr "Je instellingen en bestanden blijven behouden." #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Start SABnzbd (verborgen)" #~ msgid "Delete Logs" #~ msgstr "Verwijder logging" #~ msgid "Delete Cache" #~ msgstr "Verwijder Cache" #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> WAARSCHUWING <<<<\\r\\n\\r\\nLees eerst het vrijgave " #~ "bericht of ga naar \"http://wiki.sabnzbd.org/introducing-0-6-0 !\"" SABnzbd-0.7.20/po/nsis/pl.po0000644000000000000000000000624712433712564015612 0ustar00usergroup00000000000000# Polish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-05-02 10:07+0000\n" "Last-Translator: Tomasz 'Zen' Napierala \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Idz do wiki SABnzbd" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Pokaz informacje o wydaniu" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Wspomóz projekt!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Najpierw zamknij SABnzbd.exe" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> UWAGA <<<<\\r\\n\\r\\nNajpierw przeczytaj informacje " "o wydaniu lub odwiedz http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "To odinstaluje SABnzbd z systemu" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Uruchom wraz z systemem" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Ikona pulpitu" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "powiazanie pliku NZB" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Usun program" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Skasuj obecne ustawienia" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Ten system wymaga najpierw zainstalowania bibliotek Microsoft VC90. Czy " "chcesz wykonac teraz instalacje?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Pobieranie instalatora bibliotek Microsoft..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Problem z pobieraniem, spróbowac ponownie?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Nie mozna wykonac instalacji bez bibliotek, spróbowac ponownie?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Nie mozna nadpisac istniejacej instalacji. \\n\\n Nacisnij `OK`, aby usunac " "poprzednia wersje lub `Anuluj` aby anulowac aktualizacje." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Twoje ustawienia i dane zostana zachowane." #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Uruchom SABnzbd (ukryty)" #~ msgid "Delete Cache" #~ msgstr "Usun pamiec podreczna" #~ msgid "Delete Logs" #~ msgstr "Skasuj zapis logów" SABnzbd-0.7.20/po/nsis/pl.px0000644000000000000000000000630212433712556015614 0ustar00usergroup00000000000000# Polish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-05-02 10:07+0000\n" "Last-Translator: Tomasz 'Zen' Napierala \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Idź do wiki SABnzbd" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Pokaż informacje o wydaniu" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Wspomóż projekt!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Najpierw zamknij SABnzbd.exe" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> UWAGA <<<<\\r\\n\\r\\nNajpierw przeczytaj informacje " "o wydaniu lub odwiedź http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "To odinstaluje SABnzbd z systemu" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Uruchom wraz z systemem" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Ikona pulpitu" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "powiązanie pliku NZB" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Usuń program" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Skasuj obecne ustawienia" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Ten system wymaga najpierw zainstalowania bibliotek Microsoft VC90. Czy " "chcesz wykonać teraz instalację?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Pobieranie instalatora bibliotek Microsoft..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Problem z pobieraniem, spróbować ponownie?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Nie można wykonać instalacji bez bibliotek, spróbować ponownie?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Nie można nadpisać istniejącej instalacji. \\n\\n Naciśnij `OK`, aby usunąć " "poprzednia wersję lub `Anuluj` aby anulować aktualizację." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Twoje ustawienia i dane zostaną zachowane." #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Uruchom SABnzbd (ukryty)" #~ msgid "Delete Cache" #~ msgstr "Usuń pamięć podręczną" #~ msgid "Delete Logs" #~ msgstr "Skasuj zapis logów" SABnzbd-0.7.20/po/nsis/pt_BR.po0000644000000000000000000000720212433712556016176 0ustar00usergroup00000000000000# Brazilian Portuguese translation for sabnzbd # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-06-17 03:09+0000\n" "Last-Translator: lrrosa \n" "Language-Team: Brazilian Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Vá para a Wiki do SABnzbd" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Mostrar Notas de Lançamento" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Apoie o projeto. Faça uma doação!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Por favor, feche \"SABnzbd.exe\" primeiro" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> ATENÇÃO <<<<\\r\\n\\r\\nPor favor, verifique primeiro " "as notas de lançamento ou vá até http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Isso irá desinstalar SABnzbd de seu sistema" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Executar na inicialização" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Ícone na Área de Trabalho" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "Associação com Arquivos NZB" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Excluir o Programa" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Apagar Configurações" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Este sistema precisa que a biblioteca runtime Microsoft VC90 seja instalada " "antes. Você quer fazer isso agora?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Baixando o instalador runtime da Microsoft ..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Houve um erro de download. Quer tentar novamente?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Não é possível instalar sem a biblioteca runtime. Quer repetir?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Você não pode substituir uma instalação existente. \\n\\nClique `OK` para " "remover a versão anterior ou `Cancelar` para cancelar esta atualização." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Suas configurações e os dados serão preservados." #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Iniciar SABnzbd (oculto)" #~ msgid "Delete Cache" #~ msgstr "Apagar Cache" #~ msgid "Delete Logs" #~ msgstr "Apagar Logs" #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> ATENÇÃO <<<<\\r\\n\\r\\nPor favor, verifique primeiro " #~ "as notas de lançamento ou vá até http://wiki.sabnzbd.org/introducing-0-7-0 !" SABnzbd-0.7.20/po/nsis/ro.po0000644000000000000000000000701712433712564015613 0ustar00usergroup00000000000000# Romanian translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-05-04 12:45+0000\n" "Last-Translator: nicusor \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Dute la Wiki SABnzbd" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Aratã Notele de Publicare" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Sustine proiectul, Doneazã!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Închideti mai întâi \"SABnzbd.exe\"" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> ATENTIE <<<<\\r\\n\\r\\nVã rugãm, sã verificati mai " "întâi notele de publicare sau sã vizitati " "http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Acest lucru va dezinstala SABnzbd din sistem" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Executare la pornire" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Icoanã Desktop" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "Asociere cu Fisierele NZB" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Sterge Program" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Stergeti Setãri" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Acest sistem necesitã librãria Microsoft VC90 instalatã. Dortiti sã faceti " "asta acum ?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Descãrcare rutinã instalare Microsoft..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Eroare descãrcare, încerc din nou?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Nu pot instala fãrã rutinã librãrie, încerc din nou?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Nu puteti suprascrie instalarea existentã. \\n\\nClick `OK` pentru a elimina " "versiunea anterioarã sau `Anulare` pentru a anula actualizarea." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Setãrile si informatiile vor fi salvate." #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> ATENTIE <<<<\\r\\n\\r\\nVã rugãm, verificati mai " #~ "întâi notele de publicare sau mergeti la http://wiki.sabnzbd.org/introducing-" #~ "0-6-0 !" #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Porneste SABnzbd (ascuns)" #~ msgid "Delete Cache" #~ msgstr "Stergeti Cache" #~ msgid "Delete Logs" #~ msgstr "Stergeti Activitate" SABnzbd-0.7.20/po/nsis/ro.px0000644000000000000000000000704512433712556015626 0ustar00usergroup00000000000000# Romanian translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-05-04 12:45+0000\n" "Last-Translator: nicusor \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Dute la Wiki SABnzbd" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Arată Notele de Publicare" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Susţine proiectul, Donează!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Închideţi mai întâi \"SABnzbd.exe\"" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> ATENŢIE <<<<\\r\\n\\r\\nVă rugăm, să verificaţi mai " "întâi notele de publicare sau să vizitaţi " "http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Acest lucru va dezinstala SABnzbd din sistem" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Executare la pornire" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Icoană Desktop" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "Asociere cu Fişierele NZB" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Şterge Program" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Ştergeţi Setări" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Acest sistem necesită librăria Microsoft VC90 instalată. Dortiți să faceți " "asta acum ?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Descărcare rutină instalare Microsoft..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Eroare descărcare, încerc din nou?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Nu pot instala fără rutină librărie, încerc din nou?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Nu puteți suprascrie instalarea existentă. \\n\\nClick `OK` pentru a elimina " "versiunea anterioară sau `Anulare` pentru a anula actualizarea." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Setările şi informaţiile vor fi salvate." #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> ATENŢIE <<<<\\r\\n\\r\\nVă rugăm, verificaţi mai " #~ "întâi notele de publicare sau mergeţi la http://wiki.sabnzbd.org/introducing-" #~ "0-6-0 !" #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Porneşte SABnzbd (ascuns)" #~ msgid "Delete Cache" #~ msgstr "Ştergeţi Cache" #~ msgid "Delete Logs" #~ msgstr "Ştergeţi Activitate" SABnzbd-0.7.20/po/nsis/SABnsis.pot0000644000000000000000000000360412433712556016660 0ustar00usergroup00000000000000# # SABnzbd Translation Template file NSIS # Copyright (C) 2011-2012 by the SABnzbd Team # team@sabnzbd.org # msgid "" msgstr "" "Project-Id-Version: SABnzbd-0.7.x\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: shypike@sabnzbd.org\n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 7bit\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "" #: NSIS_Installer.nsi:433 msgid " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "" #: NSIS_Installer.nsi:447 msgid "This system requires the Microsoft runtime library VC90 to be installed first. Do you want to do that now?" msgstr "" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "" #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "" #: NSIS_Installer.nsi:455 msgid "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade." msgstr "" #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "" SABnzbd-0.7.20/po/nsis/sv.po0000644000000000000000000000706512433712556015627 0ustar00usergroup00000000000000# Swedish translation for sabnzbd # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sabnzbd package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sabnzbd\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-08-14 18:42+0000\n" "PO-Revision-Date: 2012-05-15 19:42+0000\n" "Last-Translator: Andreas Lindberg \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-08-15 05:11+0000\n" "X-Generator: Launchpad (build 15801)\n" #: NSIS_Installer.nsi:425 msgid "Go to the SABnzbd Wiki" msgstr "Gå till SABnzbd Wiki" #: NSIS_Installer.nsi:427 msgid "Show Release Notes" msgstr "Visa releasenoteringar" #: NSIS_Installer.nsi:429 msgid "Support the project, Donate!" msgstr "Donera och stöd detta projekt!" #: NSIS_Installer.nsi:431 msgid "Please close \"SABnzbd.exe\" first" msgstr "Var vänlig stäng \"SABnzbd.exe\" först" #: NSIS_Installer.nsi:433 msgid "" " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " "release notes or go to http://wiki.sabnzbd.org/introducing-0-7-0 !" msgstr "" " >>>> VARNING <<<<\\r\\n\\r\\nVänligen läs först " "releasenoteringarna eller gå till http://wiki.sabnzbd.org/introducing-0-7-0 !" #: NSIS_Installer.nsi:435 msgid "This will uninstall SABnzbd from your system" msgstr "Detta kommer att avinstallera SABnzbd från systemet" #: NSIS_Installer.nsi:437 msgid "Run at startup" msgstr "Kör vid uppstart" #: NSIS_Installer.nsi:439 msgid "Desktop Icon" msgstr "Skrivbordsikon" #: NSIS_Installer.nsi:441 msgid "NZB File association" msgstr "NZB Filassosication" #: NSIS_Installer.nsi:443 msgid "Delete Program" msgstr "Radera programmet" #: NSIS_Installer.nsi:445 msgid "Delete Settings" msgstr "Radera inställningar" #: NSIS_Installer.nsi:447 msgid "" "This system requires the Microsoft runtime library VC90 to be installed " "first. Do you want to do that now?" msgstr "" "Detta system kräver att Microsofts runtimebibliotek VC90 är installerat. " "Vill du göra detta nu?" #: NSIS_Installer.nsi:449 msgid "Downloading Microsoft runtime installer..." msgstr "Laddar ned Microsofts runtimeinstaller..." #: NSIS_Installer.nsi:451 msgid "Download error, retry?" msgstr "Misslyckat nedladdningsförsök, försök igen?" #: NSIS_Installer.nsi:453 msgid "Cannot install without runtime library, retry?" msgstr "Kan inte installera utan runtimebibliotek, försök igen?" #: NSIS_Installer.nsi:455 msgid "" "You cannot overwrite an existing installation. \\n\\nClick `OK` to remove " "the previous version or `Cancel` to cancel this upgrade." msgstr "" "Kan inte skriva över en existerande installation. \\n\\nKlicka 'OK' för att " "avinstallera tidigare version eller 'Avbryt' för att avbryta denna " "uppgradering." #: NSIS_Installer.nsi:457 msgid "Your settings and data will be preserved." msgstr "Dina inställningar och ditt data kommer att bevaras." #~ msgid "Start SABnzbd (hidden)" #~ msgstr "Starta SABnzbd (dold)" #~ msgid "Delete Logs" #~ msgstr "Ta bort logg" #~ msgid "Delete Cache" #~ msgstr "Ta bort temporär-mapp" #~ msgid "" #~ " >>>> WARNING <<<<\\r\\n\\r\\nPlease, first check the " #~ "release notes or go to http://wiki.sabnzbd.org/introducing-0-6-0 !" #~ msgstr "" #~ " >>>> VARNING <<<<\\r\\n\\r\\nVar vänlig och läs versions " #~ "noteringarna eller gå till http://wiki.sabnzbd.org/introducing-0-6-0 !" SABnzbd-0.7.20/sabnzbd/api.py0000644000000000000000000021125412433712602016000 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.api - api """ import os import logging import re import datetime import time import cherrypy import locale try: locale.setlocale(locale.LC_ALL, "") except: # Work-around for Python-ports with bad "locale" support pass try: import win32api, win32file except ImportError: pass import sabnzbd from sabnzbd.constants import * import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.downloader import Downloader from sabnzbd.nzbqueue import NzbQueue, set_priority, sort_queue, scan_jobs, repair_job import sabnzbd.nzbstuff as nzbstuff import sabnzbd.scheduler as scheduler from sabnzbd.skintext import SKIN_TEXT from sabnzbd.utils.rsslib import RSS, Item from sabnzbd.utils.json import JsonWriter from sabnzbd.utils.pathbrowser import folders_at_path from sabnzbd.misc import loadavg, to_units, diskfree, disktotal, get_ext, \ get_filename, int_conv, globber, time_format, remove_all, \ starts_with_path, cat_convert from sabnzbd.encoding import xml_name, unicoder, special_fixer, platform_encode, html_escape from sabnzbd.postproc import PostProcessor from sabnzbd.articlecache import ArticleCache from sabnzbd.utils.servertests import test_nntp_server_dict from sabnzbd.newzbin import Bookmarks from sabnzbd.rating import Rating from sabnzbd.bpsmeter import BPSMeter from sabnzbd.database import build_history_info, unpack_history_info, get_history_handle import sabnzbd.growler import sabnzbd.rss import sabnzbd.emailer #------------------------------------------------------------------------------ # API error messages _MSG_NO_VALUE = 'expect one parameter' _MSG_NO_VALUE2 = 'expect two parameters' _MSG_INT_VALUE = 'expect integer value' _MSG_NO_ITEM = 'item does not exist' _MSG_NOT_IMPLEMENTED = 'not implemented' _MSG_NO_FILE = 'no file given' _MSG_NO_PATH = 'file does not exist' _MSG_OUTPUT_FORMAT = 'Format not supported' _MSG_NO_SUCH_CONFIG = 'Config item does not exist' _MSG_BAD_SERVER_PARMS = 'Incorrect server settings' #------------------------------------------------------------------------------ # For Windows: determine executable extensions if os.name == 'nt': PATHEXT = os.environ.get('PATHEXT', '').lower().split(';') else: PATHEXT = [] #------------------------------------------------------------------------------ def api_handler(kwargs): """ API Dispatcher """ mode = kwargs.get('mode', '') output = kwargs.get('output') name = kwargs.get('name', '') callback = kwargs.get('callback', '') if isinstance(mode, list): mode = mode[0] if isinstance(output, list): output = output[0] response = _api_table.get(mode, _api_undefined)(name, output, kwargs) if output == 'json' and callback: response = '%s(%s)' % (callback, response) return response #------------------------------------------------------------------------------ def _api_get_config(name, output, kwargs): """ API: accepts output, keyword, section """ res, data = config.get_dconfig(kwargs.get('section'), kwargs.get('keyword')) return report(output, keyword='config', data=data) def _api_set_config(name, output, kwargs): """ API: accepts output, keyword, section """ if kwargs.get('section') == 'servers': kwargs['keyword'] = handle_server_api(output, kwargs) elif kwargs.get('section') == 'rss': kwargs['keyword'] = handle_rss_api(output, kwargs) elif kwargs.get('section') == 'categories': kwargs['keyword'] = handle_cat_api(output, kwargs) else: res = config.set_config(kwargs) if not res: return report(output, _MSG_NO_SUCH_CONFIG) config.save_config() res, data = config.get_dconfig(kwargs.get('section'), kwargs.get('keyword')) return report(output, keyword='config', data=data) def _api_del_config(name, output, kwargs): """ API: accepts output, keyword, section """ if del_from_section(kwargs): return report(output) else: return report(output, _MSG_NOT_IMPLEMENTED) def _api_qstatus(name, output, kwargs): """ API: accepts output """ if output == 'json': # Compatibility Fix: # Old qstatus did not have a keyword, so do not use one now. keyword = '' else: keyword = 'queue' return report(output, keyword=keyword, data=qstatus_data()) #------------------------------------------------------------------------------ def _api_queue(name, output, kwargs): """ API: Dispatcher for mode=queue """ value = kwargs.get('value', '') return _api_queue_table.get(name, _api_queue_default)(output, value, kwargs) def _api_queue_delete(output, value, kwargs): """ API: accepts output, value """ if value.lower()=='all': NzbQueue.do.remove_all() return report(output) elif value: items = value.split(',') del_files = int_conv(kwargs.get('del_files')) NzbQueue.do.remove_multiple(items, del_files) return report(output) else: return report(output, _MSG_NO_VALUE) def _api_queue_delete_nzf(output, value, kwargs): """ API: accepts value(=nzo_id), value2(=nzf_id) """ value2 = kwargs.get('value2') if value and value2: NzbQueue.do.remove_nzf(value, value2) return report(output) else: return report(output, _MSG_NO_VALUE2) def _api_queue_rename(output, value, kwargs): """ API: accepts output, value(=old name), value2(=new name), value3(=password) """ value2 = kwargs.get('value2') value3 = kwargs.get('value3') if value and value2: NzbQueue.do.change_name(value, special_fixer(value2), special_fixer(value3)) return report(output) else: return report(output, _MSG_NO_VALUE2) def _api_queue_change_complete_action(output, value, kwargs): """ API: accepts output, value(=action) """ sabnzbd.change_queue_complete_action(value) return report(output) def _api_queue_purge(output, value, kwargs): """ API: accepts output """ NzbQueue.do.remove_all() return report(output) def _api_queue_pause(output, value, kwargs): """ API: accepts output, value(=list of nzo_id) """ if value: items = value.split(',') NzbQueue.do.pause_multiple_nzo(items) return report(output) def _api_queue_resume(output, value, kwargs): """ API: accepts output, value(=list of nzo_id) """ if value: items = value.split(',') NzbQueue.do.resume_multiple_nzo(items) return report(output) def _api_queue_priority(output, value, kwargs): """ API: accepts output, value(=nzo_id), value2(=priority) """ value2 = kwargs.get('value2') if value and value2: try: try: priority = int(value2) except: return report(output, _MSG_INT_VALUE) pos = set_priority(value, priority) # Returns the position in the queue, -1 is incorrect job-id return report(output, keyword='position', data=pos) except: return report(output, _MSG_NO_VALUE2) else: return report(output, _MSG_NO_VALUE2) def _api_queue_sort(output, value, kwargs): """ API: accepts output, sort, dir """ sort = kwargs.get('sort') direction = kwargs.get('dir', '') if sort: sort_queue(sort, direction) return report(output) else: return report(output, _MSG_NO_VALUE2) def _api_queue_default(output, value, kwargs): """ API: accepts output, sort, dir, start, limit """ sort = kwargs.get('sort') direction = kwargs.get('dir', '') start = kwargs.get('start') limit = kwargs.get('limit') trans = kwargs.get('trans') if output in ('xml', 'json'): if sort and sort != 'index': reverse = direction.lower() == 'desc' sort_queue(sort, reverse) # &history=1 will show unprocessed items in the history history = bool(kwargs.get('history')) info, pnfo_list, bytespersec, verbose_list, dictn = \ build_queue(history=history, start=start, limit=limit, output=output, trans=trans) info['categories'] = info.pop('cat_list') info['scripts'] = info.pop('script_list') return report(output, keyword='queue', data=remove_callable(info)) elif output == 'rss': return rss_qstatus() else: return report(output, _MSG_NOT_IMPLEMENTED) def _api_queue_rating(output, value, kwargs): """ API: accepts output, value(=nzo_id), type, setting, detail """ vote_map = {'up': Rating.VOTE_UP, 'down': Rating.VOTE_DOWN} flag_map = {'spam': Rating.FLAG_SPAM, 'encrypted': Rating.FLAG_ENCRYPTED, 'expired': Rating.FLAG_EXPIRED, 'other': Rating.FLAG_OTHER, 'comment': Rating.FLAG_COMMENT} type = kwargs.get('type') setting = kwargs.get('setting') if value: try: video = setting if type == 'video' and setting != "-" else None audio = setting if type == 'audio' and setting != "-" else None vote = vote_map[setting] if type == 'vote' else None flag = flag_map[setting] if type == 'flag' else None if cfg.rating_enable(): Rating.do.update_user_rating(value, video, audio, vote, flag, kwargs.get('detail')) return report(output) except: return report(output, _MSG_BAD_SERVER_PARMS) else: return report(output, _MSG_NO_VALUE) #------------------------------------------------------------------------------ def _api_options(name, output, kwargs): """ API: accepts output """ return options_list(output) def _api_translate(name, output, kwargs): """ API: accepts output, value(=acronym) """ return report(output, keyword='value', data=Tx(kwargs.get('value', ''))) def _api_addfile(name, output, kwargs): """ API: accepts name, output, pp, script, cat, priority, nzbname """ # When uploading via flash it will send the nzb in a kw arg called Filedata if name is None or isinstance(name, str) or isinstance(name, unicode): name = kwargs.get('Filedata') # Normal upload will send the nzb in a kw arg called nzbfile if name is None or isinstance(name, str) or isinstance(name, unicode): name = kwargs.get('nzbfile') if hasattr(name, 'getvalue'): #Side effect of next line is that attribute .value is created #which is needed to make add_nzbfile() work size = name.length elif hasattr(name, 'value'): size = len(name.value) else: size = 0 if name is not None and size and name.filename: cat = kwargs.get('cat') xcat = kwargs.get('xcat') if not cat and xcat: # Indexer category, so do mapping cat = cat_convert(xcat) res = sabnzbd.add_nzbfile(name, kwargs.get('pp'), kwargs.get('script'), cat, kwargs.get('priority'), kwargs.get('nzbname')) return report(output, keyword='', data={'status':res[0]==0, 'nzo_ids' : res[1]}, compat=True) else: return report(output, _MSG_NO_VALUE) def _api_retry(name, output, kwargs): """ API: accepts name, output, value(=nzo_id), nzbfile(=optional NZB) """ value = kwargs.get('value') # When uploading via flash it will send the nzb in a kw arg called Filedata if name is None or isinstance(name, str) or isinstance(name, unicode): name = kwargs.get('Filedata') # Normal upload will send the nzb in a kw arg called nzbfile if name is None or isinstance(name, str) or isinstance(name, unicode): name = kwargs.get('nzbfile') nzo_id = retry_job(value, name) if nzo_id: if isinstance(nzo_id, list): nzo_id = nzo_id[0] return report(output, keyword='', data={'status' : True, 'nzo_id' : nzo_id}) else: return report(output, _MSG_NO_ITEM) def _api_addlocalfile(name, output, kwargs): """ API: accepts name, output, pp, script, cat, priority, nzbname """ if name and isinstance(name, list): name = name[0] if name: if os.path.exists(name): fn = get_filename(name) if fn: pp = kwargs.get('pp') script = kwargs.get('script') cat = kwargs.get('cat') xcat = kwargs.get('xcat') if not cat and xcat: # Indexer category, so do mapping cat = cat_convert(xcat) priority = kwargs.get('priority') nzbname = kwargs.get('nzbname') if get_ext(name) in ('.zip', '.rar'): res = sabnzbd.dirscanner.ProcessArchiveFile(\ fn, name, pp=pp, script=script, cat=cat, priority=priority, keep=True, nzbname=nzbname) elif get_ext(name) in ('.nzb', '.gz'): res = sabnzbd.dirscanner.ProcessSingleFile(\ fn, name, pp=pp, script=script, cat=cat, priority=priority, keep=True, nzbname=nzbname) else: return report(output, _MSG_NO_FILE) else: return report(output, _MSG_NO_PATH) return report(output, keyword='', data={'status':res[0]==0, 'nzo_ids' : res[1]}, compat=True) else: return report(output, _MSG_NO_VALUE) def _api_switch(name, output, kwargs): """ API: accepts output, value(=first id), value2(=second id) """ value = kwargs.get('value') value2 = kwargs.get('value2') if value and value2: pos, prio = NzbQueue.do.switch(value, value2) # Returns the new position and new priority (if different) if output not in ('xml', 'json'): return report(output, data=(pos, prio)) else: return report(output, keyword='result', data={'position':pos, 'priority':prio}) else: return report(output, _MSG_NO_VALUE2) def _api_change_cat(name, output, kwargs): """ API: accepts output, value(=nzo_id), value2(=category) """ value = kwargs.get('value') value2 = kwargs.get('value2') if value and value2: nzo_id = value cat = value2 if cat == 'None': cat = None NzbQueue.do.change_cat(nzo_id, cat) return report(output) else: return report(output, _MSG_NO_VALUE) def _api_change_script(name, output, kwargs): """ API: accepts output, value(=nzo_id), value2(=script) """ value = kwargs.get('value') value2 = kwargs.get('value2') if value and value2: nzo_id = value script = value2 if script.lower() == 'none': script = None NzbQueue.do.change_script(nzo_id, script) return report(output) else: return report(output, _MSG_NO_VALUE) def _api_change_opts(name, output, kwargs): """ API: accepts output, value(=nzo_id), value2(=pp) """ value = kwargs.get('value') value2 = kwargs.get('value2') if value and value2 and value2.isdigit(): NzbQueue.do.change_opts(value, int(value2)) return report(output) def _api_fullstatus(name, output, kwargs): """ API: not implemented """ return report(output, _MSG_NOT_IMPLEMENTED + ' YET') #xml_full() def _api_history(name, output, kwargs): """ API: accepts output, value(=nzo_id), start, limit, search """ value = kwargs.get('value', '') start = kwargs.get('start') limit = kwargs.get('limit') search = kwargs.get('search') failed_only = kwargs.get('failed_only') if not limit: limit = cfg.history_limit() if name == 'delete': special = value.lower() del_files = bool(int_conv(kwargs.get('del_files'))) if special in ('all', 'failed', 'completed'): history_db = cherrypy.thread_data.history_db if special in ('all', 'failed'): if del_files: del_job_files(history_db.get_failed_paths(search)) history_db.remove_failed(search) if special in ('all', 'completed'): history_db.remove_completed(search) return report(output) elif value: jobs = value.split(',') for job in jobs: del_hist_job(job, del_files) return report(output) else: return report(output, _MSG_NO_VALUE) elif not name: history, pnfo_list, bytespersec = build_header(True) grand, month, week, day = BPSMeter.do.get_sums() history['total_size'], history['month_size'], history['week_size'], history['day_size'] = \ to_units(grand), to_units(month), to_units(week), to_units(day) history['slots'], fetched_items, history['noofslots'] = build_history(start=start, limit=limit, verbose=True, search=search, failed_only=failed_only) return report(output, keyword='history', data=remove_callable(history)) else: return report(output, _MSG_NOT_IMPLEMENTED) def _api_get_files(name, output, kwargs): """ API: accepts output, value(=nzo_id) """ value = kwargs.get('value') if value: return report(output, keyword='files', data=build_file_list(value)) else: return report(output, _MSG_NO_VALUE) _RE_NEWZBIN_URL = re.compile(r'/browse/post/(\d+)') def _api_addid(names, output, kwargs): """ API: accepts name, output, pp, script, cat, priority, nzbname """ pp = kwargs.get('pp') script = kwargs.get('script') cat = kwargs.get('cat') priority = kwargs.get('priority') nzbnames = kwargs.get('nzbname') if not isinstance(names, list): names = [names] if not isinstance(nzbnames, list): nzbnames = [nzbnames] for n in xrange(len(names)): name = names[n] if n < len(nzbnames): nzbname = nzbnames[n] else: nzbname = '' newzbin_url = _RE_NEWZBIN_URL.search(name.lower()) if name: name = name.strip() if name and (name.isdigit() or len(name)==5): sabnzbd.add_msgid(name, pp, script, cat, priority, nzbname) elif newzbin_url: sabnzbd.add_msgid(newzbin_url.group(1), pp, script, cat, priority, nzbname) elif name: sabnzbd.add_url(name, pp, script, cat, priority, nzbname) if len(names) > 0: return report(output) else: return report(output, _MSG_NO_VALUE) def _api_pause(name, output, kwargs): """ API: accepts output """ scheduler.plan_resume(0) Downloader.do.pause() return report(output) def _api_resume(name, output, kwargs): """ API: accepts output """ scheduler.plan_resume(0) sabnzbd.unpause_all() return report(output) def _api_shutdown(name, output, kwargs): """ API: accepts output """ sabnzbd.halt() cherrypy.engine.exit() sabnzbd.SABSTOP = True return report(output) def _api_warnings(name, output, kwargs): """ API: accepts name, output """ if name == 'clear': return report(output, keyword="warnings", data=sabnzbd.GUIHANDLER.clear()) elif name == 'show': return report(output, keyword="warnings", data=sabnzbd.GUIHANDLER.content()) elif name: return report(output, _MSG_NOT_IMPLEMENTED) return report(output, keyword="warnings", data=sabnzbd.GUIHANDLER.content()) def _api_get_cats(name, output, kwargs): """ API: accepts output """ return report(output, keyword="categories", data=list_cats(False)) def _api_get_scripts(name, output, kwargs): """ API: accepts output """ data = [ unicoder(val) for val in list_scripts() ] return report(output, keyword="scripts", data=data) def _api_version(name, output, kwargs): """ API: accepts output """ return report(output, keyword='version', data=sabnzbd.__version__) def _api_auth(name, output, kwargs): """ API: accepts output """ auth = 'None' if not cfg.disable_key(): auth = 'badkey' key = kwargs.get('key', '') if not key: auth = 'apikey' else: if key == cfg.nzb_key(): auth = 'nzbkey' if key == cfg.api_key(): auth = 'apikey' elif cfg.username() and cfg.password(): auth = 'login' return report(output, keyword='auth', data=auth) def _api_newzbin(name, output, kwargs): """ API: accepts output """ if name == 'get_bookmarks': Bookmarks.do.run(force=True) return report(output) return report(output, _MSG_NOT_IMPLEMENTED) def _api_restart(name, output, kwargs): """ API: accepts output """ sabnzbd.halt() cherrypy.engine.restart() return report(output) def _api_restart_repair(name, output, kwargs): """ API: accepts output """ sabnzbd.request_repair() sabnzbd.halt() cherrypy.engine.restart() return report(output) def _api_disconnect(name, output, kwargs): """ API: accepts output """ Downloader.do.disconnect() return report(output) def _api_osx_icon(name, output, kwargs): """ API: accepts output, value """ value = kwargs.get('value', '1').strip() cfg.osx_menu.set(value != '0') return report(output) def _api_rescan(name, output, kwargs): """ API: accepts output """ scan_jobs(all=False, action=True) return report(output) def _api_eval_sort(name, output, kwargs): """ API: evaluate sorting expression """ import sabnzbd.tvsort name = kwargs.get('name', '') value = kwargs.get('value', '') title = kwargs.get('title') multipart = kwargs.get('movieextra', '') path = sabnzbd.tvsort.eval_sort(value, title, name, multipart) if path is None: return report(output, _MSG_NOT_IMPLEMENTED) else: return report(output, keyword='result', data=path) def _api_watched_now(name, output, kwargs): """ API: accepts output """ sabnzbd.dirscanner.dirscan() return report(output) def _api_resume_pp(name, output, kwargs): """ API: accepts output """ PostProcessor.do.paused = False return report(output) def _api_pause_pp(name, output, kwargs): """ API: accepts output """ PostProcessor.do.paused = True return report(output) def _api_rss_now(name, output, kwargs): """ API: accepts output """ # Run RSS scan async, because it can take a long time scheduler.force_rss() return report(output) def _api_reset_quota(name, output, kwargs): """ Reset quota left """ BPSMeter.do.reset_quota(force=True) def _api_test_email(name, output, kwargs): """ API: send a test email, return result """ logging.info("Sending testmail") pack = {} pack['download'] = ['action 1', 'action 2'] pack['unpack'] = ['action 1', 'action 2'] res = sabnzbd.emailer.endjob('I had a d\xe8ja vu', 123, 'unknown', True, os.path.normpath(os.path.join(cfg.complete_dir.get_path(), '/unknown/I had a d\xe8ja vu')), 123*MEBI, None, pack, 'my_script', 'Line 1\nLine 2\nLine 3\nd\xe8ja vu\n', 0, test=kwargs) if res == 'Email succeeded': res = None return report(output, error=res) def _api_test_notif(name, output, kwargs): """ API: send a test notification, return result """ logging.info("Sending test notification") res = sabnzbd.growler.send_notification('SABnzbd', T('Test Notification'), 'other', wait=True, test=kwargs) return report(output, error=res) def _api_undefined(name, output, kwargs): """ API: accepts output """ return report(output, _MSG_NOT_IMPLEMENTED) #------------------------------------------------------------------------------ def _api_browse(name, output, kwargs): """ Return tree of local path """ compact = kwargs.get('compact') if compact and compact == '1': paths = [] name = platform_encode(kwargs.get('term', '')) paths = [entry['path'] for entry in folders_at_path(os.path.dirname(name)) if 'path' in entry] return report(output, keyword='', data=paths) else: name = platform_encode(name) paths = folders_at_path(name, True) return report(output, keyword='paths', data=paths) #------------------------------------------------------------------------------ def _api_config(name, output, kwargs): """ API: Dispather for "config" """ return _api_config_table.get(name, _api_config_undefined)(output, kwargs) def _api_config_speedlimit(output, kwargs): """ API: accepts output, value(=speed) """ value = kwargs.get('value') if not value: value = '0' if value.isdigit(): try: value = int(value) except: return report(output, _MSG_NO_VALUE) Downloader.do.limit_speed(value) return report(output) else: return report(output, _MSG_NO_VALUE) def _api_config_get_speedlimit(output, kwargs): """ API: accepts output """ return report(output, keyword='speedlimit', data=int(Downloader.do.get_limit())) def _api_config_set_colorscheme(output, kwargs): """ API: accepts output, value(=color for primary), value2(=color for secundary) """ value = kwargs.get('value') value2 = kwargs.get('value2') if value: cfg.web_color.set(value) if value2: cfg.web_color2.set(value2) if value or value2: return report(output) else: return report(output, _MSG_NO_VALUE) def _api_config_set_pause(output, kwargs): """ API: accepts output, value(=pause interval) """ value = kwargs.get('value') scheduler.plan_resume(int_conv(value)) return report(output) def _api_config_set_apikey(output, kwargs): """ API: accepts output """ cfg.api_key.set(config.create_api_key()) config.save_config() return report(output, keyword='apikey', data=cfg.api_key()) def _api_config_set_nzbkey(output, kwargs): """ API: accepts output """ cfg.nzb_key.set(config.create_api_key()) config.save_config() return report(output, keyword='nzbkey', data=cfg.nzb_key()) def _api_config_test_server(output, kwargs): """ API: accepts output, server-parms """ result, msg = test_nntp_server_dict(kwargs) response = {'result': result, 'message': msg} if output: return report(output, data=response) else: return msg def _api_config_undefined(output, kwargs): """ API: accepts output """ return report(output, _MSG_NOT_IMPLEMENTED) def _api_server_stats(name, output, kwargs): """ API: accepts output """ sum_t, sum_m, sum_w, sum_d = BPSMeter.do.get_sums() stats = {'total': sum_t, 'month': sum_m, 'week': sum_w, 'day': sum_d} stats['servers'] = {} for svr in config.get_servers(): t, m, w, d = BPSMeter.do.amounts(svr) stats['servers'][svr] = {'total': t or 0, 'month': m or 0, 'week': w or 0, 'day': d or 0} return report(output, keyword='', data=stats) #------------------------------------------------------------------------------ _api_table = { 'server_stats' : _api_server_stats, 'get_config' : _api_get_config, 'set_config' : _api_set_config, 'del_config' : _api_del_config, 'qstatus' : _api_qstatus, 'queue' : _api_queue, 'options' : _api_options, 'translate' : _api_translate, 'addfile' : _api_addfile, 'retry' : _api_retry, 'addlocalfile' : _api_addlocalfile, 'switch' : _api_switch, 'change_cat' : _api_change_cat, 'change_script' : _api_change_script, 'change_opts' : _api_change_opts, 'fullstatus' : _api_fullstatus, 'history' : _api_history, 'get_files' : _api_get_files, 'addurl' : _api_addid, 'addid' : _api_addid, 'pause' : _api_pause, 'resume' : _api_resume, 'shutdown' : _api_shutdown, 'warnings' : _api_warnings, 'config' : _api_config, 'get_cats' : _api_get_cats, 'get_scripts' : _api_get_scripts, 'version' : _api_version, 'auth' : _api_auth, 'newzbin' : _api_newzbin, 'restart' : _api_restart, 'restart_repair' : _api_restart_repair, 'disconnect' : _api_disconnect, 'osx_icon' : _api_osx_icon, 'rescan' : _api_rescan, 'eval_sort' : _api_eval_sort, 'watched_now' : _api_watched_now, 'resume_pp' : _api_resume_pp, 'pause_pp' : _api_pause_pp, 'rss_now' : _api_rss_now, 'browse' : _api_browse, 'reset_quota' : _api_reset_quota, 'test_email' : _api_test_email, 'test_notif' : _api_test_notif, } _api_queue_table = { 'delete' : _api_queue_delete, 'delete_nzf' : _api_queue_delete_nzf, 'rename' : _api_queue_rename, 'change_complete_action' : _api_queue_change_complete_action, 'purge' : _api_queue_purge, 'pause' : _api_queue_pause, 'resume' : _api_queue_resume, 'priority' : _api_queue_priority, 'sort' : _api_queue_sort, 'rating' : _api_queue_rating } _api_config_table = { 'speedlimit' : _api_config_speedlimit, 'set_speedlimit' : _api_config_speedlimit, 'get_speedlimit' : _api_config_get_speedlimit, 'set_colorscheme' : _api_config_set_colorscheme, 'set_pause' : _api_config_set_pause, 'set_apikey' : _api_config_set_apikey, 'set_nzbkey' : _api_config_set_nzbkey, 'test_server' : _api_config_test_server } #------------------------------------------------------------------------------ def report(output, error=None, keyword='value', data=None, callback=None, compat=False): """ Report message in json, xml or plain text If error is set, only an status/error report is made. If no error and no data, only a status report is made. Else, a data report is made (optional 'keyword' for outer XML section). 'compat' is a special case for compatibility for ascii ouput """ if output == 'json': content = "application/json;charset=UTF-8" if error: info = {'status':False, 'error':error} elif data is None: info = {'status':True} else: if hasattr(data,'__iter__') and not keyword: info = data else: info = {keyword:data} response = JsonWriter().write(info) if callback: response = '%s(%s)' % (callback, response) elif output == 'xml': if not keyword: # xml always needs an outer keyword, even when json doesn't keyword = 'result' content = "text/xml" xmlmaker = xml_factory() if error: status_str = xmlmaker.run('result', {'status':False, 'error':error}) elif data is None: status_str = xmlmaker.run('result', {'status':True}) else: status_str = xmlmaker.run(keyword, data) response = '\n%s\n' % status_str else: content = "text/plain" if error: response = "error: %s\n" % error elif compat or data is None: response = 'ok\n' else: if type(data) in (list, tuple): # Special handling for list/tuple (backward compatibility) data = [str(val) for val in data] data = ' '.join(data) if isinstance(data, unicode): response = u'%s\n' % data else: response = '%s\n' % str(data) cherrypy.response.headers['Content-Type'] = content cherrypy.response.headers['Pragma'] = 'no-cache' return response #------------------------------------------------------------------------------ class xml_factory(object): """ Recursive xml string maker. Feed it a mixed tuple/dict/item object and will output into an xml string Current limitations: In Two tiered lists hardcoded name of "item": In Three tiered lists hardcoded name of "slot": """ def __init__(self): self.__text = '' def _tuple(self, keyw, lst): text = [] for item in lst: text.append(self.run(keyw, item)) return ''.join(text) def _dict(self, keyw, lst): text = [] for key in lst.keys(): text.append(self.run(key, lst[key])) if keyw: return '<%s>%s\n' % (keyw, ''.join(text), keyw) else: return '' def _list(self, keyw, lst): text = [] for cat in lst: if isinstance(cat, dict): text.append(self._dict(plural_to_single(keyw, 'slot'), cat)) elif isinstance(cat, list): text.append(self._list(plural_to_single(keyw, 'list'), cat)) elif isinstance(cat, tuple): text.append(self._tuple(plural_to_single(keyw, 'tuple'), cat)) else: if not isinstance(cat, basestring): cat = str(cat) name = plural_to_single(keyw, 'item') text.append('<%s>%s\n' % (name, xml_name(cat, encoding='utf-8'), name)) if keyw: return '<%s>%s\n' % (keyw, ''.join(text), keyw) else: return '' def run(self, keyw, lst): if isinstance(lst, dict): text = self._dict(keyw, lst) elif isinstance(lst, list): text = self._list(keyw, lst) elif isinstance(lst, tuple): text = self._tuple(keyw, lst) elif keyw: text = '<%s>%s\n' % (keyw, xml_name(lst, encoding='utf-8'), keyw) else: text = '' return text #------------------------------------------------------------------------------ def handle_server_api(output, kwargs): """ Special handler for API-call 'set_config' [servers] """ name = kwargs.get('keyword') if not name: name = kwargs.get('name') if name: server = config.get_config('servers', name) if server: server.set_dict(kwargs) old_name = name else: config.ConfigServer(name, kwargs) old_name = None Downloader.do.update_server(old_name, name) return name #------------------------------------------------------------------------------ def handle_rss_api(output, kwargs): """ Special handler for API-call 'set_config' [rss] """ name = kwargs.get('keyword') if not name: name = kwargs.get('name') if not name: return None feed = config.get_config('rss', name) if feed: feed.set_dict(kwargs) else: config.ConfigRSS(name, kwargs) return name #------------------------------------------------------------------------------ def handle_cat_api(output, kwargs): """ Special handler for API-call 'set_config' [categories] """ name = kwargs.get('keyword') if not name: name = kwargs.get('name') if not name: return None feed = config.get_config('categories', name) if feed: feed.set_dict(kwargs) else: config.ConfigCat(name, kwargs) return name #------------------------------------------------------------------------------ def build_queue(web_dir=None, root=None, verbose=False, prim=True, webdir='', verbose_list=None, dictionary=None, history=False, start=None, limit=None, dummy2=None, trans=False, output=None): if output: converter = unicoder else: converter = xml_name if not verbose_list: verbose_list = [] if dictionary: dictn = dictionary else: dictn = [] #build up header full of basic information info, pnfo_list, bytespersec = build_header(prim, webdir) info['isverbose'] = verbose cookie = cherrypy.request.cookie if cookie.has_key('queue_details'): info['queue_details'] = str(int_conv(cookie['queue_details'].value)) else: info['queue_details'] = '0' if cfg.newzbin_username() and cfg.newzbin_password(): info['newzbinDetails'] = True if cfg.refresh_rate() > 0: info['refresh_rate'] = str(cfg.refresh_rate()) else: info['refresh_rate'] = '' datestart = datetime.datetime.now() info['script_list'] = list_scripts() info['cat_list'] = list_cats(output is None) info['rating_enable'] = bool(cfg.rating_enable()) n = 0 found_active = False running_bytes = 0 slotinfo = [] nzo_ids = [] limit = int_conv(limit) start = int_conv(start) if history: #Collect nzo's from the history that are downloaded but not finished (repairing, extracting) slotinfo = format_history_for_queue() #if the specified start value is greater than the amount of history items, do no include the history (used for paging the queue) if len(slotinfo) < start: slotinfo = [] else: slotinfo = [] info['noofslots'] = len(pnfo_list) + len(slotinfo) info['start'] = start info['limit'] = limit info['finish'] = info['start'] + info['limit'] if info['finish'] > info['noofslots']: info['finish'] = info['noofslots'] for pnfo in pnfo_list: repair = pnfo[PNFO_REPAIR_FIELD] unpack = pnfo[PNFO_UNPACK_FIELD] delete = pnfo[PNFO_DELETE_FIELD] script = pnfo[PNFO_SCRIPT_FIELD] nzo_id = pnfo[PNFO_NZO_ID_FIELD] cat = pnfo[PNFO_EXTRA_FIELD1] if not cat: cat = 'None' filename = pnfo[PNFO_FILENAME_FIELD] msgid = pnfo[PNFO_MSGID_FIELD] bytesleft = pnfo[PNFO_BYTES_LEFT_FIELD] bytes = pnfo[PNFO_BYTES_FIELD] average_date = pnfo[PNFO_AVG_DATE_FIELD] status = pnfo[PNFO_STATUS_FIELD] priority = pnfo[PNFO_PRIORITY_FIELD] mbleft = (bytesleft / MEBI) mb = (bytes / MEBI) missing = pnfo[PNFO_MISSING_FIELD] if verbose or verbose_list: finished_files = pnfo[PNFO_FINISHED_FILES_FIELD] active_files = pnfo[PNFO_ACTIVE_FILES_FIELD] queued_files = pnfo[PNFO_QUEUED_FILES_FIELD] nzo_ids.append(nzo_id) slot = {'index':n, 'nzo_id':str(nzo_id)} unpackopts = sabnzbd.opts_to_pp(repair, unpack, delete) slot['unpackopts'] = str(unpackopts) if script: slot['script'] = script else: slot['script'] = 'None' slot['msgid'] = msgid slot['filename'] = converter(filename) slot['cat'] = cat slot['mbleft'] = "%.2f" % mbleft slot['mb'] = "%.2f" % mb if not output: slot['mb_fmt'] = locale.format('%d', int(mb), True) slot['mbdone_fmt'] = locale.format('%d', int(mb-mbleft), True) slot['size'] = format_bytes(bytes) slot['sizeleft'] = format_bytes(bytesleft) if not Downloader.do.paused and status not in (Status.PAUSED, Status.FETCHING) and not found_active: if status == Status.CHECKING: slot['status'] = Status.CHECKING else: slot['status'] = Status.DOWNLOADING found_active = True else: slot['status'] = "%s" % (status) if priority == TOP_PRIORITY: slot['priority'] = 'Force' elif priority == REPAIR_PRIORITY: slot['priority'] = 'Repair' elif priority == HIGH_PRIORITY: slot['priority'] = 'High' elif priority == LOW_PRIORITY: slot['priority'] = 'Low' else: slot['priority'] = 'Normal' if mb == mbleft: slot['percentage'] = "0" else: slot['percentage'] = "%s" % (int(((mb-mbleft) / mb) * 100)) slot['missing'] = missing if (Downloader.do.paused or Downloader.do.postproc or status not in (Status.DOWNLOADING, Status.QUEUED)) \ and priority != TOP_PRIORITY: slot['timeleft'] = '0:00:00' slot['eta'] = 'unknown' else: running_bytes += bytesleft slot['timeleft'] = calc_timeleft(running_bytes, bytespersec) try: datestart = datestart + datetime.timedelta(seconds=bytesleft / bytespersec) #new eta format: 16:00 Fri 07 Feb slot['eta'] = '%s' % datestart.strftime(time_format('%H:%M %a %d %b')) except: datestart = datetime.datetime.now() slot['eta'] = 'unknown' if status == Status.GRABBING: slot['avg_age'] = '---' else: slot['avg_age'] = calc_age(average_date, bool(trans)) slot['verbosity'] = "" if web_dir: finished = [] active = [] queued = [] if verbose or nzo_id in verbose_list:#this will list files in the xml output, wanted yes/no? slot['verbosity'] = "True" for tup in finished_files: bytes_left, bytes, fn, date = tup fn = converter(fn) age = calc_age(date) line = {'filename':fn, 'mbleft':"%.2f" % (bytes_left / MEBI), 'mb':"%.2f" % (bytes / MEBI), 'size': format_bytes(bytes), 'sizeleft': format_bytes(bytes_left), 'age':age} finished.append(line) for tup in active_files: bytes_left, bytes, fn, date, nzf_id = tup fn = converter(fn) age = calc_age(date) line = {'filename':fn, 'mbleft':"%.2f" % (bytes_left / MEBI), 'mb':"%.2f" % (bytes / MEBI), 'size': format_bytes(bytes), 'sizeleft': format_bytes(bytes_left), 'nzf_id':nzf_id, 'age':age} active.append(line) for tup in queued_files: _set, bytes_left, bytes, fn, date = tup fn = converter(fn) _set = converter(_set) age = calc_age(date) line = {'filename':fn, 'set':_set, 'mbleft':"%.2f" % (bytes_left / MEBI), 'mb':"%.2f" % (bytes / MEBI), 'size': format_bytes(bytes), 'sizeleft': format_bytes(bytes_left), 'age':age} queued.append(line) slot['finished'] = finished slot['active'] = active slot['queued'] = queued rating = Rating.do.get_rating_by_nzo(nzo_id) slot['has_rating'] = rating is not None if rating: slot['rating_avg_video'] = rating.avg_video slot['rating_avg_audio'] = rating.avg_audio if (start <= n and n < start + limit) or not limit: slotinfo.append(slot) n += 1 if slotinfo: info['slots'] = slotinfo else: info['slots'] = [] verbose_list = [] #Paging of the queue using limit and/or start values if limit > 0: try: if start > 0: if start > len(pnfo_list): pnfo_list = [] else: end = start+limit if start+limit > len(pnfo_list): end = len(pnfo_list) pnfo_list = pnfo_list[start:end] else: if not limit > len(pnfo_list): pnfo_list = pnfo_list[:limit] except: pass return info, pnfo_list, bytespersec, verbose_list, dictn #------------------------------------------------------------------------------ def fast_queue(): """ Return paused, bytes_left, bpsnow, time_left """ bytes_left = NzbQueue.do.remaining() paused = Downloader.do.paused bpsnow = BPSMeter.do.get_bps() time_left = calc_timeleft(bytes_left, bpsnow) return paused, bytes_left, bpsnow, time_left #------------------------------------------------------------------------------ def qstatus_data(): """Build up the queue status as a nested object and output as a JSON object """ qnfo = NzbQueue.do.queue_info() pnfo_list = qnfo[QNFO_PNFO_LIST_FIELD] jobs = [] bytesleftprogess = 0 bpsnow = BPSMeter.do.get_bps() for pnfo in pnfo_list: filename = pnfo[PNFO_FILENAME_FIELD] msgid = pnfo[PNFO_MSGID_FIELD] bytesleft = pnfo[PNFO_BYTES_LEFT_FIELD] / MEBI bytesleftprogess += pnfo[PNFO_BYTES_LEFT_FIELD] bytes = pnfo[PNFO_BYTES_FIELD] / MEBI nzo_id = pnfo[PNFO_NZO_ID_FIELD] jobs.append( { "id" : nzo_id, "mb":bytes, "mbleft":bytesleft, "filename":unicoder(filename), "msgid":msgid, "timeleft":calc_timeleft(bytesleftprogess, bpsnow) } ) state = "IDLE" if Downloader.do.paused: state = Status.PAUSED elif qnfo[QNFO_BYTES_LEFT_FIELD] / MEBI > 0: state = Status.DOWNLOADING status = { "state" : state, "pp_active" : not PostProcessor.do.empty(), "paused" : Downloader.do.paused, "pause_int" : scheduler.pause_int(), "kbpersec" : bpsnow / KIBI, "speed" : to_units(bpsnow, dec_limit=1), "mbleft" : qnfo[QNFO_BYTES_LEFT_FIELD] / MEBI, "mb" : qnfo[QNFO_BYTES_FIELD] / MEBI, "noofslots" : len(pnfo_list), "have_warnings" : str(sabnzbd.GUIHANDLER.count()), "diskspace1" : diskfree(cfg.download_dir.get_path()), "diskspace2" : diskfree(cfg.complete_dir.get_path()), "timeleft" : calc_timeleft(qnfo[QNFO_BYTES_LEFT_FIELD], bpsnow), "loadavg" : loadavg(), "jobs" : jobs } return status #------------------------------------------------------------------------------ def build_file_list(id): qnfo = NzbQueue.do.queue_info() pnfo_list = qnfo[QNFO_PNFO_LIST_FIELD] jobs = [] for pnfo in pnfo_list: nzo_id = pnfo[PNFO_NZO_ID_FIELD] if nzo_id == id: finished_files = pnfo[PNFO_FINISHED_FILES_FIELD] active_files = pnfo[PNFO_ACTIVE_FILES_FIELD] queued_files = pnfo[PNFO_QUEUED_FILES_FIELD] n = 0 for tup in finished_files: bytes_left, bytes, fn, date = tup fn = xml_name(fn) age = calc_age(date) line = {'filename':fn, 'mbleft':"%.2f" % (bytes_left / MEBI), 'mb':"%.2f" % (bytes / MEBI), 'bytes':"%.2f" % bytes, 'age':age, 'id':str(n), 'status':'finished'} jobs.append(line) n += 1 for tup in active_files: bytes_left, bytes, fn, date, nzf_id = tup fn = xml_name(fn) age = calc_age(date) line = {'filename':fn, 'mbleft':"%.2f" % (bytes_left / MEBI), 'mb':"%.2f" % (bytes / MEBI), 'bytes':"%.2f" % bytes, 'nzf_id':nzf_id, 'age':age, 'id':str(n), 'status':'active'} jobs.append(line) n += 1 for tup in queued_files: _set, bytes_left, bytes, fn, date = tup fn = xml_name(fn) _set = xml_name(_set) age = calc_age(date) line = {'filename':fn, 'set':_set, 'mbleft':"%.2f" % (bytes_left / MEBI), 'mb':"%.2f" % (bytes / MEBI), 'bytes':"%.2f" % bytes, 'age':age, 'id':str(n), 'status':'queued'} jobs.append(line) n += 1 return jobs #------------------------------------------------------------------------------ def json_list(section, lst): """Output a simple list as a JSON object """ n = 0 d = [] for item in lst: c = {} c['id'] = '%s' % n c['name'] = item n += 1 d.append(c) return { section : d } #------------------------------------------------------------------------------ def rss_qstatus(): """ Return a RSS feed with the queue status """ qnfo = NzbQueue.do.queue_info() pnfo_list = qnfo[QNFO_PNFO_LIST_FIELD] rss = RSS() rss.channel.title = "SABnzbd Queue" rss.channel.description = "Overview of current downloads" rss.channel.link = "http://%s:%s/sabnzbd/queue" % ( \ cfg.cherryhost(), cfg.cherryport() ) rss.channel.language = "en" item = Item() item.title = 'Total ETA: %s - Queued: %.2f MB - Speed: %.2f kB/s' % \ ( calc_timeleft(qnfo[QNFO_BYTES_LEFT_FIELD], BPSMeter.do.get_bps()), qnfo[QNFO_BYTES_LEFT_FIELD] / MEBI, BPSMeter.do.get_bps() / KIBI ) rss.addItem(item) sum_bytesleft = 0 for pnfo in pnfo_list: filename = pnfo[PNFO_FILENAME_FIELD] msgid = pnfo[PNFO_MSGID_FIELD] bytesleft = pnfo[PNFO_BYTES_LEFT_FIELD] / MEBI bytes = pnfo[PNFO_BYTES_FIELD] / MEBI mbleft = (bytesleft / MEBI) mb = (bytes / MEBI) nzo_id = pnfo[PNFO_NZO_ID_FIELD] if mb == mbleft: percentage = "0%" else: percentage = "%s%%" % (int(((mb-mbleft) / mb) * 100)) filename = xml_name(filename) name = u'%s (%s)' % (filename, percentage) item = Item() item.title = name if msgid: item.link = "https://%s/browse/post/%s/" % (cfg.newzbin_url(), msgid) else: item.link = "http://%s:%s/sabnzbd/history" % ( \ cfg.cherryhost(), cfg.cherryport() ) item.guid = nzo_id status_line = [] status_line.append('') #Total MB/MB left status_line.append('
    Remain/Total: %.2f/%.2f MB
    ' % (bytesleft, bytes)) #ETA sum_bytesleft += pnfo[PNFO_BYTES_LEFT_FIELD] status_line.append("
    ETA: %s
    " % calc_timeleft(sum_bytesleft, BPSMeter.do.get_bps())) status_line.append("
    Age: %s
    " % calc_age(pnfo[PNFO_AVG_DATE_FIELD])) status_line.append("") item.description = ''.join(status_line) rss.addItem(item) rss.channel.lastBuildDate = std_time(time.time()) rss.channel.pubDate = rss.channel.lastBuildDate rss.channel.ttl = "1" return rss.write() #------------------------------------------------------------------------------ def options_list(output): return report(output, keyword='options', data= { 'yenc' : sabnzbd.decoder.HAVE_YENC, 'par2' : sabnzbd.newsunpack.PAR2_COMMAND, 'par2c' : sabnzbd.newsunpack.PAR2C_COMMAND, 'rar' : sabnzbd.newsunpack.RAR_COMMAND, 'zip' : sabnzbd.newsunpack.ZIP_COMMAND, 'nice' : sabnzbd.newsunpack.NICE_COMMAND, 'ionice' : sabnzbd.newsunpack.IONICE_COMMAND, 'ssl' : sabnzbd.newswrapper.HAVE_SSL }) #------------------------------------------------------------------------------ def retry_job(job, new_nzb): """ Re enter failed job in the download queue """ if job: history_db = cherrypy.thread_data.history_db path = history_db.get_path(job) if path: nzo_id = repair_job(platform_encode(path), new_nzb) history_db.remove_history(job) return nzo_id return None #------------------------------------------------------------------------------ def del_job_files(job_paths): """ Remove files of each path in the list """ for path in job_paths: if path and path.lower().startswith(cfg.download_dir.get_path().lower()): remove_all(path, recursive=True) #------------------------------------------------------------------------------ def del_hist_job(job, del_files): """ Remove history element """ if job: path = PostProcessor.do.get_path(job) if path: PostProcessor.do.delete(job, del_files=del_files) else: history_db = cherrypy.thread_data.history_db path = history_db.get_path(job) PostProcessor.do.delete(job, del_files=del_files) history_db.remove_history(job) if path and del_files and path.lower().startswith(cfg.download_dir.get_path().lower()): remove_all(path, recursive=True) return True #------------------------------------------------------------------------------ def Tspec(txt): """ Translate special terms """ if txt == 'None': return T('None') elif txt in ('Default', '*'): return T('Default') else: return txt _SKIN_CACHE = {} # Stores pre-translated acronyms # This special is to be used in interface.py for template processing # to be passed for the $T function: so { ..., 'T' : Ttemplate, ...} def Ttemplate(txt): """ Translation function for Skin texts """ global _SKIN_CACHE if txt in _SKIN_CACHE: return _SKIN_CACHE[txt] else: tra = html_escape(Tx(SKIN_TEXT.get(txt, txt))) _SKIN_CACHE[txt] = tra return tra def clear_trans_cache(): """ Clean cache for skin translations """ global _SKIN_CACHE dummy = _SKIN_CACHE _SKIN_CACHE = {} del dummy sabnzbd.WEBUI_READY = True def build_header(prim, webdir=''): try: uptime = calc_age(sabnzbd.START) except: uptime = "-" if prim: color = sabnzbd.WEB_COLOR else: color = sabnzbd.WEB_COLOR2 if not color: color = '' header = { 'T': Ttemplate, 'Tspec': Tspec, 'Tx' : Ttemplate, 'version':sabnzbd.__version__, 'paused': Downloader.do.paused or Downloader.do.postproc, 'pause_int': scheduler.pause_int(), 'paused_all': sabnzbd.PAUSED_ALL, 'uptime':uptime, 'color_scheme':color } speed_limit = Downloader.do.get_limit() if speed_limit <= 0: speed_limit = '' header['helpuri'] = 'http://wiki.sabnzbd.org/' header['diskspace1'] = "%.2f" % diskfree(cfg.download_dir.get_path()) header['diskspace2'] = "%.2f" % diskfree(cfg.complete_dir.get_path()) header['diskspacetotal1'] = "%.2f" % disktotal(cfg.download_dir.get_path()) header['diskspacetotal2'] = "%.2f" % disktotal(cfg.complete_dir.get_path()) header['loadavg'] = loadavg() header['speedlimit'] = "%s" % speed_limit header['restart_req'] = sabnzbd.RESTART_REQ header['have_warnings'] = str(sabnzbd.GUIHANDLER.count()) header['last_warning'] = sabnzbd.GUIHANDLER.last().replace('WARNING', Ta('WARNING:')).replace('ERROR', Ta('ERROR:')) header['active_lang'] = cfg.language() header['newzbin_url'] = cfg.newzbin_url() header['my_lcldata'] = sabnzbd.DIR_LCLDATA header['my_home'] = sabnzbd.DIR_HOME header['webdir'] = webdir header['newzbin_url'] = cfg.newzbin_url() header['finishaction'] = sabnzbd.QUEUECOMPLETE header['nt'] = sabnzbd.WIN32 header['darwin'] = sabnzbd.DARWIN header['power_options'] = sabnzbd.WIN32 or sabnzbd.DARWIN or sabnzbd.LINUX_POWER header['session'] = cfg.api_key() header['uniconfig'] = cfg.uniconfig() and sabnzbd.WEB_DIRC bytespersec = BPSMeter.do.get_bps() qnfo = NzbQueue.do.queue_info() bytesleft = qnfo[QNFO_BYTES_LEFT_FIELD] bytes = qnfo[QNFO_BYTES_FIELD] header['kbpersec'] = "%.2f" % (bytespersec / KIBI) header['speed'] = to_units(bytespersec, spaces=1, dec_limit=1) header['mbleft'] = "%.2f" % (bytesleft / MEBI) header['mb'] = "%.2f" % (bytes / MEBI) header['sizeleft'] = format_bytes(bytesleft) header['size'] = format_bytes(bytes) header['quota'] = to_units(BPSMeter.do.quota) header['have_quota'] = bool(BPSMeter.do.quota > 0.0) header['left_quota'] = to_units(BPSMeter.do.left) header['pp_pause_event'] = sabnzbd.scheduler.pp_pause_event() status = '' if Downloader.do.paused or Downloader.do.postproc: status = Status.PAUSED elif bytespersec > 0: status = Status.DOWNLOADING else: status = 'Idle' header['status'] = status anfo = ArticleCache.do.cache_info() header['cache_art'] = str(anfo[ANFO_ARTICLE_SUM_FIELD]) header['cache_size'] = format_bytes(anfo[ANFO_CACHE_SIZE_FIELD]) header['cache_max'] = str(anfo[ANFO_CACHE_LIMIT_FIELD]) header['nzb_quota'] = '' if sabnzbd.NEW_VERSION: header['new_release'], header['new_rel_url'] = sabnzbd.NEW_VERSION.split(';') else: header['new_release'] = '' header['new_rel_url'] = '' header['timeleft'] = calc_timeleft(bytesleft, bytespersec) try: datestart = datetime.datetime.now() + datetime.timedelta(seconds=bytesleft / bytespersec) #new eta format: 16:00 Fri 07 Feb header['eta'] = '%s' % datestart.strftime(time_format('%H:%M %a %d %b')) except: datestart = datetime.datetime.now() header['eta'] = T('unknown') return (header, qnfo[QNFO_PNFO_LIST_FIELD], bytespersec) #------------------------------------------------------------------------------ def build_history(start=None, limit=None, verbose=False, verbose_list=None, search=None, failed_only=0): if not verbose_list: verbose_list = [] limit = int_conv(limit) if not limit: limit = 1000000 start = int_conv(start) failed_only = int_conv(failed_only) def matches_search(text, search_text): # Replace * with .* and ' ' with . search_text = search_text.strip().replace('*','.*').replace(' ','.*') + '.*?' try: re_search = re.compile(search_text, re.I) except: logging.error(Ta('Failed to compile regex for search term: %s'), search_text) return False return re_search.search(text) # Grab any items that are active or queued in postproc queue = PostProcessor.do.get_queue() # Filter out any items that don't match the search if search: queue = [nzo for nzo in queue if matches_search(nzo.final_name, search)] # Multi-page support for postproc items full_queue_size = len(queue) if start > full_queue_size: # On a page where we shouldn't show postproc items queue = [] h_limit = limit else: try: if limit: queue = queue[start:start+limit] else: queue = queue[start:] except: pass # Remove the amount of postproc items from the db request for history items h_limit = max(limit - len(queue), 0) h_start = max(start - full_queue_size, 0) # Aquire the db instance try: history_db = cherrypy.thread_data.history_db close_db = False except: # Required for repairs at startup because Cherrypy isn't active yet history_db = get_history_handle() close_db = True # Fetch history items if not h_limit: items, fetched_items, total_items = history_db.fetch_history(h_start, 1, search, failed_only) items = [] fetched_items = 0 else: items, fetched_items, total_items = history_db.fetch_history(h_start, h_limit, search, failed_only) # Fetch which items should show details from the cookie k = [] if verbose: details_show_all = True else: details_show_all = False cookie = cherrypy.request.cookie if cookie.has_key('history_verbosity'): k = cookie['history_verbosity'].value c_path = cookie['history_verbosity']['path'] c_age = cookie['history_verbosity']['max-age'] c_version = cookie['history_verbosity']['version'] if k == 'all': details_show_all = True k = k.split(',') k.extend(verbose_list) # Reverse the queue to add items to the top (faster than insert) items.reverse() # Add the postproc items to the top of the history items = get_active_history(queue, items) # Unreverse the queue items.reverse() retry_folders = [] for item in items: if details_show_all: item['show_details'] = 'True' else: if item['nzo_id'] in k: item['show_details'] = 'True' else: item['show_details'] = '' if item['bytes']: item['size'] = format_bytes(item['bytes']) else: item['size'] = '' if not item.has_key('loaded'): item['loaded'] = False path = platform_encode(item.get('path', '')) item['retry'] = int(bool(item.get('status') == 'Failed' and \ path and \ path not in retry_folders and \ starts_with_path(path, cfg.download_dir.get_path()) and \ os.path.exists(path)) and \ not bool(globber(os.path.join(path, JOB_ADMIN), 'SABnzbd_n*')) \ ) if item['retry']: retry_folders.append(path) if Rating.do: rating = Rating.do.get_rating_by_nzo(item['nzo_id']) else: rating = None item['has_rating'] = rating is not None if rating: item['rating_avg_video'] = rating.avg_video item['rating_avg_audio'] = rating.avg_audio item['rating_avg_vote_up'] = rating.avg_vote_up item['rating_avg_vote_down'] = rating.avg_vote_down item['rating_user_video'] = rating.user_video item['rating_user_audio'] = rating.user_audio item['rating_user_vote'] = rating.user_vote total_items += full_queue_size fetched_items = len(items) if close_db: history_db.close() return (items, fetched_items, total_items) #------------------------------------------------------------------------------ def format_history_for_queue(): ''' Retrieves the information on currently active history items, and formats them for displaying in the queue ''' slotinfo = [] history_items = get_active_history() for item in history_items: slot = {'nzo_id':item['nzo_id'], 'msgid':item['report'], 'filename':xml_name(item['name']), 'loaded':False, 'stages':item['stage_log'], 'status':item['status'], 'bytes':item['bytes'], 'size':item['size']} slotinfo.append(slot) return slotinfo def get_active_history(queue=None, items=None): # Get the currently in progress and active history queue. if items is None: items = [] if queue is None: queue = PostProcessor.do.get_queue() for nzo in queue: history = build_history_info(nzo) item = {} item['completed'], item['name'], item['nzb_name'], item['category'], item['pp'], item['script'], item['report'], \ item['url'], item['status'], item['nzo_id'], item['storage'], item['path'], item['script_log'], \ item['script_line'], item['download_time'], item['postproc_time'], item['stage_log'], \ item['downloaded'], item['completeness'], item['fail_message'], item['url_info'], item['bytes'] = history item['action_line'] = nzo.action_line item = unpack_history_info(item) item['loaded'] = nzo.pp_active if item['bytes']: item['size'] = format_bytes(item['bytes']) else: item['size'] = '' # Queue display needs Unicode instead of UTF-8 for kw in item: if isinstance(item[kw], str): item[kw] = item[kw].decode('utf-8') items.append(item) return items #------------------------------------------------------------------------------ def format_bytes(bytes): b = to_units(bytes) if b == '': return b else: return b + 'B' def calc_timeleft(bytesleft, bps): """ Calculate the time left in the format HH:MM:SS """ try: totalseconds = int(bytesleft / bps) minutes, seconds = divmod(totalseconds, 60) hours, minutes = divmod(minutes, 60) if minutes < 10: minutes = '0%s' % minutes if seconds < 10: seconds = '0%s' % seconds return '%s:%s:%s' % (hours, minutes, seconds) except: return '0:00:00' def calc_age(date, trans=False): """ Calculate the age difference between now and date. Value is returned as either days, hours, or minutes. When 'trans' is True, time symbols will be translated. """ if trans: d = T('d') #: Single letter abbreviation of day h = T('h') #: Single letter abbreviation of hour m = T('m') #: Single letter abbreviation of minute else: d = 'd' h = 'h' m = 'm' try: now = datetime.datetime.now() #age = str(now - date).split(".")[0] #old calc_age #time difference dage = now-date seconds = dage.seconds #only one value should be returned #if it is less than 1 day then it returns in hours, unless it is less than one hour where it returns in minutes if dage.days: age = '%s%s' % (dage.days, d) elif seconds/3600: age = '%s%s' % (seconds/3600, h) else: age = '%s%s' % (seconds/60, m) except: age = "-" return age def std_time(when): # Fri, 16 Nov 2007 16:42:01 GMT +0100 item = time.strftime(time_format('%a, %d %b %Y %H:%M:%S'), time.localtime(when)) item += " GMT %+05d" % (-time.timezone/36) return item def list_scripts(default=False): """ Return a list of script names, optionally with 'Default' added """ lst = [] path = cfg.script_dir.get_path() if path and os.access(path, os.R_OK): for script in globber(path): if os.path.isfile(script): if (sabnzbd.WIN32 and os.path.splitext(script)[1].lower() in PATHEXT and \ not (win32api.GetFileAttributes(script) & win32file.FILE_ATTRIBUTE_HIDDEN)) or \ script.endswith('.py') or \ (not sabnzbd.WIN32 and os.access(script, os.X_OK) and not os.path.basename(script).startswith('.')): lst.append(os.path.basename(script)) lst.insert(0, 'None') if default: lst.insert(0, 'Default') return lst def list_cats(default=True): """ Return list of categories, when default==False use '*' for Default category """ lst = sorted(config.get_categories().keys()) if default: lst.remove('*') lst.insert(0, 'Default') return lst def remove_callable(dic): """ Remove all callable items from dictionary """ for key, value in dic.items(): if callable(value): del dic[key] return dic #------------------------------------------------------------------------------ _PLURAL_TO_SINGLE = { 'categories' : 'category', 'servers' : 'server', 'rss' : 'feed', 'scripts' : 'script', 'warnings' : 'warning', 'files' : 'file', 'jobs' : 'job' } def plural_to_single(kw, def_kw=''): try: return _PLURAL_TO_SINGLE[kw] except KeyError: return def_kw #------------------------------------------------------------------------------ def del_from_section(kwargs): """ Remove keyword in section """ section = kwargs.get('section', '') if section in ('servers', 'rss', 'categories'): keyword = kwargs.get('keyword') if keyword: item = config.get_config(section, keyword) if item: item.delete() del item config.save_config() if section == 'servers': Downloader.do.update_server(keyword, None) return True else: return False #------------------------------------------------------------------------------ def history_remove_failed(): """ Remove all failed jobs from history, including files """ logging.info('Scheduled removal of all failed jobs') history_db = get_history_handle() del_job_files(history_db.get_failed_paths()) history_db.remove_failed() history_db.close() del history_db SABnzbd-0.7.20/sabnzbd/articlecache.py0000644000000000000000000001372212433712602017636 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.articlecache - Article cache handling """ import logging import threading import sabnzbd from sabnzbd.decorators import synchronized from sabnzbd.constants import GIGI ARTICLE_LOCK = threading.Lock() class ArticleCache(object): do = None def __init__(self): self.__cache_limit_org = 0 self.__cache_limit = 0 self.__cache_size = 0 self.__article_list = [] # List of buffered articles self.__article_table = {} # Dict of buffered articles ArticleCache.do = self @synchronized(ARTICLE_LOCK) def cache_info(self): return (len(self.__article_list), self.__cache_size, self.__cache_limit_org) @synchronized(ARTICLE_LOCK) def new_limit(self, limit): """ Called when cache limit changes """ self.__cache_limit_org = limit if limit < 0: self.__cache_limit = GIGI else: self.__cache_limit = min(limit, GIGI) @synchronized(ARTICLE_LOCK) def save_article(self, article, data): nzf = article.nzf nzo = nzf.nzo if nzf.deleted or nzo.deleted: # Do not discard this article because the # file might still be processed at this moment!! if sabnzbd.LOG_ALL: logging.debug("%s would be discarded", article) # return saved_articles = article.nzf.nzo.saved_articles if article not in saved_articles: saved_articles.append(article) if self.__cache_limit: if self.__cache_limit < 0: self.__add_to_cache(article, data) else: data_size = len(data) while (self.__cache_size > (self.__cache_limit - data_size)) \ and self.__article_list: ## Flush oldest article in cache old_article = self.__article_list.pop(0) old_data = self.__article_table.pop(old_article) self.__cache_size -= len(old_data) ## No need to flush if this is a refreshment article if old_article != article: self.__flush_article(old_article, old_data) ## Does our article fit into our limit now? if (self.__cache_size + data_size) <= self.__cache_limit: self.__add_to_cache(article, data) else: self.__flush_article(article, data) else: self.__flush_article(article, data) @synchronized(ARTICLE_LOCK) def load_article(self, article): data = None nzo = article.nzf.nzo if article in self.__article_list: data = self.__article_table.pop(article) self.__article_list.remove(article) self.__cache_size -= len(data) if sabnzbd.LOG_ALL: logging.debug("Loaded %s from cache", article) elif article.art_id: data = sabnzbd.load_data(article.art_id, nzo.workpath, remove=True, do_pickle=False, silent=True) if article in nzo.saved_articles: nzo.saved_articles.remove(article) return data @synchronized(ARTICLE_LOCK) def flush_articles(self): self.__cache_size = 0 while self.__article_list: article = self.__article_list.pop(0) data = self.__article_table.pop(article) self.__flush_article(article, data) @synchronized(ARTICLE_LOCK) def purge_articles(self, articles): if sabnzbd.LOG_ALL: logging.debug("Purgable articles -> %s", articles) for article in articles: if article in self.__article_list: self.__article_list.remove(article) data = self.__article_table.pop(article) self.__cache_size -= len(data) if article.art_id: sabnzbd.remove_data(article.art_id, article.nzf.nzo.workpath) def __flush_article(self, article, data): nzf = article.nzf nzo = nzf.nzo if nzf.deleted or nzo.deleted: # Do not discard this article because the # file might still be processed at this moment!! if sabnzbd.LOG_ALL: logging.debug("%s would be discarded", article) # return art_id = article.get_art_id() if art_id: if sabnzbd.LOG_ALL: logging.debug("Flushing %s to disk", article) # Save data, but don't complain when destistation folder is missing # because this flush may come after completion of the NZO. sabnzbd.save_data(data, art_id, nzo.workpath, do_pickle = False, silent=True) else: logging.warning("Flushing %s failed -> no art_id", article) def __add_to_cache(self, article, data): if article in self.__article_table: self.__cache_size -= len(self.__article_table[article]) else: self.__article_list.append(article) self.__article_table[article] = data self.__cache_size += len(data) if sabnzbd.LOG_ALL: logging.debug("Added %s to cache", article) ### Create the instance ArticleCache() SABnzbd-0.7.20/sabnzbd/assembler.py0000644000000000000000000003735512433712602017214 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.assembler - threaded assembly/decoding of files """ import os import Queue import binascii import logging import struct import re from threading import Thread from time import sleep try: import hashlib new_md5 = hashlib.md5 except: import md5 new_md5 = md5.new import sabnzbd from sabnzbd.misc import get_filepath, sanitize_filename, get_unique_path, renamer, \ set_permissions, flag_file from sabnzbd.constants import QCHECK_FILE import sabnzbd.cfg as cfg from sabnzbd.articlecache import ArticleCache from sabnzbd.postproc import PostProcessor import sabnzbd.downloader from sabnzbd.utils.rarfile import RarFile, is_rarfile from sabnzbd.encoding import latin1, unicoder, is_utf8 from sabnzbd.rating import Rating #------------------------------------------------------------------------------ class Assembler(Thread): do = None # Link to the instance of this method def __init__(self, queue=None): Thread.__init__(self) if queue: self.queue = queue else: self.queue = Queue.Queue() Assembler.do = self def stop(self): self.process(None) def process(self, job): self.queue.put(job) def run(self): import sabnzbd.nzbqueue while 1: job = self.queue.get() if not job: logging.info("Shutting down") break nzo, nzf = job if nzf: sabnzbd.CheckFreeSpace() filename = sanitize_filename(nzf.filename) nzf.filename = filename dupe = nzo.check_for_dupe(nzf) filepath = get_filepath(cfg.download_dir.get_path(), nzo, filename) if filepath: logging.info('Decoding %s %s', filepath, nzf.type) try: filepath = _assemble(nzf, filepath, dupe) except IOError, (errno, strerror): if nzo.deleted: # Job was deleted, ignore error pass else: # 28 == disk full => pause downloader if errno == 28: logging.error(Ta('Disk full! Forcing Pause')) else: logging.error(Ta('Disk error on creating file %s'), latin1(filepath)) # Pause without saving sabnzbd.downloader.Downloader.do.pause(save=False) except: logging.error('Fatal error in Assembler', exc_info=True) break nzf.remove_admin() setname = nzf.setname if nzf.is_par2 and (nzo.md5packs.get(setname) is None): pack = GetMD5Hashes(filepath)[0] if pack: nzo.md5packs[setname] = pack logging.debug('Got md5pack for set %s', setname) if check_encrypted_rar(nzo, filepath): if cfg.pause_on_pwrar() == 1: logging.warning(Ta('WARNING: Paused job "%s" because of encrypted RAR file'), latin1(nzo.final_name)) nzo.pause() else: logging.warning(Ta('WARNING: Aborted job "%s" because of encrypted RAR file'), latin1(nzo.final_name)) nzo.fail_msg = T('Aborted, encryption detected') import sabnzbd.nzbqueue sabnzbd.nzbqueue.NzbQueue.do.end_job(nzo) unwanted = rar_contains_unwanted_file(filepath) if unwanted: logging.warning(Ta('WARNING: In "%s" unwanted extension in RAR file. Unwanted file is %s '), latin1(nzo.final_name), unwanted) logging.debug(Ta('Unwanted extension is in rar file %s'), filepath) if cfg.action_on_unwanted_extensions() == 1 and nzo.unwanted_ext == 0: logging.debug('Unwanted extension ... pausing') nzo.unwanted_ext = 1 nzo.pause() if cfg.action_on_unwanted_extensions() == 2: logging.debug('Unwanted extension ... aborting') nzo.fail_msg = T('Aborted, unwanted extension detected') import sabnzbd.nzbqueue sabnzbd.nzbqueue.NzbQueue.do.end_job(nzo) filter, reason = nzo_filtered_by_rating(nzo) if filter == 1: logging.warning(Ta('WARNING: Paused job "%s" because of rating (%s)'), latin1(nzo.final_name), reason) nzo.pause() elif filter == 2: logging.warning(Ta('WARNING: Aborted job "%s" because of rating (%s)'), latin1(nzo.final_name), reason) nzo.fail_msg = T('Aborted, rating filter matched (%s)') % reason import sabnzbd.nzbqueue sabnzbd.nzbqueue.NzbQueue.do.end_job(nzo) nzf.completed = True else: sabnzbd.nzbqueue.NzbQueue.do.remove(nzo.nzo_id, add_to_history=False, cleanup=False) PostProcessor.do.process(nzo) def _assemble(nzf, path, dupe): if os.path.exists(path): unique_path = get_unique_filename(path) if dupe: path = unique_path else: renamer(path, unique_path) fout = open(path, 'ab') if cfg.quick_check(): md5 = new_md5() else: md5 = None _type = nzf.type decodetable = nzf.decodetable for articlenum in decodetable: sleep(0.001) article = decodetable[articlenum] data = ArticleCache.do.load_article(article) if not data: logging.info(Ta('%s missing'), article) else: # yenc data already decoded, flush it out if _type == 'yenc': fout.write(data) if md5: md5.update(data) # need to decode uu data now elif _type == 'uu': data = data.split('\r\n') chunks = [] for line in data: if not line: continue if line == '-- ' or line.startswith('Posted via '): continue try: tmpdata = binascii.a2b_uu(line) chunks.append(tmpdata) except binascii.Error, msg: ## Workaround for broken uuencoders by ##/Fredrik Lundh nbytes = (((ord(line[0])-32) & 63) * 4 + 5) / 3 try: tmpdata = binascii.a2b_uu(line[:nbytes]) chunks.append(tmpdata) except binascii.Error, msg: logging.info('Decode failed in part %s: %s', article.article, msg) data = ''.join(chunks) fout.write(data) if md5: md5.update(data) fout.flush() fout.close() set_permissions(path) if md5: nzf.md5sum = md5.digest() del md5 return path def file_has_articles(nzf): """ Do a quick check to see if any articles are present for this file. Destructive: only to be used to differentiate between unknown encoding and no articles. """ has = False decodetable = nzf.decodetable for articlenum in decodetable: sleep(0.01) article = decodetable[articlenum] data = ArticleCache.do.load_article(article) if data: has = True return has # For a full description of the par2 specification, visit: # http://parchive.sourceforge.net/docs/specifications/parity-volume-spec/article-spec.html def GetMD5Hashes(fname, force=False): """ Get the hash table from a PAR2 file Return as dictionary, indexed on names and True for utf8-encoded names """ new_encoding = True table = {} if force or not flag_file(os.path.split(fname)[0], QCHECK_FILE): try: f = open(fname, 'rb') except: return table, new_encoding new_encoding = False try: header = f.read(8) while header: name, hash = ParseFilePacket(f, header) new_encoding |= is_utf8(name) if name: table[name] = hash header = f.read(8) except (struct.error, IndexError): logging.info('Cannot use corrupt par2 file for QuickCheck, "%s"', fname) table = {} except: logging.debug('QuickCheck parser crashed in file %s', fname) logging.info('Traceback: ', exc_info=True) table = {} f.close() return table, new_encoding def ParseFilePacket(f, header): """ Look up and analyse a FileDesc package """ nothing = None, None if header != 'PAR2\0PKT': return nothing # Length must be multiple of 4 and at least 20 len = struct.unpack(' 0) and (clean_keyword in filename) audio = cfg.rating_filter_abort_audio() if abort else cfg.rating_filter_pause_audio() video = cfg.rating_filter_abort_video() if abort else cfg.rating_filter_pause_video() spam = cfg.rating_filter_abort_spam() if abort else cfg.rating_filter_pause_spam() spam_confirm = cfg.rating_filter_abort_spam_confirm() if abort else cfg.rating_filter_pause_spam_confirm() encrypted = cfg.rating_filter_abort_encrypted() if abort else cfg.rating_filter_pause_encrypted() encrypted_confirm = cfg.rating_filter_abort_encrypted_confirm() if abort else cfg.rating_filter_pause_encrypted_confirm() downvoted = cfg.rating_filter_abort_downvoted() if abort else cfg.rating_filter_pause_downvoted() keywords = cfg.rating_filter_abort_keywords() if abort else cfg.rating_filter_pause_keywords() if (video > 0) and (rating.avg_video > 0) and (rating.avg_video <= video): return T('video') if (audio > 0) and (rating.avg_audio > 0) and (rating.avg_audio <= audio): return T('audio') if (spam and ((rating.avg_spam_cnt > 0) or rating.avg_encrypted_confirm)) or (spam_confirm and rating.avg_spam_confirm): return T('spam') if (encrypted and ((rating.avg_encrypted_cnt > 0) or rating.avg_encrypted_confirm)) or (encrypted_confirm and rating.avg_encrypted_confirm): return T('passworded') if downvoted and (rating.avg_vote_up < rating.avg_vote_down): return T('downvoted') if any(check_keyword(k) for k in keywords.split(',')): return T('keywords') return None SABnzbd-0.7.20/sabnzbd/bpsmeter.py0000644000000000000000000003416712433712602017056 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.bpsmeter - bpsmeter """ import time import logging import re import sabnzbd from sabnzbd.constants import BYTES_FILE_NAME import sabnzbd.cfg as cfg DAY = float(24*60*60) WEEK = DAY * 7 #------------------------------------------------------------------------------ def tomorrow(t): """ Return timestamp for tomorrow (midnight) """ now = time.localtime(t) ntime = (now[0], now[1], now[2], 0, 0, 0, now[6], now[7], now[8]) return time.mktime(ntime) + DAY def this_week(t): """ Return timestamp for start of this week (monday) """ while 1: tm = time.localtime(t) if tm.tm_wday == 0: break t -= DAY monday = (tm.tm_year, tm.tm_mon, tm.tm_mday, 0, 0, 0, 0, 0, tm.tm_isdst) return time.mktime(monday) def next_week(t): """ Return timestamp for start of next week (monday) """ return this_week(t) + WEEK def this_month(t): """ Return timestamp for start of next month """ now = time.localtime(t) ntime = (now[0], now[1], 1, 0, 0, 0, 0, 0, now[8]) return time.mktime(ntime) _DAYS = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) def last_month_day(tm): """ Return last day of this month """ year, month = tm[:2] day = _DAYS[month] # This simple formula for leap years is good enough if day == 28 and (year % 4) == 0: day = 29 return day def this_month_day(t=None): """ Return current day of the week, month 1..31 """ t = t or time.localtime(t) return time.localtime(t).tm_mday def this_week_day(t=None): """ Return current day of the week 1..7 """ t = t or time.localtime(t) return time.localtime(t).tm_wday + 1 def next_month(t): """ Return timestamp for start of next month """ now = time.localtime(t) month = now.tm_mon + 1 year = now.tm_year if month > 12: month = 1 year += 1 ntime = (year, month, 1, 0, 0, 0, 0, 0, now[8]) return time.mktime(ntime) class BPSMeter(object): do = None def __init__(self): t = time.time() self.start_time = t self.log_time = t self.last_update = t self.bps = 0.0 self.day_total = {} self.week_total = {} self.month_total = {} self.grand_total = {} self.end_of_day = tomorrow(t) # Time that current day will end self.end_of_week = next_week(t) # Time that current day will end self.end_of_month = next_month(t) # Time that current month will end self.q_day = 1 # Day of quota reset self.q_period = 'm' # Daily/Weekly/Monthly quota = d/w/m self.quota = self.left = 0.0 # Quota and remaining quota self.have_quota = False # Flag for quota active self.q_time = 0L # Next reset time for quota self.q_hour = 0 # Quota reset hour self.q_minute = 0 # Quota reset minute BPSMeter.do = self def save(self): """ Save admin to disk """ if self.grand_total or self.day_total or self.week_total or self.month_total: data = (self.last_update, self.grand_total, self.day_total, self.week_total, self.month_total, self.end_of_day, self.end_of_week, self.end_of_month, self.quota, self.left, self.q_time ) sabnzbd.save_admin(data, BYTES_FILE_NAME) def defaults(self): """ Get the latest data from the database and assign to a fake server """ logging.debug('Setting default BPS meter values') import sabnzbd.database history_db = sabnzbd.database.get_history_handle() grand, month, week = history_db.get_history_size() history_db.close() self.grand_total = {} self.month_total = {} self.week_total = {} self.day_total = {} if grand: self.grand_total['x'] = grand if month: self.month_total['x'] = month if week: self.week_total['x'] = week self.quota = self.left = cfg.quota_size.get_float() def read(self): """ Read admin from disk, return True when pause is needed """ res = False quota = self.left = cfg.quota_size.get_float() # Quota for this period self.have_quota = bool(cfg.quota_size()) data = sabnzbd.load_admin(BYTES_FILE_NAME) try: self.last_update, self.grand_total, \ self.day_total, self.week_total, self.month_total, \ self.end_of_day, self.end_of_week, self.end_of_month = data[:8] if len(data) == 11: self.quota, self.left, self.q_time = data[8:] logging.debug('Read quota q=%s l=%s reset=%s', self.quota, self.left, self.q_time) if abs(quota - self.quota) > 0.5: self.change_quota() else: self.quota = self.left = cfg.quota_size.get_float() res = self.reset_quota() except: self.defaults() # Force update of counters and validate data try: for server in self.grand_total: self.update(server) except TypeError: self.defaults() self.update() return res def update(self, server=None, amount=0, testtime=None): """ Update counters for "server" with "amount" bytes """ if testtime: t = testtime else: t = time.time() if t > self.end_of_day: # current day passed. get new end of day self.day_total = {} self.end_of_day = tomorrow(t) - 1.0 if t > self.end_of_week: self.week_total = {} self.end_of_week = next_week(t) - 1.0 if t > self.end_of_month: self.month_total = {} self.end_of_month = next_month(t) - 1.0 if server: if server not in self.day_total: self.day_total[server] = 0L self.day_total[server] += amount if server not in self.week_total: self.week_total[server] = 0L self.week_total[server] += amount if server not in self.month_total: self.month_total[server] = 0L self.month_total[server] += amount if server not in self.grand_total: self.grand_total[server] = 0L self.grand_total[server] += amount # Quota check if self.have_quota: self.left -= amount if self.left <= 0.0: from sabnzbd.downloader import Downloader if Downloader.do and not Downloader.do.paused: Downloader.do.pause() logging.warning(Ta('Quota spent, pausing downloading')) # Speedometer try: self.bps = (self.bps * (self.last_update - self.start_time) + amount) / (t - self.start_time) except: self.bps = 0.0 self.last_update = t check_time = t - 5.0 if self.start_time < check_time: self.start_time = check_time if self.bps < 0.01: self.reset() elif self.log_time < check_time: logging.debug("bps: %s", self.bps) self.log_time = t def reset(self): t = time.time() self.start_time = t self.log_time = t self.last_update = t self.bps = 0.0 def get_sums(self): """ return tuple of grand, month, week, day totals """ return (sum([v for v in self.grand_total.values()]), sum([v for v in self.month_total.values()]), sum([v for v in self.week_total.values()]), sum([v for v in self.day_total.values()]) ) def amounts(self, server): """ Return grand, month, week, day totals for specified server """ return self.grand_total.get(server, 0L), \ self.month_total.get(server, 0L), \ self.week_total.get(server, 0L), \ self.day_total.get(server, 0L) def clear_server(self, server): """ Clean counters for specified server """ if server in self.day_total: del self.day_total[server] if server in self.week_total : del self.week_total[server] if server in self.month_total: del self.month_total[server] if server in self.grand_total: del self.grand_total[server] def get_bps(self): return self.bps def reset_quota(self, force=False): """ Check if it's time to reset the quota, optionally resuming Return True, when still paused """ if force or (self.have_quota and time.time() > (self.q_time - 50)): self.quota = self.left = cfg.quota_size.get_float() logging.info('Quota was reset to %s', self.quota) if cfg.quota_resume(): logging.info('Auto-resume due to quota reset') if sabnzbd.downloader.Downloader.do: sabnzbd.downloader.Downloader.do.resume() self.next_reset() return False else: return True def next_reset(self, t=None): """ Determine next reset time """ t = t or time.time() tm = time.localtime(t) if self.q_period == 'd': nx = (tm[0], tm[1], tm[2], self.q_hour, self.q_minute, 0, 0, 0, tm[8]) if (tm.tm_hour * 60 + tm.tm_min) >= (self.q_hour * 60 + self.q_minute): # If today's moment has passed, it will happen tomorrow t = time.mktime(nx) + 24 * 3600 tm = time.localtime(t) elif self.q_period == 'w': if self.q_day < tm.tm_wday+1 or (self.q_day == tm.tm_wday+1 and (tm.tm_hour * 60 + tm.tm_min) >= (self.q_hour * 60 + self.q_minute)): tm = time.localtime(next_week(t)) dif = abs(self.q_day - tm.tm_wday - 1) t = time.mktime(tm) + dif * 24 * 3600 tm = time.localtime(t) elif self.q_period == 'm': if self.q_day < tm.tm_mday or (self.q_day == tm.tm_mday and (tm.tm_hour * 60 + tm.tm_min) >= (self.q_hour * 60 + self.q_minute)): tm = time.localtime(next_month(t)) day = min(last_month_day(tm), self.q_day) tm = (tm[0], tm[1], day, self.q_hour, self.q_minute, 0, 0, 0, tm[8]) else: return tm = (tm[0], tm[1], tm[2], self.q_hour, self.q_minute, 0, 0, 0, tm[8]) self.q_time = time.mktime(tm) logging.debug('Will reset quota at %s', tm) def change_quota(self, allow_resume=True): """ Update quota, potentially pausing downloader """ if not self.have_quota and self.quota < 0.5: # Never set, use last period's size per = cfg.quota_period() sums = self.get_sums() if per == 'd': self.left = sums[3] elif per == 'w': self.left = sums[2] elif per == 'm': self.left = sums[1] self.have_quota = bool(cfg.quota_size()) if self.have_quota: quota = cfg.quota_size.get_float() if self.quota: # Quota change, recalculate amount left self.left = quota - (self.quota - self.left) else: # If previously no quota, self.left holds this period's usage self.left = quota - self.left self.quota = quota else: self.quota = self.left = 0L self.update(0) self.next_reset() if self.left > 0.5: from sabnzbd.downloader import Downloader if allow_resume and cfg.quota_resume() and Downloader.do and Downloader.do.paused: Downloader.do.resume() # Pattern = # The and part can both be optional __re_day = re.compile('^\s*(\d+)[^:]*') __re_hm = re.compile('(\d+):(\d+)\s*$') def get_quota(self): """ If quota active, return check-function, hour, minute """ if self.have_quota: self.q_period = cfg.quota_period()[0].lower() self.q_day = 1 self.q_hour = self.q_minute = 0 txt = cfg.quota_day().lower() m = self.__re_day.search(txt) if m: self.q_day = int(m.group(1)) m = self.__re_hm.search(txt) if m: self.q_hour = int(m.group(1)) self.q_minute = int(m.group(2)) if self.q_period == 'w': self.q_day = max(1, self.q_day) self.q_day = min(7, self.q_day) elif self.q_period == 'm': self.q_day = max(1, self.q_day) self.q_day = min(31, self.q_day) else: self.q_day = 1 self.change_quota(allow_resume=False) return quota_handler, self.q_hour, self.q_minute else: return None, 0, 0 def midnight(self): """ Midnight action: dummy update for all servers """ for server in self.day_total: self.update(server) def quota_handler(): """ To be called from scheduler """ logging.debug('Checking quota') BPSMeter.do.reset_quota() def midnight_action(): if BPSMeter.do: BPSMeter.do.midnight() BPSMeter() SABnzbd-0.7.20/sabnzbd/cfg.py0000644000000000000000000003627512433712602015776 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.cfg - Configuration Parameters """ import re import sabnzbd from sabnzbd.constants import DEF_HOST, DEF_PORT_WIN_SSL, DEF_PORT_WIN, DEF_STDINTF, \ DEF_DOWNLOAD_DIR, DEF_NZBBACK_DIR, DEF_PORT_UNIX_SSL, \ NORMAL_PRIORITY, DEF_SCANRATE, DEF_PORT_UNIX, DEF_COMPLETE_DIR, \ DEF_ADMIN_DIR, NOTIFY_KEYS from sabnzbd.config import OptionBool, OptionNumber, OptionPassword, \ OptionDir, OptionStr, OptionList, no_nonsense, \ validate_octal, validate_safedir, validate_dir_exists, \ create_api_key, validate_notempty #------------------------------------------------------------------------------ # Email validation support # RE_VAL = re.compile('[^@ ]+@[^.@ ]+\.[^.@ ]') def validate_email(value): global email_endjob, email_full, email_rss if email_endjob() or email_full() or email_rss(): if isinstance(value, list): values = value else: values = [value] for addr in values: if not (addr and RE_VAL.match(addr)): return T('%s is not a valid email address') % addr, None return None, value def validate_server(value): """ Check if server non-empty""" global email_endjob, email_full, email_rss if value == '' and (email_endjob() or email_full() or email_rss()): return T('Server address required'), None else: return None, value #------------------------------------------------------------------------------ if sabnzbd.WIN32: DEF_FOLDER_MAX = 128 else: DEF_FOLDER_MAX = 256 #------------------------------------------------------------------------------ # Configuration instances # quick_check = OptionBool('misc', 'quick_check', True) fail_on_crc = OptionBool('misc', 'fail_on_crc', True) send_group = OptionBool('misc', 'send_group', False) sfv_check = OptionBool('misc', 'sfv_check', True) email_server = OptionStr('misc', 'email_server', validation=validate_server) email_to = OptionList('misc', 'email_to', validation=validate_email) email_from = OptionStr('misc', 'email_from', validation=validate_email) email_account = OptionStr('misc', 'email_account') email_pwd = OptionPassword('misc', 'email_pwd') email_endjob = OptionNumber('misc', 'email_endjob', 0, 0, 2) email_full = OptionBool('misc', 'email_full', False) email_dir = OptionDir('misc', 'email_dir', create=True) email_rss = OptionBool('misc', 'email_rss', False) version_check = OptionNumber('misc', 'check_new_rel', 1) autobrowser = OptionBool('misc', 'auto_browser', True) replace_illegal = OptionBool('misc', 'replace_illegal', True) pre_script = OptionStr('misc', 'pre_script', 'None') start_paused = OptionBool('misc', 'start_paused', False) enable_unrar = OptionBool('misc', 'enable_unrar', True) enable_unzip = OptionBool('misc', 'enable_unzip', True) enable_recursive = OptionBool('misc', 'enable_recursive', True) enable_filejoin = OptionBool('misc', 'enable_filejoin', True) enable_tsjoin = OptionBool('misc', 'enable_tsjoin', True) enable_par_cleanup = OptionBool('misc', 'enable_par_cleanup', True) never_repair = OptionBool('misc', 'never_repair', False) ignore_unrar_dates = OptionBool('misc', 'ignore_unrar_dates', False) overwrite_files = OptionBool('misc', 'overwrite_files', False) flat_unpack = OptionBool('misc', 'flat_unpack', False) par_option = OptionStr('misc', 'par_option', '', validation=no_nonsense) nice = OptionStr('misc', 'nice', '', validation=no_nonsense) ionice = OptionStr('misc', 'ionice', '', validation=no_nonsense) ignore_wrong_unrar = OptionBool('misc', 'ignore_wrong_unrar', False) par2_multicore = OptionBool('misc', 'par2_multicore', True) allow_64bit_tools = OptionBool('misc', 'allow_64bit_tools', True) allow_streaming = OptionBool('misc', 'allow_streaming', False) pre_check = OptionBool('misc', 'pre_check', False) fail_hopeless = OptionBool('misc', 'fail_hopeless', False) req_completion_rate = OptionNumber('misc', 'req_completion_rate', 100.2, 100, 200) newzbin_username = OptionStr('newzbin', 'username') newzbin_password = OptionPassword('newzbin', 'password') newzbin_bookmarks = OptionBool('newzbin', 'bookmarks', False) newzbin_unbookmark = OptionBool('newzbin', 'unbookmark', True) bookmark_rate = OptionNumber('newzbin', 'bookmark_rate', 60, minval=15, maxval=24*60) newzbin_url = OptionStr('newzbin', 'url', 'www.newzbin2.es') rating_enable = OptionBool('misc', 'rating_enable', False) rating_host = OptionStr('misc', 'rating_host', 'api.oznzb.com') rating_api_key = OptionStr('misc', 'rating_api_key') rating_feedback = OptionBool('misc', 'rating_feedback', True) rating_filter_enable = OptionBool('misc', 'rating_filter_enable', False) rating_filter_abort_audio = OptionNumber('misc', 'rating_filter_abort_audio', 0) rating_filter_abort_video = OptionNumber('misc', 'rating_filter_abort_video', 0) rating_filter_abort_encrypted = OptionBool('misc', 'rating_filter_abort_encrypted', False) rating_filter_abort_encrypted_confirm = OptionBool('misc', 'rating_filter_abort_encrypted_confirm', False) rating_filter_abort_spam = OptionBool('misc', 'rating_filter_abort_spam', False) rating_filter_abort_spam_confirm = OptionBool('misc', 'rating_filter_abort_spam_confirm', False) rating_filter_abort_downvoted = OptionBool('misc', 'rating_filter_abort_downvoted', False) rating_filter_abort_keywords = OptionStr('misc', 'rating_filter_abort_keywords') rating_filter_pause_audio = OptionNumber('misc', 'rating_filter_pause_audio', 0) rating_filter_pause_video = OptionNumber('misc', 'rating_filter_pause_video', 0) rating_filter_pause_encrypted = OptionBool('misc', 'rating_filter_pause_encrypted', False) rating_filter_pause_encrypted_confirm = OptionBool('misc', 'rating_filter_pause_encrypted_confirm', False) rating_filter_pause_spam = OptionBool('misc', 'rating_filter_pause_spam', False) rating_filter_pause_spam_confirm = OptionBool('misc', 'rating_filter_pause_spam_confirm', False) rating_filter_pause_downvoted = OptionBool('misc', 'rating_filter_pause_downvoted', False) rating_filter_pause_keywords = OptionStr('misc', 'rating_filter_pause_keywords') top_only = OptionBool('misc', 'top_only', False) autodisconnect = OptionBool('misc', 'auto_disconnect', True) queue_complete = OptionStr('misc', 'queue_complete') queue_complete_pers = OptionBool('misc', 'queue_complete_pers', False) replace_spaces = OptionBool('misc', 'replace_spaces', False) replace_dots = OptionBool('misc', 'replace_dots', False) no_dupes = OptionNumber('misc', 'no_dupes', 0) ignore_samples = OptionNumber('misc', 'ignore_samples', 0, 0, 2) create_group_folders = OptionBool('misc', 'create_group_folders', False) auto_sort = OptionBool('misc', 'auto_sort', False) folder_rename = OptionBool('misc', 'folder_rename', True) folder_max_length = OptionNumber('misc', 'folder_max_length', DEF_FOLDER_MAX, 20, 65000) pause_on_pwrar = OptionBool('misc', 'pause_on_pwrar', True) prio_sort_list = OptionList('misc', 'prio_sort_list') enable_meta = OptionBool('misc', 'enable_meta', True) safe_postproc = OptionBool('misc', 'safe_postproc', True) empty_postproc = OptionBool('misc', 'empty_postproc', False) pause_on_post_processing = OptionBool('misc', 'pause_on_post_processing', False) ampm = OptionBool('misc', 'ampm', False) rss_filenames = OptionBool('misc', 'rss_filenames', False) rss_odd_titles = OptionList('misc', 'rss_odd_titles', ['nzbindex.nl/', 'nzbindex.com/', 'nzbclub.com/']) schedules = OptionList('misc', 'schedlines') enable_tv_sorting = OptionBool('misc', 'enable_tv_sorting', False) tv_sort_string = OptionStr('misc', 'tv_sort_string') tv_sort_countries = OptionNumber('misc', 'tv_sort_countries', 1) tv_categories = OptionList('misc', 'tv_categories', '') movie_rename_limit = OptionStr('misc', 'movie_rename_limit', '100M') enable_movie_sorting = OptionBool('misc', 'enable_movie_sorting', False) movie_sort_string = OptionStr('misc', 'movie_sort_string') movie_sort_extra = OptionStr('misc', 'movie_sort_extra', '-cd%1', strip=False) movie_extra_folders = OptionBool('misc', 'movie_extra_folder', False) movie_categories = OptionList('misc', 'movie_categories', ['movies']) enable_date_sorting = OptionBool('misc', 'enable_date_sorting', False) date_sort_string = OptionStr('misc', 'date_sort_string') date_categories = OptionStr('misc', 'date_categories', ['tv']) matrix_username = OptionStr('nzbmatrix', 'username') matrix_apikey = OptionStr('nzbmatrix', 'apikey') matrix_del_bookmark = OptionBool('nzbmatrix', 'del_bookmark', True) xxx_username = OptionStr('nzbxxx', 'username') xxx_apikey = OptionStr('nzbxxx', 'apikey') configlock = OptionBool('misc', 'config_lock', 0) umask = OptionStr('misc', 'permissions', '', validation=validate_octal) download_dir = OptionDir('misc', 'download_dir', DEF_DOWNLOAD_DIR, create=False, validation=validate_safedir) download_free = OptionStr('misc', 'download_free') complete_dir = OptionDir('misc', 'complete_dir', DEF_COMPLETE_DIR, create=False, \ apply_umask=True, validation=validate_notempty) script_dir = OptionDir('misc', 'script_dir', create=True) nzb_backup_dir = OptionDir('misc', 'nzb_backup_dir', DEF_NZBBACK_DIR) cache_dir = OptionDir('misc', 'cache_dir', 'cache', create=False, validation=validate_safedir) admin_dir = OptionDir('misc', 'admin_dir', DEF_ADMIN_DIR, validation=validate_safedir) #log_dir = OptionDir('misc', 'log_dir', 'logs') dirscan_dir = OptionDir('misc', 'dirscan_dir', create=False) dirscan_speed = OptionNumber('misc', 'dirscan_speed', DEF_SCANRATE, 0, 3600) size_limit = OptionStr('misc', 'size_limit', '0') password_file = OptionDir('misc', 'password_file', '', create=False) fsys_type = OptionNumber('misc', 'fsys_type', 0, 0, 2) wait_for_dfolder = OptionBool('misc', 'wait_for_dfolder', False) warn_empty_nzb = OptionBool('misc', 'warn_empty_nzb', True) sanitize_safe = OptionBool('misc', 'sanitize_safe', False) cherryhost = OptionStr('misc', 'host', DEF_HOST) if sabnzbd.WIN32: cherryport = OptionStr('misc', 'port', DEF_PORT_WIN) else: cherryport = OptionStr('misc', 'port', DEF_PORT_UNIX) if sabnzbd.WIN32: https_port = OptionStr('misc', 'https_port', DEF_PORT_WIN_SSL) else: https_port = OptionStr('misc', 'https_port', DEF_PORT_UNIX_SSL) username = OptionStr('misc', 'username') password = OptionPassword('misc', 'password') login_realm = OptionStr('misc', 'login_realm', 'SABnzbd') bandwidth_limit = OptionNumber('misc', 'bandwidth_limit', 0) refresh_rate = OptionNumber('misc', 'refresh_rate', 0) rss_rate = OptionNumber('misc', 'rss_rate', 60, 15, 24*60) cache_limit = OptionStr('misc', 'cache_limit') web_dir = OptionStr('misc', 'web_dir', DEF_STDINTF) web_dir2 = OptionStr('misc', 'web_dir2') web_color = OptionStr('misc', 'web_color', '') web_color2 = OptionStr('misc', 'web_color2') cleanup_list = OptionList('misc', 'cleanup_list') warned_old_queue = OptionBool('misc', 'warned_old_queue', False) unwanted_extensions = OptionList('misc', 'unwanted_extensions') action_on_unwanted_extensions = OptionNumber('misc', 'action_on_unwanted_extensions', 0) log_web = OptionBool('logging', 'enable_cherrypy_logging', False) log_dir = OptionDir('misc', 'log_dir', 'logs', validation=validate_notempty) log_level = OptionNumber('logging', 'log_level', 1, -1, 2) log_size = OptionStr('logging', 'max_log_size', '5242880') log_backups = OptionNumber('logging', 'log_backups', 5, 1, 1024) log_new = OptionBool('logging', 'log_new', False) https_cert = OptionDir('misc', 'https_cert', 'server.cert', create=False) https_key = OptionDir('misc', 'https_key', 'server.key', create=False) https_chain = OptionDir('misc','https_chain', create=False) enable_https = OptionBool('misc', 'enable_https', False) language = OptionStr('misc', 'language', 'en') ssl_type = OptionStr('misc', 'ssl_type', 'v23') unpack_check = OptionBool('misc', 'unpack_check', True) no_penalties = OptionBool('misc', 'no_penalties', False) randomize_server_ip = OptionBool('misc', 'randomize_server_ip', False) ipv6_servers = OptionNumber('misc', 'ipv6_servers', 1, 0, 2) # Internal options, not saved in INI file debug_delay = OptionNumber('misc', 'debug_delay', 0, add=False) api_key = OptionStr('misc', 'api_key', create_api_key()) nzb_key = OptionStr('misc', 'nzb_key', create_api_key()) disable_key = OptionBool('misc', 'disable_api_key', False) api_warnings = OptionBool('misc', 'api_warnings', True) local_range = OptionStr('misc', 'local_range') max_art_tries = OptionNumber('misc', 'max_art_tries', 3, 2) max_art_opt = OptionBool('misc', 'max_art_opt', False) use_pickle = OptionBool('misc', 'use_pickle', False) no_ipv6 = OptionBool('misc', 'no_ipv6', False) growl_server = OptionStr('growl', 'growl_server') growl_password = OptionPassword('growl', 'growl_password') growl_enable = OptionBool('growl', 'growl_enable', not sabnzbd.DARWIN_ML) ntfosd_enable = OptionBool('growl', 'ntfosd_enable', not sabnzbd.WIN32 and not sabnzbd.DARWIN) ncenter_enable = OptionBool('growl', 'ncenter_enable', sabnzbd.DARWIN) notify_classes = OptionList('growl', 'notify_classes', NOTIFY_KEYS) quota_size = OptionStr('misc', 'quota_size') quota_day = OptionStr('misc', 'quota_day') quota_resume = OptionBool('misc', 'quota_resume', False) quota_period = OptionStr('misc', 'quota_period', 'm') osx_menu = OptionBool('misc', 'osx_menu', True) osx_speed = OptionBool('misc', 'osx_speed', True) keep_awake = OptionBool('misc', 'keep_awake', True) win_menu = OptionBool('misc', 'win_menu', True) uniconfig = OptionBool('misc', 'uniconfig', True) allow_incomplete_nzb = OptionBool('misc', 'allow_incomplete_nzb', False) marker_file = OptionStr('misc', 'nomedia_marker', '') wait_ext_drive = OptionNumber('misc', 'wait_ext_drive', 5, 1, 60) history_limit = OptionNumber('misc', 'history_limit', 50, 0) show_sysload = OptionNumber('misc', 'show_sysload', 2, 0, 2) web_watchdog = OptionBool('misc', 'web_watchdog', False) warn_dupl_jobs = OptionBool('misc', 'warn_dupl_jobs', True) new_nzb_on_failure = OptionBool('misc', 'new_nzb_on_failure', False) #------------------------------------------------------------------------------ # Set root folders for Folder config-items # def set_root_folders(home, lcldata): email_dir.set_root(home) download_dir.set_root(home) complete_dir.set_root(home) script_dir.set_root(home) nzb_backup_dir.set_root(lcldata) cache_dir.set_root(lcldata) admin_dir.set_root(lcldata) dirscan_dir.set_root(home) log_dir.set_root(lcldata) password_file.set_root(home) def set_root_folders2(): https_cert.set_root(admin_dir.get_path()) https_key.set_root(admin_dir.get_path()) https_chain.set_root(admin_dir.get_path()) SABnzbd-0.7.20/sabnzbd/config.py0000644000000000000000000007651212433712602016502 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.config - Configuration Support """ import os import logging import threading import shutil import sabnzbd.misc from sabnzbd.constants import CONFIG_VERSION, NORMAL_PRIORITY, DEFAULT_PRIORITY from sabnzbd.utils import listquote from sabnzbd.utils import configobj from sabnzbd.decorators import synchronized CONFIG_LOCK = threading.Lock() SAVE_CONFIG_LOCK = threading.Lock() CFG = {} # Holds INI structure # uring re-write this variable is global allow # direct access to INI structure database = {} # Holds the option dictionary modified = False # Signals a change in option dictionary # Should be reset after saving to settings file class Option(object): """ Basic option class, basic fields """ def __init__(self, section, keyword, default_val=None, add=True): """ Basic option section : single section or comma-separated list of sections a list will be a hierarchy: "foo, bar" --> [foo][[bar]] keyword : keyword in the (last) section default_val : value returned when no value has been set callback : procedure to call when value is succesfully changed """ self.__sections = section.split(',') self.__keyword = keyword self.__default_val = default_val self.__value = None self.__callback = None # Add myself to the config dictionary if add: global database anchor = database for section in self.__sections: if section not in anchor: anchor[section] = {} anchor = anchor[section] anchor[keyword] = self def __call__(self): """ get() replacement """ return self.get() def get(self): """ Retrieve value field """ if self.__value != None: return self.__value else: return self.__default_val def get_string(self): return str(self.get()) def get_dict(self, safe=False): """ Return value a dictionary """ return { self.__keyword : self.get() } def set_dict(self, dict): """ Set value based on dictionary """ try: return self.set(dict['value']) except KeyError: return False def __set(self, value): """ Set new value, no validation """ global modified if (value != None): if type(value) == type([]) or type(value) == type({}) or value != self.__value: self.__value = value modified = True if self.__callback: self.__callback() return None def set(self, value): return self.__set(value) def default(self): return self.__default_val def callback(self, callback): """ Set callback function """ self.__callback = callback def ident(self): """ Return section-list and keyword """ return self.__sections, self.__keyword class OptionNumber(Option): """ Numeric option class, int/float is determined from default value """ def __init__(self, section, keyword, default_val=0, minval=None, maxval=None, validation=None, add=True): Option.__init__(self, section, keyword, default_val, add=add) self.__minval = minval self.__maxval = maxval self.__validation = validation self.__int = type(default_val) == type(0) def set(self, value): """ set new value, limited by range """ if value != None: try: if self.__int: value = int(value) else: value = float(value) except ValueError: value = self._Option__default_val if self.__validation: error, val = self.__validation(value) self._Option__set(val) else: if (self.__maxval != None) and value > self.__maxval: value = self.__maxval elif (self.__minval != None) and value < self.__minval: value = self.__minval self._Option__set(value) return None class OptionBool(Option): """ Boolean option class """ def __init__(self, section, keyword, default_val=False, add=True): Option.__init__(self, section, keyword, int(default_val), add=add) def set(self, value): if value is None: value = 0 try: self._Option__set(int(value)) except ValueError: self._Option__set(0) return None class OptionDir(Option): """ Directory option class """ def __init__(self, section, keyword, default_val='', apply_umask=False, create=True, validation=None, add=True): self.__validation = validation self.__root = '' # Base directory for relative paths self.__apply_umask = apply_umask self.__create = create Option.__init__(self, section, keyword, default_val, add=add) def get_path(self): """ Return full absolute path """ value = self.get() path = '' if value: path = sabnzbd.misc.real_path(self.__root, value) if self.__create and not os.path.exists(path): res, path = sabnzbd.misc.create_real_path(self.ident()[1], self.__root, value, self.__apply_umask) return path def test_path(self): """ Return True if path exists """ value = self.get() if value: return os.path.exists(sabnzbd.misc.real_path(self.__root, value)) else: return False def set_root(self, root): """ Set new root, is assumed to be valid """ self.__root = root def set(self, value, create=False): """ Set new dir value, validate and create if needed Return None when directory is accepted Return error-string when not accepted, value will not be changed 'create' means try to create (but don't set permanent create flag) """ error = None if value != None and (create or value != self.get()): value = value.strip() if self.__validation: error, value = self.__validation(self.__root, value, self._Option__default_val) if not error: if value and (self.__create or create): res, path = sabnzbd.misc.create_real_path(self.ident()[1], self.__root, value, self.__apply_umask) if not res: error = Ta("Cannot create %s folder %s") % (self.ident()[1], path) if not error: self._Option__set(value) return error def set_create(self, value): """ Set auto-creation value """ self.__create = value class OptionList(Option): """ List option class """ def __init__(self, section, keyword, default_val=None, validation=None, add=True): self.__validation = validation if default_val is None: default_val = [] Option.__init__(self, section, keyword, default_val, add=add) def set(self, value): """ Set the list given a comma-separated string or a list""" error = None if value is not None: if not isinstance(value, list): if '"' not in value and ',' not in value: value = value.split() else: value = listquote.simplelist(value) if self.__validation: error, value = self.__validation(value) if not error: self._Option__set(value) return error def get_string(self): """ Return the list as a comma-separated string """ lst = self.get() if type(lst) == type(""): return lst txt = '' r = len(lst) for n in xrange(r): txt += lst[n] if n < r-1: txt += ', ' return txt class OptionStr(Option): """ String class """ def __init__(self, section, keyword, default_val='', validation=None, add=True, strip=True): Option.__init__(self, section, keyword, default_val, add=add) self.__validation = validation self.__strip = strip def get_float(self): """ Return value converted to a float, allowing KMGT notation """ return sabnzbd.misc.from_units(self.get()) def get_int(self): """ Return value converted to an int, allowing KMGT notation """ return int(self.get_float()) def set(self, value): """ Set stripped value """ error = None if type(value) == type('') and self.__strip: value = value.strip() if self.__validation: error, val = self.__validation(value) self._Option__set(val) else: self._Option__set(value) return error class OptionPassword(Option): """ Password class """ def __init__(self, section, keyword, default_val='', add=True): Option.__init__(self, section, keyword, default_val, add=add) self.get_string = self.get_stars def get(self): """ Return decoded password """ value = self._Option__value if value is None: return self._Option__default_val else: return decode_password(value, self.ident()) def get_stars(self): """ Return decoded password as asterisk string """ return '*' * len(decode_password(self.get(), self.ident())) def get_dict(self, safe=False): """ Return value a dictionary """ if safe: return { self._Option__keyword : self.get_stars() } else: return { self._Option__keyword : self.get() } def set(self, pw): """ Set password, encode it """ if (pw != None and pw == '') or (pw and pw.strip('*')): self._Option__set(encode_password(pw)) return None @synchronized(CONFIG_LOCK) def add_to_database(section, keyword, obj): """ add object as secion/keyword to INI database """ global database if section not in database: database[section] = {} database[section][keyword] = obj @synchronized(CONFIG_LOCK) def delete_from_database(section, keyword): """ Remove section/keyword from INI database """ global database, CFG, modified del database[section][keyword] if section == 'servers' and '[' in keyword: keyword = keyword.replace('[', '{').replace(']', '}') try: del CFG[section][keyword] except KeyError: pass modified = True class ConfigServer(object): """ Class defining a single server """ def __init__(self, name, values): self.__name = name name = 'servers,' + self.__name self.host = OptionStr(name, 'host', '', add=False) self.port = OptionNumber(name, 'port', 119, 0, 2**16-1, add=False) self.timeout = OptionNumber(name, 'timeout', 120, 30, 240, add=False) self.username = OptionStr(name, 'username', '', add=False) self.password = OptionPassword(name, 'password', '', add=False) self.connections = OptionNumber(name, 'connections', 1, 0, 100, add=False) self.fillserver = OptionBool(name, 'fillserver', False, add=False) self.ssl = OptionBool(name, 'ssl', False, add=False) self.enable = OptionBool(name, 'enable', True, add=False) self.optional = OptionBool(name, 'optional', False, add=False) self.retention = OptionNumber(name, 'retention', add=False) self.set_dict(values) add_to_database('servers', self.__name, self) def set_dict(self, values): """ Set one or more fields, passed as dictionary """ for kw in ('host', 'port', 'timeout', 'username', 'password', 'connections', 'fillserver', 'ssl', 'enable', 'optional', 'retention'): try: value = values[kw] except KeyError: continue exec 'self.%s.set(value)' % kw return True def get_dict(self, safe=False): """ Return a dictionary with all attributes """ dict = {} dict['name'] = self.__name dict['host'] = self.host() dict['port'] = self.port() dict['timeout'] = self.timeout() dict['username'] = self.username() if safe: dict['password'] = self.password.get_stars() else: dict['password'] = self.password() dict['connections'] = self.connections() dict['fillserver'] = self.fillserver() dict['ssl'] = self.ssl() dict['enable'] = self.enable() dict['optional'] = self.optional() dict['retention'] = self.retention() return dict def delete(self): """ Remove from database """ delete_from_database('servers', self.__name) def rename(self, name): """ Give server new identity """ delete_from_database('servers', self.__name) self.__name = name add_to_database('servers', self.__name, self) def ident(self): return 'servers', self.__name class ConfigCat(object): """ Class defining a single category """ def __init__(self, name, values): self.__name = name name = 'categories,' + name self.pp = OptionStr(name, 'pp', '', add=False) self.script = OptionStr(name, 'script', 'Default', add=False) self.dir = OptionDir(name, 'dir', add=False, create=False) self.newzbin = OptionList(name, 'newzbin', add=False) self.priority = OptionNumber(name, 'priority', DEFAULT_PRIORITY, add=False) self.set_dict(values) add_to_database('categories', self.__name, self) def set_dict(self, values): """ Set one or more fields, passed as dictionary """ for kw in ('pp', 'script', 'dir', 'newzbin', 'priority'): try: value = values[kw] except KeyError: continue exec 'self.%s.set(value)' % kw return True def get_dict(self, safe=False): """ Return a dictionary with all attributes """ dict = {} dict['name'] = self.__name dict['pp'] = self.pp() dict['script'] = self.script() dict['dir'] = self.dir() dict['newzbin'] = self.newzbin.get_string() dict['priority'] = self.priority() return dict def delete(self): """ Remove from database """ delete_from_database('categories', self.__name) class OptionFilters(Option): """ Filter list class """ def __init__(self, section, keyword, add=True): Option.__init__(self, section, keyword, add=add) self.set([]) def move(self, current, new): """ Move filter from position 'current' to 'new' """ lst = self.get() try: item = lst.pop(current) lst.insert(new, item) except IndexError: return self.set(lst) def update(self, pos, value): """ Update filter 'pos' definition, value is a list Append if 'pos' outside list """ lst = self.get() try: lst[pos] = value except IndexError: lst.append(value) self.set(lst) def delete(self, pos): """ Remove filter 'pos' """ lst = self.get() try: lst.pop(pos) except IndexError: return self.set(lst) def get_dict(self, safe=False): """ Return filter list as a dictionary with keys 'filter[0-9]+' """ dict = {} n = 0 for filter in self.get(): dict['filter'+str(n)] = filter n = n + 1 return dict def set_dict(self, values): """ Create filter list from dictionary with keys 'filter[0-9]+' """ filters = [] for n in xrange(len(values)): kw = 'filter%d' % n val = values.get(kw) if val is not None: val = values[kw] if type(val) == type([]): filters.append(val) else: filters.append(listquote.simplelist(val)) while len(filters[-1]) < 7: filters[-1].append('1') if not filters[-1][6]: filters[-1][6] = '1' if filters: self.set(filters) return True class ConfigRSS(object): """ Class defining a single Feed definition """ def __init__(self, name, values): self.__name = name name = 'rss,' + name self.uri = OptionStr(name, 'uri', add=False) self.cat = OptionStr(name, 'cat', add=False) self.pp = OptionStr(name, 'pp', '', add=False) self.script = OptionStr(name, 'script', add=False) self.enable = OptionBool(name, 'enable', add=False) self.priority = OptionNumber(name, 'priority', DEFAULT_PRIORITY, DEFAULT_PRIORITY, 2, add=False) self.filters = OptionFilters(name, 'filters', add=False) self.filters.set([['', '', '', 'A', '*', DEFAULT_PRIORITY, '1']]) self.set_dict(values) add_to_database('rss', self.__name, self) def set_dict(self, values): """ Set one or more fields, passed as dictionary """ for kw in ('uri', 'cat', 'pp', 'script', 'priority', 'enable'): try: value = values[kw] except KeyError: continue exec 'self.%s.set(value)' % kw self.filters.set_dict(values) return True def get_dict(self, safe=False): """ Return a dictionary with all attributes """ dict = {} dict['name'] = self.__name dict['uri'] = self.uri() dict['cat'] = self.cat() dict['pp'] = self.pp() dict['script'] = self.script() dict['enable'] = self.enable() dict['priority'] = self.priority() filters = self.filters.get_dict() for kw in filters: dict[kw] = filters[kw] return dict def delete(self): """ Remove from database """ delete_from_database('rss', self.__name) def ident(self): return 'rss', self.__name def get_dconfig(section, keyword, nested=False): """ Return a config values dictonary, Single item or slices based on 'section', 'keyword' """ data = {} if not section: for section in database.keys(): res, conf = get_dconfig(section, None, True) data.update(conf) elif not keyword: try: sect = database[section] except KeyError: return False, {} if section in ('servers', 'categories', 'rss'): data[section] = [] for keyword in sect.keys(): res, conf = get_dconfig(section, keyword, True) data[section].append(conf) else: data[section] = {} for keyword in sect.keys(): res, conf = get_dconfig(section, keyword, True) data[section].update(conf) else: try: item = database[section][keyword] except KeyError: return False, {} data = item.get_dict(safe=True) if not nested: if section in ('servers', 'categories', 'rss'): data = {section : [ data ]} else: data = {section : data} return True, data def get_config(section, keyword): """ Return a config object, based on 'section', 'keyword' """ try: return database[section][keyword] except KeyError: logging.debug('Missing configuration item %s,%s', section, keyword) return None def set_config(kwargs): """ Set a config item, using values in dictionary """ try: item = database[kwargs.get('section')][kwargs.get('keyword')] except KeyError: return False item.set_dict(kwargs) return True def delete(section, keyword): """ Delete specific config item """ try: database[section][keyword].delete() except KeyError: return ################################################################################ # # INI file support # # This does input and output of configuration to an INI file. # It translates this data structure to the config database. @synchronized(SAVE_CONFIG_LOCK) def read_config(path): """ Read the complete INI file and check its version number if OK, pass values to config-database """ return _read_config(path) def _read_config(path, try_backup=False): """ Read the complete INI file and check its version number if OK, pass values to config-database """ global CFG, database, modified if try_backup or not os.path.exists(path): # Not found, try backup try: shutil.copyfile(path + '.bak', path) try_backup = True except IOError: pass if not os.path.exists(path): # No file found, create default INI file try: if not sabnzbd.WIN32: prev = os.umask(077) fp = open(path, "w") fp.write("__version__=%s\n[misc]\n[logging]\n" % CONFIG_VERSION) fp.close() if not sabnzbd.WIN32: os.umask(prev) except IOError: return False, 'Cannot create INI file %s' % path try: CFG = configobj.ConfigObj(path) try: if int(CFG['__version__']) > int(CONFIG_VERSION): return False, "Incorrect version number %s in %s" % (CFG['__version__'], path) except (KeyError, ValueError): CFG['__version__'] = CONFIG_VERSION except configobj.ConfigObjError, strerror: if try_backup: return False, '"%s" is not a valid configuration file
    Error message: %s' % (path, strerror) else: return _read_config(path, True) CFG['__version__'] = CONFIG_VERSION if 'misc' in CFG: compatibility_fix(CFG['misc']) if 'rss' in CFG: newzbin_fix(CFG['rss']) # Use CFG data to set values for all static options for section in database: if section not in ('servers', 'categories', 'rss'): for option in database[section]: sec, kw = database[section][option].ident() sec = sec[-1] try: database[section][option].set(CFG[sec][kw]) except KeyError: pass define_categories() define_rss() define_servers() modified = False return True, "" @synchronized(SAVE_CONFIG_LOCK) def save_config(force=False): """ Update Setup file with current option values """ global CFG, database, modified assert isinstance(CFG, configobj.ConfigObj) if not (modified or force): return True for section in database: if section in ('servers', 'categories', 'rss'): try: CFG[section] except KeyError: CFG[section] = {} for subsec in database[section]: if section == 'servers': subsec_mod = subsec.replace('[', '{').replace(']','}') else: subsec_mod = subsec try: CFG[section][subsec_mod] except KeyError: CFG[section][subsec_mod] = {} items = database[section][subsec].get_dict() CFG[section][subsec_mod] = items else: for option in database[section]: sec, kw = database[section][option].ident() sec = sec[-1] try: CFG[sec] except KeyError: CFG[sec] = {} value = database[section][option]() if type(value) == type(True): CFG[sec][kw] = str(int(value)) elif type(value) == type(0): CFG[sec][kw] = str(value) else: CFG[sec][kw] = value res = False filename = CFG.filename bakname = filename + '.bak' # Check if file is writable if not sabnzbd.misc.is_writable(filename): logging.error(Ta('Cannot write to INI file %s'), filename) return res # copy current file to backup try: shutil.copyfile(filename, bakname) except: # Something wrong with the backup, logging.warning(Ta('Cannot create backup file for %s'), bakname) logging.info("Traceback: ", exc_info = True) # Write new config file try: CFG.write() modified = False res = True except: logging.error(Ta('Cannot write to INI file %s'), filename) logging.info("Traceback: ", exc_info = True) return res def define_servers(): """ Define servers listed in the Setup file return a list of ConfigServer instances """ global CFG try: for server in CFG['servers']: svr = CFG['servers'][server] ConfigServer(server.replace('{', '[').replace('}', ']'), svr) except KeyError: pass def get_servers(): global database try: return database['servers'] except KeyError: return {} def define_categories(force=False): """ Define categories listed in the Setup file return a list of ConfigCat instances """ global CFG, categories try: for cat in CFG['categories']: ConfigCat(cat, CFG['categories'][cat]) except KeyError: pass def old_def(item, default): """ Get old INI setting from [misc], if missing use 'default' """ try: return CFG['misc'][item] except KeyError: return default def get_categories(cat=0): """ Return link to categories section. This section will always contain special category '*' When 'cat' is given, a link to that category or to '*' is returned """ global database if 'categories' not in database: database['categories'] = {} cats = database['categories'] if '*' not in cats: ConfigCat('*', {'pp' : old_def('dirscan_opts', '3'), 'script' : old_def('dirscan_script', 'None'), \ 'priority' : old_def('dirscan_priority', NORMAL_PRIORITY)}) save_config(True) if not isinstance(cat, int): try: cats = cats[cat] except KeyError: cats = cats['*'] return cats def define_rss(): """ Define rss-feeds listed in the Setup file return a list of ConfigRSS instances """ global CFG try: for r in CFG['rss']: ConfigRSS(r, CFG['rss'][r]) except KeyError: pass def get_rss(): global database try: return database['rss'] except KeyError: return {} def get_filename(): global CFG return CFG.filename ################################################################################ # # Default Validation handlers # __PW_PREFIX = '!!!encoded!!!' #------------------------------------------------------------------------------ def encode_password(pw): """ Encode password in hexadecimal if needed """ enc = False if pw: encPW = __PW_PREFIX for c in pw: cnum = ord(c) if c == '#' or cnum < 33 or cnum > 126: enc = True encPW += '%2x' % cnum if enc: return encPW return pw def decode_password(pw, name): """ Decode hexadecimal encoded password but only decode when prefixed """ decPW = '' if pw and pw.startswith(__PW_PREFIX): for n in range(len(__PW_PREFIX), len(pw), 2): try: ch = chr( int(pw[n] + pw[n+1], 16) ) except ValueError: logging.error(Ta('Incorrectly encoded password %s'), name) return '' decPW += ch return decPW else: return pw def no_nonsense(value): """ Strip and Filter out None and 'None' from strings """ value = str(value).strip() if value.lower() == 'none': value = '' return None, value def validate_octal(value): """ Check if string is valid octal number """ if not value: return None, value try: int(value, 8) return None, value except: return Ta('%s is not a correct octal value') % value, None def validate_no_unc(root, value, default): """ Check if path isn't a UNC path """ # Only need to check the 'value' part if value and not value.startswith(r'\\'): return validate_notempty(root, value, default) else: return Ta('UNC path "%s" not allowed here') % value, None def validate_safedir(root, value, default): """ Allow only when queues are empty and no UNC """ if sabnzbd.empty_queues(): return validate_no_unc(root, value, default) else: return Ta('Error: Queue not empty, cannot change folder.'), None def validate_dir_exists(root, value, default): """ Check if directory exists """ p = sabnzbd.misc.real_path(root, value) if os.path.exists(p): return None, value else: return Ta('Folder "%s" does not exist') % p, None def validate_notempty(root, value, default): """ If value is empty, return default """ if value: return None, value else: return None, default def create_api_key(): """ Return a new randomized API_KEY """ import time try: from hashlib import md5 except ImportError: from md5 import md5 import random # Create some values to seed md5 t = str(time.time()) r = str(random.random()) # Create the md5 instance and give it the current time m = md5(t) # Update the md5 instance with the random variable m.update(r) # Return a hex digest of the md5, eg 49f68a5c8493ec2c0bf489821c21fc3b return m.hexdigest() #------------------------------------------------------------------------------ _FIXES = \ ( ('bandwith_limit', 'bandwidth_limit'), ('enable_par_multicore', 'par2_multicore') ) def compatibility_fix(cf): """ Convert obsolete INI entries """ for item in _FIXES: old, new = item try: cf[new] except KeyError: try: cf[new] = cf[old] del cf[old] except KeyError: pass try: cf['rating_host'] = cf['rating_host'].replace('www.oznzb.com', 'api.oznzb.com') except KeyError: pass def newzbin_fix(cf): """ Replace old newzbin links """ for feed in cf: item = cf[feed].get('uri') if item and 'newzbin.com' in item: cf[feed]['uri'] = item.replace('newzbin.com', 'newzbin2.es') SABnzbd-0.7.20/sabnzbd/constants.py0000644000000000000000000001133512433712602017241 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. CONFIG_VERSION = 19 QUEUE_VERSION = 9 POSTPROC_QUEUE_VERSION = 1 PNFO_REPAIR_FIELD = 0 PNFO_UNPACK_FIELD = 1 PNFO_DELETE_FIELD = 2 PNFO_SCRIPT_FIELD = 3 PNFO_NZO_ID_FIELD = 4 PNFO_FILENAME_FIELD = 5 PNFO_UNPACKSTRHT_FIELD = 6 PNFO_MSGID_FIELD = 7 PNFO_EXTRA_FIELD1 = 8 PNFO_EXTRA_FIELD2 = 9 PNFO_BYTES_LEFT_FIELD = 10 PNFO_BYTES_FIELD = 11 PNFO_AVG_DATE_FIELD = 12 PNFO_FINISHED_FILES_FIELD = 13 PNFO_ACTIVE_FILES_FIELD = 14 PNFO_QUEUED_FILES_FIELD = 15 PNFO_STATUS_FIELD = 16 PNFO_PRIORITY_FIELD = 17 PNFO_MISSING_FIELD = 18 QNFO_BYTES_FIELD = 0 QNFO_BYTES_LEFT_FIELD = 1 QNFO_PNFO_LIST_FIELD = 2 QNFO_Q_SIZE_LIST_FIELD = 3 ANFO_ARTICLE_SUM_FIELD = 0 ANFO_CACHE_SIZE_FIELD = 1 ANFO_CACHE_LIMIT_FIELD = 2 GIGI = float(2 ** 30) MEBI = float(2 ** 20) KIBI = float(2 ** 10) BYTES_FILE_NAME = 'totals%s.sab' % QUEUE_VERSION QUEUE_FILE_TMPL = 'queue%s.sab' QUEUE_FILE_NAME = QUEUE_FILE_TMPL % QUEUE_VERSION POSTPROC_QUEUE_FILE_NAME = 'postproc%s.sab' % POSTPROC_QUEUE_VERSION RSS_FILE_NAME = 'rss_data.sab' BOOKMARK_FILE_NAME = 'bookmarks.sab' SCAN_FILE_NAME = 'watched_data.sab' TERM_FLAG_FILE = 'running.sab' FUTURE_Q_FOLDER = 'future' JOB_ADMIN = '__ADMIN__' VERIFIED_FILE = '__verified__' QCHECK_FILE = '__skip_qcheck__' RENAMES_FILE = '__renames__' ATTRIB_FILE = 'SABnzbd_attrib' REPAIR_REQUEST = 'repair-all.sab' DB_HISTORY_VERSION = 1 DB_QUEUE_VERSION = 1 DB_HISTORY_NAME = 'history%s.db' % DB_HISTORY_VERSION DB_QUEUE_NAME = 'queue%s.db' % DB_QUEUE_VERSION DEF_DOWNLOAD_DIR = 'Downloads/incomplete' DEF_COMPLETE_DIR = 'Downloads/complete' DEF_CACHE_DIR = 'cache' DEF_ADMIN_DIR = 'admin' DEF_LOG_DIR = 'logs' DEF_NZBBACK_DIR = '' DEF_LANGUAGE = 'locale' DEF_INTERFACES = 'interfaces' DEF_INT_LANGUAGE = 'locale' DEF_EMAIL_TMPL = 'email' DEF_STDCONFIG = 'Config' DEF_STDINTF = 'Plush' DEF_SKIN_COLORS = {'smpl':'white', 'classic':'darkblue', 'mobile':'light', 'plush' : 'gold'} DEF_MAIN_TMPL = 'templates/main.tmpl' DEF_INI_FILE = 'sabnzbd.ini' DEF_HOST = 'localhost' DEF_PORT_WIN = 8080 DEF_PORT_UNIX = 8080 DEF_PORT_WIN_SSL = 9090 DEF_PORT_UNIX_SSL= 9090 DEF_WORKDIR = 'sabnzbd' DEF_LOG_FILE = 'sabnzbd.log' DEF_LOG_ERRFILE = 'sabnzbd.error.log' DEF_LOG_CHERRY = 'cherrypy.log' DEF_TIMEOUT = 60 MIN_TIMEOUT = 10 MAX_TIMEOUT = 200 DEF_LOGLEVEL = 1 DEF_SCANRATE = 5 DEF_QRATE = 0 MIN_DECODE_QUEUE = 5 MAX_DECODE_QUEUE = 10 MAX_WARNINGS = 20 REPAIR_PRIORITY = 3 TOP_PRIORITY = 2 HIGH_PRIORITY = 1 NORMAL_PRIORITY = 0 LOW_PRIORITY = -1 DEFAULT_PRIORITY = -100 PAUSED_PRIORITY = -2 DUP_PRIORITY = -3 STOP_PRIORITY = -4 #(MATCHER, [EXTRA,MATCHERS]) series_match = [ (r'( [sS]|[\d]+)x(\d+)', # 1x01 [ r'^[-\.]+([sS]|[\d])+x(\d+)', r'^[-\.](\d+)' ] ), (r'[Ss](\d+)[\.\-]?[Ee](\d+)', # S01E01 [ r'^[-\.]+[Ss](\d+)[\.\-]?[Ee](\d+)', r'^[-\.](\d+)' ] ), (r'[ \-_\.](\d)(\d{2,2})[ \-_\.]', # .101. / _101_ / etc. [ ] ), (r'[ \-_\.](\d)(\d{2,2})$', # .101 at end of title [ ] ) ] date_match = [r'(\d{4})\W(\d{1,2})\W(\d{1,2})', #2008-10-16 r'(\d{1,2})\W(\d{1,2})\W(\d{4})'] #10.16.2008 year_match = r'[\W]([1|2]\d{3})([^\w]|$)' # Something '(YYYY)' or '.YYYY.' or ' YYYY ' sample_match = r'((^|[\W_])sample\d*[\W_])|(-s\.\w+$)' # something-sample.avi something-s.avi class Status(): COMPLETED = 'Completed' CHECKING = 'Checking' DOWNLOADING = 'Downloading' EXTRACTING = 'Extracting' FAILED = 'Failed' FETCHING = 'Fetching' GRABBING = 'Grabbing' MOVING = 'Moving' PAUSED = 'Paused' QUEUED = 'Queued' QUICK_CHECK = 'QuickCheck' REPAIRING = 'Repairing' RUNNING = 'Running' VERIFYING = 'Verifying' NOTIFY_KEYS = ('startup', 'download', 'pp', 'complete', 'other') SABnzbd-0.7.20/sabnzbd/database.py0000644000000000000000000003471312433712602016776 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.database - Database Support """ try: import sqlite3 except: try: import pysqlite2.dbapi2 as sqlite3 except: pass import os import time import datetime import zlib import logging import sabnzbd import sabnzbd.cfg from sabnzbd.constants import DB_HISTORY_NAME from sabnzbd.encoding import unicoder from sabnzbd.bpsmeter import this_week, this_month from sabnzbd.misc import format_source_url _HISTORY_DB = None # Will contain full path to history database _DONE_CLEANING = False # Ensure we only do one Vacuum per session def get_history_handle(): """ Get an instance of the history db hanlder """ global _HISTORY_DB if not _HISTORY_DB: _HISTORY_DB = os.path.join(sabnzbd.cfg.admin_dir.get_path(), DB_HISTORY_NAME) return HistoryDB(_HISTORY_DB) def convert_search(search): """ Convert classic wildcard to SQL wildcard """ if not search: # Default value search = '' else: # Allow * for wildcard matching and space search = search.replace('*','%').replace(' ', '%') # Allow ^ for start of string and $ for end of string if search and search.startswith('^'): search = search.replace('^','') search += '%' elif search and search.endswith('$'): search = search.replace('$','') search = '%' + search else: search = '%' + search + '%' return search # Note: Add support for execute return values class HistoryDB(object): def __init__(self, db_path): global _DONE_CLEANING #Thread.__init__(self) if not os.path.exists(db_path): create_table = True else: create_table = False if sabnzbd.WIN32 and isinstance(db_path, str): self.con = sqlite3.connect(db_path.decode('latin-1').encode('utf-8')) else: self.con = sqlite3.connect(db_path) self.con.row_factory = dict_factory self.c = self.con.cursor() if create_table: self.create_history_db() elif not _DONE_CLEANING: # Run VACUUM on sqlite # When an object (table, index, or trigger) is dropped from the database, it leaves behind empty space # http://www.sqlite.org/lang_vacuum.html _DONE_CLEANING = True self.execute('VACUUM') def execute(self, command, args=(), save=False): ''' Wrapper for executing SQL commands ''' try: if args and isinstance(args, tuple): self.c.execute(command, args) else: self.c.execute(command) if save: self.save() return True except: logging.error(Ta('SQL Command Failed, see log')) logging.debug("SQL: %s" , command) logging.info("Traceback: ", exc_info = True) try: self.con.rollback() except: logging.debug("Rollback Failed:", exc_info = True) return False def create_history_db(self): self.execute(""" CREATE TABLE "history" ( "id" INTEGER PRIMARY KEY, "completed" INTEGER NOT NULL, "name" TEXT NOT NULL, "nzb_name" TEXT NOT NULL, "category" TEXT, "pp" TEXT, "script" TEXT, "report" TEXT, "url" TEXT, "status" TEXT, "nzo_id" TEXT, "storage" TEXT, "path" TEXT, "script_log" BLOB, "script_line" TEXT, "download_time" INTEGER, "postproc_time" INTEGER, "stage_log" TEXT, "downloaded" INTEGER, "completeness" INTEGER, "fail_message" TEXT, "url_info" TEXT, "bytes" INTEGER, "meta" TEXT ) """) def save(self): try: self.con.commit() except: logging.error(Ta('SQL Commit Failed, see log')) logging.info("Traceback: ", exc_info = True) def close(self): try: self.c.close() self.con.close() except: logging.error(Ta('Failed to close database, see log')) logging.info("Traceback: ", exc_info = True) def remove_completed(self, search=None): search = convert_search(search) return self.execute("""DELETE FROM history WHERE name LIKE ? AND status = 'Completed'""", (search,), save=True) def get_failed_paths(self, search=None): """ Return list of all storage paths of failed jobs (may contain non-existing or empty paths) """ search = convert_search(search) fetch_ok = self.execute("""SELECT path FROM history WHERE name LIKE ? AND status = 'Failed'""", (search,)) if fetch_ok: return [item.get('path') for item in self.c.fetchall()] else: return [] def remove_failed(self, search=None): search = convert_search(search) return self.execute("""DELETE FROM history WHERE name LIKE ? AND status = 'Failed'""", (search,), save=True) def remove_history(self, jobs=None): if jobs is None: self.remove_completed() else: if not isinstance(jobs, list): jobs = [jobs] for job in jobs: self.execute("""DELETE FROM history WHERE nzo_id=?""", (job,)) self.save() def add_history_db(self, nzo, storage, path, postproc_time, script_output, script_line): t = build_history_info(nzo, storage, path, postproc_time, script_output, script_line) if self.execute("""INSERT INTO history (completed, name, nzb_name, category, pp, script, report, url, status, nzo_id, storage, path, script_log, script_line, download_time, postproc_time, stage_log, downloaded, completeness, fail_message, url_info, bytes) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", t): self.save() def fetch_history(self, start=None, limit=None, search=None, failed_only=0): search = convert_search(search) # Get the number of results if failed_only: res = self.execute('select count(*) from History WHERE name LIKE ? AND STATUS = "Failed"', (search,)) else: res = self.execute('select count(*) from History WHERE name LIKE ?', (search,)) total_items = -1 if res: try: total_items = self.c.fetchone().get('count(*)') except AttributeError: pass if not start: start = 0 if not limit: limit = total_items t = (search, start, limit) if failed_only: fetch_ok = self.execute('''SELECT * FROM history WHERE name LIKE ? AND STATUS = "Failed" ORDER BY completed desc LIMIT ?, ?''', t) else: fetch_ok = self.execute('''SELECT * FROM history WHERE name LIKE ? ORDER BY completed desc LIMIT ?, ?''', t) if fetch_ok: items = self.c.fetchall() else: items = [] fetched_items = len(items) # Unpack the single line stage log # Stage Name is seperated by ::: stage lines by ; and stages by \r\n items = [unpack_history_info(item) for item in items] return (items, fetched_items, total_items) def get_history_size(self): """ Returns the total size of the history and amounts downloaded in the last month and week """ # Total Size of the history total = 0 if self.execute('''SELECT sum(bytes) FROM history'''): try: total = self.c.fetchone().get('sum(bytes)') except AttributeError: pass # Amount downloaded this month #r = time.gmtime(time.time()) #month_timest = int(time.mktime((r.tm_year, r.tm_mon, 0, 0, 0, 1, r.tm_wday, r.tm_yday, r.tm_isdst))) month_timest = int(this_month(time.time())) month = 0 if self.execute('''SELECT sum(bytes) FROM history WHERE "completed">?''', (month_timest,)): try: month = self.c.fetchone().get('sum(bytes)') except AttributeError: pass # Amount downloaded this week week_timest = int(this_week(time.time())) week = 0 if self.execute('''SELECT sum(bytes) FROM history WHERE "completed">?''', (week_timest,)): try: week = self.c.fetchone().get('sum(bytes)') except AttributeError: pass return (total, month, week) def get_script_log(self, nzo_id): data = '' t = (nzo_id,) if self.execute('SELECT script_log FROM history WHERE nzo_id=?', t): try: data = zlib.decompress(self.c.fetchone().get('script_log')) except: pass return data def get_name(self, nzo_id): t = (nzo_id,) name = '' if self.execute('SELECT name FROM history WHERE nzo_id=?', t): try: name = self.c.fetchone().get('name') except AttributeError: pass return name def get_path(self, nzo_id): t = (nzo_id,) path = '' if self.execute('SELECT path FROM history WHERE nzo_id=?', t): try: path = self.c.fetchone().get('path') except AttributeError: pass return path def dict_factory(cursor, row): d = {} for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d def build_history_info(nzo, storage='', downpath='', postproc_time=0, script_output='', script_line=''): ''' Collects all the information needed for the database ''' if not downpath: downpath = nzo.downpath path = decode_factory(downpath) storage = decode_factory(storage) script_line = decode_factory(script_line) flagRepair, flagUnpack, flagDelete = nzo.repair_opts nzo_info = decode_factory(nzo.nzo_info) # Get the url and newzbin msgid report = decode_factory(nzo_info.get('msgid', '')) if report: url = format_source_url(report) else: url = decode_factory(nzo.url) #group = nzo.group completed = int(time.time()) name = decode_factory(nzo.final_name) nzb_name = decode_factory(nzo.filename) category = decode_factory(nzo.cat) pps = ['','R','U','D'] try: pp = pps[sabnzbd.opts_to_pp(flagRepair, flagUnpack, flagDelete)] except: pp = '' script = decode_factory(nzo.script) status = decode_factory(nzo.status) nzo_id = nzo.nzo_id bytes = nzo.bytes_downloaded if script_output: # Compress the output of the script script_log = sqlite3.Binary(zlib.compress(script_output)) # else: script_log = '' download_time = decode_factory(nzo_info.get('download_time', 0)) downloaded = nzo.bytes_downloaded completeness = 0 fail_message = decode_factory(nzo.fail_msg) url_info = nzo_info.get('details', '') or nzo_info.get('more_info', '') # Get the dictionary containing the stages and their unpack process stages = decode_factory(nzo.unpack_info) # Pack the ditionary up into a single string # Stage Name is seperated by ::: stage lines by ; and stages by \r\n lines = [] for key, results in stages.iteritems(): lines.append('%s:::%s' % (key, ';'.join(results))) stage_log = '\r\n'.join(lines) return (completed, name, nzb_name, category, pp, script, report, url, status, nzo_id, storage, path, \ script_log, script_line, download_time, postproc_time, stage_log, downloaded, completeness, \ fail_message, url_info, bytes,) def unpack_history_info(item): ''' Expands the single line stage_log from the DB into a python dictionary for use in the history display ''' # Stage Name is seperated by ::: stage lines by ; and stages by \r\n if item['stage_log']: try: lines = item['stage_log'].split('\r\n') except: logging.error(T('Invalid stage logging in history for %s') + ' (\\r\\n)', unicoder(item['name'])) logging.debug('Lines: %s', item['stage_log']) lines = [] item['stage_log'] = [] for line in lines: stage = {} try: key, logs = line.split(':::') except: logging.debug('Missing key:::logs "%s"', line) key = line logs = '' stage['name'] = key stage['actions'] = [] try: logs = logs.split(';') except: logging.error(T('Invalid stage logging in history for %s') + ' (;)', unicoder(item['name'])) logging.debug('Logs: %s', logs) logs = [] for log in logs: stage['actions'].append(log) item['stage_log'].append(stage) if item['script_log']: item['script_log'] = zlib.decompress(item['script_log'][:]) # The action line is only available for items in the postproc queue if not item.has_key('action_line'): item['action_line'] = '' return item def decode_factory(text): ''' Recursivly looks through the supplied argument and converts and text to Unicode ''' if isinstance(text, str): return unicoder(text) elif isinstance(text, list): new_text = [] for t in text: new_text.append(decode_factory(t)) return new_text elif isinstance(text, dict): new_text = {} for key in text: new_text[key] = decode_factory(text[key]) return new_text else: return text SABnzbd-0.7.20/sabnzbd/decoder.py0000644000000000000000000003027012433712602016631 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.decoder - article decoder """ import Queue import binascii import logging import re from time import sleep from threading import Thread try: import _yenc HAVE_YENC = True except ImportError: HAVE_YENC = False import sabnzbd from sabnzbd.constants import MAX_DECODE_QUEUE, MIN_DECODE_QUEUE from sabnzbd.articlecache import ArticleCache import sabnzbd.downloader import sabnzbd.cfg as cfg from sabnzbd.encoding import name_fixer from sabnzbd.misc import match_str #------------------------------------------------------------------------------- class CrcError(Exception): def __init__(self, needcrc, gotcrc, data): Exception.__init__(self) self.needcrc = needcrc self.gotcrc = gotcrc self.data = data class BadYenc(Exception): def __init__(self): Exception.__init__(self) #------------------------------------------------------------------------------- class Decoder(Thread): def __init__(self, servers): Thread.__init__(self) self.queue = Queue.Queue() self.servers = servers def decode(self, article, lines): self.queue.put((article, lines)) if self.queue.qsize() > MAX_DECODE_QUEUE: sabnzbd.downloader.Downloader.do.delay() def stop(self): self.queue.put(None) def run(self): from sabnzbd.nzbqueue import NzbQueue while 1: sleep(0.001) art_tup = self.queue.get() if not art_tup: break if self.queue.qsize() < MIN_DECODE_QUEUE and sabnzbd.downloader.Downloader.do.delayed: sabnzbd.downloader.Downloader.do.undelay() article, lines = art_tup nzf = article.nzf nzo = nzf.nzo art_id = article.article killed = False data = None register = True # Finish article found = False # Proper article found if lines: logme = None try: if nzo.precheck: raise BadYenc register = True logging.debug("Decoding %s", art_id) data = decode(article, lines) nzf.article_count += 1 found = True except IOError, e: logme = Ta('Decoding %s failed') % art_id logging.warning(logme) logging.info("Traceback: ", exc_info = True) sabnzbd.downloader.Downloader.do.pause() article.fetcher = None NzbQueue.do.reset_try_lists(nzf, nzo) register = False except CrcError, e: logme = Ta('CRC Error in %s (%s -> %s)') % (art_id, e.needcrc, e.gotcrc) logging.info(logme) data = e.data if cfg.fail_on_crc(): new_server_found = self.__search_new_server(article) if new_server_found: register = False logme = None except BadYenc: # Handles precheck and badly formed articles killed = False found = False if nzo.precheck and lines and lines[0].startswith('223 '): # STAT was used, so we only get a status code found = True else: # Examine headers (for precheck) or body (for download) # And look for DMCA clues (while skipping "X-" headers) for line in lines: lline = line.lower() if 'message-id:' in lline: found = True if not line.startswith('X-') and match_str(lline, ('dmca', 'removed', 'cancel', 'blocked')): killed = True break if killed: logme = 'Article removed from server (%s)' logging.info(logme, art_id) if nzo.precheck: if found and not killed: # Pre-check, proper article found, just register logging.debug('Server has article %s', art_id) register = True elif not killed and not found: logme = Ta('Badly formed yEnc article in %s') % art_id logging.info(logme) if not found or killed: new_server_found = self.__search_new_server(article) if new_server_found: register = False logme = None except: logme = Ta('Unknown Error while decoding %s') % art_id logging.info(logme) logging.info("Traceback: ", exc_info = True) new_server_found = self.__search_new_server(article) if new_server_found: register = False logme = None if logme: if killed: article.nzf.nzo.inc_log('killed_art_log', art_id) else: article.nzf.nzo.inc_log('bad_art_log', art_id) else: new_server_found = self.__search_new_server(article) if new_server_found: register = False elif nzo.precheck: found = False if data: ArticleCache.do.save_article(article, data) if register: NzbQueue.do.register_article(article, found) def __search_new_server(self, article): from sabnzbd.nzbqueue import NzbQueue article.add_to_try_list(article.fetcher) nzf = article.nzf nzo = nzf.nzo new_server_found = False fill_server_found = False for server in self.servers: if server.active and not article.server_in_try_list(server): if server.fillserver: fill_server_found = True else: new_server_found = True break # Only found one (or more) fill server(s) if not new_server_found and fill_server_found: article.allow_fill_server = True new_server_found = True if new_server_found: article.fetcher = None article.tries = 0 ## Allow all servers to iterate over this nzo and nzf again ## NzbQueue.do.reset_try_lists(nzf, nzo) if sabnzbd.LOG_ALL: logging.debug('%s => found at least one untested server', article) else: msg = Ta('%s => missing from all servers, discarding') % article logging.info(msg) article.nzf.nzo.inc_log('missing_art_log', msg) return new_server_found #------------------------------------------------------------------------------- YDEC_TRANS = ''.join([chr((i + 256 - 42) % 256) for i in xrange(256)]) def decode(article, data): data = strip(data) ## No point in continuing if we don't have any data left if data: nzf = article.nzf yenc, data = yCheck(data) ybegin, ypart, yend = yenc decoded_data = None #Deal with non-yencoded posts if not ybegin: found = False try: for i in xrange(min(40, len(data))): if data[i].startswith('begin '): nzf.filename = name_fixer(data[i].split(None, 2)[2]) nzf.type = 'uu' found = True break if found: for n in xrange(i+1): data.pop(0) if data[-1] == 'end': data.pop() if data[-1] == '`': data.pop() except IndexError: raise BadYenc() if found: decoded_data = '\r\n'.join(data) else: raise BadYenc() #Deal with yenc encoded posts elif (ybegin and yend): if 'name' in ybegin: nzf.filename = name_fixer(ybegin['name']) else: logging.debug("Possible corrupt header detected " + \ "=> ybegin: %s", ybegin) nzf.type = 'yenc' # Decode data if HAVE_YENC: decoded_data, crc = _yenc.decode_string(''.join(data))[:2] partcrc = '%08X' % ((crc ^ -1) & 2**32L - 1) else: data = ''.join(data) for i in (0, 9, 10, 13, 27, 32, 46, 61): j = '=%c' % (i + 64) data = data.replace(j, chr(i)) decoded_data = data.translate(YDEC_TRANS) crc = binascii.crc32(decoded_data) partcrc = '%08X' % (crc & 2**32L - 1) if ypart: crcname = 'pcrc32' else: crcname = 'crc32' if crcname in yend: _partcrc = '0' * (8 - len(yend[crcname])) + yend[crcname].upper() else: _partcrc = None logging.debug("Corrupt header detected " + \ "=> yend: %s", yend) if not (_partcrc == partcrc): raise CrcError(_partcrc, partcrc, decoded_data) else: raise BadYenc() return decoded_data def yCheck(data): ybegin = None ypart = None yend = None ## Check head for i in xrange(min(40, len(data))): try: if data[i].startswith('=ybegin '): splits = 3 if data[i].find(' part=') > 0: splits += 1 if data[i].find(' total=') > 0: splits += 1 ybegin = ySplit(data[i], splits) if data[i+1].startswith('=ypart '): ypart = ySplit(data[i+1]) data = data[i+2:] break else: data = data[i+1:] break except IndexError: break ## Check tail for i in xrange(-1, -11, -1): try: if data[i].startswith('=yend '): yend = ySplit(data[i]) data = data[:i] break except IndexError: break return ((ybegin, ypart, yend), data) # Example: =ybegin part=1 line=128 size=123 name=-=DUMMY=- abc.par YSPLIT_RE = re.compile(r'([a-zA-Z0-9]+)=') def ySplit(line, splits = None): fields = {} if splits: parts = YSPLIT_RE.split(line, splits)[1:] else: parts = YSPLIT_RE.split(line)[1:] if len(parts) % 2: return fields for i in range(0, len(parts), 2): key, value = parts[i], parts[i+1] fields[key] = value.strip() return fields def strip(data): while data and not data[0]: data.pop(0) while data and not data[-1]: data.pop() for i in xrange(len(data)): if data[i][:2] == '..': data[i] = data[i][1:] return data SABnzbd-0.7.20/sabnzbd/decorators.py0000644000000000000000000000314112433712602017366 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ################################################################################ # Decorators # ################################################################################ from threading import RLock, Condition NZBQUEUE_LOCK = RLock() CV = Condition(NZBQUEUE_LOCK) def synchronized(lock): def wrap(f): def newFunction(*args, **kw): lock.acquire() try: return f(*args, **kw) finally: lock.release() return newFunction return wrap def synchronized_CV(func): global CV def call_func(*params, **kparams): CV.acquire() try: return func(*params, **kparams) finally: CV.notifyAll() CV.release() return call_func SABnzbd-0.7.20/sabnzbd/dirscanner.py0000644000000000000000000003244612433712602017363 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.dirscanner - Scanner for Watched Folder """ import os import time import logging import re import zipfile import gzip import threading import sabnzbd from sabnzbd.constants import * from sabnzbd.utils.rarfile import is_rarfile, RarFile import sabnzbd.nzbstuff as nzbstuff import sabnzbd.misc as misc import sabnzbd.config as config import sabnzbd.cfg as cfg def name_to_cat(fname, cat=None): """ Retrieve category from file name, but only if "cat" is None. """ if cat is None and fname.startswith('{{'): n = fname.find('}}') if n > 2: cat = fname[2:n].strip() fname = fname[n+2:].strip() logging.debug('Job %s has category %s', fname, cat) return fname, cat def CompareStat(tup1, tup2): """ Test equality of two stat-tuples, content-related parts only """ if tup1.st_ino != tup2.st_ino: return False if tup1.st_size != tup2.st_size: return False if tup1.st_mtime != tup2.st_mtime: return False if tup1.st_ctime != tup2.st_ctime: return False return True def ProcessArchiveFile(filename, path, pp=None, script=None, cat=None, catdir=None, keep=False, priority=None, url='', nzbname=None): """ Analyse ZIP file and create job(s). Accepts ZIP files with ONLY nzb/nfo/folder files in it. returns (status, nzo_ids) status: -1==Error/Retry, 0==OK, 1==Ignore """ from sabnzbd.nzbqueue import add_nzo nzo_ids = [] if catdir is None: catdir = cat filename, cat = name_to_cat(filename, catdir) if zipfile.is_zipfile(path): try: zf = zipfile.ZipFile(path) except: return -1, [] elif is_rarfile(path): try: zf = RarFile(path) except: return -1, [] else: return 1, [] status = 1 names = zf.namelist() names.sort() nzbcount = 0 for name in names: name = name.lower() if not (name.endswith('.nzb') or name.endswith('.nfo') or name.endswith('/')): status = 1 break elif name.endswith('.nzb'): status = 0 nzbcount += 1 if status == 0: if nzbcount != 1: nzbname = None for name in names: if name.lower().endswith('.nzb'): try: data = zf.read(name) except: zf.close() return -1, [] name = re.sub(r'\[.*nzbmatrix.com\]', '', name) name = os.path.basename(name) if data: try: nzo = nzbstuff.NzbObject(name, 0, pp, script, data, cat=cat, url=url, priority=priority, nzbname=nzbname) except: nzo = None if nzo: nzo_ids.append(add_nzo(nzo)) nzo.update_rating() zf.close() try: if not keep: os.remove(path) except: logging.error(Ta('Error removing %s'), path) logging.info("Traceback: ", exc_info = True) status = 1 else: zf.close() status = 1 return status, nzo_ids def ProcessSingleFile(filename, path, pp=None, script=None, cat=None, catdir=None, keep=False, priority=None, nzbname=None, reuse=False, nzo_info=None, dup_check=True, url=''): """ Analyse file and create a job from it Supports NZB, NZB.GZ and GZ.NZB-in-disguise returns (status, nzo_ids) status: -2==Error/retry, -1==Error, 0==OK, 1==OK-but-ignorecannot-delete """ from sabnzbd.nzbqueue import add_nzo nzo_ids = [] if catdir is None: catdir = cat try: f = open(path, 'rb') b1 = f.read(1) b2 = f.read(1) f.close() if (b1 == '\x1f' and b2 == '\x8b'): # gzip file or gzip in disguise name = filename.replace('.nzb.gz', '.nzb') f = gzip.GzipFile(path, 'rb') else: name = filename f = open(path, 'rb') data = f.read() f.close() except: logging.warning(Ta('Cannot read %s'), path) logging.info("Traceback: ", exc_info = True) return -2, nzo_ids if name: name, cat = name_to_cat(name, catdir) # The name is used as the name of the folder, so sanitize it using folder specific santization if not nzbname: # Prevent embedded password from being damaged by sanitize and trimming nzbname = os.path.split(name)[1] try: nzo = nzbstuff.NzbObject(name, 0, pp, script, data, cat=cat, priority=priority, nzbname=nzbname, nzo_info=nzo_info, url=url, reuse=reuse, dup_check=dup_check) except TypeError: # Duplicate, ignore nzo = None except ValueError: # Empty, but correct file return -1, nzo_ids except: if data.find("= 0 and data.find(" 0) and not self.shutdown and not self.trigger: time.sleep(1.0) x = x - 1 self.trigger = False if self.dirscan_speed and not self.shutdown: self.scan() def scan(self): """ Do one scan of the watched folder """ def run_dir(folder, catdir): try: files = os.listdir(folder) except: if not self.error_reported and not catdir: logging.error(Ta('Cannot read Watched Folder %s'), folder) self.error_reported = True files = [] for filename in files: path = os.path.join(folder, filename) if os.path.isdir(path) or path in self.ignored or filename[0] == '.': continue ext = os.path.splitext(path)[1].lower() candidate = ext in ('.nzb', '.zip', '.gz', '.rar') if candidate: try: stat_tuple = os.stat(path) except: continue else: self.ignored[path] = 1 if path in self.suspected: if CompareStat(self.suspected[path], stat_tuple): # Suspected file still has the same attributes continue else: del self.suspected[path] if candidate and stat_tuple.st_size > 0: logging.info('Trying to import %s', path) # Wait until the attributes are stable for 1 second # but give up after 3 sec stable = False for n in xrange(3): time.sleep(1.0) try: stat_tuple_tmp = os.stat(path) except: continue if CompareStat(stat_tuple, stat_tuple_tmp): stable = True break else: stat_tuple = stat_tuple_tmp if not stable: continue # Handle ZIP files, but only when containing just NZB files if ext in ('.zip', '.rar') : res, nzo_ids = ProcessArchiveFile(filename, path, catdir=catdir, url=path) if res == -1: self.suspected[path] = stat_tuple elif res == 0: self.error_reported = False else: self.ignored[path] = 1 # Handle .nzb, .nzb.gz or gzip-disguised-as-nzb elif ext == '.nzb' or filename.lower().endswith('.nzb.gz'): res, nzo_id = ProcessSingleFile(filename, path, catdir=catdir, url=path) if res < 0: self.suspected[path] = stat_tuple elif res == 0: self.error_reported = False else: self.ignored[path] = 1 else: self.ignored[path] = 1 CleanList(self.ignored, folder, files) CleanList(self.suspected, folder, files) if not self.busy: self.busy = True dirscan_dir = self.dirscan_dir if dirscan_dir and not sabnzbd.PAUSED_ALL: run_dir(dirscan_dir, None) try: list = os.listdir(dirscan_dir) except: if not self.error_reported: logging.error(Ta('Cannot read Watched Folder %s'), dirscan_dir) self.error_reported = True list = [] cats = config.get_categories() for dd in list: dpath = os.path.join(dirscan_dir, dd) if os.path.isdir(dpath) and dd.lower() in cats: run_dir(dpath, dd.lower()) self.busy = False def dirscan(): """ Wrapper required for scheduler """ logging.info('Scheduled or manual watched folder scan') DirScanner.do.scan() SABnzbd-0.7.20/sabnzbd/downloader.py0000644000000000000000000010123212433712602017357 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.downloader - download engine """ import time import select import logging from threading import Thread, RLock from nntplib import NNTPPermanentError import socket import random import sabnzbd from sabnzbd.decorators import synchronized, synchronized_CV, CV from sabnzbd.decoder import Decoder from sabnzbd.newswrapper import NewsWrapper, request_server_info import sabnzbd.growler as growler from sabnzbd.constants import * import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.bpsmeter import BPSMeter import sabnzbd.scheduler #------------------------------------------------------------------------------ # Timeout penalty in minutes for each cause _PENALTY_UNKNOWN = 3 # Unknown cause _PENALTY_502 = 5 # Unknown 502 _PENALTY_TIMEOUT = 10 # Server doesn't give an answer (multiple times) _PENALTY_SHARE = 10 # Account sharing detected _PENALTY_TOOMANY = 10 # Too many connections _PENALTY_PERM = 10 # Permanent error, like bad username/password _PENALTY_SHORT = 1 # Minimal penalty when no_penalties is set _PENALTY_VERYSHORT = 0.1 # Error 400 without cause clues TIMER_LOCK = RLock() #------------------------------------------------------------------------------ class Server(object): def __init__(self, id, host, port, timeout, threads, fillserver, ssl, username = None, password = None, optional=False, retention=0): self.id = id self.newid = None self.restart = False self.host = host self.port = port self.timeout = timeout self.threads = threads self.fillserver = fillserver self.ssl = ssl self.optional = optional self.retention = retention self.username = username self.password = password self.busy_threads = [] self.idle_threads = [] self.active = True self.bad_cons = 0 self.errormsg = '' self.warning = '' self.info = None # Will hold getaddrinfo() list self.request = False # True if a getaddrinfo() request is pending self.have_body = 'free.xsusenet.com' not in host self.have_stat = True # Assume server has "STAT", until proven otherwise for i in range(threads): self.idle_threads.append(NewsWrapper(self, i+1)) @property def hostip(self): """ Return a random entry from the possible IPs """ if cfg.randomize_server_ip() and self.info and len(self.info) > 1: rnd = random.randint(0, len(self.info)-1) ip = self.info[rnd][4][0] logging.debug('For server %s, using IP %s' % (self.host, ip)) else: ip = self.host return ip def stop(self, readers, writers): for nw in self.idle_threads: try: fno = nw.nntp.sock.fileno() except: fno = None if fno and fno in readers: readers.pop(fno) if fno and fno in writers: writers.pop(fno) nw.terminate(quit=True) self.idle_threads = [] def __repr__(self): return "%s:%s" % (self.host, self.port) #------------------------------------------------------------------------------ class Downloader(Thread): """ Singleton Downloader Thread """ do = None def __init__(self, paused=False): Thread.__init__(self) logging.debug("Initializing downloader/decoder") # Used for scheduled pausing self.paused = paused #used for throttling bandwidth and scheduling bandwidth changes self.bandwidth_limit = cfg.bandwidth_limit() cfg.bandwidth_limit.callback(self.speed_set) # Used for reducing speed self.delayed = False self.postproc = False self.shutdown = False # A user might change server parms again before server restart is ready. # Keep a counter to prevent multiple restarts self.__restart = 0 self.force_disconnect = False self.read_fds = {} self.write_fds = {} self.servers = [] self._timers = {} for server in config.get_servers(): self.init_server(None, server) self.decoder = Decoder(self.servers) Downloader.do = self def init_server(self, oldserver, newserver): """ Setup or re-setup single server When oldserver is defined and in use, delay startup. Return True when newserver is primary Note that the server names are "host:port" strings! """ primary = False create = False servers = config.get_servers() if newserver in servers: srv = servers[newserver] enabled = srv.enable() host = srv.host() port = srv.port() timeout = srv.timeout() threads = srv.connections() fillserver = srv.fillserver() primary = enabled and (not fillserver) and (threads > 0) ssl = srv.ssl() and sabnzbd.newswrapper.HAVE_SSL username = srv.username() password = srv.password() optional = srv.optional() retention = float(srv.retention() * 24 * 3600) # days ==> seconds create = True if oldserver: for n in xrange(len(self.servers)): if self.servers[n].id == oldserver: # Server exists, do re-init later create = False self.servers[n].newid = newserver self.servers[n].restart = True self.__restart += 1 break if create and enabled and host and port and threads: self.servers.append(Server(newserver, host, port, timeout, threads, fillserver, ssl, username, password, optional, retention)) return primary @synchronized_CV def set_paused_state(self, state): """ Set Downloader to specified paused state """ self.paused = state @synchronized_CV def resume(self): logging.info("Resuming") self.paused = False @synchronized_CV def pause(self, save=True): """ Pause the downloader, optionally saving admin """ if not self.paused: self.paused = True logging.info("Pausing") growler.send_notification("SABnzbd", T('Paused'), 'download') if self.is_paused(): BPSMeter.do.reset() if cfg.autodisconnect(): self.disconnect() if save: sabnzbd.save_state() @synchronized_CV def delay(self): logging.debug("Delaying") self.delayed = True @synchronized_CV def undelay(self): logging.debug("Undelaying") self.delayed = False @synchronized_CV def wait_for_postproc(self): logging.info("Waiting for post-processing to finish") self.postproc = True @synchronized_CV def resume_from_postproc(self): logging.info("Post-processing finished, resuming download") self.postproc = False def disconnect(self): self.force_disconnect = True @synchronized_CV def limit_speed(self, value): self.bandwidth_limit = int(value) logging.info("Bandwidth limit set to %s", value) def get_limit(self): return self.bandwidth_limit def speed_set(self): self.bandwidth_limit = cfg.bandwidth_limit() def is_paused(self): from sabnzbd.nzbqueue import NzbQueue if not self.paused: return False else: if NzbQueue.do.has_forced_items(): return False else: return True def active_primaries(self): """ Check if any primary server is defined and active """ for server in self.servers: if server.active and not server.fillserver: return True return False def nzo_servers(self, nzo): return filter(nzo.server_in_try_list, self.servers) def maybe_block_server(self, server): from sabnzbd.nzbqueue import NzbQueue if server.optional and server.active and (server.bad_cons/server.threads) > 3: # Optional and active server had too many problems, # disable it now and send a re-enable plan to the scheduler server.bad_cons = 0 server.active = False server.errormsg = T('Server %s will be ignored for %s minutes') % ('', _PENALTY_TIMEOUT) logging.warning(Ta('Server %s will be ignored for %s minutes'), server.id, _PENALTY_TIMEOUT) self.plan_server(server.id, _PENALTY_TIMEOUT) # Remove all connections to server for nw in server.idle_threads + server.busy_threads: self.__reset_nw(nw, "forcing disconnect", warn=False, wait=False, quit=False) # Make sure server address resolution is refreshed server.info = None NzbQueue.do.reset_all_try_lists() def run(self): from sabnzbd.nzbqueue import NzbQueue self.decoder.start() # Kick BPS-Meter to check quota BPSMeter.do.update() while 1: for server in self.servers: assert isinstance(server, Server) for nw in server.busy_threads[:]: if (nw.nntp and nw.nntp.error_msg) or (nw.timeout and time.time() > nw.timeout): if (nw.nntp and nw.nntp.error_msg): self.__reset_nw(nw, "", warn=False) else: self.__reset_nw(nw, "timed out") server.bad_cons += 1 self.maybe_block_server(server) if server.restart: if not server.busy_threads: newid = server.newid server.stop(self.read_fds, self.write_fds) self.servers.remove(server) if newid: self.init_server(None, newid) self.__restart -= 1 NzbQueue.do.reset_all_try_lists() # Have to leave this loop, because we removed element break else: # Restart pending, don't add new articles continue assert isinstance(server, Server) if not server.idle_threads or server.restart or self.is_paused() or self.shutdown or self.delayed or self.postproc: continue if not (server.active and NzbQueue.do.has_articles_for(server)): continue for nw in server.idle_threads[:]: assert isinstance(nw, NewsWrapper) if nw.timeout: if time.time() < nw.timeout: continue else: nw.timeout = None if not server.active: break if server.info is None: self.maybe_block_server(server) request_server_info(server) break article = NzbQueue.do.get_article(server) if not article: break if server.retention and article.nzf.nzo.avg_stamp < time.time() - server.retention: # Article too old for the server, treat as missing if sabnzbd.LOG_ALL: logging.debug('Article %s too old for %s:%s', article.article, server.host, server.port) self.decoder.decode(article, None) break server.idle_threads.remove(nw) server.busy_threads.append(nw) nw.article = article if nw.connected: self.__request_article(nw) else: try: logging.info("%s@%s:%s: Initiating connection", nw.thrdnum, server.host, server.port) nw.init_connect(self.write_fds) except: logging.error(Ta('Failed to initialize %s@%s:%s'), nw.thrdnum, server.host, server.port) logging.info("Traceback: ", exc_info = True) self.__reset_nw(nw, "failed to initialize") # Exit-point if self.shutdown: empty = True for server in self.servers: if server.busy_threads: empty = False break if empty: self.decoder.stop() self.decoder.join() for server in self.servers: server.stop(self.read_fds, self.write_fds) logging.info("Shutting down") break if self.force_disconnect: for server in self.servers: for nw in server.idle_threads + server.busy_threads: quit = nw.connected and server.active self.__reset_nw(nw, "forcing disconnect", warn=False, wait=False, quit=quit) # Make sure server address resolution is refreshed server.info = None self.force_disconnect = False # => Select readkeys = self.read_fds.keys() writekeys = self.write_fds.keys() if readkeys or writekeys: read, write, error = select.select(readkeys, writekeys, (), 1.0) else: read, write, error = ([], [], []) BPSMeter.do.reset() time.sleep(1.0) CV.acquire() while (NzbQueue.do.is_empty() or self.is_paused() or self.delayed or self.postproc) and not \ self.shutdown and not self.__restart: CV.wait() CV.release() self.force_disconnect = False for selected in write: nw = self.write_fds[selected] fileno = nw.nntp.sock.fileno() if fileno not in self.read_fds: self.read_fds[fileno] = nw if fileno in self.write_fds: self.write_fds.pop(fileno) if not read: BPSMeter.do.update() continue for selected in read: nw = self.read_fds[selected] article = nw.article server = nw.server if article: nzo = article.nzf.nzo try: bytes, done, skip = nw.recv_chunk() except: bytes, done, skip = (0, False, False) if skip: BPSMeter.do.update() continue if bytes < 1: self.__reset_nw(nw, "server closed connection", warn=False, wait=False) continue else: if self.bandwidth_limit: bps = BPSMeter.do.get_bps() bps += bytes limit = self.bandwidth_limit * 1024 if bps > limit: while BPSMeter.do.get_bps() > limit: time.sleep(0.05) BPSMeter.do.update() BPSMeter.do.update(server.id, bytes) if nzo: nzo.bytes_downloaded += bytes nzo.update_avg_kbs(BPSMeter.do.get_bps()) if len(nw.lines) == 1: code = nw.lines[0][:3] if not nw.connected or code == '480': done = False try: nw.finish_connect(code) if sabnzbd.LOG_ALL: logging.debug("%s@%s:%s last message -> %s", nw.thrdnum, nw.server.host, nw.server.port, nw.lines[0]) nw.lines = [] nw.data = '' except NNTPPermanentError, error: # Handle login problems block = False penalty = 0 msg = error.response ecode = msg[:3] display_msg = ' [%s]' % msg logging.debug('Server login problem: %s, %s', ecode, msg) if ecode in ('502', '481', '400') and clues_too_many(msg): # Too many connections: remove this thread and reduce thread-setting for server # Plan to go back to the full number after a penalty timeout if server.active: server.errormsg = Ta('Too many connections to server %s:%s') % ('', display_msg) logging.error(Ta('Too many connections to server %s:%s'), server.host, server.port) self.__reset_nw(nw, None, warn=False, destroy=True, quit=True) self.plan_server(server.id, _PENALTY_TOOMANY) server.threads -= 1 elif ecode in ('502', '481') and clues_too_many_ip(msg): # Account sharing? if server.active: server.errormsg = Ta('Probable account sharing') + display_msg name = ' (%s:%s)' % (server.host, server.port) logging.error(Ta('Probable account sharing') + name) penalty = _PENALTY_SHARE elif ecode in ('481', '482', '381') or (ecode == '502' and clues_login(msg)): # Cannot login, block this server if server.active: server.errormsg = Ta('Failed login for server %s') % display_msg logging.error(Ta('Failed login for server %s'), '%s:%s' % (server.host, server.port)) penalty = _PENALTY_PERM block = True elif ecode == '502': # Cannot connect (other reasons), block this server if server.active: server.errormsg = Ta('Cannot connect to server %s [%s]') % ('', display_msg) logging.warning(Ta('Cannot connect to server %s [%s]'), '%s:%s' % (server.host, server.port), msg) if clues_pay(msg): penalty = _PENALTY_PERM else: penalty = _PENALTY_502 block = True elif ecode == '400': # Temp connection problem? if server.active: logging.debug('Unspecified error 400 from server %s', server.host) penalty = _PENALTY_VERYSHORT block = True else: # Unknown error, just keep trying if server.active: server.errormsg = Ta('Cannot connect to server %s [%s]') % ('', display_msg) logging.error(Ta('Cannot connect to server %s [%s]'), '%s:%s' % (server.host, server.port), msg) penalty = _PENALTY_UNKNOWN if block or (penalty and server.optional): if server.active: server.active = False if (not server.optional) and cfg.no_penalties(): penalty = _PENALTY_SHORT if penalty and (block or server.optional): logging.info('Server %s ignored for %s minutes', server.id, penalty) self.plan_server(server.id, penalty) NzbQueue.do.reset_all_try_lists() self.__reset_nw(nw, None, warn=False, quit=True) continue except: logging.error(Ta('Connecting %s@%s:%s failed, message=%s'), nw.thrdnum, nw.server.host, nw.server.port, nw.lines[0]) # No reset-warning needed, above logging is sufficient self.__reset_nw(nw, None, warn=False) if nw.connected: logging.info("Connecting %s@%s:%s finished", nw.thrdnum, nw.server.host, nw.server.port) self.__request_article(nw) elif code == '223': done = True logging.debug('Article <%s> is present', article.article) self.decoder.decode(article, nw.lines) elif code == '211': done = False logging.debug("group command ok -> %s", nw.lines) nw.group = nw.article.nzf.nzo.group nw.lines = [] nw.data = '' self.__request_article(nw) elif code in ('411', '423', '430'): done = True nw.lines = None logging.info('Thread %s@%s:%s: Article ' + \ '%s missing (error=%s)', nw.thrdnum, nw.server.host, nw.server.port, article.article, code) elif code == '480': if server.active: server.active = False server.errormsg = T('Server %s requires user/password') % '' self.plan_server(server.id, 0) NzbQueue.do.reset_all_try_lists() msg = T('Server %s requires user/password') % ('%s:%s' % (nw.server.host, nw.server.port)) self.__reset_nw(nw, msg, quit=True) elif code == '500': if nzo.precheck: # Assume "STAT" command is not supported server.have_stat = False logging.debug('Server %s does not support STAT', server.host) else: # Assume "BODY" command is not supported server.have_body = False logging.debug('Server %s does not support BODY', server.host) nw.lines = [] nw.data = '' self.__request_article(nw) if done: server.bad_cons = 0 # Succesful data, clear "bad" counter if sabnzbd.LOG_ALL: logging.debug('Thread %s@%s:%s: %s done', nw.thrdnum, server.host, server.port, article.article) self.decoder.decode(article, nw.lines) nw.soft_reset() server.busy_threads.remove(nw) server.idle_threads.append(nw) def __lookup_nw(self, nw): ''' Find the fileno matching the nw, needed for closed connections ''' for f in self.read_fds: if self.read_fds[f] == nw: return f for f in self.write_fds: if self.read_fds[f] == nw: return f return None def __reset_nw(self, nw, errormsg, warn=True, wait=True, destroy=False, quit=False): from sabnzbd.nzbqueue import NzbQueue server = nw.server article = nw.article fileno = None if nw.nntp: try: fileno = nw.nntp.sock.fileno() except: fileno = self.__lookup_nw(nw) destroy = True nw.nntp.error_msg = None if warn and errormsg: server.warning = errormsg logging.info('Thread %s@%s:%s: ' + errormsg, nw.thrdnum, server.host, server.port) elif errormsg: logging.info('Thread %s@%s:%s: ' + errormsg, nw.thrdnum, server.host, server.port) if nw in server.busy_threads: server.busy_threads.remove(nw) if not (destroy or nw in server.idle_threads): server.idle_threads.append(nw) if fileno and fileno in self.write_fds: self.write_fds.pop(fileno) if fileno and fileno in self.read_fds: self.read_fds.pop(fileno) if article: if article.tries > cfg.max_art_tries() and (article.fetcher.optional or not cfg.max_art_opt()): # Too many tries on this server, consider article missing self.decoder.decode(article, None) else: # Remove this server from try_list article.fetcher = None nzf = article.nzf nzo = nzf.nzo ## Allow all servers to iterate over each nzo/nzf again ## NzbQueue.do.reset_try_lists(nzf, nzo) if destroy: nw.terminate(quit=quit) else: nw.hard_reset(wait, quit=quit) def __request_article(self, nw): try: nzo = nw.article.nzf.nzo if cfg.send_group() and nzo.group != nw.group: group = nzo.group if sabnzbd.LOG_ALL: logging.debug('Thread %s@%s:%s: GROUP <%s>', nw.thrdnum, nw.server.host, nw.server.port, group) nw.send_group(group) else: if sabnzbd.LOG_ALL: logging.debug('Thread %s@%s:%s: BODY %s', nw.thrdnum, nw.server.host, nw.server.port, nw.article.article) nw.body(nzo.precheck) fileno = nw.nntp.sock.fileno() if fileno not in self.read_fds: self.read_fds[fileno] = nw except socket.error, err: logging.info('Looks like server closed connection: %s', err) self.__reset_nw(nw, "server broke off connection", quit=False) except: logging.error('Suspect error in downloader') logging.info("Traceback: ", exc_info = True) self.__reset_nw(nw, "server broke off connection", quit=False) #------------------------------------------------------------------------------ # Timed restart of servers admin. # For each server all planned events are kept in a list. # When the first timer of a server fires, all other existing timers # are neutralized. # Each server has a dictionary entry, consisting of a list of timestamps. @synchronized(TIMER_LOCK) def plan_server(self, server_id, interval): """ Plan the restart of a server in 'interval' minutes """ logging.debug('Set planned server resume %s in %s mins', server_id, interval) if server_id not in self._timers: self._timers[server_id] = [] stamp = time.time() + 60.0 * interval self._timers[server_id].append(stamp) if interval: sabnzbd.scheduler.plan_server(self.trigger_server, [server_id, stamp], interval) @synchronized(TIMER_LOCK) def trigger_server(self, server_id, timestamp): """ Called by scheduler, start server if timer still valid """ logging.debug('Trigger planned server resume %s', server_id) if server_id in self._timers: if timestamp in self._timers[server_id]: del self._timers[server_id] self.init_server(server_id, server_id) @synchronized_CV @synchronized(TIMER_LOCK) def unblock(self, server_id): # Remove timer try: del self._timers[server_id] except KeyError: pass # Activate server if it was inactive for server in self.servers: if server.id == server_id and not server.active: logging.debug('Unblock server %s', server_id) self.init_server(server_id, server_id) break def unblock_all(self): for server_id in self._timers.keys(): self.unblock(server_id) @synchronized_CV @synchronized(TIMER_LOCK) def check_timers(self): """ Make sure every server without a non-expired timer is active """ # Clean expired timers now = time.time() kicked = [] for server_id in self._timers.keys(): if not [stamp for stamp in self._timers[server_id] if stamp >= now]: logging.debug('Forcing re-evaluation of server %s', server_id) del self._timers[server_id] self.init_server(server_id, server_id) kicked.append(server_id) # Activate every inactive server without an active timer for server in self.servers: if server.id not in self._timers: if server.id not in kicked and not server.active: logging.debug('Forcing activation of server %s', server.id) self.init_server(server.id, server.id) @synchronized_CV def update_server(self, oldserver, newserver): self.init_server(oldserver, newserver) @synchronized_CV def wakeup(self): """ Just rattle the semaphore """ pass def stop(self): self.shutdown = True growler.send_notification("SABnzbd",T('Shutting down'), 'startup') def stop(): CV.acquire() try: Downloader.do.stop() finally: CV.notifyAll() CV.release() try: Downloader.do.join() except: pass #------------------------------------------------------------------------------ def clues_login(text): """ Check for any "failed login" clues in the response code """ text = text.lower() for clue in ('username', 'password', 'invalid', 'authen', 'access denied'): if clue in text: return True return False def clues_too_many(text): """ Check for any "too many connections" clues in the response code """ text = text.lower() for clue in ('exceed', 'connections', 'too many', 'threads', 'limit'): if clue in text: return True return False def clues_too_many_ip(text): """ Check for any "account sharing" clues in the response code """ text = text.lower() for clue in ('simultaneous ip', 'multiple ip'): if clue in text: return True return False def clues_pay(text): """ Check for messages about payments """ text = text.lower() for clue in ('credits', 'paym', 'expired'): if clue in text: return True return False SABnzbd-0.7.20/sabnzbd/emailer.py0000644000000000000000000002753712433712602016656 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.emailer - Send notification emails """ #------------------------------------------------------------------------------ from sabnzbd.utils import ssmtplib import smtplib import os import logging import re import time import glob from sabnzbd.constants import * import sabnzbd from sabnzbd.misc import to_units, split_host, time_format from sabnzbd.encoding import EmailFilter, latin1 import sabnzbd.cfg as cfg def errormsg(msg): logging.error(latin1(msg)) return msg ################################################################################ # EMAIL_SEND # # ################################################################################ def send(message, email_to, test=None): """ Send message if message non-empty and email-parms are set """ # we should not use CFG if we are testing. we should use values # from UI instead. if test: email_server = test.get('email_server') email_from = test.get('email_from') email_account = test.get('email_account') email_pwd = test.get('email_pwd') if email_pwd and not email_pwd.replace('*', ''): # If all stars, get stored password instead email_pwd = cfg.email_pwd() else: email_server = cfg.email_server() email_from = cfg.email_from() email_account = cfg.email_account() email_pwd = cfg.email_pwd() # email_to is replaced at send_with_template, since it can be an array if not message.strip('\n\r\t '): return "Skipped empty message" if email_server and email_to and email_from: message = _prepare_message(message) server, port = split_host(email_server) if not port: port = 25 logging.debug("Connecting to server %s:%s", server, port) try: mailconn = ssmtplib.SMTP_SSL(server, port) mailconn.ehlo() logging.debug("Connected to server %s:%s", server, port) except Exception, errorcode: if errorcode[0]: # Non SSL mail server logging.debug("Non-SSL mail server detected " \ "reconnecting to server %s:%s", server, port) try: mailconn = smtplib.SMTP(server, port) mailconn.ehlo() except: return errormsg(T('Failed to connect to mail server')) else: return errormsg(T('Failed to connect to mail server')) # TLS support if mailconn.ehlo_resp: m = re.search('STARTTLS', mailconn.ehlo_resp, re.IGNORECASE) if m: logging.debug("TLS mail server detected") try: mailconn.starttls() mailconn.ehlo() except: return errormsg(T('Failed to initiate TLS connection')) # Authentication if (email_account != "") and (email_pwd != ""): try: mailconn.login(email_account, email_pwd) except smtplib.SMTPHeloError: return errormsg(T("The server didn't reply properly to the helo greeting")) except smtplib.SMTPAuthenticationError: return errormsg(T("Failed to authenticate to mail server")) except smtplib.SMTPException: return errormsg(T("No suitable authentication method was found")) except: return errormsg(T("Unknown authentication failure in mail server")) try: mailconn.sendmail(email_from, email_to, message) msg = None except smtplib.SMTPHeloError: msg = errormsg('The server didn\'t reply properly to the helo greeting.') except smtplib.SMTPRecipientsRefused: msg = errormsg('The server rejected ALL recipients (no mail was sent).') except smtplib.SMTPSenderRefused: msg = errormsg('The server didn\'t accept the from_addr.') except smtplib.SMTPDataError: msg = errormsg('The server replied with an unexpected error code (other than a refusal of a recipient).') except: msg = errormsg(T('Failed to send e-mail')) try: mailconn.close() except: errormsg(T('Failed to close mail connection')) if msg: return msg else: logging.info("Notification e-mail succesfully sent") return T('Email succeeded') def get_email_date(): """ Return un-localized date string for the Date: field """ # Get locale indepedant date/time string: "Sun May 22 20:15:12 2011" day, month, dayno, hms, year = time.asctime(time.gmtime()).split() return '%s, %s %s %s %s +0000' % (day, dayno, month, year, hms) ################################################################################ # email_endjob # # ################################################################################ from Cheetah.Template import Template def send_with_template(prefix, parm, test=None): """ Send an email using template """ parm['from'] = cfg.email_from() parm['date'] = get_email_date() lst = [] path = cfg.email_dir.get_path() if path and os.path.exists(path): try: lst = glob.glob(os.path.join(path, '%s-*.tmpl' % prefix)) except: logging.error(Ta('Cannot find email templates in %s'), path) else: path = os.path.join(sabnzbd.DIR_PROG, DEF_EMAIL_TMPL) tpath = os.path.join(path, '%s-%s.tmpl' % (prefix, cfg.language())) if os.path.exists(tpath): lst = [tpath] else: lst = [os.path.join(path, '%s-en.tmpl' % prefix)] sent = False for temp in lst: if os.access(temp, os.R_OK): source = _decode_file(temp) if source: sent = True if test: recipients = [ test.get('email_to') ] else: recipients = cfg.email_to() if len(recipients): for recipient in recipients: parm['to'] = recipient message = Template(source=source, searchList=[parm], filter=EmailFilter, compilerSettings={'directiveStartToken': ''}) ret = send(message.respond(), recipient, test) del message else: ret = T('No recipients given, no email sent') else: ret = T('Invalid encoding of email template %s') % temp errormsg(ret) if not sent: ret = T('No email templates found') errormsg(ret) return ret def endjob(filename, msgid, cat, status, path, bytes, fail_msg, stages, script, script_output, script_ret, test=None): """ Send end-of-job email """ # Translate the stage names tr = sabnzbd.api.Ttemplate if not status and fail_msg: xstages = {tr('stage-fail'): (fail_msg,)} else: xstages = {} for stage in stages: lines = [] for line in stages[stage]: if '\n' in line or '
    ' in line: lines.extend(line.replace('
    ', '\n').split('\n')) else: lines.append(line) xstages[tr('stage-'+stage.lower())] = lines parm = {} parm['status'] = status parm['name'] = filename parm['path'] = path parm['msgid'] = str(msgid) parm['stages'] = xstages parm['script'] = script parm['script_output'] = script_output parm['script_ret'] = script_ret parm['cat'] = cat parm['size'] = "%sB" % to_units(bytes) parm['end_time'] = time.strftime(time_format('%Y-%m-%d %H:%M:%S'), time.localtime(time.time())) return send_with_template('email', parm, test) def rss_mail(feed, jobs): """ Send notification email containing list of files """ parm = {'amount' : len(jobs), 'feed' : feed, 'jobs' : jobs} return send_with_template('rss', parm) def badfetch_mail(msg, url): """ Send notification email about failed NZB fetch """ parm = {'url' : url, 'msg' : msg} return send_with_template('badfetch', parm) ################################################################################ # EMAIL_DISKFULL # # ################################################################################ def diskfull(): """ Send email about disk full, no templates """ if cfg.email_full(): return send(T('''To: %s From: %s Date: %s Subject: SABnzbd reports Disk Full Hi, SABnzbd has stopped downloading, because the disk is almost full. Please make room and resume SABnzbd manually. ''') % (cfg.email_to.get_string(), cfg.email_from(), get_email_date()), cfg.email_to()) else: return "" ################################################################################ def _decode_file(path): """ Return content of file in Unicode string using encoding as specified in the file. Work-around for dumb handling of decoding by Cheetah. """ fp = open(path, 'r') txt = fp.readline() m = re.search(r'#encoding[:\s]+(\S+)', txt) if m and m.group(1): encoding = m.group(1) else: encoding = 'latin-1' source = fp.read() fp.close() try: return source.decode(encoding) except: return '' ################################################################################ from email.message import Message from email.header import Header from email.encoders import encode_quopri RE_HEADER = re.compile(r'^([^:]+):(.*)') def _prepare_message(txt): """ Apply the proper encoding to all email fields. The body will be Latin-1, the headers will be 'quopri'd when necessary. """ def plain(val): """ Return True when val is plain ASCII """ try: val.decode('ascii') return True except: return False # Use Latin-1 because not all email clients know UTF-8. code = 'ISO-8859-1' msg = Message() payload = [] body = False header = False for line in txt.encode(code, 'replace').split('\n'): if header and not line: body = True if body: payload.append(line) else: m = RE_HEADER.search(line) if m: header = True keyword = m.group(1).strip() value = m.group(2).strip() if plain(value): # Don't encode if not needed, because some email clients # choke when headers like "date" are encoded. msg.add_header(keyword, value) else: header = Header(value, code) msg[keyword] = header msg.set_payload('\n'.join(payload), code) # Check for proper encoding, else call it explicitly if not msg.has_key('Content-Transfer-Encoding'): encode_quopri(msg) return msg.as_string() SABnzbd-0.7.20/sabnzbd/encoding.py0000644000000000000000000002447212433712602017021 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.encoding - Unicoded filename support """ import locale from xml.sax.saxutils import escape from Cheetah.Filters import Filter #import unicodedata import sabnzbd gUTF = False def auto_fsys(): global gUTF try: if sabnzbd.DARWIN: gUTF = True else: gUTF = locale.getdefaultlocale()[1].lower().find('utf') >= 0 except: # Incorrect locale implementation, assume the worst gUTF = False def change_fsys(value): global gUTF if not sabnzbd.WIN32 and not sabnzbd.DARWIN: if value == 1: gUTF = False elif value == 2: gUTF = True else: auto_fsys() def reliable_unpack_names(): """ See if it is safe to rely on unrar names """ if sabnzbd.WIN32 or sabnzbd.DARWIN: return True else: return gUTF def platform_encode(p): """ Return the correct encoding for the platform: Latin-1 for Windows/Posix-non-UTF and UTF-8 for OSX/Posix-UTF """ if isinstance(p, unicode): if gUTF: return p.encode('utf-8') else: return p.encode('latin-1', 'replace') elif isinstance(p, basestring): if gUTF: try: p.decode('utf-8') return p except: return p.decode('latin-1').encode('utf-8') else: try: return p.decode('utf-8').encode('latin-1', 'replace') except: return p else: return p def name_fixer(p): """ Return UTF-8 encoded string, if appropriate for the platform """ if gUTF and p: return p.decode('Latin-1', 'replace').encode('utf-8', 'replace').replace('?', '_') else: return p def is_utf8(p): """ Return True when p is UTF-8 or plain ASCII """ utf8 = True try: p.decode('ascii') except: try: p.decode('utf-8') except: utf8 = False return utf8 def special_fixer(p): """ Return string appropriate for the platform. Also takes care of the situation where a non-Windows/UTF-8 system receives a latin-1 encoded name. """ if sabnzbd.WIN32: try: return p.decode('utf-8').encode('latin-1', 'replace').replace('?', '_') except: return p else: if gUTF: try: # First see if it isn't just UTF-8 p.decode('utf-8') if sabnzbd.DARWIN and '&#' in p: p = fixup_ff4(p) return p except: # Now assume it's latin-1 try: return p.decode('Latin-1').encode('utf-8') except: return p else: return p def unicoder(p): """ Make sure a Unicode string is returned """ if isinstance(p, unicode): return p if isinstance(p, str): if gUTF: try: return p.decode('utf-8') except: return p.decode('latin-1', 'replace') return p.decode('latin-1', 'replace') else: return unicode(str(p)) def unicode2local(p): """ Convert Unicode filename to appropriate local encoding Leave ? characters for uncovertible characters """ if sabnzbd.WIN32: return p.encode('Latin-1', 'replace') else: return p.encode('utf-8', 'replace') def xml_name(p, keep_escape=False, encoding=None): """ Prepare name for use in HTML/XML contect """ if isinstance(p, unicode): pass elif isinstance(p, str): if sabnzbd.DARWIN or encoding == 'utf-8': p = p.decode('utf-8', 'replace') elif gUTF: p = p.decode('utf-8', 'replace') else: p = p.decode('Latin-1', 'replace') else: p = str(p) if keep_escape: return p.encode('ascii', 'xmlcharrefreplace') else: return escape(p).encode('ascii', 'xmlcharrefreplace') def latin1(txt): """ When Unicode or UTF-8, convert to Latin-1 """ if isinstance(txt, unicode): return txt.encode('latin-1', 'replace').replace('?', '_') elif txt and gUTF: #return unicodedata.normalize('NFC', txt.decode('utf-8')).encode('latin-1', 'replace').replace('?', '_') return txt.decode('utf-8').encode('latin-1', 'replace').replace('?', '_') else: return txt def encode_for_xml(ustr, encoding='ascii'): """ Encode unicode_data for use as XML or HTML, with characters outside of the encoding converted to XML numeric character references. """ if isinstance(ustr, unicode): pass elif isinstance(ustr, str): ustr = ustr.decode('Latin-1', 'replace') else: ustr = unicode(str(ustr)) return ustr.encode(encoding, 'xmlcharrefreplace') def titler(p): """ title() replacement Python's title() fails with Latin-1, so use Unicode detour. """ if isinstance(p, unicode): return p.title() elif gUTF: try: return p.decode('utf-8').title().encode('utf-8') except: return p.decode('latin-1', 'replace').title().encode('latin-1', 'replace') else: return p.decode('latin-1', 'replace').title().encode('latin-1', 'replace') class LatinFilter(Filter): """ Make sure Cheetah gets only Unicode strings """ def filter(self, val, str=str, **kw): if isinstance(val, unicode): return val elif isinstance(val, basestring): try: if sabnzbd.WIN32: return val.decode('latin-1') else: return val.decode('utf-8') except: return val.decode('latin-1', 'replace') elif val is None: return u'' else: return unicode(str(val)) class EmailFilter(Filter): """ Make sure Cheetah gets only Unicode strings First try utf-8, then latin1 """ def filter(self, val, str=str, **kw): if isinstance(val, unicode): return val elif isinstance(val, basestring): try: return val.decode('utf-8') except: return val.decode('latin-1', 'replace') elif val is None: return u'' else: return unicode(str(val)) ################################################################################ # # Map CodePage-850 characters to Python's pseudo-Unicode 8bit ASCII # # Use to transform 8-bit console output to plain Python strings # import string TAB_850 = \ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F" \ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" \ "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF" \ "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF" \ "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF" \ "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF" \ "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF" \ "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF" TAB_LATIN = \ "\xC7\xFC\xE9\xE2\xE4\xE0\xE5\xE7\xEA\xEB\xE8\xEF\xEE\xEC\xC4\xC5" \ "\xC9\xE6\xC6\xF4\xF6\xF2\xFB\xF9\xFF\xD6\xDC\xF8\xA3\xD8\xD7\x66" \ "\xE1\xED\xF3\xFA\xF1\xD1\xAA\xBA\xBF\xAE\xAC\xDB\xBC\xA1\xAB\xBB" \ "\x7E\x7E\x7E\x7E\x7E\xC1\xC2\xC0\xA9\x7E\x7E\x7E\x7E\xA2\xA5\x7E" \ "\x7E\x7E\x7E\x7E\x7E\x7E\xE3\xc3\x7E\x7E\x7E\x7E\x7E\x7E\x7E\xA4" \ "\xF0\xD0\xCA\xCB\xC8\x7E\xCD\xCE\xCF\x7E\x7E\x7E\x7E\xA6\xCC\x7E" \ "\xD3\xDF\xD4\xD2\xF5\xD5\xB5\xFE\xDE\xDA\xDB\xD9\xFD\xDD\xAF\xB4" \ "\xAD\xB1\x5F\xBE\xB6\xA7\xF7\xB8\xB0\xA8\xB7\xB9\xB3\xB2\x7E\xA0" gTABLE_850_LATIN = string.maketrans(TAB_850, TAB_LATIN) gTABLE_LATIN_850 = string.maketrans(TAB_LATIN, TAB_850) def TRANS(p): """ For Windows: Translate CP850 to Python's Latin-1 """ global gTABLE_850_LATIN if sabnzbd.WIN32: return p.translate(gTABLE_850_LATIN) else: return p def UNTRANS(p): """ For Windows: Translate Python's Latin-1 to CP850 """ global gTABLE_LATIN_850 if sabnzbd.WIN32: return p.translate(gTABLE_LATIN_850) else: return p def fixup_ff4(p): """ Fix incompatibility between CherryPy and Firefox-4 on OSX, where a filename contains &#xx; encodings """ name = [] start = amp = False for ch in p: if start: if ch.isdigit(): num += ch elif ch == ';': name.append(unichr(int(num)).encode('utf8')) start = False else: name.append('&#%s%s' % (num, ch)) start = False elif ch == '&': amp = True elif amp: amp = False if ch == '#': start = True num = '' else: name.append('&' + ch) else: name.append(ch) return ''.join(name) _HTML_TABLE = { #'&' : '&', # Not yet, texts need to be cleaned from HTML first #'>' : '>', # Not yet, texts need to be cleaned from HTML first #'<' : '<', # Not yet, texts need to be cleaned from HTML first '"' : '"', "'" : ''' } def html_escape(txt): """ Replace HTML metacharacters with &-constructs """ # Replacement for inefficient xml.sax.saxutils.escape function if [True for ch in _HTML_TABLE if ch in txt]: return ''.join((_HTML_TABLE.get(ch, ch) for ch in txt)) else: return txt auto_fsys() SABnzbd-0.7.20/sabnzbd/growler.py0000644000000000000000000003016012433712602016703 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # """ sabnzbd.growler - Send notifications to Growl """ #------------------------------------------------------------------------------ from __future__ import with_statement import os.path import logging import socket import time import subprocess from threading import Thread import sabnzbd import sabnzbd.cfg from sabnzbd.encoding import unicoder, latin1 from sabnzbd.constants import NOTIFY_KEYS from gntp import GNTPRegister from gntp.notifier import GrowlNotifier try: import Growl # Detect classic Growl (older than 1.3) _HAVE_CLASSIC_GROWL = os.path.isfile('/Library/PreferencePanes/Growl.prefPane/Contents/MacOS/Growl') except ImportError: _HAVE_CLASSIC_GROWL = False try: import warnings # Make any warnings exceptions, so that pynotify is ignored # PyNotify will not work with Python 2.5 (due to next three lines) with warnings.catch_warnings(): warnings.simplefilter("error") import pynotify _HAVE_NTFOSD = True except: _HAVE_NTFOSD = False #------------------------------------------------------------------------------ # Define translatable message table TT = lambda x:x NOTIFICATION = { 'startup' : TT('Startup/Shutdown'), #: Message class for Growl server 'download' : TT('Added NZB'), #: Message class for Growl server 'pp' : TT('Post-processing started'), #: Message class for Growl server 'complete' : TT('Job finished'), #: Message class for Growl server 'other' : TT('Other Messages') #: Message class for Growl server } #------------------------------------------------------------------------------ # Setup platform dependent Growl support # _GROWL = None # Instance of the Notifier after registration _GROWL_REG = False # Succesful registration #------------------------------------------------------------------------------ def get_icon(): icon = os.path.join(os.path.join(sabnzbd.DIR_PROG, 'icons'), 'sabnzbd.ico') if not os.path.isfile(icon): icon = os.path.join(sabnzbd.DIR_PROG, 'sabnzbd.ico') if os.path.isfile(icon): if sabnzbd.WIN32 or sabnzbd.DARWIN: fp = open(icon, 'rb') icon = fp.read() fp.close else: # Due to a bug in GNTP, need this work-around for Linux/Unix icon = 'http://sabnzbdplus.sourceforge.net/version/sabnzbd.ico' else: icon = None return icon #------------------------------------------------------------------------------ def change_value(): """ Signal that we should register with a new Growl server """ global _GROWL_REG _GROWL_REG = False #------------------------------------------------------------------------------ def have_ntfosd(): """ Return if any PyNotify support is present """ return bool(_HAVE_NTFOSD) #------------------------------------------------------------------------------ def send_notification(title , msg, gtype, wait=False, test=None): """ Send Notification message Return '' when OK, otherwise an error string """ res = [] if gtype in sabnzbd.cfg.notify_classes() or wait: # support testing values from UI if (test): ncenter_enable = test.get('ncenter_enable') == 'true' ntfosd_enable = test.get('ntfosd_enable') == 'true' growl_enable = test.get('growl_enable') == 'true' growl_server = test.get('growl_server') or None else: ncenter_enable = sabnzbd.cfg.ncenter_enable() ntfosd_enable = sabnzbd.cfg.ntfosd_enable() growl_enable = sabnzbd.cfg.growl_enable() growl_server = sabnzbd.cfg.growl_server() if sabnzbd.DARWIN_ML and ncenter_enable: res.append(send_notification_center(title, msg, gtype)) if growl_enable: if _HAVE_CLASSIC_GROWL and not growl_server: return send_local_growl(title, msg, gtype) else: if wait: # we only test with wait=True res.append(send_growl(title, msg, gtype, test)) else: res.append('ok') Thread(target=send_growl, args=(title, msg, gtype)).start() time.sleep(0.5) if ntfosd_enable and have_ntfosd(): res.append(send_notify_osd(title, msg)) return ' / '.join([r for r in res if r]) #------------------------------------------------------------------------------ def reset_growl(): """ Reset Growl (after changing language) """ global _GROWL, _GROWL_REG _GROWL = None _GROWL_REG = False #------------------------------------------------------------------------------ def register_growl(test=None): """ Register this app with Growl """ error = None if (test): growl_server = test.get('growl_server') growl_password = test.get('growl_password') else: growl_server = sabnzbd.cfg.growl_server() growl_password = sabnzbd.cfg.growl_password() host, port = sabnzbd.misc.split_host(growl_server) sys_name = hostname(host) # Clean up persistent data in GNTP to make re-registration work GNTPRegister.notifications = [] GNTPRegister.headers = {} growler = GrowlNotifier( applicationName = 'SABnzbd%s' % sys_name, applicationIcon = get_icon(), notifications = [Tx(NOTIFICATION[key]) for key in NOTIFY_KEYS], hostname = host or 'localhost', port = port or 23053, password = growl_password or None ) try: ret = growler.register() if ret is None or isinstance(ret, bool): logging.info('Registered with Growl') ret = growler else: error = 'Cannot register with Growl %s' % str(ret) logging.debug(error) del growler ret = None except socket.error, err: error = 'Cannot register with Growl %s' % str(err) logging.debug(error) del growler ret = None except: error = 'Unknown Growl registration error' logging.debug(error) logging.info("Traceback: ", exc_info = True) del growler ret = None return ret, error #------------------------------------------------------------------------------ def send_growl(title , msg, gtype, test=None): """ Send Growl message """ global _GROWL, _GROWL_REG for n in (0, 1): if not _GROWL_REG: _GROWL = None if test: reset_growl() if not _GROWL: _GROWL, error = register_growl(test) if _GROWL: assert isinstance(_GROWL, GrowlNotifier) _GROWL_REG = True if not isinstance(msg, str) and not isinstance(msg, unicode): msg = str(msg) logging.debug('Send to Growl: %s %s %s', gtype, latin1(title), latin1(msg)) try: ret = _GROWL.notify( noteType = Tx(NOTIFICATION.get(gtype, 'other')), title = title, description = unicoder(msg), ) if ret is None or isinstance(ret, bool): result = None elif ret[0] == '401': _GROWL = False else: logging.debug('Growl error %s', ret) result = 'Growl error %s', ret except socket.error, err: error = 'Growl error %s' % err logging.debug(error) result = error except: error = 'Growl error (unknown)' logging.debug(error) result = error else: result = error if test: reset_growl() return result return None #------------------------------------------------------------------------------ # Local OSX Growl support # if _HAVE_CLASSIC_GROWL: _local_growl = None if os.path.isfile('sabnzbdplus.icns'): _OSX_ICON = Growl.Image.imageFromPath('sabnzbdplus.icns') elif os.path.isfile('osx/resources/sabnzbdplus.icns'): _OSX_ICON = Growl.Image.imageFromPath('osx/resources/sabnzbdplus.icns') else: _OSX_ICON = Growl.Image.imageWithIconForApplication('Terminal') def send_local_growl(title , msg, gtype): """ Send to local Growl server, OSX-only """ global _local_growl if not _local_growl: notes = [Tx(NOTIFICATION[key]) for key in NOTIFY_KEYS] _local_growl = Growl.GrowlNotifier( applicationName = 'SABnzbd', applicationIcon = _OSX_ICON, notifications = notes, defaultNotifications = notes ) _local_growl.register() _local_growl.notify(Tx(NOTIFICATION.get(gtype, 'other')), title, msg) return None #------------------------------------------------------------------------------ # Ubuntu NotifyOSD Support # if _HAVE_NTFOSD: _NTFOSD = False def send_notify_osd(title, message): """ Send a message to NotifyOSD """ global _NTFOSD error = 'NotifyOSD not working' if sabnzbd.cfg.ntfosd_enable(): icon = os.path.join(sabnzbd.DIR_PROG, 'sabnzbd.ico') _NTFOSD = _NTFOSD or pynotify.init('icon-summary-body') if _NTFOSD: logging.info('Send to NotifyOSD: %s / %s', latin1(title), latin1(message)) try: note = pynotify.Notification(title, message, icon) note.show() except: # Apparently not implemented on this system logging.info(error) return error return None else: return error else: return 'Not enabled' def ncenter_path(): """ Return path of Notification Center tool, if it exists """ tool = os.path.normpath(os.path.join(sabnzbd.DIR_PROG, '../Resources/SABnzbd.app/Contents/MacOS/SABnzbd')) if os.path.exists(tool): return tool else: return None def send_notification_center(title, msg, gtype): """ Send message to Mountain Lion's Notification Center """ tool = ncenter_path() if tool: try: command = [tool, '-title', title, '-message', msg, '-group', Tx(NOTIFICATION.get(gtype, 'other')), '-sender', 'org.sabnzbd.team'] proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) output = proc.stdout.read() proc.wait() if 'Notification delivered' in output or 'Removing previously' in output: output = '' except: logging.info('Cannot run notifier "%s"', tool) logging.debug("Traceback: ", exc_info = True) output = 'Notifier tool crashed' else: output = 'Notifier app not found' return output.strip('*\n ') #------------------------------------------------------------------------------ def hostname(host=True): """ Return host's pretty name """ if sabnzbd.WIN32: sys_name = os.environ.get('computername', 'unknown') else: try: sys_name = os.uname()[1] except: sys_name = 'unknown' if host: return '@%s' % sys_name.lower() else: return '' SABnzbd-0.7.20/sabnzbd/interface.py0000644000000000000000000030027612433712602017172 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.interface - webinterface """ import os import time import cherrypy import logging import re import urllib from xml.sax.saxutils import escape from sabnzbd.utils.rsslib import RSS, Item import sabnzbd import sabnzbd.rss import sabnzbd.scheduler as scheduler from Cheetah.Template import Template from sabnzbd.misc import real_path, to_units, \ diskfree, sanitize_foldername, time_format, HAVE_AMPM, \ cat_to_opts, int_conv, globber, remove_all, get_base_url from sabnzbd.panic import panic_old_queue from sabnzbd.newswrapper import GetServerParms from sabnzbd.newzbin import Bookmarks from sabnzbd.rating import Rating from sabnzbd.bpsmeter import BPSMeter from sabnzbd.encoding import TRANS, xml_name, LatinFilter, unicoder, special_fixer, \ platform_encode, latin1, encode_for_xml import sabnzbd.config as config import sabnzbd.cfg as cfg import sabnzbd.newsunpack from sabnzbd.postproc import PostProcessor from sabnzbd.downloader import Downloader from sabnzbd.nzbqueue import NzbQueue import sabnzbd.wizard from sabnzbd.utils.servertests import test_nntp_server_dict from sabnzbd.constants import * from sabnzbd.lang import list_languages, set_language from sabnzbd.api import list_scripts, list_cats, del_from_section, \ api_handler, build_queue, rss_qstatus, \ retry_job, build_header, build_history, del_job_files, \ format_bytes, calc_age, std_time, report, del_hist_job, Ttemplate, \ _api_test_email, _api_test_notif #------------------------------------------------------------------------------ # Global constants DIRECTIVES = { 'directiveStartToken': '', 'prioritizeSearchListOverSelf' : True } FILTER = LatinFilter #------------------------------------------------------------------------------ # def check_server(host, port): """ Check if server address resolves properly """ if host.lower() == 'localhost' and sabnzbd.AMBI_LOCALHOST: return badParameterResponse(T('Warning: LOCALHOST is ambiguous, use numerical IP-address.')) if GetServerParms(host, int_conv(port)): return "" else: return badParameterResponse(T('Server address "%s:%s" is not valid.') % (host, port)) def check_access(): """ Check if external address is allowed """ referrer = cherrypy.request.remote.ip return referrer in ('127.0.0.1', '::1') or referrer.startswith(cfg.local_range()) def ConvertSpecials(p): """ Convert None to 'None' and 'Default' to '' """ if p is None: p = 'None' elif p.lower() == T('Default').lower(): p = '' return p def Raiser(root, **kwargs): args = {} for key in kwargs: val = kwargs.get(key) if val: args[key] = val root = '%s?%s' % (root, urllib.urlencode(args)) return cherrypy.HTTPRedirect(root) def queueRaiser(root, kwargs): return Raiser(root, start=kwargs.get('start'), limit=kwargs.get('limit'), search=kwargs.get('search'), _dc=kwargs.get('_dc')) def dcRaiser(root, kwargs): return Raiser(root, _dc=kwargs.get('_dc')) def rssRaiser(root, kwargs): return Raiser(root, feed=kwargs.get('feed')) #------------------------------------------------------------------------------ def IsNone(value): """ Return True if either None, 'None' or '' """ return value==None or value=="" or value.lower()=='none' def Strip(txt): """ Return stripped string, can handle None """ try: return txt.strip() except: return None #------------------------------------------------------------------------------ # Web login support def get_users(): users = {} users[cfg.username()] = cfg.password() return users def encrypt_pwd(pwd): return pwd def set_auth(conf): """ Set the authentication for CherryPy """ if cfg.username() and cfg.password(): conf.update({'tools.basic_auth.on' : True, 'tools.basic_auth.realm' : cfg.login_realm(), 'tools.basic_auth.users' : get_users, 'tools.basic_auth.encrypt' : encrypt_pwd}) conf.update({'/api':{'tools.basic_auth.on' : False}, '/m/api':{'tools.basic_auth.on' : False}, '/sabnzbd/api':{'tools.basic_auth.on' : False}, '/sabnzbd/m/api':{'tools.basic_auth.on' : False}, }) else: conf.update({'tools.basic_auth.on':False}) def check_session(kwargs): """ Check session key """ if not check_access(): return u'No access' key = kwargs.get('session') if not key: key = kwargs.get('apikey') msg = None if not key: logging.warning(Ta('Missing Session key')) msg = T('Error: Session Key Required') elif key != cfg.api_key(): logging.warning(Ta('Error: Session Key Incorrect')) msg = T('Error: Session Key Incorrect') return msg #------------------------------------------------------------------------------ def check_apikey(kwargs, nokey=False): """ Check api key or nzbkey Return None when OK, otherwise an error message """ def log_warning(txt): txt = '%s %s>%s' % (txt, cherrypy.request.remote.ip, cherrypy.request.headers.get('User-Agent', '??')) logging.warning('%s', txt) output = kwargs.get('output') mode = kwargs.get('mode', '') callback = kwargs.get('callback') # Don't give a visible warning: these commands are used by some # external utilities to detect if username/password is required # The cfg item can suppress all visible warnings special = mode in ('get_scripts', 'qstatus') or not cfg.api_warnings.get() # For NZB upload calls, a separate key can be used nzbkey = kwargs.get('mode', '') in ('addid', 'addurl', 'addfile', 'addlocalfile') if not nzbkey and not check_access(): return report(output, 'No access') # First check APIKEY, if OK that's sufficient if not (cfg.disable_key() or nokey): key = kwargs.get('apikey') if not key: if not special: log_warning(Ta('API Key missing, please enter the api key from Config->General into your 3rd party program:')) return report(output, 'API Key Required', callback=callback) elif nzbkey and key == cfg.nzb_key(): return None elif key == cfg.api_key(): return None else: log_warning(Ta('API Key incorrect, Use the api key from Config->General in your 3rd party program:')) return report(output, 'API Key Incorrect', callback=callback) # No active APIKEY, check web credentials instead if cfg.username() and cfg.password(): if kwargs.get('ma_username') == cfg.username() and kwargs.get('ma_password') == cfg.password(): pass else: if not special: log_warning(Ta('Authentication missing, please enter username/password from Config->General into your 3rd party program:')) return report(output, 'Missing authentication', callback=callback) return None #------------------------------------------------------------------------------ class NoPage(object): def __init__(self): pass @cherrypy.expose def index(self, **kwargs): return badParameterResponse(T('Error: No secondary interface defined.')) class MainPage(object): def __init__(self, web_dir, root, web_dir2=None, root2=None, web_dirc=None, prim=True, first=0): self.__root = root self.__web_dir = web_dir self.__prim = prim if first >= 1 and web_dir2: # Setup addresses for secondary skin self.m = MainPage(web_dir2, root2, web_dirc=web_dirc, prim=False) if first == 2: # Setup addresses with /sabnzbd prefix for primary and secondary skin self.sabnzbd = MainPage(web_dir, '/sabnzbd/', web_dir2, '/sabnzbd/m/', web_dirc=web_dirc, prim=True, first=1) self.queue = QueuePage(web_dir, root+'queue/', prim) self.history = HistoryPage(web_dir, root+'history/', prim) self.status = Status(web_dir, root+'status/', prim) if cfg.uniconfig() and web_dirc: self.config = ConfigPage(web_dirc, root+'config/', prim) else: self.config = ConfigPage(web_dir, root+'config/', prim) self.nzb = NzoPage(web_dir, root+'nzb/', prim) self.wizard = sabnzbd.wizard.Wizard(web_dir, root+'wizard/', prim) @cherrypy.expose def index(self, **kwargs): if not check_access(): return Protected() if sabnzbd.OLD_QUEUE and not cfg.warned_old_queue(): cfg.warned_old_queue.set(True) config.save_config() return panic_old_queue() if kwargs.get('skip_wizard') or config.get_servers(): info, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) if cfg.newzbin_username() and cfg.newzbin_password.get_stars(): info['newzbinDetails'] = True info['script_list'] = list_scripts(default=True) info['script'] = 'Default' info['cat'] = 'Default' info['cat_list'] = list_cats(True) info['have_rss_defined'] = bool(config.get_rss()) info['have_watched_dir'] = bool(cfg.dirscan_dir()) info['warning'] = '' if cfg.enable_unrar(): if sabnzbd.newsunpack.RAR_PROBLEM and not cfg.ignore_wrong_unrar(): info['warning'] = T('Your UNRAR version is not recommended, get it from http://www.rarlab.com/rar_add.htm
    ') if not sabnzbd.newsunpack.RAR_COMMAND: info['warning'] = T('No UNRAR program found, unpacking RAR files is not possible
    ') if not sabnzbd.newsunpack.PAR2_COMMAND: info['warning'] = T('No PAR2 program found, repairs not possible
    ') template = Template(file=os.path.join(self.__web_dir, 'main.tmpl'), filter=FILTER, searchList=[info], compilerSettings=DIRECTIVES) return template.respond() else: # Redirect to the setup wizard raise cherrypy.HTTPRedirect('/wizard/') #@cherrypy.expose #def reset_lang(self, **kwargs): # msg = check_session(kwargs) # if msg: return msg # set_language(cfg.language()) # raise dcRaiser(self.__root, kwargs) def add_handler(self, kwargs): if not check_access(): return Protected() id = kwargs.get('id', '') if not id: id = kwargs.get('url', '') pp = kwargs.get('pp') script = kwargs.get('script') cat = kwargs.get('cat') priority = kwargs.get('priority') redirect = kwargs.get('redirect') nzbname = kwargs.get('nzbname') RE_NEWZBIN_URL = re.compile(r'/browse/post/(\d+)') newzbin_url = RE_NEWZBIN_URL.search(id.lower()) id = Strip(id) if id and (id.isdigit() or len(id)==5): sabnzbd.add_msgid(id, pp, script, cat, priority, nzbname) elif newzbin_url: sabnzbd.add_msgid(Strip(newzbin_url.group(1)), pp, script, cat, priority, nzbname) elif id: sabnzbd.add_url(id, pp, script, cat, priority, nzbname) if not redirect: redirect = self.__root raise cherrypy.HTTPRedirect(redirect) @cherrypy.expose def addID(self, **kwargs): msg = check_session(kwargs) if msg: return msg raise self.add_handler(kwargs) @cherrypy.expose def addURL(self, **kwargs): msg = check_session(kwargs) if msg: return msg raise self.add_handler(kwargs) @cherrypy.expose def addFile(self, **kwargs): msg = check_session(kwargs) if msg: return msg nzbfile = kwargs.get('nzbfile') if nzbfile is not None and nzbfile.filename and nzbfile.value: sabnzbd.add_nzbfile(nzbfile, kwargs.get('pp'), kwargs.get('script'), kwargs.get('cat'), kwargs.get('priority', NORMAL_PRIORITY)) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def shutdown(self, **kwargs): msg = check_session(kwargs) if msg: yield msg else: yield "Initiating shutdown..." sabnzbd.halt() yield "
    SABnzbd-%s shutdown finished" % sabnzbd.__version__ cherrypy.engine.exit() sabnzbd.SABSTOP = True @cherrypy.expose def pause(self, **kwargs): msg = check_session(kwargs) if msg: return msg scheduler.plan_resume(0) Downloader.do.pause() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def resume(self, **kwargs): msg = check_session(kwargs) if msg: return msg scheduler.plan_resume(0) sabnzbd.unpause_all() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def rss(self, **kwargs): msg = check_apikey(kwargs, nokey=True) if msg: return msg if kwargs.get('mode') == 'history': return rss_history(cherrypy.url(), limit=kwargs.get('limit',50), search=kwargs.get('search')) elif kwargs.get('mode') == 'queue': return rss_qstatus() elif kwargs.get('mode') == 'warnings': return rss_warnings() @cherrypy.expose def tapi(self, **kwargs): """Handler for API over http, for template use """ msg = check_session(kwargs) if msg: return msg return api_handler(kwargs) @cherrypy.expose def api(self, **kwargs): """Handler for API over http, with explicit authentication parameters """ if not kwargs.get('tickleme') or not cfg.web_watchdog(): logging.debug('API-call from %s [%s] %s', cherrypy.request.remote.ip, \ cherrypy.request.headers.get('User-Agent', '??'), kwargs) if kwargs.get('mode', '') not in ('version', 'auth'): msg = check_apikey(kwargs) if msg: return msg return api_handler(kwargs) @cherrypy.expose def scriptlog(self, **kwargs): """ Duplicate of scriptlog of History, needed for some skins """ # No session key check, due to fixed URLs if not check_access(): return Protected() name = kwargs.get('name') if name: history_db = cherrypy.thread_data.history_db return ShowString(history_db.get_name(name), history_db.get_script_log(name)) else: raise dcRaiser(self.__root, kwargs) @cherrypy.expose def retry(self, **kwargs): """ Duplicate of retry of History, needed for some skins """ msg = check_session(kwargs) if msg: return msg job = kwargs.get('job', '') url = kwargs.get('url', '').strip() pp = kwargs.get('pp') cat = kwargs.get('cat') script = kwargs.get('script') if url and (url.isdigit() or len(url)==5): sabnzbd.add_msgid(url, pp, script, cat) elif url: sabnzbd.add_url(url, pp, script, cat, nzbname=kwargs.get('nzbname')) del_hist_job(job, del_files=True) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def retry_pp(self, **kwargs): # Duplicate of History/retry_pp to please the SMPL skin :( msg = check_session(kwargs) if msg: return msg retry_job(kwargs.get('job'), kwargs.get('nzbfile')) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def robots_txt(self): """ Keep web crawlers out """ cherrypy.response.headers['Content-Type'] = 'text/plain' return 'User-agent: *\nDisallow: /\n' #------------------------------------------------------------------------------ class NzoPage(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__verbose = False self.__prim = prim self.__cached_selection = {} #None @cherrypy.expose def default(self, *args, **kwargs): # Allowed URL's # /nzb/SABnzbd_nzo_xxxxx/ # /nzb/SABnzbd_nzo_xxxxx/details # /nzb/SABnzbd_nzo_xxxxx/files # /nzb/SABnzbd_nzo_xxxxx/bulk_operation # /nzb/SABnzbd_nzo_xxxxx/save if not check_access(): return Protected() nzo_id = None for a in args: if a.startswith('SABnzbd_nzo'): nzo_id = a break if nzo_id and NzbQueue.do.get_nzo(nzo_id): info, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) # /SABnzbd_nzo_xxxxx/bulk_operation if 'bulk_operation' in args: return self.bulk_operation(nzo_id, kwargs) # /SABnzbd_nzo_xxxxx/details elif 'details' in args: info = self.nzo_details(info, pnfo_list, nzo_id) # /SABnzbd_nzo_xxxxx/files elif 'files' in args: info = self.nzo_files(info, pnfo_list, nzo_id) # /SABnzbd_nzo_xxxxx/save elif 'save' in args: self.save_details(nzo_id, args, kwargs) return # never reached # /SABnzbd_nzo_xxxxx/ else: info = self.nzo_details(info, pnfo_list, nzo_id) info = self.nzo_files(info, pnfo_list, nzo_id) template = Template(file=os.path.join(self.__web_dir, 'nzo.tmpl'), filter=FILTER, searchList=[info], compilerSettings=DIRECTIVES) return template.respond() else: # Job no longer exists, go to main page raise dcRaiser(cherrypy._urljoin(self.__root, '../queue/'), {}) def nzo_details(self, info, pnfo_list, nzo_id): slot = {} n = 0 for pnfo in pnfo_list: if pnfo[PNFO_NZO_ID_FIELD] == nzo_id: nzo = sabnzbd.nzbqueue.get_nzo(nzo_id) repair = pnfo[PNFO_REPAIR_FIELD] unpack = pnfo[PNFO_UNPACK_FIELD] delete = pnfo[PNFO_DELETE_FIELD] unpackopts = sabnzbd.opts_to_pp(repair, unpack, delete) script = pnfo[PNFO_SCRIPT_FIELD] if script is None: script = 'None' cat = pnfo[PNFO_EXTRA_FIELD1] if not cat: cat = 'None' filename_pw = xml_name(nzo.final_name_pw_clean) filename = xml_name(nzo.final_name) if nzo.password: password = xml_name(nzo.password).replace('"', '"') else: password = '' priority = pnfo[PNFO_PRIORITY_FIELD] slot['nzo_id'] = str(nzo_id) slot['cat'] = cat slot['filename'] = filename_pw slot['filename_clean'] = filename slot['password'] = password or '' slot['script'] = script slot['priority'] = str(priority) slot['unpackopts'] = str(unpackopts) info['index'] = n break n += 1 info['slot'] = slot info['script_list'] = list_scripts() info['cat_list'] = list_cats() info['noofslots'] = len(pnfo_list) return info def nzo_files(self, info, pnfo_list, nzo_id): active = [] for pnfo in pnfo_list: if pnfo[PNFO_NZO_ID_FIELD] == nzo_id: info['nzo_id'] = nzo_id info['filename'] = xml_name(pnfo[PNFO_FILENAME_FIELD]) for tup in pnfo[PNFO_ACTIVE_FILES_FIELD]: bytes_left, bytes, fn, date, nzf_id = tup checked = False if nzf_id in self.__cached_selection and \ self.__cached_selection[nzf_id] == 'on': checked = True line = {'filename':xml_name(fn), 'mbleft':"%.2f" % (bytes_left / MEBI), 'mb':"%.2f" % (bytes / MEBI), 'size': format_bytes(bytes), 'sizeleft':format_bytes(bytes_left), 'nzf_id':nzf_id, 'age':calc_age(date), 'checked':checked} active.append(line) break info['active_files'] = active return info def save_details(self, nzo_id, args, kwargs): index = kwargs.get('index', None) name = kwargs.get('name', None) password = kwargs.get('password', None) if password == "": password = None pp = kwargs.get('pp', None) script = kwargs.get('script', None) cat = kwargs.get('cat', None) priority = kwargs.get('priority', None) nzo = sabnzbd.nzbqueue.get_nzo(nzo_id) if index != None: NzbQueue.do.switch(nzo_id, index) if name != None: NzbQueue.do.change_name(nzo_id, special_fixer(name), password) if cat != None: NzbQueue.do.change_cat(nzo_id, cat, priority) if script != None: NzbQueue.do.change_script(nzo_id,script) if pp != None: NzbQueue.do.change_opts(nzo_id,pp) if priority != None and nzo and nzo.priority != int(priority): NzbQueue.do.set_priority(nzo_id, priority) raise dcRaiser(cherrypy._urljoin(self.__root, '../queue/'), {}) def bulk_operation(self, nzo_id, kwargs): self.__cached_selection = kwargs if kwargs['action_key'] == 'Delete': for key in kwargs: if kwargs[key] == 'on': NzbQueue.do.remove_nzf(nzo_id, key) elif kwargs['action_key'] == 'Top' or kwargs['action_key'] == 'Up' or \ kwargs['action_key'] == 'Down' or kwargs['action_key'] == 'Bottom': nzf_ids = [] for key in kwargs: if kwargs[key] == 'on': nzf_ids.append(key) if kwargs['action_key'] == 'Top': NzbQueue.do.move_top_bulk(nzo_id, nzf_ids) elif kwargs['action_key'] == 'Up': NzbQueue.do.move_up_bulk(nzo_id, nzf_ids) elif kwargs['action_key'] == 'Down': NzbQueue.do.move_down_bulk(nzo_id, nzf_ids) elif kwargs['action_key'] == 'Bottom': NzbQueue.do.move_bottom_bulk(nzo_id, nzf_ids) if sabnzbd.nzbqueue.get_nzo(nzo_id): url = cherrypy._urljoin(self.__root, nzo_id) else: url = cherrypy._urljoin(self.__root, '../queue') if url and not url.endswith('/'): url += '/' raise dcRaiser(url, kwargs) #------------------------------------------------------------------------------ class QueuePage(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__verbose = False self.__verbose_list = [] self.__prim = prim @cherrypy.expose def index(self, **kwargs): if not check_access(): return Protected() start = kwargs.get('start') limit = kwargs.get('limit') dummy2 = kwargs.get('dummy2') info, pnfo_list, bytespersec, self.__verbose_list, self.__dict__ = build_queue(self.__web_dir, self.__root, self.__verbose,\ self.__prim, self.__web_dir, self.__verbose_list, self.__dict__, start=start, limit=limit, dummy2=dummy2, trans=True) template = Template(file=os.path.join(self.__web_dir, 'queue.tmpl'), filter=FILTER, searchList=[info], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def delete(self, **kwargs): msg = check_session(kwargs) if msg: return msg uid = kwargs.get('uid') del_files = int_conv(kwargs.get('del_files')) if uid: NzbQueue.do.remove(uid, False, keep_basic=not del_files, del_files=del_files) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def purge(self, **kwargs): msg = check_session(kwargs) if msg: return msg NzbQueue.do.remove_all() raise queueRaiser(self.__root, kwargs) @cherrypy.expose def removeNzf(self, **kwargs): msg = check_session(kwargs) if msg: return msg nzo_id = kwargs.get('nzo_id') nzf_id = kwargs.get('nzf_id') if nzo_id and nzf_id: NzbQueue.do.remove_nzf(nzo_id, nzf_id) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def tog_verbose(self, **kwargs): msg = check_session(kwargs) if msg: return msg self.__verbose = not self.__verbose raise queueRaiser(self.__root, kwargs) @cherrypy.expose def tog_uid_verbose(self, **kwargs): msg = check_session(kwargs) if msg: return msg uid = kwargs.get('uid') if self.__verbose_list.count(uid): self.__verbose_list.remove(uid) else: self.__verbose_list.append(uid) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def change_queue_complete_action(self, **kwargs): """ Action or script to be performed once the queue has been completed Scripts are prefixed with 'script_' """ msg = check_session(kwargs) if msg: return msg action = kwargs.get('action') sabnzbd.change_queue_complete_action(action) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def switch(self, **kwargs): msg = check_session(kwargs) if msg: return msg uid1 = kwargs.get('uid1') uid2 = kwargs.get('uid2') if uid1 and uid2: NzbQueue.do.switch(uid1, uid2) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def change_opts(self, **kwargs): msg = check_session(kwargs) if msg: return msg nzo_id = kwargs.get('nzo_id') pp = kwargs.get('pp', '') if nzo_id and pp and pp.isdigit(): NzbQueue.do.change_opts(nzo_id, int(pp)) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def change_script(self, **kwargs): msg = check_session(kwargs) if msg: return msg nzo_id = kwargs.get('nzo_id') script = kwargs.get('script', '') if nzo_id and script: if script == 'None': script = None NzbQueue.do.change_script(nzo_id, script) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def change_cat(self, **kwargs): msg = check_session(kwargs) if msg: return msg nzo_id = kwargs.get('nzo_id') cat = kwargs.get('cat', '') if nzo_id and cat: if cat == 'None': cat = None NzbQueue.do.change_cat(nzo_id, cat) cat, pp, script, priority = cat_to_opts(cat) NzbQueue.do.change_script(nzo_id, script) NzbQueue.do.change_opts(nzo_id, pp) NzbQueue.do.set_priority(nzo_id, priority) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def shutdown(self, **kwargs): msg = check_session(kwargs) if msg: yield msg else: yield "Initiating shutdown..." sabnzbd.halt() cherrypy.engine.exit() yield "
    SABnzbd-%s shutdown finished" % sabnzbd.__version__ sabnzbd.SABSTOP = True @cherrypy.expose def pause(self, **kwargs): msg = check_session(kwargs) if msg: return msg scheduler.plan_resume(0) Downloader.do.pause() raise queueRaiser(self.__root, kwargs) @cherrypy.expose def resume(self, **kwargs): msg = check_session(kwargs) if msg: return msg scheduler.plan_resume(0) sabnzbd.unpause_all() raise queueRaiser(self.__root, kwargs) @cherrypy.expose def pause_nzo(self, **kwargs): msg = check_session(kwargs) if msg: return msg uid = kwargs.get('uid', '') NzbQueue.do.pause_multiple_nzo(uid.split(',')) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def resume_nzo(self, **kwargs): msg = check_session(kwargs) if msg: return msg uid = kwargs.get('uid', '') NzbQueue.do.resume_multiple_nzo(uid.split(',')) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def set_priority(self, **kwargs): msg = check_session(kwargs) if msg: return msg sabnzbd.nzbqueue.set_priority(kwargs.get('nzo_id'), kwargs.get('priority')) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def sort_by_avg_age(self, **kwargs): msg = check_session(kwargs) if msg: return msg sabnzbd.nzbqueue.sort_queue('avg_age', kwargs.get('dir')) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def sort_by_name(self, **kwargs): msg = check_session(kwargs) if msg: return msg sabnzbd.nzbqueue.sort_queue('name', kwargs.get('dir')) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def sort_by_size(self, **kwargs): msg = check_session(kwargs) if msg: return msg sabnzbd.nzbqueue.sort_queue('size', kwargs.get('dir')) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def set_speedlimit(self, **kwargs): msg = check_session(kwargs) if msg: return msg Downloader.do.limit_speed(int_conv(kwargs.get('value'))) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def set_pause(self, **kwargs): msg = check_session(kwargs) if msg: return msg scheduler.plan_resume(int_conv(kwargs.get('value'))) raise dcRaiser(self.__root, kwargs) class HistoryPage(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__verbose = False self.__verbose_list = [] self.__failed_only = False self.__prim = prim self.__edit_rating = None @cherrypy.expose def index(self, **kwargs): if not check_access(): return Protected() start = kwargs.get('start') limit = kwargs.get('limit') search = kwargs.get('search') failed_only = kwargs.get('failed_only') if failed_only is None: failed_only = self.__failed_only history, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) history['isverbose'] = self.__verbose history['failed_only'] = failed_only history['rating_enable'] = bool(cfg.rating_enable()) if cfg.newzbin_username() and cfg.newzbin_password(): history['newzbinDetails'] = True #history_items, total_bytes, bytes_beginning = sabnzbd.history_info() #history['bytes_beginning'] = "%.2f" % (bytes_beginning / GIGI) postfix = T('B') #: Abbreviation for bytes, as in GB grand, month, week, day = BPSMeter.do.get_sums() history['total_size'], history['month_size'], history['week_size'], history['day_size'] = \ to_units(grand, postfix=postfix), to_units(month, postfix=postfix), \ to_units(week, postfix=postfix), to_units(day, postfix=postfix) history['lines'], history['fetched'], history['noofslots'] = build_history(limit=limit, start=start, verbose=self.__verbose, verbose_list=self.__verbose_list, search=search, failed_only=failed_only) for line in history['lines']: if self.__edit_rating is not None and line.get('nzo_id') == self.__edit_rating: line['edit_rating'] = True else: line['edit_rating'] = '' if search: history['search'] = escape(search) else: history['search'] = '' history['start'] = int_conv(start) history['limit'] = int_conv(limit) history['finish'] = history['start'] + history['limit'] if history['finish'] > history['noofslots']: history['finish'] = history['noofslots'] if not history['finish']: history['finish'] = history['fetched'] history['time_format'] = time_format template = Template(file=os.path.join(self.__web_dir, 'history.tmpl'), filter=FILTER, searchList=[history], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def purge(self, **kwargs): msg = check_session(kwargs) if msg: return msg history_db = cherrypy.thread_data.history_db history_db.remove_history() raise queueRaiser(self.__root, kwargs) @cherrypy.expose def delete(self, **kwargs): msg = check_session(kwargs) if msg: return msg job = kwargs.get('job') del_files = int_conv(kwargs.get('del_files')) if job: jobs = job.split(',') for job in jobs: del_hist_job(job, del_files=del_files) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def retry_pp(self, **kwargs): msg = check_session(kwargs) if msg: return msg retry_job(kwargs.get('job'), kwargs.get('nzbfile')) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def purge_failed(self, **kwargs): msg = check_session(kwargs) if msg: return msg del_files = bool(int_conv(kwargs.get('del_files'))) history_db = cherrypy.thread_data.history_db if del_files: del_job_files(history_db.get_failed_paths()) history_db.remove_failed() raise queueRaiser(self.__root, kwargs) @cherrypy.expose def reset(self, **kwargs): msg = check_session(kwargs) if msg: return msg #sabnzbd.reset_byte_counter() raise queueRaiser(self.__root, kwargs) @cherrypy.expose def tog_verbose(self, **kwargs): msg = check_session(kwargs) if msg: return msg jobs = kwargs.get('jobs') if not jobs: self.__verbose = not self.__verbose self.__verbose_list = [] else: if self.__verbose: self.__verbose = False else: jobs = jobs.split(',') for job in jobs: if job in self.__verbose_list: self.__verbose_list.remove(job) else: self.__verbose_list.append(job) raise queueRaiser(self.__root, kwargs) @cherrypy.expose def tog_failed_only(self, **kwargs): msg = check_session(kwargs) if msg: return msg self.__failed_only = not self.__failed_only raise queueRaiser(self.__root, kwargs) @cherrypy.expose def scriptlog(self, **kwargs): """ Duplicate of scriptlog of History, needed for some skins """ # No session key check, due to fixed URLs if not check_access(): return Protected() name = kwargs.get('name') if name: history_db = cherrypy.thread_data.history_db return ShowString(history_db.get_name(name), history_db.get_script_log(name)) else: raise dcRaiser(self.__root, kwargs) @cherrypy.expose def retry(self, **kwargs): msg = check_session(kwargs) if msg: return msg job = kwargs.get('job', '') url = kwargs.get('url', '').strip() pp = kwargs.get('pp') cat = kwargs.get('cat') script = kwargs.get('script') if url and (url.isdigit() or len(url)==5): sabnzbd.add_msgid(url, pp, script, cat) elif url: sabnzbd.add_url(url, pp, script, cat, nzbname=kwargs.get('nzbname')) del_hist_job(job, del_files=True) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def show_edit_rating(self, **kwargs): msg = check_session(kwargs) if msg: return msg self.__edit_rating = kwargs.get('job'); raise queueRaiser(self.__root, kwargs) @cherrypy.expose def action_edit_rating(self, **kwargs): flag_map = {'spam': Rating.FLAG_SPAM, 'encrypted': Rating.FLAG_ENCRYPTED, 'expired': Rating.FLAG_EXPIRED} msg = check_session(kwargs) if msg: return msg try: if kwargs.get('send'): video = kwargs.get('video') if kwargs.get('video') != "-" else None audio = kwargs.get('audio') if kwargs.get('audio') != "-" else None flag = flag_map.get(kwargs.get('rating_flag')) detail = kwargs.get('expired_host') if kwargs.get('expired_host') != '' else None if cfg.rating_enable(): Rating.do.update_user_rating(kwargs.get('job'), video, audio, flag, detail) except: pass self.__edit_rating = None; raise queueRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ class ConfigPage(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim self.folders = ConfigFolders(web_dir, root+'folders/', prim) self.notify = ConfigNotify(web_dir, root+'notify/', prim) self.general = ConfigGeneral(web_dir, root+'general/', prim) self.indexers = ConfigIndexers(web_dir, root+'indexers/', prim) self.rss = ConfigRss(web_dir, root+'rss/', prim) self.scheduling = ConfigScheduling(web_dir, root+'scheduling/', prim) self.server = ConfigServer(web_dir, root+'server/', prim) self.switches = ConfigSwitches(web_dir, root+'switches/', prim) self.categories = ConfigCats(web_dir, root+'categories/', prim) self.sorting = ConfigSorting(web_dir, root+'sorting/', prim) self.special = ConfigSpecial(web_dir, root+'special/', prim) @cherrypy.expose def index(self, **kwargs): if not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['configfn'] = config.get_filename() conf['cmdline'] = sabnzbd.CMDLINE new = {} for svr in config.get_servers(): new[svr] = {} conf['servers'] = new conf['folders'] = sabnzbd.nzbqueue.scan_jobs(all=False, action=False) template = Template(file=os.path.join(self.__web_dir, 'config.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def restart(self, **kwargs): msg = check_session(kwargs) if msg: yield msg else: yield T('Initiating restart...
    ') sabnzbd.halt() yield T(' 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    ') cherrypy.engine.restart() @cherrypy.expose def repair(self, **kwargs): msg = check_session(kwargs) if msg: yield msg else: sabnzbd.request_repair() yield T('Initiating restart...
    ') sabnzbd.halt() yield T(' 
    SABnzbd shutdown finished.
    Wait for about 5 second and then click the button below.

    Refresh
    ') cherrypy.engine.restart() @cherrypy.expose def delete(self, **kwargs): msg = check_session(kwargs) if msg: return msg orphan_delete(kwargs) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def add(self, **kwargs): msg = check_session(kwargs) if msg: return msg orphan_add(kwargs) raise dcRaiser(self.__root, kwargs) def orphan_delete(kwargs): path = kwargs.get('name') if path: path = platform_encode(path) path = os.path.join(cfg.download_dir.get_path(), path) remove_all(path, recursive=True) def orphan_add(kwargs): path = kwargs.get('name') if path: path = platform_encode(path) path = os.path.join(cfg.download_dir.get_path(), path) sabnzbd.nzbqueue.repair_job(path, None) #------------------------------------------------------------------------------ LIST_DIRPAGE = ( \ 'download_dir', 'download_free', 'complete_dir', 'cache_dir', 'admin_dir', 'nzb_backup_dir', 'dirscan_dir', 'dirscan_speed', 'script_dir', 'email_dir', 'permissions', 'log_dir', 'password_file' ) class ConfigFolders(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) for kw in LIST_DIRPAGE: conf[kw] = config.get_config('misc', kw)() # Temporary fix, problem with build_header conf['restart_req'] = sabnzbd.RESTART_REQ template = Template(file=os.path.join(self.__web_dir, 'config_folders.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def saveDirectories(self, **kwargs): msg = check_session(kwargs) if msg: return msg for kw in LIST_DIRPAGE: value = kwargs.get(kw) if value != None: value = platform_encode(value) if kw in ('complete_dir', 'dirscan_dir'): msg = config.get_config('misc', kw).set(value, create=True) else: msg = config.get_config('misc', kw).set(value) if msg: return badParameterResponse(msg) sabnzbd.check_incomplete_vs_complete() config.save_config() raise dcRaiser(self.__root, kwargs) SWITCH_LIST = \ ('par2_multicore', 'par_option', 'enable_unrar', 'enable_unzip', 'enable_filejoin', 'enable_tsjoin', 'send_group', 'fail_on_crc', 'top_only', 'enable_par_cleanup', 'auto_sort', 'check_new_rel', 'auto_disconnect', 'safe_postproc', 'no_dupes', 'replace_spaces', 'replace_dots', 'replace_illegal', 'auto_browser', 'ignore_samples', 'pause_on_post_processing', 'quick_check', 'nice', 'ionice', 'ssl_type', 'pre_script', 'pause_on_pwrar', 'ampm', 'sfv_check', 'folder_rename', 'unpack_check', 'quota_size', 'quota_day', 'quota_resume', 'quota_period', 'pre_check', 'max_art_tries', 'max_art_opt', 'fail_hopeless', 'rating_enable', 'rating_api_key', 'rating_feedback', 'rating_filter_enable', 'rating_filter_abort_audio', 'rating_filter_abort_video', 'rating_filter_abort_encrypted', 'rating_filter_abort_encrypted_confirm', 'rating_filter_abort_spam', 'rating_filter_abort_spam_confirm', 'rating_filter_abort_downvoted', 'rating_filter_abort_keywords', 'rating_filter_pause_audio', 'rating_filter_pause_video', 'rating_filter_pause_encrypted', 'rating_filter_pause_encrypted_confirm', 'rating_filter_pause_spam', 'rating_filter_pause_spam_confirm', 'rating_filter_pause_downvoted', 'rating_filter_pause_keywords', 'unwanted_extensions', 'action_on_unwanted_extensions' ) #------------------------------------------------------------------------------ class ConfigSwitches(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['nt'] = sabnzbd.WIN32 conf['have_nice'] = bool(sabnzbd.newsunpack.NICE_COMMAND) conf['have_ionice'] = bool(sabnzbd.newsunpack.IONICE_COMMAND) for kw in SWITCH_LIST: conf[kw] = config.get_config('misc', kw)() conf['unwanted_extensions'] = cfg.unwanted_extensions.get_string() conf['script_list'] = list_scripts() or ['None'] conf['have_ampm'] = HAVE_AMPM template = Template(file=os.path.join(self.__web_dir, 'config_switches.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def saveSwitches(self, **kwargs): msg = check_session(kwargs) if msg: return msg for kw in SWITCH_LIST: item = config.get_config('misc', kw) value = platform_encode(kwargs.get(kw)) if kw == 'unwanted_extensions' and value: value = value.lower().replace('.', '') msg = item.set(value) if msg: return badParameterResponse(msg) config.save_config() raise dcRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ SPECIAL_BOOL_LIST = \ ( 'start_paused', 'no_penalties', 'ignore_wrong_unrar', 'create_group_folders', 'queue_complete_pers', 'api_warnings', 'allow_64bit_tools', 'par2_multicore', 'never_repair', 'allow_streaming', 'ignore_unrar_dates', 'rss_filenames', 'osx_menu', 'osx_speed', 'win_menu', 'uniconfig', 'use_pickle', 'allow_incomplete_nzb', 'randomize_server_ip', 'no_ipv6', 'keep_awake', 'overwrite_files', 'empty_postproc', 'web_watchdog', 'wait_for_dfolder', 'warn_empty_nzb', 'enable_recursive', 'sanitize_safe', 'enable_meta', 'flat_unpack', 'warn_dupl_jobs', 'new_nzb_on_failure' ) SPECIAL_VALUE_LIST = \ ( 'size_limit', 'folder_max_length', 'fsys_type', 'movie_rename_limit', 'nomedia_marker', 'req_completion_rate', 'wait_ext_drive', 'history_limit', 'show_sysload', 'ipv6_servers' ) SPECIAL_LIST_LIST = \ ( 'rss_odd_titles', 'prio_sort_list', 'rating_host' ) class ConfigSpecial(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['nt'] = sabnzbd.WIN32 conf['switches'] = [ (kw, config.get_config('misc', kw)(), config.get_config('misc', kw).default()) for kw in SPECIAL_BOOL_LIST] conf['entries'] = [ (kw, config.get_config('misc', kw)(), config.get_config('misc', kw).default()) for kw in SPECIAL_VALUE_LIST] conf['entries'].extend( [ (kw, config.get_config('misc', kw).get_string(), '') for kw in SPECIAL_LIST_LIST] ) template = Template(file=os.path.join(self.__web_dir, 'config_special.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def saveSpecial(self, **kwargs): msg = check_session(kwargs) if msg: return msg for kw in SPECIAL_BOOL_LIST + SPECIAL_VALUE_LIST + SPECIAL_LIST_LIST: item = config.get_config('misc', kw) value = kwargs.get(kw) msg = item.set(value) if msg: return badParameterResponse(msg) config.save_config() raise dcRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ GENERAL_LIST = ( 'host', 'port', 'username', 'password', 'disable_api_key', 'refresh_rate', 'cache_limit', 'local_range', 'enable_https', 'https_port', 'https_cert', 'https_key', 'https_chain' ) class ConfigGeneral(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): def ListColors(web_dir): lst = [] web_dir = os.path.join(sabnzbd.DIR_INTERFACES, web_dir) dd = os.path.abspath(web_dir + '/templates/static/stylesheets/colorschemes') if (not dd) or (not os.access(dd, os.R_OK)): return lst for color in globber(dd): col = os.path.basename(color).replace('.css','') if col != "_svn" and col != ".svn": lst.append(col) return lst def add_color(dir, color): if dir: if not color: try: color = DEF_SKIN_COLORS[dir.lower()] except KeyError: return dir return '%s - %s' % (dir, color) else: return '' if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['configfn'] = config.get_filename() # Temporary fix, problem with build_header conf['restart_req'] = sabnzbd.RESTART_REQ if sabnzbd.newswrapper.HAVE_SSL: conf['have_ssl'] = 1 else: conf['have_ssl'] = 0 wlist = [] wlist2 = ['None'] interfaces = globber(sabnzbd.DIR_INTERFACES) for k in interfaces: if k.endswith(DEF_STDINTF): interfaces.remove(k) interfaces.insert(0, k) break for k in interfaces: if k.endswith(DEF_STDCONFIG): interfaces.remove(k) break for web in interfaces: rweb = os.path.basename(web) if rweb != '.svn' and rweb != '_svn' and os.access(web + '/' + DEF_MAIN_TMPL, os.R_OK): cols = ListColors(rweb) if cols: for col in cols: if rweb != 'Mobile': wlist.append(add_color(rweb, col)) wlist2.append(add_color(rweb, col)) else: if rweb != 'Mobile': wlist.append(rweb) wlist2.append(rweb) conf['web_list'] = wlist conf['web_list2'] = wlist2 # Obsolete template variables, must exist and have a value conf['web_colors'] = ['None'] conf['web_color'] = 'None' conf['web_colors2'] = ['None'] conf['web_color2'] = 'None' conf['web_dir'] = add_color(cfg.web_dir(), cfg.web_color()) conf['web_dir2'] = add_color(cfg.web_dir2(), cfg.web_color2()) conf['language'] = cfg.language() list = list_languages() if len(list) < 2: list = [] conf['lang_list'] = list conf['disable_api_key'] = cfg.disable_key() conf['host'] = cfg.cherryhost() conf['port'] = cfg.cherryport() conf['https_port'] = cfg.https_port() conf['https_cert'] = cfg.https_cert() conf['https_key'] = cfg.https_key() conf['https_chain'] = cfg.https_chain() conf['enable_https'] = cfg.enable_https() conf['username'] = cfg.username() conf['password'] = cfg.password.get_stars() conf['bandwidth_limit'] = cfg.bandwidth_limit() conf['refresh_rate'] = cfg.refresh_rate() conf['cache_limit'] = cfg.cache_limit() conf['cleanup_list'] = cfg.cleanup_list.get_string() conf['nzb_key'] = cfg.nzb_key() conf['local_range'] = cfg.local_range() conf['my_lcldata'] = cfg.admin_dir.get_path() template = Template(file=os.path.join(self.__web_dir, 'config_general.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def saveGeneral(self, **kwargs): msg = check_session(kwargs) if msg: return msg # Special handling for cache_limitstr #kwargs['cache_limit'] = kwargs.get('cache_limitstr') # Handle general options for kw in GENERAL_LIST: item = config.get_config('misc', kw) value = platform_encode(kwargs.get(kw)) msg = item.set(value) if msg: return badParameterResponse(msg) # Handle special options language = kwargs.get('language') if language and language != cfg.language(): cfg.language.set(language) set_language(language) sabnzbd.api.clear_trans_cache() cleanup_list = kwargs.get('cleanup_list') if cleanup_list and sabnzbd.WIN32: cleanup_list = cleanup_list.lower() cfg.cleanup_list.set(cleanup_list) web_dir = kwargs.get('web_dir') web_dir2 = kwargs.get('web_dir2') change_web_dir(web_dir) try: web_dir2, web_color2 = web_dir2.split(' - ') except: web_color2 = '' web_dir2_path = real_path(sabnzbd.DIR_INTERFACES, web_dir2) if web_dir2 == 'None': cfg.web_dir2.set('') elif os.path.exists(web_dir2_path): cfg.web_dir2.set(web_dir2) cfg.web_color2.set(web_color2) bandwidth_limit = kwargs.get('bandwidth_limit') if bandwidth_limit != None: bandwidth_limit = int_conv(bandwidth_limit) cfg.bandwidth_limit.set(bandwidth_limit) config.save_config() # Update CherryPy authentication set_auth(cherrypy.config) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def generateAPIKey(self, **kwargs): msg = check_session(kwargs) if msg: return msg logging.debug('API Key Changed') cfg.api_key.set(config.create_api_key()) config.save_config() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def generateNzbKey(self, **kwargs): msg = check_session(kwargs) if msg: return msg logging.debug('NZB Key Changed') cfg.nzb_key.set(config.create_api_key()) config.save_config() raise dcRaiser(self.__root, kwargs) def change_web_dir(web_dir): try: web_dir, web_color = web_dir.split(' - ') except: try: web_color = DEF_SKIN_COLORS[web_dir.lower()] except: web_color = '' web_dir_path = real_path(sabnzbd.DIR_INTERFACES, web_dir) if not os.path.exists(web_dir_path): return badParameterResponse('Cannot find web template: %s' % unicoder(web_dir_path)) else: cfg.web_dir.set(web_dir) cfg.web_color.set(web_color) #------------------------------------------------------------------------------ class ConfigServer(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) new = {} servers = config.get_servers() for svr in servers: new[svr] = servers[svr].get_dict(safe=True) t, m, w, d = BPSMeter.do.amounts(svr) if t: new[svr]['amounts'] = to_units(t), to_units(m), to_units(w), to_units(d) conf['servers'] = new if sabnzbd.newswrapper.HAVE_SSL: conf['have_ssl'] = 1 else: conf['have_ssl'] = 0 template = Template(file=os.path.join(self.__web_dir, 'config_server.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def addServer(self, **kwargs): return handle_server(kwargs, self.__root, True) @cherrypy.expose def saveServer(self, **kwargs): return handle_server(kwargs, self.__root) @cherrypy.expose def testServer(self, **kwargs): return handle_server_test(kwargs, self.__root) @cherrypy.expose def delServer(self, **kwargs): msg = check_session(kwargs) if msg: return msg kwargs['section'] = 'servers' kwargs['keyword'] = kwargs.get('server') del_from_section(kwargs) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def clrServer(self, **kwargs): msg = check_session(kwargs) if msg: return msg server = kwargs.get('server') if server: BPSMeter.do.clear_server(server) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def toggleServer(self, **kwargs): msg = check_session(kwargs) if msg: return msg server = kwargs.get('server') if server: svr = config.get_config('servers', server) svr.enable.set(not svr.enable()) config.save_config() Downloader.do.update_server(server, server) raise dcRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ def unique_svr_name(server): """ Return a unique variant on given server name """ num = 0 svr = 1 new_name = server while svr: if num: new_name = '%s@%d' % (server, num) else: new_name = '%s' % server svr = config.get_config('servers', new_name) num += 1 return new_name def handle_server(kwargs, root=None, new_svr=False): """ Internal server handler """ msg = check_session(kwargs) if msg: return msg host = kwargs.get('host', '').strip() if not host: return badParameterResponse(T('Server address required')) port = kwargs.get('port', '').strip() if not port: if not kwargs.get('ssl', '').strip(): port = '119' else: port = '563' kwargs['port'] = port if kwargs.get('connections', '').strip() == '': kwargs['connections'] = '1' if kwargs.get('enable') == '1': msg = check_server(host, port) if msg: return msg # Default server name is just the host name server = host svr = None old_server = kwargs.get('server') if old_server: svr = config.get_config('servers', old_server) if svr: server = old_server else: svr = config.get_config('servers', server) if new_svr: server = unique_svr_name(server) for kw in ('fillserver', 'ssl', 'enable', 'optional'): if kw not in kwargs.keys(): kwargs[kw] = None if svr and not new_svr: svr.set_dict(kwargs) else: old_server = None config.ConfigServer(server, kwargs) config.save_config() Downloader.do.update_server(old_server, server) if root: raise dcRaiser(root, kwargs) def handle_server_test(kwargs, root): result, msg = test_nntp_server_dict(kwargs) return msg #------------------------------------------------------------------------------ class ConfigRss(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim self.__refresh_readout = None # Set to URL when new readout is needed self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = False @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['script_list'] = list_scripts(default=True) pick_script = conf['script_list'] != [] conf['cat_list'] = list_cats(default=True) pick_cat = conf['cat_list'] != [] conf['rss_rate'] = cfg.rss_rate() rss = {} feeds = config.get_rss() for feed in feeds: rss[feed] = feeds[feed].get_dict() filters = feeds[feed].filters() rss[feed]['filters'] = filters rss[feed]['filter_states'] = [bool(sabnzbd.rss.convert_filter(f[4])) for f in filters] rss[feed]['filtercount'] = len(filters) rss[feed]['pick_cat'] = pick_cat rss[feed]['pick_script'] = pick_script rss[feed]['link'] = urllib.quote_plus(feed) rss[feed]['baselink'] = get_base_url(rss[feed]['uri']) active_feed = kwargs.get('feed', '') conf['active_feed'] = active_feed conf['rss'] = rss conf['rss_next'] = time.strftime(time_format('%H:%M'),time.localtime(sabnzbd.rss.next_run())) if active_feed: readout = bool(self.__refresh_readout) logging.debug('RSS READOUT = %s', readout) if not readout: self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = False msg = sabnzbd.rss.run_feed(active_feed, download=self.__refresh_download, force=self.__refresh_force, \ ignoreFirst=self.__refresh_ignore, readout=readout) if readout: sabnzbd.rss.save() self.__refresh_readout = None conf['error'] = msg conf['downloaded'], conf['matched'], conf['unmatched'] = GetRssLog(active_feed) # Find a unique new Feed name unum = 1 txt = Ta('Feed') #: Used as default Feed name in Config->RSS while txt + str(unum) in feeds: unum += 1 conf['feed'] = txt + str(unum) template = Template(file=os.path.join(self.__web_dir, 'config_rss.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def save_rss_rate(self, **kwargs): """ Save changed RSS automatic readout rate """ msg = check_session(kwargs) if msg: return msg cfg.rss_rate.set(kwargs.get('rss_rate')) raise rssRaiser(self.__root, kwargs) @cherrypy.expose def upd_rss_feed(self, **kwargs): """ Update Feed level attributes, legacy version: ignores 'enable' parameter """ msg = check_session(kwargs) if msg: return msg if kwargs.get('enable') is not None: del kwargs['enable'] try: cfg = config.get_rss()[kwargs.get('feed')] except KeyError: cfg = None if cfg and Strip(kwargs.get('uri')): cfg.set_dict(kwargs) config.save_config() raise rssRaiser(self.__root, kwargs) @cherrypy.expose def save_rss_feed(self, **kwargs): """ Update Feed level attributes """ msg = check_session(kwargs) if msg: return msg try: cfg = config.get_rss()[kwargs.get('feed')] except KeyError: cfg = None if 'enable' not in kwargs: kwargs['enable'] = 0 if cfg and Strip(kwargs.get('uri')): cfg.set_dict(kwargs) config.save_config() raise rssRaiser(self.__root, kwargs) @cherrypy.expose def toggle_rss_feed(self, **kwargs): """ Toggle automatic read-out flag of Feed """ msg = check_session(kwargs) if msg: return msg try: item = config.get_rss()[kwargs.get('feed')] except KeyError: item = None if cfg: item.enable.set(not item.enable()) config.save_config() if kwargs.get('table'): raise dcRaiser(self.__root, kwargs) else: raise rssRaiser(self.__root, kwargs) @cherrypy.expose def add_rss_feed(self, **kwargs): """ Add one new RSS feed definition """ msg = check_session(kwargs) if msg: return msg feed= Strip(kwargs.get('feed')).strip('[]') uri = Strip(kwargs.get('uri')) if feed and uri: try: cfg = config.get_rss()[feed] except KeyError: cfg = None if (not cfg) and uri: config.ConfigRSS(feed, kwargs) # Clear out any existing reference to this feed name # Otherwise first-run detection can fail sabnzbd.rss.clear_feed(feed) config.save_config() self.__refresh_readout = feed self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = True raise rssRaiser(self.__root, kwargs) else: raise dcRaiser(self.__root, kwargs) else: raise dcRaiser(self.__root, kwargs) @cherrypy.expose def upd_rss_filter(self, **kwargs): """ Save updated filter definition """ msg = check_session(kwargs) if msg: return msg try: cfg = config.get_rss()[kwargs.get('feed')] except KeyError: raise rssRaiser(self.__root, kwargs) pp = kwargs.get('pp') if IsNone(pp): pp = '' script = ConvertSpecials(kwargs.get('script')) cat = ConvertSpecials(kwargs.get('cat')) prio = ConvertSpecials(kwargs.get('priority')) filt = kwargs.get('filter_text') enabled = kwargs.get('enabled', '0') if filt: cfg.filters.update(int(kwargs.get('index', 0)), (cat, pp, script, kwargs.get('filter_type'), \ platform_encode(filt), prio, enabled )) # Move filter if requested index = int_conv(kwargs.get('index', '')) new_index = kwargs.get('new_index', '') if new_index and int_conv(new_index) != index: cfg.filters.move(int(index), int_conv(new_index)) config.save_config() raise rssRaiser(self.__root, kwargs) @cherrypy.expose def del_rss_feed(self, *args, **kwargs): """ Remove complete RSS feed """ msg = check_session(kwargs) if msg: return msg kwargs['section'] = 'rss' kwargs['keyword'] = kwargs.get('feed') del_from_section(kwargs) sabnzbd.rss.clear_feed(kwargs.get('feed')) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def del_rss_filter(self, **kwargs): """ Remove one RSS filter """ msg = check_session(kwargs) if msg: return msg try: cfg = config.get_rss()[kwargs.get('feed')] except KeyError: raise rssRaiser(self.__root, kwargs) cfg.filters.delete(int(kwargs.get('index', 0))) config.save_config() raise rssRaiser(self.__root, kwargs) @cherrypy.expose def download_rss_feed(self, *args, **kwargs): """ Force download of all matching jobs in a feed """ msg = check_session(kwargs) if msg: return msg if 'feed' in kwargs: feed = kwargs['feed'] self.__refresh_readout = feed self.__refresh_download = True self.__refresh_force = True self.__refresh_ignore = False raise rssRaiser(self.__root, kwargs) @cherrypy.expose def clean_rss_jobs(self, *args, **kwargs): """ Remove processed RSS jobs from UI """ msg = check_session(kwargs) if msg: return msg sabnzbd.rss.clear_downloaded(kwargs['feed']) raise rssRaiser(self.__root, kwargs) @cherrypy.expose def test_rss_feed(self, *args, **kwargs): """ Read the feed content again and show results """ msg = check_session(kwargs) if msg: return msg if 'feed' in kwargs: feed = kwargs['feed'] self.__refresh_readout = feed self.__refresh_download = False self.__refresh_force = False self.__refresh_ignore = True raise rssRaiser(self.__root, kwargs) @cherrypy.expose def download(self, **kwargs): """ Download NZB from provider (Download button) """ msg = check_session(kwargs) if msg: return msg feed = kwargs.get('feed') url = kwargs.get('url') nzbname = kwargs.get('nzbname') att = sabnzbd.rss.lookup_url(feed, url) if att: pp = att.get('pp') cat = att.get('cat') script = att.get('script') prio = att.get('prio') if url and url.isdigit(): sabnzbd.add_msgid(url, pp, script, cat, prio, nzbname) elif url: sabnzbd.add_url(url, pp, script, cat, prio, nzbname) # Need to pass the title instead sabnzbd.rss.flag_downloaded(feed, url) raise rssRaiser(self.__root, kwargs) @cherrypy.expose def rss_now(self, *args, **kwargs): """ Run an automatic RSS run now """ msg = check_session(kwargs) if msg: return msg scheduler.force_rss() raise rssRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ _SCHED_ACTIONS = ('resume', 'pause', 'pause_all', 'shutdown', 'restart', 'speedlimit', 'pause_post', 'resume_post', 'scan_folder', 'rss_scan', 'remove_failed') class ConfigScheduling(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): def get_days(): days = {} days["*"] = T('Daily') days["1"] = T('Monday') days["2"] = T('Tuesday') days["3"] = T('Wednesday') days["4"] = T('Thursday') days["5"] = T('Friday') days["6"] = T('Saturday') days["7"] = T('Sunday') return days if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) actions = [] actions.extend(_SCHED_ACTIONS) day_names = get_days() conf['schedlines'] = [] snum = 1 conf['taskinfo'] = [] for ev in scheduler.sort_schedules(all_events=False): line = ev[3] conf['schedlines'].append(line) try: m, h, day_numbers, action = line.split(' ', 3) except: continue action = action.strip() try: action, value = action.split(' ', 1) except: value = '' value = value.strip() if value == '0': value = T('off') #: "Off" value for speedlimit in scheduler if action in actions: action = Ttemplate("sch-" + action) else: try: act, server = action.split() except ValueError: act = '' if act in ('enable_server', 'disable_server'): action = Ttemplate("sch-" + act) + ' ' + server if day_numbers == "1234567": days_of_week = "Daily" elif day_numbers == "12345": days_of_week = "Weekdays" elif day_numbers == "67": days_of_week = "Weekends" else: days_of_week = ", ".join([day_names.get(i, "**") for i in day_numbers]) item = (snum, '%02d' % int(h), '%02d' % int(m), days_of_week, '%s %s' % (action, value)) conf['taskinfo'].append(item) snum += 1 actions_lng = {} for action in actions: actions_lng[action] = Ttemplate("sch-" + action) for server in config.get_servers(): actions.append(server) actions_lng[server] = server conf['actions'] = actions conf['actions_lng'] = actions_lng template = Template(file=os.path.join(self.__web_dir, 'config_scheduling.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def addSchedule(self, **kwargs): msg = check_session(kwargs) if msg: return msg minute = kwargs.get('minute') hour = kwargs.get('hour') days_of_week = ''.join([str(x) for x in kwargs.get('daysofweek', '')]) if not days_of_week: days_of_week = '1234567' action = kwargs.get('action') arguments = kwargs.get('arguments') arguments = arguments.strip().lower() if arguments in ('on', 'enable'): arguments = '1' elif arguments in ('off','disable'): arguments = '0' if minute and hour and days_of_week and action: if action == 'speedlimit': if not (arguments and arguments.isdigit()): action = '0' elif action in _SCHED_ACTIONS: arguments = '' elif action in config.get_servers(): if arguments == '1': arguments = action action = 'enable_server' else: arguments = action action = 'disable_server' else: action = None if action: sched = cfg.schedules() sched.append('%s %s %s %s %s' % (minute, hour, days_of_week, action, arguments)) cfg.schedules.set(sched) config.save_config() scheduler.restart(force=True) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def delSchedule(self, **kwargs): msg = check_session(kwargs) if msg: return msg schedules = cfg.schedules() line = kwargs.get('line') if line and line in schedules: schedules.remove(line) cfg.schedules.set(schedules) config.save_config() scheduler.restart(force=True) raise dcRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ class ConfigIndexers(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim self.__bookmarks = [] @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['username_newzbin'] = cfg.newzbin_username() conf['password_newzbin'] = cfg.newzbin_password.get_stars() conf['newzbin_bookmarks'] = int(cfg.newzbin_bookmarks()) conf['newzbin_unbookmark'] = int(cfg.newzbin_unbookmark()) conf['bookmark_rate'] = cfg.bookmark_rate() conf['bookmarks_list'] = self.__bookmarks conf['matrix_username'] = cfg.matrix_username() conf['matrix_apikey'] = cfg.matrix_apikey() conf['matrix_del_bookmark'] = int(cfg.matrix_del_bookmark()) template = Template(file=os.path.join(self.__web_dir, 'config_indexers.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def saveNewzbin(self, **kwargs): msg = check_session(kwargs) if msg: return msg cfg.newzbin_username.set(kwargs.get('username_newzbin')) cfg.newzbin_password.set(kwargs.get('password_newzbin')) cfg.newzbin_bookmarks.set(kwargs.get('newzbin_bookmarks')) cfg.newzbin_unbookmark.set(kwargs.get('newzbin_unbookmark')) cfg.bookmark_rate.set(kwargs.get('bookmark_rate')) cfg.matrix_username.set(kwargs.get('matrix_username')) cfg.matrix_apikey.set(kwargs.get('matrix_apikey')) cfg.matrix_del_bookmark.set(kwargs.get('matrix_del_bookmark')) config.save_config() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def saveMatrix(self, **kwargs): msg = check_session(kwargs) if msg: return msg cfg.matrix_username.set(kwargs.get('matrix_username')) cfg.matrix_apikey.set(kwargs.get('matrix_apikey')) cfg.matrix_del_bookmark.set(kwargs.get('matrix_del_bookmark')) config.save_config() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def getBookmarks(self, **kwargs): msg = check_session(kwargs) if msg: return msg Bookmarks.do.run(force=True) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def showBookmarks(self, **kwargs): msg = check_session(kwargs) if msg: return msg self.__bookmarks = Bookmarks.do.bookmarksList() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def hideBookmarks(self, **kwargs): msg = check_session(kwargs) if msg: return msg self.__bookmarks = [] raise dcRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ class ConfigCats(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) if cfg.newzbin_username() and cfg.newzbin_password(): conf['newzbinDetails'] = True conf['script_list'] = list_scripts(default=True) categories = config.get_categories() conf['have_cats'] = len(categories) > 1 conf['defdir'] = cfg.complete_dir.get_path() empty = { 'name':'', 'pp':'-1', 'script':'', 'dir':'', 'newzbin':'', 'priority':DEFAULT_PRIORITY } slotinfo = [] for cat in sorted(categories.keys()): slot = categories[cat].get_dict() slot['name'] = cat slot['newzbin'] = slot['newzbin'].replace('"', '"') slotinfo.append(slot) slotinfo.insert(1, empty) conf['slotinfo'] = slotinfo template = Template(file=os.path.join(self.__web_dir, 'config_cat.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def delete(self, **kwargs): msg = check_session(kwargs) if msg: return msg kwargs['section'] = 'categories' kwargs['keyword'] = kwargs.get('name') del_from_section(kwargs) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def save(self, **kwargs): msg = check_session(kwargs) if msg: return msg name = kwargs.get('name', '*') if name == '*': newname = name else: newname = kwargs.get('newname', '').strip(' []') if newname: if name: config.delete('categories', name) name = newname.lower() if kwargs.get('dir'): kwargs['dir'] = platform_encode(kwargs['dir']) config.ConfigCat(name, kwargs) config.save_config() raise dcRaiser(self.__root, kwargs) SORT_LIST = ( \ 'enable_tv_sorting', 'tv_sort_string', 'tv_categories', 'enable_movie_sorting', 'movie_sort_string', 'movie_sort_extra', 'movie_extra_folder', 'enable_date_sorting', 'date_sort_string', 'movie_categories', 'date_categories' ) #------------------------------------------------------------------------------ class ConfigSorting(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['complete_dir'] = cfg.complete_dir.get_path() for kw in SORT_LIST: conf[kw] = config.get_config('misc', kw)() conf['cat_list'] = list_cats(False) template = Template(file=os.path.join(self.__web_dir, 'config_sorting.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def saveSorting(self, **kwargs): msg = check_session(kwargs) if msg: return msg try: kwargs['movie_categories'] = kwargs['movie_cat'] except: pass try: kwargs['date_categories'] = kwargs['date_cat'] except: pass try: kwargs['tv_categories'] = kwargs['tv_cat'] except: pass for kw in SORT_LIST: item = config.get_config('misc', kw) value = platform_encode(kwargs.get(kw)) msg = item.set(value) if msg: return badParameterResponse(msg) config.save_config() raise dcRaiser(self.__root, kwargs) #------------------------------------------------------------------------------ class Status(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim @cherrypy.expose def index(self, **kwargs): if not check_access(): return Protected() header, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) header['logfile'] = sabnzbd.LOGFILE header['weblogfile'] = sabnzbd.WEBLOGFILE header['loglevel'] = str(cfg.log_level()) header['lastmail'] = None # Obsolete, keep for compatibility header['folders'] = sabnzbd.nzbqueue.scan_jobs(all=False, action=False) header['configfn'] = config.get_filename() header['servers'] = [] for server in Downloader.do.servers[:]: busy = [] connected = 0 for nw in server.idle_threads[:]: if nw.connected: connected += 1 for nw in server.busy_threads[:]: article = nw.article art_name = "" nzf_name = "" nzo_name = "" if article: nzf = article.nzf nzo = nzf.nzo art_name = xml_name(article.article) #filename field is not always present try: nzf_name = xml_name(nzf.filename) except: #attribute error nzf_name = xml_name(nzf.subject) nzo_name = xml_name(nzo.final_name) busy.append((nw.thrdnum, art_name, nzf_name, nzo_name)) if nw.connected: connected += 1 if server.warning and not (connected or server.errormsg): connected = unicoder(server.warning) if server.request and not server.info: connected = T(' Resolving address') busy.sort() header['servers'].append((server.id, '', connected, busy, server.ssl, server.active, server.errormsg, server.fillserver, server.optional)) wlist = [] for w in sabnzbd.GUIHANDLER.content(): w = w.replace('WARNING', Ta('WARNING:')).replace('ERROR', Ta('ERROR:')) wlist.insert(0, unicoder(w)) header['warnings'] = wlist template = Template(file=os.path.join(self.__web_dir, 'status.tmpl'), filter=FILTER, searchList=[header], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def reset_quota(self, **kwargs): msg = check_session(kwargs) if msg: return msg BPSMeter.do.reset_quota(force=True) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def disconnect(self, **kwargs): msg = check_session(kwargs) if msg: return msg Downloader.do.disconnect() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def showlog(self, **kwargs): msg = check_session(kwargs) if msg: return msg try: sabnzbd.LOGHANDLER.flush() except: pass return cherrypy.lib.static.serve_file(sabnzbd.LOGFILE, "application/x-download", "attachment") @cherrypy.expose def showweb(self, **kwargs): msg = check_session(kwargs) if msg: return msg if sabnzbd.WEBLOGFILE: return cherrypy.lib.static.serve_file(sabnzbd.WEBLOGFILE, "application/x-download", "attachment") else: return "Web logging is off!" @cherrypy.expose def clearwarnings(self, **kwargs): msg = check_session(kwargs) if msg: return msg sabnzbd.GUIHANDLER.clear() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def change_loglevel(self, **kwargs): msg = check_session(kwargs) if msg: return msg cfg.log_level.set(kwargs.get('loglevel')) config.save_config() raise dcRaiser(self.__root, kwargs) @cherrypy.expose def unblock_server(self, **kwargs): msg = check_session(kwargs) if msg: return msg Downloader.do.unblock(kwargs.get('server')) # Short sleep so that UI shows new server status time.sleep(1.0) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def delete(self, **kwargs): msg = check_session(kwargs) if msg: return msg orphan_delete(kwargs) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def add(self, **kwargs): msg = check_session(kwargs) if msg: return msg orphan_add(kwargs) raise dcRaiser(self.__root, kwargs) def Protected(): return badParameterResponse("Configuration is locked") def badParameterResponse(msg): """Return a html page with error message and a 'back' button """ return ''' SABnzbd %s - %s

    %s

    %s

    ''' % (sabnzbd.__version__, T('ERROR:'), T('Incorrect parameter'), unicoder(msg), T('Back')) def ShowFile(name, path): """Return a html page listing a file and a 'back' button """ try: f = open(path, "r") msg = TRANS(f.read()) f.close() except: msg = "FILE NOT FOUND\n" return ''' %s

    %s

    %s
    


    ''' % (name, T('Back'), name, escape(msg)) def ShowString(name, string): """Return a html page listing a file and a 'back' button """ try: msg = TRANS(string) except: msg = "Encoding Error\n" return ''' %s

    %s

               %s
               


    ''' % (xml_name(name), T('Back'), xml_name(name), escape(unicoder(msg))) def ShowOK(url): return ''' %s


    %s

    ''' % (escape(url), T('Back'), T('Job "%s" was re-added to the queue') % escape(url)) def GetRssLog(feed): def make_item(job): url = job.get('url', '') title = xml_name(job.get('title', '')) if url.isdigit(): title = '%s' % (cfg.newzbin_url(), url, title) else: title = title if sabnzbd.rss.special_rss_site(url): nzbname = "" else: nzbname = xml_name(job.get('title', '')) return url, \ title, \ '*' * int(job.get('status', '').endswith('*')), \ job.get('rule', 0), \ nzbname jobs = sabnzbd.rss.show_result(feed) names = jobs.keys() # Sort in the order the jobs came from the feed names.sort(lambda x, y: jobs[x].get('order', 0) - jobs[y].get('order', 0)) good = [make_item(jobs[job]) for job in names if jobs[job]['status'][0] == 'G'] bad = [make_item(jobs[job]) for job in names if jobs[job]['status'][0] == 'B'] # Sort in reverse order of time stamp for 'Done' dnames = [job for job in jobs.keys() if jobs[job]['status'] == 'D'] dnames.sort(lambda x, y: int(jobs[y].get('time', 0) - jobs[x].get('time', 0))) done = [xml_name(jobs[job]['title']) for job in dnames] return done, good, bad def ShowRssLog(feed, all): """Return a html page listing an RSS log and a 'back' button """ jobs = sabnzbd.rss.show_result(feed) names = jobs.keys() # Sort in the order the jobs came from the feed names.sort(lambda x, y: jobs[x].get('order', 0) - jobs[y].get('order', 0)) qfeed = escape(feed.replace('/','%2F').replace('?', '%3F')) doneStr = [] for x in names: job = jobs[x] if job['status'][0] == 'D': doneStr.append('%s
    ' % xml_name(job['title'])) goodStr = [] for x in names: job = jobs[x] if job['status'][0] == 'G': goodStr.append('') badStr = [] for x in names: job = jobs[x] if job['status'][0] == 'B': badStr.append('') if all: return ''' %s

    %s

    %s

    %s
    %s
    %s
    %s
    %s
    %s
    ''' % (escape(feed), T('Back'), escape(feed), T('Jobs marked with a \'*\' will not be automatically downloaded.'), T('Matched'), \ ''.join(goodStr), T('Not matched'), ''.join(badStr), T('Downloaded'), ''.join(doneStr)) else: return ''' %s

    %s

    %s
    %s
    ''' % (escape(feed), T('Back'), escape(feed), T('Downloaded so far'), ''.join(doneStr)) #------------------------------------------------------------------------------ LIST_EMAIL = ( 'email_endjob', 'email_full', 'email_server', 'email_to', 'email_from', 'email_account', 'email_pwd', 'email_dir', 'email_rss' ) LIST_GROWL = ('growl_enable', 'growl_server', 'growl_password', 'ntfosd_enable', 'ncenter_enable') class ConfigNotify(object): def __init__(self, web_dir, root, prim): self.__root = root self.__web_dir = web_dir self.__prim = prim self.__lastmail = None @cherrypy.expose def index(self, **kwargs): if cfg.configlock() or not check_access(): return Protected() conf, pnfo_list, bytespersec = build_header(self.__prim, self.__web_dir) conf['my_home'] = sabnzbd.DIR_HOME conf['lastmail'] = self.__lastmail conf['have_growl'] = True conf['have_ntfosd'] = sabnzbd.growler.have_ntfosd() conf['have_ncenter'] = sabnzbd.DARWIN_ML and bool(sabnzbd.growler.ncenter_path()) for kw in LIST_EMAIL: conf[kw] = config.get_config('misc', kw).get_string() for kw in LIST_GROWL: conf[kw] = config.get_config('growl', kw).get_string() conf['notify_list'] = NOTIFY_KEYS conf['notify_classes'] = cfg.notify_classes.get_string() conf['notify_texts'] = sabnzbd.growler.NOTIFICATION template = Template(file=os.path.join(self.__web_dir, 'config_notify.tmpl'), filter=FILTER, searchList=[conf], compilerSettings=DIRECTIVES) return template.respond() @cherrypy.expose def saveEmail(self, **kwargs): msg = check_session(kwargs) if msg: return msg for kw in LIST_EMAIL: msg = config.get_config('misc', kw).set(platform_encode(kwargs.get(kw))) if msg: return badParameterResponse(T('Incorrect value for %s: %s') % (kw, unicoder(msg))) for kw in LIST_GROWL: msg = config.get_config('growl', kw).set(platform_encode(kwargs.get(kw))) if msg: return badParameterResponse(T('Incorrect value for %s: %s') % (kw, unicoder(msg))) cfg.notify_classes.set(kwargs.get('notify_classes', '')) config.save_config() self.__lastmail = None raise dcRaiser(self.__root, kwargs) @cherrypy.expose def testmail(self, **kwargs): msg = check_session(kwargs) if msg: return msg self.__lastmail = _api_test_email(name=None, output=None, kwargs=None) raise dcRaiser(self.__root, kwargs) @cherrypy.expose def testnotification(self, **kwargs): msg = check_session(kwargs) if msg: return msg _api_test_notif(name=None, output=None, kwargs=None) raise dcRaiser(self.__root, kwargs) def rss_history(url, limit=50, search=None): url = url.replace('rss','') youngest = None rss = RSS() rss.channel.title = "SABnzbd History" rss.channel.description = "Overview of completed downloads" rss.channel.link = "http://sourceforge.net/projects/sabnzbdplus/" rss.channel.language = "en" items, fetched_items, max_items = build_history(limit=limit, search=search) for history in items: item = Item() item.pubDate = std_time(history['completed']) item.title = history['name'] if not youngest: youngest = history['completed'] elif history['completed'] < youngest: youngest = history['completed'] if history['report']: item.link = "https://%s/browse/post/%s/" % (cfg.newzbin_url(), history['report']) elif history['url_info']: item.link = history['url_info'] else: item.link = url item.guid = history['nzo_id'] stageLine = [] for stage in history['stage_log']: stageLine.append("
    Stage %s
    " % stage['name']) actions = [] for action in stage['actions']: actions.append("
    %s
    " % (action)) actions.sort() actions.reverse() for act in actions: stageLine.append(act) stageLine.append("") item.description = ''.join(stageLine) rss.addItem(item) rss.channel.lastBuildDate = std_time(youngest) rss.channel.pubDate = std_time(time.time()) return rss.write() def rss_warnings(): """ Return an RSS feed with last warnings/errors """ rss = RSS() rss.channel.title = "SABnzbd Warnings" rss.channel.description = "Overview of warnings/errors" rss.channel.link = "http://sourceforge.net/projects/sabnzbdplus/" rss.channel.language = "en" for warn in sabnzbd.GUIHANDLER.content(): item = Item() item.title = warn rss.addItem(item) rss.channel.lastBuildDate = std_time(time.time()) rss.channel.pubDate = rss.channel.lastBuildDate return rss.write() SABnzbd-0.7.20/sabnzbd/lang.py0000644000000000000000000001644612433712602016156 0ustar00usergroup00000000000000#!/usr/bin/python -OO # -*- coding: utf-8 -*- # Copyright 2011 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.lang - Language support """ # This module should be the first non-standard import to # be done at the top of the application's main file. # This will ensure that the default language is available # and the special functions are active. # # Required keywords for pygettext.py: -k T -k Ta -k TT # # The following pseudo-builtins are provided. # T() Unicode translation # Ta() Latin-1 translation # Tx() Unicode translation of an expression (not a literal string) # TT() Dummy translation, use to mark table entries for POT scanning import gettext, __builtin__ import glob, os, operator, locale # This module cannot import any application modules!! __all__ = ['set_locale_info', 'set_language', 'list_languages'] _DOMAIN = '' # Holds translation domain _LOCALEDIR = '' # Holds path to the translation base folder def set_locale_info(domain, localedir): """ Setup the domain and localedir for translations """ global _DOMAIN, _LOCALEDIR _DOMAIN = domain _LOCALEDIR = localedir def set_language(language=None): """ Activate language, empty language will set default texts. """ if not language: language = '' # 'codeset' will determine the output of lgettext lng = gettext.translation(_DOMAIN, _LOCALEDIR, [language], fallback=True, codeset='latin-1') # The unicode flag will make _() return Unicode lng.install(unicode=True, names=['lgettext']) __builtin__.__dict__['T'] = __builtin__.__dict__['_'] # Unicode __builtin__.__dict__['Ta'] = __builtin__.__dict__['lgettext'] # Latin-1 __builtin__.__dict__['Tx'] = __builtin__.__dict__['_'] # Dynamic translation (unicode) __builtin__.__dict__['TT'] = lambda x:x # Use in text tables def list_languages(): """ Return sorted list of (lang-code, lang-string) pairs, representing the available languages. When any language file is found, the default tuple ('en', 'English') will be included. Otherwise an empty list is returned. """ # Findst find all the MO files. # Each folder should also contain a dummy text file giving the language # Example: # /nl/LC_MESSAGES/SABnzbd.mo # /nl/LC_MESSAGES/Nederlands lst = [] for path in glob.glob(os.path.join(_LOCALEDIR, '*')): if os.path.isdir(path) and not path.endswith('en'): lngname = os.path.basename(path) lng = locale.normalize(lngname) # Example: 'pt_BR.ISO8859-1' lng_short = lng[:lng.find('_')] lng_full = lng[:lng.find('.')] # First try full language string, e.g. 'pt_BR' language = LanguageTable.get(lng_full, (lng_full, lng_full)) if language[0] == lng_full: # Full language string not defined: try short form, e.g. 'pt' language = LanguageTable.get(lng_short, (lng_short, lng_short)) lng = lng_short else: lng = lng_full language = language[1].decode('utf-8') lst.append((lng, language)) if lst: lst.append(('en', 'English')) return sorted(lst, key=operator.itemgetter(1)) else: return lst LanguageTable = { 'aa' : ('Afar', 'Afaraf'), 'af' : ('Afrikaans', 'Afrikaans'), 'ak' : ('Akan', 'Akan'), 'sq' : ('Albanian', 'Shqip'), 'an' : ('Aragonese', 'Aragonés'), 'ae' : ('Avestan', 'Avesta'), 'ay' : ('Aymara', 'Aymararu'), 'bm' : ('Bambara', 'Bamanankan'), 'eu' : ('Basque', 'Euskara'), 'bi' : ('Bislama', 'Bislama'), 'bs' : ('Bosnian', 'Bosanskijezik'), 'br' : ('Breton', 'Brezhoneg'), 'ca' : ('Catalan', 'Català'), 'ch' : ('Chamorro', 'Chamoru'), 'kw' : ('Cornish', 'Kernewek'), 'co' : ('Corsican', 'Corsu'), 'hr' : ('Croatian', 'Hrvatski'), 'cs' : ('Czech', 'Cesky, ceština'), 'da' : ('Danish', 'Dansk'), 'nl' : ('Dutch', 'Nederlands'), 'en' : ('English', 'English'), 'eo' : ('Esperanto', 'Esperanto'), 'et' : ('Estonian', 'Eesti'), 'fo' : ('Faroese', 'Føroyskt'), 'fj' : ('Fijian', 'Vosa Vakaviti'), 'fi' : ('Finnish', 'Suomi'), 'fr' : ('French', 'Français'), 'gl' : ('Galician', 'Galego'), 'de' : ('German', 'Deutsch'), 'hz' : ('Herero', 'Otjiherero'), 'ho' : ('Hiri Motu', 'Hiri Motu'), 'hu' : ('Hungarian', 'Magyar'), 'id' : ('Indonesian', 'Bahasa Indonesia'), 'ga' : ('Irish', 'Gaeilge'), 'io' : ('Ido', 'Ido'), 'is' : ('Icelandic', 'Íslenska'), 'it' : ('Italian', 'Italiano'), 'jv' : ('Javanese', 'BasaJawa'), 'rw' : ('Kinyarwanda', 'Ikinyarwanda'), 'kg' : ('Kongo', 'KiKongo'), 'kj' : ('Kwanyama', 'Kuanyama'), 'la' : ('Latin', 'Lingua latina'), 'lb' : ('Luxembourgish', 'Lëtzebuergesch'), 'lg' : ('Luganda', 'Luganda'), 'li' : ('Limburgish', 'Limburgs'), 'ln' : ('Lingala', 'Lingála'), 'lt' : ('Lithuanian', 'Lietuviukalba'), 'lv' : ('Latvian', 'Latviešuvaloda'), 'gv' : ('Manx', 'Gaelg'), 'mg' : ('Malagasy', 'Malagasy fiteny'), 'mt' : ('Maltese', 'Malti'), 'nb' : ('Norwegian Bokmål', 'Norsk bokmål'), 'nn' : ('Norwegian Nynorsk', 'Norsk nynorsk'), 'no' : ('Norwegian', 'Norsk'), 'oc' : ('Occitan', 'Occitan'), 'om' : ('Oromo', 'Afaan Oromoo'), 'pl' : ('Polish', 'Polski'), 'pt' : ('Portuguese', 'Português'), 'pt_BR' : ('Portuguese Brazillian', 'Português Brasileiro'), 'rm' : ('Romansh', 'Rumantsch grischun'), 'rn' : ('Kirundi', 'kiRundi'), 'ro' : ('Romanian', 'Româna'), 'sc' : ('Sardinian', 'Sardu'), 'se' : ('Northern Sami', 'Davvisámegiella'), 'sm' : ('Samoan', 'Gagana fa\'a Samoa'), 'gd' : ('Gaelic', 'Gàidhlig'), 'sn' : ('Shona', 'Chi Shona'), 'sk' : ('Slovak', 'Slovencina'), 'sl' : ('Slovene', 'Slovenšcina'), 'st' : ('Southern Sotho', 'Sesotho'), 'es' : ('Spanish Castilian', 'Español, castellano'), 'su' : ('Sundanese', 'Basa Sunda'), 'sw' : ('Swahili', 'Kiswahili'), 'ss' : ('Swati', 'SiSwati'), 'sv' : ('Swedish', 'Svenska'), 'tn' : ('Tswana', 'Setswana'), 'to' : ('Tonga (Tonga Islands)', 'faka Tonga'), 'tr' : ('Turkish', 'Türkçe'), 'ts' : ('Tsonga', 'Xitsonga'), 'tw' : ('Twi', 'Twi'), 'ty' : ('Tahitian', 'Reo Tahiti'), 'wa' : ('Walloon', 'Walon'), 'cy' : ('Welsh', 'Cymraeg'), 'wo' : ('Wolof', 'Wollof'), 'fy' : ('Western Frisian', 'Frysk'), 'xh' : ('Xhosa', 'isi Xhosa'), 'yo' : ('Yoruba', 'Yorùbá'), 'zu' : ('Zulu', 'isi Zulu'), } # Setup a safe null-translation set_language() SABnzbd-0.7.20/sabnzbd/misc.py0000644000000000000000000014445612433712602016173 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.misc - misc classes """ import os import sys import logging import urllib import re import shutil import threading import subprocess import socket import time import glob import stat import Queue try: socket.ssl _HAVE_SSL = True except: _HAVE_SSL = False import sabnzbd from sabnzbd.decorators import synchronized from sabnzbd.constants import DEFAULT_PRIORITY, FUTURE_Q_FOLDER, JOB_ADMIN, GIGI, Status, MEBI import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.encoding import unicoder, latin1 import sabnzbd.growler as growler RE_VERSION = re.compile('(\d+)\.(\d+)\.(\d+)([a-zA-Z]*)(\d*)') RE_UNITS = re.compile('(\d+\.*\d*)\s*([KMGTP]{0,1})', re.I) TAB_UNITS = ('', 'K', 'M', 'G', 'T', 'P') # Check if strings are defined for AM and PM HAVE_AMPM = bool(time.strftime('%p', time.localtime())) #------------------------------------------------------------------------------ def time_format(format): """ Return time-format string adjusted for 12/24 hour clock setting """ if cfg.ampm() and HAVE_AMPM: return format.replace('%H:%M:%S', '%I:%M:%S %p').replace('%H:%M', '%I:%M %p') else: return format #------------------------------------------------------------------------------ def safe_lower(txt): """ Return lowercased string. Return '' for None """ if txt: return txt.lower() else: return '' #------------------------------------------------------------------------------ def globber(path, pattern='*'): """ Do a glob.glob(), disabling the [] pattern in 'path' """ if pattern: return glob.glob(os.path.join(path, pattern).replace('[', '[[]')) else: return glob.glob(path.replace('[', '[[]')) #------------------------------------------------------------------------------ def cat_to_opts(cat, pp=None, script=None, priority=None): """ Derive options from category, if options not already defined. Specified options have priority over category-options. If no valid category is given, special category '*' will supply default values """ def_cat = config.get_categories('*') cat = safe_lower(cat) if cat in ('', 'none', 'default'): cat = '*' try: my_cat = config.get_categories()[cat] except KeyError: my_cat = def_cat if pp is None: pp = my_cat.pp() if pp == '': pp = def_cat.pp() if not script: script = my_cat.script() if safe_lower(script) in ('', 'default'): script = def_cat.script() if priority is None or priority == DEFAULT_PRIORITY: priority = my_cat.priority() if priority == DEFAULT_PRIORITY: priority = def_cat.priority() #logging.debug('Cat->Attrib cat=%s pp=%s script=%s prio=%s', cat, pp, script, priority) return cat, pp, script, priority #------------------------------------------------------------------------------ _wildcard_to_regex = { '\\': r'\\', '^' : r'\^', '$' : r'\$', '.' : r'\.', '[' : r'\[', ']' : r'\]', '(' : r'\(', ')' : r'\)', '+' : r'\+', '?' : r'.' , '|' : r'\|', '{' : r'\{', '}' : r'\}', '*' : r'.*' } def wildcard_to_re(text): """ Convert plain wildcard string (with '*' and '?') to regex. """ return ''.join([_wildcard_to_regex.get(ch, ch) for ch in text]) #------------------------------------------------------------------------------ def cat_convert(cat): """ Convert newzbin/nzbs.org category/group-name to user categories. If no match found, but newzbin-cat equals user-cat, then return user-cat If no match found, return None """ newcat = cat found = False if cat and cat.lower() != 'none': cats = config.get_categories() for ucat in cats: try: newzbin = cats[ucat].newzbin() if type(newzbin) != type([]): newzbin = [newzbin] except: newzbin = [] for name in newzbin: if re.search('^%s$' % wildcard_to_re(name), cat, re.I): if '.' not in name: logging.debug('Convert index site category "%s" to user-cat "%s"', cat, ucat) else: logging.debug('Convert group "%s" to user-cat "%s"', cat, ucat) newcat = ucat found = True break if found: break if not found: for ucat in cats: if cat.lower() == ucat.lower(): found = True break if found: return newcat else: return None ################################################################################ # sanitize_filename # ################################################################################ if sabnzbd.WIN32: # the colon should be here too, but we'll handle that separately CH_ILLEGAL = r'\/<>?*|"' CH_LEGAL = r'++{}!@#`' else: CH_ILLEGAL = r'/' CH_LEGAL = r'+' def sanitize_filename(name): """ Return filename with illegal chars converted to legal ones and with the par2 extension always in lowercase """ if not name: return name illegal = CH_ILLEGAL legal = CH_LEGAL if ':' in name: if sabnzbd.WIN32: # Compensate for the odd way par2 on Windows substitutes a colon character name = name.replace(':', '3A') elif sabnzbd.DARWIN: # Compensate for the foolish way par2 on OSX handles a colon character name = name[name.rfind(':')+1:] lst = [] for ch in name.strip(): if ch in illegal: ch = legal[illegal.find(ch)] lst.append(ch) name = ''.join(lst) if not name: name = 'unknown' name, ext = os.path.splitext(name) lowext = ext.lower() if lowext == '.par2' and lowext != ext: ext = lowext return name + ext FL_ILLEGAL = CH_ILLEGAL + ':\x92"' FL_LEGAL = CH_LEGAL + "-''" uFL_ILLEGAL = FL_ILLEGAL.decode('latin-1') uFL_LEGAL = FL_LEGAL.decode('latin-1') def sanitize_foldername(name, limit=True): """ Return foldername with dodgy chars converted to safe ones Remove any leading and trailing dot and space characters """ if not name: return name if isinstance(name, unicode): illegal = uFL_ILLEGAL legal = uFL_LEGAL else: illegal = FL_ILLEGAL legal = FL_LEGAL if cfg.sanitize_safe(): # Remove all bad Windows chars too illegal += r'\/<>?*|":' legal += r'++{}!@#`;' repl = cfg.replace_illegal() lst = [] for ch in name.strip(): if ch in illegal: if repl: ch = legal[illegal.find(ch)] lst.append(ch) else: lst.append(ch) name = ''.join(lst) name = name.strip() if name != '.' and name != '..': name = name.rstrip('.') if not name: name = 'unknown' maxlen = cfg.folder_max_length() if limit and len(name) > maxlen: name = name[:maxlen] return name #------------------------------------------------------------------------------ def sanitize_and_trim_path(path): """ Remove illegal characters and trim element size """ path = path.strip() path = path.replace('\\', '/') parts = path.split('/') if sabnzbd.WIN32 and len(parts[0]) == 2 and ':' in parts[0]: new_path = parts[0] + '/' parts.pop(0) elif path.startswith('//'): new_path = '//' elif path.startswith('/'): new_path = '/' else: new_path = '' for part in parts: new_path = os.path.join(new_path, sanitize_foldername(part)) return os.path.abspath(os.path.normpath(new_path)) #------------------------------------------------------------------------------ def flag_file(path, flag, create=False): """ Create verify flag file or return True if it already exists """ path = os.path.join(path, JOB_ADMIN) path = os.path.join(path, flag) if create: try: f = open(path, 'w') f.write('ok\n') f.close() return True except IOError: return False else: return os.path.exists(path) ################################################################################ # DirPermissions # ################################################################################ def create_all_dirs(path, umask=False): """ Create all required path elements and set umask on all Return True if last elelent could be made or exists """ result = True if sabnzbd.WIN32: try: os.makedirs(path) except: result = False else: list = [] list.extend(path.split('/')) path = '' for d in list: if d: path += '/' + d if not os.path.exists(path): try: os.mkdir(path) result = True except: result = False if umask: mask = cfg.umask() if mask: try: os.chmod(path, int(mask, 8) | 0700) except: pass return result ################################################################################ # Real_Path # ################################################################################ def real_path(loc, path): """ When 'path' is relative, return normalized join of 'loc' and 'path' When 'path' is absolute, return normalized path A path starting with ~ will be located in the user's Home folder """ # The Windows part is a bit convoluted because # os.path.join() doesn't behave the same for all Python versions if path: path = path.strip() else: path = '' if path: if not sabnzbd.WIN32 and path.startswith('~/'): path = path.replace('~', sabnzbd.DIR_HOME, 1) if sabnzbd.WIN32: path = path.replace('/', '\\') if len(path) > 1 and path[0].isalpha() and path[1] == ':': if len(path) == 2 or path[2] != '\\': path = path.replace(':', ':\\', 1) elif path.startswith('\\\\'): pass elif path.startswith('\\'): if len(loc) > 1 and loc[0].isalpha() and loc[1] == ':': path = loc[:2] + path else: path = os.path.join(loc, path) elif path[0] != '/': path = os.path.join(loc, path) else: path = loc return os.path.normpath(os.path.abspath(path)) ################################################################################ # Create_Real_Path # ################################################################################ def create_real_path(name, loc, path, umask=False): """ When 'path' is relative, create join of 'loc' and 'path' When 'path' is absolute, create normalized path 'name' is used for logging. Optional 'umask' will be applied. Returns ('success', 'full path') """ if path: my_dir = real_path(loc, path) if not os.path.exists(my_dir): logging.info('%s directory: %s does not exist, try to create it', name, my_dir) if not create_all_dirs(my_dir, umask): logging.error(Ta('Cannot create directory %s'), my_dir) return (False, my_dir) if os.access(my_dir, os.R_OK + os.W_OK): return (True, my_dir) else: logging.error(Ta('%s directory: %s error accessing'), name, my_dir) return (False, my_dir) else: return (False, "") ################################################################################ # get_user_shellfolders # # Return a dictionary with Windows Special Folders # Read info from the registry ################################################################################ def get_user_shellfolders(): """ Return a dictionary with Windows Special Folders """ import _winreg values = {} # Open registry hive try: hive = _winreg.ConnectRegistry(None, _winreg.HKEY_CURRENT_USER) except WindowsError: logging.error(Ta('Cannot connect to registry hive HKEY_CURRENT_USER.')) return values # Then open the registry key where Windows stores the Shell Folder locations try: key = _winreg.OpenKey(hive, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") except WindowsError: logging.error(Ta('Cannot open registry key "%s".'), r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders") _winreg.CloseKey(hive) return values try: for i in range(0, _winreg.QueryInfoKey(key)[1]): name, value, val_type = _winreg.EnumValue(key, i) try: values[name] = value.encode('latin-1') except UnicodeEncodeError: try: # If the path name cannot be converted to latin-1 (contains high ASCII value strings) # then try and use the short name import win32api # Need to make sure the path actually exists, otherwise ignore if os.path.exists(value): values[name] = win32api.GetShortPathName(value) except: # probably a pywintypes.error error such as folder does not exist logging.error("Traceback: ", exc_info = True) values[name] = 'c:\\' i += 1 _winreg.CloseKey(key) _winreg.CloseKey(hive) return values except WindowsError: # On error, return empty dict. logging.error(Ta('Failed to read registry keys for special folders')) _winreg.CloseKey(key) _winreg.CloseKey(hive) return {} #------------------------------------------------------------------------------ def windows_variant(): """ Determine Windows variant Return vista_plus, x64 """ from win32api import GetVersionEx from win32con import VER_PLATFORM_WIN32_NT import _winreg vista_plus = x64 = False maj, min, buildno, plat, csd = GetVersionEx() if plat == VER_PLATFORM_WIN32_NT: vista_plus = maj > 5 if vista_plus: # Must be done the hard way, because the Python runtime lies to us. # This does *not* work: # return os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' # because the Python runtime returns 'X86' even on an x64 system! key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment") for n in xrange(_winreg.QueryInfoKey(key)[1]): name, value, val_type = _winreg.EnumValue(key, n) if name == 'PROCESSOR_ARCHITECTURE': x64 = value.upper() == u'AMD64' break _winreg.CloseKey(key) return vista_plus, x64 #------------------------------------------------------------------------------ _SERVICE_KEY = 'SYSTEM\\CurrentControlSet\\services\\' _SERVICE_PARM = 'CommandLine' def get_serv_parms(service): """ Get the service command line parameters from Registry """ import _winreg value = [] try: key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, _SERVICE_KEY + service) for n in xrange(_winreg.QueryInfoKey(key)[1]): name, value, val_type = _winreg.EnumValue(key, n) if name == _SERVICE_PARM: break _winreg.CloseKey(key) except WindowsError: pass for n in xrange(len(value)): value[n] = latin1(value[n]) return value def set_serv_parms(service, args): """ Set the service command line parameters in Registry """ import _winreg uargs = [] for arg in args: uargs.append(unicoder(arg)) try: key = _winreg.CreateKey(_winreg.HKEY_LOCAL_MACHINE, _SERVICE_KEY + service) _winreg.SetValueEx(key, _SERVICE_PARM, None, _winreg.REG_MULTI_SZ, uargs) _winreg.CloseKey(key) except WindowsError: return False return True ################################################################################ # Check latest version # # Perform an online version check # Syntax of online version file: # # # # # The latter two lines are only present when a alpha/beta/rc is available. # Formula for the version numbers (line 1 and 3). # - ..[rc|beta|alpha] # # The value for a final version is assumned to be 99. # The value for the beta/rc version is 1..98, with RC getting # a boost of 80 and Beta of 40. # This is done to signal alpha/beta/rc users of availability of the final # version (which is implicitly 99). # People will only be informed to upgrade to a higher alpha/beta/rc version, if # they are already using an alpha/beta/rc. # RC's are valued higher than Beta's, which are valued higher than Alpha's. # ################################################################################ def convert_version(text): """ Convert version string to numerical value and a testversion indicator """ version = 0 test = True m = RE_VERSION.search(text) if m: version = int(m.group(1))*1000000 + int(m.group(2))*10000 + int(m.group(3))*100 try: if m.group(4).lower() == 'rc': version = version + 80 elif m.group(4).lower() == 'beta': version = version + 40 version = version + int(m.group(5)) except: version = version + 99 test = False return version, test def check_latest_version(): """ Do an online check for the latest version """ if not cfg.version_check(): return current, testver = convert_version(sabnzbd.__version__) if not current: logging.debug("Unsupported release number (%s), will not check", sabnzbd.__version__) return try: fn = urllib.urlretrieve('http://sabnzbdplus.sourceforge.net/version/latest')[0] f = open(fn, 'r') data = f.read() f.close() os.remove(fn) except: return try: latest_label = data.split()[0] except: latest_label = '' try: url = data.split()[1] except: url = '' try: latest_testlabel = data.split()[2] except: latest_testlabel = '' try: url_beta = data.split()[3] except: url_beta = url latest, dummy = convert_version(latest_label) latest_test, dummy = convert_version(latest_testlabel) logging.debug("Checked for a new release, cur= %s, latest= %s (on %s)", current, latest, url) if latest_test and cfg.version_check() > 1: # User always wants to see the latest test release latest = latest_test url = url_beta if testver and current < latest: # This is a test version, but user has't seen the # "Final" of this one yet, so show the Final sabnzbd.NEW_VERSION = "%s;%s" % (latest_label, url) elif current < latest: # This one is behind, show latest final sabnzbd.NEW_VERSION = "%s;%s" % (latest_label, url) elif testver and current < latest_test: # This is a test version beyond the latest Final, so show latest Alpha/Beta/RC sabnzbd.NEW_VERSION = "%s;%s" % (latest_testlabel, url_beta) def from_units(val): """ Convert K/M/G/T/P notation to float """ val = str(val).strip().upper() if val == "-1": return val m = RE_UNITS.search(val) if m: if m.group(2): val = float(m.group(1)) unit = m.group(2) n = 0 while unit != TAB_UNITS[n]: val = val * 1024.0 n = n+1 else: val = m.group(1) try: return float(val) except: return 0.0 else: return 0.0 def to_units(val, spaces=0, dec_limit=2, postfix=''): """ Convert number to K/M/G/T/P notation Add "spaces" if not ending in letter dig_limit==1 show single decimal for M and higher dig_limit==2 show single decimal for G and higher """ decimals = 0 if val < 0: sign = '-' else: sign = '' val = str(abs(val)).strip() n = 0 try: val = float(val) except: return '' while (val > 1023.0) and (n < 5): val = val / 1024.0 n = n + 1 unit = TAB_UNITS[n] if not unit: unit = ' ' * spaces if n > dec_limit: decimals = 1 else: decimals = 0 format = '%%s%%.%sf %%s%%s' % decimals return format % (sign, val, unit, postfix) #------------------------------------------------------------------------------ def same_file(a, b): """ Return 0 if A and B have nothing in common return 1 if A and B are actually the same path return 2 if B is a subfolder of A """ a = os.path.normpath(os.path.abspath(a)) b = os.path.normpath(os.path.abspath(b)) if sabnzbd.WIN32 or sabnzbd.DARWIN: a = a.lower() b = b.lower() if b.startswith(a): return 2 if "samefile" in os.path.__dict__: try: return int(os.path.samefile(a, b)) except: return 0 else: return int(a == b) #------------------------------------------------------------------------------ def exit_sab(value): """ Leave the program after flushing stderr/stdout """ sys.stderr.flush() sys.stdout.flush() if getattr(sys, 'frozen', None) == 'macosx_app': sabnzbd.SABSTOP = True from PyObjCTools import AppHelper AppHelper.stopEventLoop() sys.exit(value) #------------------------------------------------------------------------------ def split_host(srv): """ Split host:port notation, allowing for IPV6 """ # Cannot use split, because IPV6 of "a:b:c:port" notation # Split on the last ':' mark = srv.rfind(':') if mark < 0: host = srv else: host = srv[0 : mark] port = srv[mark+1 :] try: port = int(port) except: port = None return (host, port) #------------------------------------------------------------------------------ def check_mount(path): """ Return False if volume isn't mounted on Linux or OSX Retry 6 times with an interval of 1 sec. """ if sabnzbd.DARWIN: m = re.search(r'^(/Volumes/[^/]+)/', path, re.I) elif sabnzbd.WIN32: m = re.search(r'^([a-z]:\\)', path, re.I) else: m = re.search(r'^(/(?:mnt|media)/[^/]+)/', path) if m: for n in xrange(cfg.wait_ext_drive() or 1): if os.path.exists(m.group(1)): return True logging.debug('Waiting for %s to come online', m.group(1)) time.sleep(1) return not m #------------------------------------------------------------------------------ # Locked directory operations DIR_LOCK = threading.RLock() @synchronized(DIR_LOCK) def get_unique_path(dirpath, n=0, create_dir=True): """ Determine a unique folder or filename """ if not check_mount(dirpath): return dirpath path = dirpath if n: path = "%s.%s" % (dirpath, n) if not os.path.exists(path): if create_dir: return create_dirs(path) else: return path else: return get_unique_path(dirpath, n=n+1, create_dir=create_dir) @synchronized(DIR_LOCK) def get_unique_filename(path): """ Check if path is unique. If not, add number like: "/path/name.NUM.ext". """ num = 1 while os.path.exists(path): path, fname = os.path.split(path) name, ext = os.path.splitext(fname) fname = "%s.%d%s" % (name, num, ext) num += 1 path = os.path.join(path, fname) return path @synchronized(DIR_LOCK) def create_dirs(dirpath): """ Create directory tree, obeying permissions """ if not os.path.exists(dirpath): logging.info('Creating directories: %s', dirpath) if not create_all_dirs(dirpath, True): logging.error(Ta('Failed making (%s)'), dirpath) return None return dirpath @synchronized(DIR_LOCK) def move_to_path(path, new_path): """ Move a file to a new path, optionally give unique filename Return (ok, new_path) """ ok = True overwrite = cfg.overwrite_files() if overwrite and os.path.exists(new_path): try: os.remove(new_path) except: overwrite = False if not overwrite: new_path = get_unique_filename(new_path) if new_path: logging.debug("Moving. Old path:%s new path:%s overwrite?:%s", path, new_path, overwrite) try: # First try cheap rename renamer(path, new_path) except: # Cannot rename, try copying try: if not os.path.exists(os.path.dirname(new_path)): create_dirs(os.path.dirname(new_path)) shutil.copyfile(path, new_path) os.remove(path) except: if not (cfg.marker_file() and cfg.marker_file() in path): logging.error(Ta('Failed moving %s to %s'), path, new_path) logging.info("Traceback: ", exc_info = True) ok = False return ok, new_path @synchronized(DIR_LOCK) def cleanup_empty_directories(path): """ Remove all empty folders inside (and including) 'path' """ path = os.path.normpath(path) while 1: repeat = False for root, dirs, files in os.walk(path, topdown=False): if not dirs and not files and root != path: try: remove_dir(root) repeat = True except: pass if not repeat: break try: remove_dir(path) except: pass @synchronized(DIR_LOCK) def get_filepath(path, nzo, filename): """ Create unique filepath """ # This procedure is only used by the Assembler thread # It does no umask setting # It uses the dir_lock for the (rare) case that the # download_dir is equal to the complete_dir. dirname = nzo.work_name created = nzo.created dName = dirname if not created: for n in xrange(200): dName = dirname if n: dName += '.' + str(n) try: os.mkdir(os.path.join(path, dName)) break except: pass nzo.work_name = dName nzo.created = True fPath = os.path.join(os.path.join(path, dName), filename) fPath, ext = os.path.splitext(fPath) n = 0 while True: if n: fullPath = "%s.%d%s" % (fPath, n, ext) else: fullPath = fPath + ext if os.path.exists(fullPath): n = n + 1 else: break return fullPath def make_script_path(script): """ Return full script path, if any valid script exists, else None """ s_path = None path = cfg.script_dir.get_path() if path and script: if script.lower() not in ('none', 'default'): s_path = os.path.join(path, script) if not os.path.exists(s_path): s_path = None return s_path def get_admin_path(newstyle, name, future): """ Return news-style full path to job-admin folder of names job or else the old cache path """ if newstyle: if future: return os.path.join(cfg.admin_dir.get_path(), FUTURE_Q_FOLDER) else: return os.path.join(os.path.join(cfg.download_dir.get_path(), name), JOB_ADMIN) else: return cfg.cache_dir.get_path() def bad_fetch(nzo, url, msg='', retry=False, content=False): """ Create History entry for failed URL Fetch msg : message to be logged retry : make retry link in histort content : report in history that cause is a bad NZB file """ if msg: msg = unicoder(msg) else: msg = '' pp = nzo.pp if pp is None: pp = '' else: pp = '&pp=%s' % str(pp) cat = nzo.cat if cat: cat = '&cat=%s' % urllib.quote(cat) else: cat = '' script = nzo.script if script: script = '&script=%s' % urllib.quote(script) else: script = '' nzo.status = Status.FAILED if url: nzo.filename = url nzo.final_name = url.strip() if content: # Bad content msg = T('Unusable NZB file') else: # Failed fetch msg = ' (' + msg + ')' if retry: nzbname = nzo.custom_name if nzbname: nzbname = '&nzbname=%s' % urllib.quote(nzbname) else: nzbname = '' text = T('URL Fetching failed; %s') + ', ' + T('Try again') + '' parms = (msg, cfg.api_key(), urllib.quote(url), nzo.nzo_id, pp, cat, script, nzbname) nzo.fail_msg = text % parms else: nzo.fail_msg = msg if isinstance(url, int) or url.isdigit(): url = 'Newzbin #%s' % url growler.send_notification(T('URL Fetching failed; %s') % '', '%s\n%s' % (msg, url), 'other') if cfg.email_endjob() > 0: #import sabnzbd.emailer sabnzbd.emailer.badfetch_mail(msg, url) from sabnzbd.nzbqueue import NzbQueue assert isinstance(NzbQueue.do, NzbQueue) NzbQueue.do.remove(nzo.nzo_id, add_to_history=True) def on_cleanup_list(filename, skip_nzb=False): """ Return True if a filename matches the clean-up list """ lst = cfg.cleanup_list() if lst: name, ext = os.path.splitext(filename) ext = ext.strip().lower() name = name.strip() for k in lst: item = k.strip().strip('.').lower() item = '.' + item if (item == ext or (ext == '' and item == name)) and not (skip_nzb and item == '.nzb'): return True return False def get_ext(filename): """ Return lowercased file extension """ try: return os.path.splitext(filename)[1].lower() except: return '' def get_filename(path): """ Return path without the file extension """ try: return os.path.split(path)[1] except: return '' def memory_usage(): try: # Probably only works on Linux because it uses /proc//statm t = open('/proc/%d/statm' % os.getpid()) v = t.read().split() t.close() virt = int(_PAGE_SIZE * int(v[0]) / MEBI) res = int(_PAGE_SIZE * int(v[1]) / MEBI) return "V=%sM R=%sM" % (virt, res) except: return '' try: _PAGE_SIZE = os.sysconf("SC_PAGE_SIZE") except: _PAGE_SIZE = 0 _HAVE_STATM = _PAGE_SIZE and memory_usage() def loadavg(): """ Return 1, 5 and 15 minute load average of host or "" if not supported """ p = '' if not sabnzbd.WIN32 and not sabnzbd.DARWIN: opt = cfg.show_sysload() if opt: try: p = '%.2f | %.2f | %.2f' % os.getloadavg() except: pass if opt > 1 and _HAVE_STATM: p = '%s | %s' % (p, memory_usage()) return p def format_time_string(seconds, days=0): """ Return a formatted and translated time string """ seconds = int_conv(seconds) completestr = [] if days: completestr.append('%s %s' % (days, s_returner('day', days))) if (seconds/3600) >= 1: completestr.append('%s %s' % (seconds/3600, s_returner('hour', (seconds/3600)))) seconds -= (seconds/3600)*3600 if (seconds/60) >= 1: completestr.append('%s %s' % (seconds/60, s_returner('minute',(seconds/60)))) seconds -= (seconds/60)*60 if seconds > 0: completestr.append('%s %s' % (seconds, s_returner('second', seconds))) elif not completestr: completestr.append('0 %s' % s_returner('second', 0)) p = ' '.join(completestr) if isinstance(p, unicode): return p.encode('latin-1') else: return p def s_returner(item, value): """ Return a plural form of 'item', based on 'value' (english only) """ if value == 1: return Tx(item) else: return Tx(item + 's') def int_conv(value): """ Safe conversion to int (can handle None) """ try: value = int(value) except: value = 0 return value #------------------------------------------------------------------------------ # Diskfree if sabnzbd.WIN32: # windows diskfree try: # Careful here, because win32api test hasn't been done yet! import win32api except: pass def diskfree(_dir): """ Return amount of free diskspace in GBytes """ try: available, disk_size, total_free = win32api.GetDiskFreeSpaceEx(_dir) return available / GIGI except: return 0.0 def disktotal(_dir): """ Return amount of free diskspace in GBytes """ try: available, disk_size, total_free = win32api.GetDiskFreeSpaceEx(_dir) return disk_size / GIGI except: return 0.0 else: try: os.statvfs # posix diskfree def diskfree(_dir): """ Return amount of free diskspace in GBytes """ try: s = os.statvfs(_dir) if s.f_bavail < 0: return float(sys.maxint) * float(s.f_frsize) / GIGI else: return float(s.f_bavail) * float(s.f_frsize) / GIGI except OSError: return 0.0 def disktotal(_dir): """ Return amount of total diskspace in GBytes """ try: s = os.statvfs(_dir) if s.f_blocks < 0: return float(sys.maxint) * float(s.f_frsize) / GIGI else: return float(s.f_blocks) * float(s.f_frsize) / GIGI except OSError: return 0.0 except ImportError: def diskfree(_dir): return 10.0 def disktotal(_dir): return 20.0 def create_https_certificates(ssl_cert, ssl_key): """ Create self-signed HTTPS certificares and store in paths 'ssl_cert' and 'ssl_key' """ try: from OpenSSL import crypto from sabnzbd.utils.certgen import createKeyPair, createCertRequest, createCertificate, \ TYPE_RSA, serial except: logging.warning(Ta('pyopenssl module missing, please install for https access')) return False # Create the CA Certificate cakey = createKeyPair(TYPE_RSA, 1024) careq = createCertRequest(cakey, CN='Certificate Authority') cacert = createCertificate(careq, (careq, cakey), serial, (0, 60*60*24*365*10)) # ten years cname = 'SABnzbd' pkey = createKeyPair(TYPE_RSA, 1024) req = createCertRequest(pkey, CN=cname) cert = createCertificate(req, (cacert, cakey), serial, (0, 60*60*24*365*10)) # ten years # Save the key and certificate to disk try: open(ssl_key, 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)) open(ssl_cert, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) except: logging.error(Ta('Error creating SSL key and certificate')) logging.info("Traceback: ", exc_info = True) return False return True def find_on_path(targets): """ Search the PATH for a program and return full path """ if sabnzbd.WIN32: paths = os.getenv('PATH').split(';') else: paths = os.getenv('PATH').split(':') if isinstance(targets, basestring): targets = ( targets, ) for path in paths: for target in targets: target_path = os.path.abspath(os.path.join(path, target)) if os.path.isfile(target_path) and os.access(target_path, os.X_OK): return target_path return None #------------------------------------------------------------------------------ _RE_IP4 = re.compile(r'inet\s+(addr:\s*){0,1}(\d+\.\d+\.\d+\.\d+)') _RE_IP6 = re.compile(r'inet6\s+(addr:\s*){0,1}([0-9a-f:]+)', re.I) def ip_extract(): """ Return list of IP addresses of this system """ ips = [] program = find_on_path('ip') if program: program = [program, 'a'] else: program = find_on_path('ifconfig') if program: program = [program] if sabnzbd.WIN32 or not program: try: info = socket.getaddrinfo(socket.gethostname(), None) except: # Hostname does not resolve, use localhost info = socket.getaddrinfo('localhost', None) for item in info: ips.append(item[4][0]) else: p = subprocess.Popen(program, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=None, creationflags=0) output = p.stdout.read() p.wait() for line in output.split('\n'): m = _RE_IP4.search(line) if not (m and m.group(2)): m = _RE_IP6.search(line) if m and m.group(2): ips.append(m.group(2)) return ips #------------------------------------------------------------------------------ def renamer(old, new): """ Rename file/folder with retries for Win32 """ # Sanitize last part of new name path, name = os.path.split(new) # Use the more stringent folder rename to end up with a nicer name, # but do not trim size new = os.path.join(path, sanitize_foldername(name, False)) logging.debug('Renaming "%s" to "%s"', old, new) if sabnzbd.WIN32: retries = 15 while retries > 0: try: os.rename(old, new) return except WindowsError, err: logging.debug('Error renaming "%s" to "%s" <%s>', old, new, err) if err[0] == 32: logging.debug('Retry rename %s to %s', old, new) retries -= 1 else: raise WindowsError(err) time.sleep(3) raise WindowsError(err) else: os.rename(old, new) def remove_dir(path): """ Remove directory with retries for Win32 """ if sabnzbd.WIN32: retries = 15 while retries > 0: try: os.rmdir(path) return except WindowsError, err: if err[0] == 32: logging.debug('Retry delete %s', path) retries -= 1 else: raise WindowsError(err) time.sleep(3) raise WindowsError(err) else: os.rmdir(path) def remove_all(path, pattern='*', keep_folder=False, recursive=False): """ Remove folder and all its content (optionally recursive) """ if os.path.exists(path): files = globber(path, pattern) if pattern == '*' and not sabnzbd.WIN32: files.extend(globber(path, '.*')) for f in files: if os.path.isfile(f): try: os.remove(f) except: logging.info('Cannot remove file %s', f) elif recursive: remove_all(f, pattern, False, True) if not keep_folder: try: os.rmdir(path) except: logging.info('Cannot remove folder %s', path) def is_writable(path): """ Return True is file is writable (also when non-existent) """ if os.path.isfile(path): return bool(os.stat(path).st_mode & stat.S_IWUSR) else: return True def format_source_url(url): """ Format URL suitable for 'Source' stage """ if _HAVE_SSL: prot = 'https' else: prot = 'http:' if url and str(url).isdigit(): return '%s://%s/browse/post/%s/' % (prot, cfg.newzbin_url(), str(url)) else: return url RE_URL = re.compile(r'://([^/]+)/') def get_base_url(url): m = RE_URL.search(url) if m: return m.group(1) else: return '' def match_str(text, matches): ''' Return first matching element of list 'matches' in 'text', otherwise None ''' for match in matches: if match in text: return match return None def starts_with_path(path, prefix): ''' Return True if 'path' starts with 'prefix', considering case-sensitivity of filesystem ''' if sabnzbd.WIN32 or sabnzbd.DARWIN: return path.lower().startswith(prefix.lower()) else: return path.startswith(prefix) def set_chmod(path, permissions, report): """ Set 'permissions' on 'path', report any errors when 'report' is True """ try: os.chmod(path, permissions) except: lpath = path.lower() if report and '.appledouble' not in lpath and '.ds_store' not in lpath: logging.error(Ta('Cannot change permissions of %s'), path) logging.info("Traceback: ", exc_info = True) def set_permissions(path, recursive=True): """ Give folder tree and its files their proper permissions """ if not sabnzbd.WIN32: umask = cfg.umask() try: # Make sure that user R is on umask = int(umask, 8) | int('0400', 8) report = True except ValueError: # No or no valid permissions # Use the effective permissions of the session # Don't report errors (because the system might not support it) umask = int('0777', 8) & (sabnzbd.ORG_UMASK ^ int('0777', 8)) report = False # Remove X bits for files umask_file = umask & int('7666', 8) if os.path.isdir(path): if recursive: # Parse the dir/file tree and set permissions for root, dirs, files in os.walk(path): set_chmod(root, umask, report) for name in files: set_chmod(os.path.join(root, name), umask_file, report) else: set_chmod(path, umask, report) else: set_chmod(path, umask_file, report) #------------------------------------------------------------------------------ # Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. # Passes Python2.7's test suite and incorporates all the latest updates. class OrderedDict(dict): # An inherited dict maps keys to values. # The inherited dict provides __getitem__, __len__, __contains__, and get. # The remaining methods are order-aware. # Big-O running times for all methods are the same as for regular dictionaries. # The internal self.__map dictionary maps keys to links in a doubly linked list. # The circular doubly linked list starts and ends with a sentinel element. # The sentinel element never gets deleted (this simplifies the algorithm). # Each link is stored as a list of length three: [PREV, NEXT, KEY]. def __init__(self, *args, **kwds): '''Initialize an ordered dictionary. Signature is the same as for regular dictionaries, but keyword arguments are not recommended because their insertion order is arbitrary. ''' if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: self.__root except AttributeError: self.__root = root = [] # sentinel node root[:] = [root, root, None] self.__map = {} self.__update(*args, **kwds) def __setitem__(self, key, value, dict_setitem=dict.__setitem__): # Setting a new item creates a new link which goes at the end of the linked # list, and the inherited dictionary is updated with the new key/value pair. if key not in self: root = self.__root last = root[0] last[1] = root[0] = self.__map[key] = [last, root, key] dict_setitem(self, key, value) def __delitem__(self, key, dict_delitem=dict.__delitem__): # Deleting an existing item uses self.__map to find the link which is # then removed by updating the links in the predecessor and successor nodes. dict_delitem(self, key) link_prev, link_next, key = self.__map.pop(key) link_prev[1] = link_next link_next[0] = link_prev def __iter__(self): root = self.__root curr = root[1] while curr is not root: yield curr[2] curr = curr[1] def __reversed__(self): root = self.__root curr = root[0] while curr is not root: yield curr[2] curr = curr[0] def clear(self): try: for node in self.__map.itervalues(): del node[:] root = self.__root root[:] = [root, root, None] self.__map.clear() except AttributeError: pass dict.clear(self) def popitem(self, last=True): '''od.popitem() -> (k, v), return and remove a (key, value) pair. Pairs are returned in LIFO order if last is true or FIFO order if false. ''' if not self: raise KeyError('dictionary is empty') root = self.__root if last: link = root[0] link_prev = link[0] link_prev[1] = root root[0] = link_prev else: link = root[1] link_next = link[1] root[1] = link_next link_next[0] = root key = link[2] del self.__map[key] value = dict.pop(self, key) return key, value # -- the following methods do not depend on the internal structure -- def keys(self): return list(self) def values(self): return [self[key] for key in self] def items(self): return [(key, self[key]) for key in self] def iterkeys(self): return iter(self) def itervalues(self): for k in self: yield self[k] def iteritems(self): for k in self: yield (k, self[k]) def update(*args, **kwds): if len(args) > 2: raise TypeError('update() takes at most 2 positional ' 'arguments (%d given)' % (len(args),)) elif not args: raise TypeError('update() takes at least 1 argument (0 given)') self = args[0] # Make progressively weaker assumptions about "other" other = () if len(args) == 2: other = args[1] if isinstance(other, dict): for key in other: self[key] = other[key] elif hasattr(other, 'keys'): for key in other.keys(): self[key] = other[key] else: for key, value in other: self[key] = value for key, value in kwds.items(): self[key] = value __update = update # let subclasses override update without breaking __init__ __marker = object() def pop(self, key, default=__marker): if key in self: result = self[key] del self[key] return result if default is self.__marker: raise KeyError(key) return default def setdefault(self, key, default=None): if key in self: return self[key] self[key] = default return default def __repr__(self, _repr_running={}): call_key = id(self), _get_ident() if call_key in _repr_running: return '...' _repr_running[call_key] = 1 try: if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__, self.items()) finally: del _repr_running[call_key] def __reduce__(self): items = [[k, self[k]] for k in self] inst_dict = vars(self).copy() for k in vars(OrderedDict()): inst_dict.pop(k, None) if inst_dict: return (self.__class__, (items,), inst_dict) return self.__class__, (items,) def copy(self): return self.__class__(self) @classmethod def fromkeys(cls, iterable, value=None): d = cls() for key in iterable: d[key] = value return d def __eq__(self, other): if isinstance(other, OrderedDict): return len(self)==len(other) and self.items() == other.items() return dict.__eq__(self, other) def __ne__(self, other): return not self == other # -- the following methods are only used in Python 2.7 -- def viewkeys(self): return KeysView(self) def viewvalues(self): return ValuesView(self) def viewitems(self): return ItemsView(self) #------------------------------------------------------------------------------ # A queue which ignores duplicates but maintains ordering class OrderedSetQueue(Queue.Queue): def _init(self, maxsize): self.maxsize = maxsize self.queue = OrderedDict() def _put(self, item): self.queue[item] = None def _get(self): return self.queue.popitem()[0] SABnzbd-0.7.20/sabnzbd/newsunpack.py0000644000000000000000000017051012433712602017404 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.newsunpack """ import os import sys import re import subprocess import logging from time import time import binascii import shutil import sabnzbd from sabnzbd.encoding import TRANS, UNTRANS, unicode2local, name_fixer, \ reliable_unpack_names, unicoder, latin1, platform_encode from sabnzbd.utils.rarfile import RarFile, is_rarfile from sabnzbd.misc import format_time_string, find_on_path, make_script_path, int_conv, \ flag_file, real_path, globber from sabnzbd.tvsort import SeriesSorter import sabnzbd.cfg as cfg from sabnzbd.constants import Status, QCHECK_FILE, RENAMES_FILE load_data = save_data = None if sabnzbd.WIN32: try: import win32api from win32con import SW_HIDE from win32process import STARTF_USESHOWWINDOW, IDLE_PRIORITY_CLASS except ImportError: pass else: # Define dummy WindowsError for non-Windows class WindowsError(Exception): def __init__(self, value): self.parameter = value def __str__(self): return repr(self.parameter) # Regex globals RAR_RE = re.compile(r'\.(?Ppart\d*\.rar|rar|r\d\d|s\d\d|t\d\d|u\d\d|v\d\d|\d\d\d)$', re.I) RAR_RE_V3 = re.compile(r'\.(?Ppart\d*)$', re.I) LOADING_RE = re.compile(r'^Loading "(.+)"') TARGET_RE = re.compile(r'^(?:File|Target): "(.+)" -') EXTRACTFROM_RE = re.compile(r'^Extracting\sfrom\s(.+)') SPLITFILE_RE = re.compile(r'\.(\d\d\d$)', re.I) ZIP_RE = re.compile(r'\.(zip$)', re.I) VOLPAR2_RE = re.compile(r'\.*vol[0-9]+\+[0-9]+\.par2', re.I) FULLVOLPAR2_RE = re.compile(r'(.*[^.])(\.*vol[0-9]+\+[0-9]+\.par2)', re.I) TS_RE = re.compile(r'\.(\d+)\.(ts$)', re.I) PAR2_COMMAND = None PAR2C_COMMAND = None RAR_COMMAND = None NICE_COMMAND = None ZIP_COMMAND = None IONICE_COMMAND = None RAR_PROBLEM = False CURL_COMMAND = None def find_programs(curdir): """Find external programs """ global load_data, save_data def check(path, program): p = os.path.abspath(os.path.join(path, program)) if os.access(p, os.X_OK): return p else: return None # Another crazy Python import bug work-around load_data = sabnzbd.load_data save_data = sabnzbd.save_data if sabnzbd.DARWIN: try: os_version = run_simple('sw_vers -productVersion') #par2-sl from Macpar Deluxe 4.1 is only 10.6 and later if int(os_version.split('.')[1]) >= 6: sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, 'osx/par2/par2-sl') else: sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, 'osx/par2/par2-classic') except: sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, 'osx/par2/par2-classic') if sabnzbd.DARWIN_INTEL: sabnzbd.newsunpack.RAR_COMMAND = check(curdir, 'osx/unrar/unrar') else: sabnzbd.newsunpack.RAR_COMMAND = check(curdir, 'osx/unrar/unrar-ppc') if sabnzbd.WIN32: if sabnzbd.WIN64 and cfg.allow_64bit_tools.get(): sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, 'win/par2/x64/par2.exe') sabnzbd.newsunpack.RAR_COMMAND = check(curdir, 'win/unrar/x64/UnRAR.exe') if not sabnzbd.newsunpack.PAR2_COMMAND: sabnzbd.newsunpack.PAR2_COMMAND = check(curdir, 'win/par2/par2.exe') if not sabnzbd.newsunpack.RAR_COMMAND: sabnzbd.newsunpack.RAR_COMMAND = check(curdir, 'win/unrar/UnRAR.exe') sabnzbd.newsunpack.PAR2C_COMMAND = check(curdir, 'win/par2/par2-classic.exe') sabnzbd.newsunpack.ZIP_COMMAND = check(curdir, 'win/unzip/unzip.exe') sabnzbd.newsunpack.CURL_COMMAND = check(curdir, 'lib/curl.exe') else: if not sabnzbd.newsunpack.PAR2_COMMAND: sabnzbd.newsunpack.PAR2_COMMAND = find_on_path('par2') if not sabnzbd.newsunpack.RAR_COMMAND: sabnzbd.newsunpack.RAR_COMMAND = find_on_path(('unrar', 'rar', 'unrar3', 'rar3',)) sabnzbd.newsunpack.NICE_COMMAND = find_on_path('nice') sabnzbd.newsunpack.IONICE_COMMAND = find_on_path('ionice') sabnzbd.newsunpack.ZIP_COMMAND = find_on_path('unzip') if not (sabnzbd.WIN32 or sabnzbd.DARWIN): sabnzbd.newsunpack.RAR_PROBLEM = not unrar_check(sabnzbd.newsunpack.RAR_COMMAND) #------------------------------------------------------------------------------ def external_processing(extern_proc, complete_dir, filename, msgid, nicename, cat, group, status, failure_url): """ Run a user postproc script, return console output and exit value """ command = [str(extern_proc), str(complete_dir), str(filename), str(nicename), str(msgid), str(cat), str(group), str(status)] if failure_url: command.extend(str(failure_url)) if extern_proc.endswith('.py') and (sabnzbd.WIN32 or not os.access(extern_proc, os.X_OK)): command.insert(0, 'python') stup, need_shell, command, creationflags = build_command(command) env = fix_env() logging.info('Running external script %s(%s, %s, %s, %s, %s, %s, %s, %s)', extern_proc, complete_dir, filename, nicename, msgid, cat, group, status, failure_url) try: p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, env=env, creationflags=creationflags) except: logging.debug("Failed script %s, Traceback: ", extern_proc, exc_info = True) return "Cannot run script %s\r\n" % extern_proc, -1 output = p.stdout.read() ret = p.wait() return output, ret #------------------------------------------------------------------------------ def SimpleRarExtract(rarfile, name): """ Extract single file from rar archive, returns (retcode, data) """ command = [sabnzbd.newsunpack.RAR_COMMAND, "p", "-inul", rarfile, name] stup, need_shell, command, creationflags = build_command(command) p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, creationflags=creationflags) output = p.stdout.read() ret = p.wait() return ret, output #------------------------------------------------------------------------------ def unpack_magic(nzo, workdir, workdir_complete, dele, one_folder, joinables, zips, rars, ts, depth=0): """ Do a recursive unpack from all archives in 'workdir' to 'workdir_complete' """ if depth > 5: logging.warning('Unpack nesting too deep [%s]', latin1(nzo.final_name)) return False, [] depth += 1 if depth == 1: # First time, ignore anything in workdir_complete xjoinables, xzips, xrars, xts = build_filelists(workdir, None) else: xjoinables, xzips, xrars, xts = build_filelists(workdir, workdir_complete) rerun = False newfiles = [] error = 0 new_joins = new_rars = new_zips = new_ts = None if cfg.enable_filejoin(): new_joins = [jn for jn in xjoinables if jn not in joinables] if new_joins: rerun = True logging.info('Filejoin starting on %s', workdir) error, newf = file_join(nzo, workdir, workdir_complete, dele, new_joins) if newf: newfiles.extend(newf) logging.info('Filejoin finished on %s', workdir) nzo.set_action_line() if cfg.enable_unrar(): new_rars = [rar for rar in xrars if rar not in rars] if new_rars: rerun = True logging.info('Unrar starting on %s', workdir) error, newf = rar_unpack(nzo, workdir, workdir_complete, dele, one_folder, new_rars) if newf: newfiles.extend(newf) logging.info('Unrar finished on %s', workdir) nzo.set_action_line() if cfg.enable_unzip(): new_zips = [zip for zip in xzips if zip not in zips] if new_zips: rerun = True logging.info('Unzip starting on %s', workdir) if unzip(nzo, workdir, workdir_complete, dele, one_folder, new_zips): error = 1 logging.info('Unzip finished on %s', workdir) nzo.set_action_line() if cfg.enable_tsjoin(): new_ts = [_ts for _ts in xts if _ts not in ts] if new_ts: rerun = True logging.info('TS Joining starting on %s', workdir) error, newf = file_join(nzo, workdir, workdir_complete, dele, new_ts) if newf: newfiles.extend(newf) logging.info('TS Joining finished on %s', workdir) nzo.set_action_line() if rerun and (cfg.enable_recursive() or new_ts or new_joins): z, y = unpack_magic(nzo, workdir, workdir_complete, dele, one_folder, xjoinables, xzips, xrars, xts, depth) if z: error = z if y: newfiles.extend(y) return error, newfiles #------------------------------------------------------------------------------ # Filejoin Functions #------------------------------------------------------------------------------ def match_ts(file): """ Return True if file is a joinable TS file """ match = TS_RE.search(file) if not match: return False, '', 0 num = int(match.group(1)) try: set = file[:match.start()] set += '.ts' except: set = '' return match, set, num def clean_up_joinables(names): """ Remove joinable files and their .1 backups """ for name in names: if os.path.exists(name): logging.debug("Deleting %s", name) try: os.remove(name) except: pass name1 = name + ".1" if os.path.exists(name1): logging.debug("Deleting %s", name1) try: os.remove(name1) except: pass def get_seq_number(name): """ Return sequence number if name as an int """ head, tail = os.path.splitext(name) if tail == '.ts': match, set, num = match_ts(name) else: num = tail[1:] if num.isdigit(): return int(num) else: return 0 def file_join(nzo, workdir, workdir_complete, delete, joinables): """ Join and joinable files in 'workdir' to 'workdir_complete' and when succesful, delete originals """ newfiles = [] bufsize = 24*1024*1024 # Create matching sets from the list of files joinable_sets = {} joinable_set = None for joinable in joinables: head, tail = os.path.splitext(joinable) if tail == '.ts': head = match_ts(joinable)[1] if head not in joinable_sets: joinable_sets[head] = [] joinable_sets[head].append(joinable) logging.debug("joinable_sets: %s", joinable_sets) try: # Handle each set for joinable_set in joinable_sets: current = joinable_sets[joinable_set] joinable_sets[joinable_set].sort() # If par2 already did the work, just remove the files if os.path.exists(joinable_set): logging.debug("file_join(): Skipping %s, (probably) joined by par2", joinable_set) if delete: clean_up_joinables(current) # done, go to next set continue # Only join when there is more than one file size = len(current) if size < 2: continue # Prepare joined file filename = joinable_set if workdir_complete: filename = filename.replace(workdir, workdir_complete) logging.debug("file_join(): Assembling %s", filename) joined_file = open(filename, 'ab') # Join the segments n = get_seq_number(current[0]) seq_error = n > 1 for joinable in current: if get_seq_number(joinable) != n: seq_error = True perc = (100.0 / size) * n logging.debug("Processing %s", joinable) nzo.set_action_line(T('Joining'), '%.0f%%' % perc) f = open(joinable, 'rb') shutil.copyfileobj(f, joined_file, bufsize) f.close() if delete: logging.debug("Deleting %s", joinable) os.remove(joinable) n += 1 # Remove any remaining .1 files clean_up_joinables(current) # Finish up joined_file.flush() joined_file.close() newfiles.append(filename) if seq_error: msg = T('Incomplete sequence of joinable files') nzo.fail_msg = T('File join of %s failed') % unicoder(joinable_set) nzo.set_unpack_info('Filejoin', T('[%s] Error "%s" while joining files') % (unicoder(joinable_set), msg)) logging.error(Ta('Error "%s" while running file_join on %s'), msg, latin1(nzo.final_name)) else: msg = T('[%s] Joined %s files') % (unicoder(joinable_set), size) nzo.set_unpack_info('Filejoin', msg, set=joinable_set) except: msg = sys.exc_info()[1] nzo.fail_msg = T('File join of %s failed') % msg nzo.set_unpack_info('Filejoin', T('[%s] Error "%s" while joining files') % (unicoder(joinable_set), msg)) logging.error(Ta('Error "%s" while running file_join on %s'), msg, latin1(nzo.final_name)) return True, [] return False, newfiles #------------------------------------------------------------------------------ # (Un)Rar Functions #------------------------------------------------------------------------------ def rar_unpack(nzo, workdir, workdir_complete, delete, one_folder, rars): """ Unpack multiple sets 'rars' of RAR files from 'workdir' to 'workdir_complete. When 'delete' is set, originals will be deleted. When 'one_folder' is set, all files will be in a single folder """ extracted_files = [] success = False rar_sets = {} for rar in rars: rar_set = os.path.splitext(os.path.basename(rar))[0] if RAR_RE_V3.search(rar_set): rar_set = os.path.splitext(rar_set)[0] if not rar_set in rar_sets: rar_sets[rar_set] = [] rar_sets[rar_set].append(rar) logging.debug('Rar_sets: %s', rar_sets) for rar_set in rar_sets: # Run the RAR extractor rar_sets[rar_set].sort(rar_sort) rarpath = rar_sets[rar_set][0] if workdir_complete and rarpath.startswith(workdir): extraction_path = workdir_complete else: extraction_path = os.path.split(rarpath)[0] logging.info("Extracting rarfile %s (belonging to %s) to %s", rarpath, rar_set, extraction_path) try: fail, newfiles, rars = rar_extract(rarpath, len(rar_sets[rar_set]), one_folder, nzo, rar_set, extraction_path) success = not fail except: success = False msg = sys.exc_info()[1] nzo.set_fail = T('Unpacking failed, %s') % msg setname = nzo.final_name nzo.set_unpack_info('Unpack', T('[%s] Error "%s" while unpacking RAR files') % (unicoder(setname), msg)) logging.error(Ta('Error "%s" while running rar_unpack on %s'), msg, latin1(setname)) logging.debug("Traceback: ", exc_info = True) if success: logging.debug('rar_unpack(): Rars: %s', rars) logging.debug('rar_unpack(): Newfiles: %s', newfiles) extracted_files.extend(newfiles) # Delete the old files if we have to if success and delete and newfiles: for rar in rars: logging.info("Deleting %s", rar) try: os.remove(rar) except OSError: logging.warning(Ta('Deleting %s failed!'), latin1(rar)) brokenrar = '%s.1' % rar if os.path.exists(brokenrar): logging.info("Deleting %s", brokenrar) try: os.remove(brokenrar) except OSError: logging.warning(Ta('Deleting %s failed!'), latin1(brokenrar)) return fail, extracted_files def rar_extract(rarfile, numrars, one_folder, nzo, setname, extraction_path): """ Unpack single rar set 'rarfile' to 'extraction_path', with password tries Return fail==0(ok)/fail==1(error)/fail==2(wrong password), new_files, rars """ fail = 0 new_files = None rars = [] if nzo.password: logging.info('Got a password set by user') passwords = [nzo.password.strip()] else: passwords = [] # Append meta passwords, to prevent changing the original list passwords.extend(nzo.meta.get('password', [])) if passwords: logging.info('Read %s passwords from meta data in NZB', len(passwords)) pw_file = cfg.password_file.get_path() if pw_file: try: pwf = open(pw_file, 'r') lines = pwf.read().split('\n') # Remove empty lines and space-only passwords and remove surrounding spaces pws = [pw.strip('\r\n ') for pw in lines if pw.strip('\r\n ')] passwords.extend(pws) pwf.close() logging.info('Read %s passwords from file %s', len(pws), pw_file) except IOError: logging.info('Failed to read the passwords file %s', pw_file) if nzo.password: # If an explicit password was set, add a retry without password, just in case. passwords.append('') elif not passwords or not nzo.encrypted: # If we're not sure about encryption, start with empty password # and make sure we have at least the empty password passwords.insert(0, '') for password in passwords: if password: logging.debug('Trying unrar with password "%s"', password) msg = T('Trying unrar with password "%s"') % unicoder(password) nzo.fail_msg = msg nzo.set_unpack_info('Unpack', msg) fail, new_files, rars = rar_extract_core(rarfile, numrars, one_folder, nzo, setname, extraction_path, password) if fail != 2: break if fail == 2: logging.error('%s (%s)', Ta('Unpacking failed, archive requires a password'), latin1(os.path.split(rarfile)[1])) return fail, new_files, rars def rar_extract_core(rarfile, numrars, one_folder, nzo, setname, extraction_path, password): """ Unpack single rar set 'rarfile' to 'extraction_path' Return fail==0(ok)/fail==1(error)/fail==2(wrong password)/fail==3(crc-error), new_files, rars """ start = time() logging.debug("rar_extract(): Extractionpath: %s", extraction_path) try: zf = RarFile(rarfile) expected_files = zf.unamelist() zf.close() except: logging.info('Archive %s probably has full encryption', rarfile) expected_files = [] if password: password = '-p%s' % password else: password = '-p-' ############################################################################ if one_folder or cfg.flat_unpack(): action = 'e' else: action = 'x' if cfg.overwrite_files(): overwrite = '-o+' # Enable overwrite rename = '-o+' # Dummy else: overwrite = '-o-' # Disable overwrite rename = '-or' # Auto renaming if sabnzbd.WIN32: # Use all flags command = ['%s' % RAR_COMMAND, action, '-idp', overwrite, rename, '-ai', password, '%s' % rarfile, '%s/' % extraction_path] elif RAR_PROBLEM: # Use only oldest options (specifically no "-or") command = ['%s' % RAR_COMMAND, action, '-idp', overwrite, password, '%s' % rarfile, '%s/' % extraction_path] else: # Don't use "-ai" (not needed for non-Windows) command = ['%s' % RAR_COMMAND, action, '-idp', overwrite, rename, password, '%s' % rarfile, '%s/' % extraction_path] if cfg.ignore_unrar_dates(): command.insert(3, '-tsm-') stup, need_shell, command, creationflags = build_command(command) logging.debug("Running unrar %s", command) p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, creationflags=creationflags) proc = p.stdout if p.stdin: p.stdin.close() nzo.set_action_line(T('Unpacking'), '00/%02d' % numrars) # Loop over the output from rar! curr = 0 extracted = [] rarfiles = [] fail = 0 while 1: line = proc.readline() if not line: break line = line.strip() if line.startswith('Extracting from'): filename = TRANS((re.search(EXTRACTFROM_RE, line).group(1))) if filename not in rarfiles: rarfiles.append(filename) curr += 1 nzo.set_action_line(T('Unpacking'), '%02d/%02d' % (curr, numrars)) elif line.startswith('Cannot find volume'): filename = os.path.basename(TRANS(line[19:])) nzo.fail_msg = T('Unpacking failed, unable to find %s') % unicoder(filename) msg = ('[%s] '+Ta('Unpacking failed, unable to find %s')) % (setname, latin1(filename)) nzo.set_unpack_info('Unpack', unicoder(msg), set=setname) logging.warning(Ta('ERROR: unable to find "%s"'), latin1(filename)) fail = 1 elif line.endswith('- CRC failed'): filename = TRANS(line[:-12].strip()) nzo.fail_msg = T('Unpacking failed, CRC error') msg = ('[%s] '+Ta('ERROR: CRC failed in "%s"')) % (setname, latin1(filename)) nzo.set_unpack_info('Unpack', unicoder(msg), set=setname) logging.warning(Ta('ERROR: CRC failed in "%s"'), latin1(setname)) fail = 2 # Older unrar versions report a wrong password as a CRC error elif line.startswith('Write error'): nzo.fail_msg = T('Unpacking failed, write error or disk is full?') msg = ('[%s] ' + Ta('Unpacking failed, write error or disk is full?')) % setname nzo.set_unpack_info('Unpack', unicoder(msg), set=setname) logging.error(Ta('ERROR: write error (%s)'), line[11:]) fail = 1 elif line.startswith('Cannot create'): line2 = proc.readline() if 'must not exceed 260' in line2: nzo.fail_msg = T('Unpacking failed, path is too long') msg = '[%s] %s: %s' % (Ta('Unpacking failed, path is too long'), setname, line[13:]) logging.error(Ta('ERROR: path too long (%s)'), line[13:]) else: nzo.fail_msg = T('Unpacking failed, write error or disk is full?') msg = '[%s] %s: %s' % (Ta('Unpacking failed, write error or disk is full?'), setname, line[13:]) logging.error(Ta('ERROR: write error (%s)'), line[13:]) nzo.set_unpack_info('Unpack', unicoder(msg), set=setname) fail = 1 elif line.startswith('ERROR: '): nzo.fail_msg = T('Unpacking failed, see log') logging.warning(Ta('ERROR: %s'), (line[7:])) msg = ('[%s] '+Ta('ERROR: %s')) % (latin1(setname), line[7:]) nzo.set_unpack_info('Unpack', unicoder(msg), set=setname) fail = 1 elif 'The specified password is incorrect' in line or \ ('ncrypted file' in line and (('CRC failed' in line) or ('Checksum error' in line))): # unrar 3.x: "Encrypted file: CRC failed in oLKQfrcNVivzdzSG22a2xo7t001.part1.rar (password incorrect ?)" # unrar 4.x: "CRC failed in the encrypted file oLKQfrcNVivzdzSG22a2xo7t001.part1.rar. Corrupt file or wrong password." # unrar 5.x: "Checksum error in the encrypted file oLKQfrcNVivzdzSG22a2xo7t001.part1.rar. Corrupt file or wrong password." # unrar 5.01 : "The specified password is incorrect." m = re.search('encrypted file (.+)\. Corrupt file', line) if not m: # unrar 3.x syntax m = re.search('Encrypted file: CRC failed in (.+) \(password', line) if m: filename = TRANS(m.group(1)).strip() else: filename = os.path.split(rarfile)[1] nzo.fail_msg = T('Unpacking failed, archive requires a password') msg = ('[%s][%s] '+Ta('Unpacking failed, archive requires a password')) % (setname, latin1(filename)) nzo.set_unpack_info('Unpack', unicoder(msg), set=setname) fail = 2 elif 'is not RAR archive' in line: # Unrecognizable RAR file m = re.search('(.+) is not RAR archive', line) if m: filename = TRANS(m.group(1)).strip() else: filename = '???' nzo.fail_msg = T('Unusable RAR file') msg = ('[%s][%s] '+ Ta('Unusable RAR file')) % (setname, latin1(filename)) nzo.set_unpack_info('Unpack', unicoder(msg), set=setname) fail = 3 else: m = re.search(r'^(Extracting|Creating|...)\s+(.*?)\s+OK\s*$', line) if m: extracted.append(real_path(extraction_path, TRANS(m.group(2)))) if fail: if proc: proc.close() p.wait() return fail, (), () if proc: proc.close() p.wait() if cfg.unpack_check(): if reliable_unpack_names() and not RAR_PROBLEM: missing = [] # Loop through and check for the presence of all the files the archive contained for path in expected_files: if one_folder or cfg.flat_unpack(): path = os.path.split(path)[1] path = unicode2local(path) if '?' in path: logging.info('Skipping check of file %s', path) continue fullpath = os.path.join(extraction_path, path) logging.debug("Checking existence of %s", latin1(fullpath)) if path.endswith('/'): # Folder continue if not os.path.exists(fullpath): # There was a missing file, show a warning missing.append(path) logging.info(Ta('Missing expected file: %s => unrar error?'), latin1(path)) if missing: nzo.fail_msg = T('Unpacking failed, an expected file was not unpacked') logging.debug("Expecting files: %s" % str(expected_files)) msg = T('Unpacking failed, these file(s) are missing:') + ';' + u';'.join([unicoder(item) for item in missing]) nzo.set_unpack_info('Unpack', msg, set=setname) return (1, (), ()) else: logging.info('Skipping unrar file check due to unreliable file names or old unrar') nzo.fail_msg = '' msg = T('Unpacked %s files/folders in %s') % (str(len(extracted)), format_time_string(time() - start)) nzo.set_unpack_info('Unpack', '[%s] %s' % (unicoder(setname), msg), set=setname) logging.info('%s', msg) return 0, extracted, rarfiles #------------------------------------------------------------------------------ # (Un)Zip Functions #------------------------------------------------------------------------------ def unzip(nzo, workdir, workdir_complete, delete, one_folder, zips): """ Unpack multiple sets 'zips' of ZIP files from 'workdir' to 'workdir_complete. When 'delete' is ste, originals will be deleted. """ try: i = 0 unzip_failed = False tms = time() for _zip in zips: logging.info("Starting extract on zipfile: %s ", _zip) nzo.set_action_line(T('Unpacking'), '%s' % unicoder(_zip)) if workdir_complete and _zip.startswith(workdir): extraction_path = workdir_complete else: extraction_path = os.path.split(_zip)[0] if ZIP_Extract(_zip, extraction_path, one_folder): unzip_failed = True else: i += 1 msg = T('%s files in %s') % (str(i), format_time_string(time() - tms)) nzo.set_unpack_info('Unpack', msg) # Delete the old files if we have to if delete and not unzip_failed: i = 0 for _zip in zips: logging.info("Deleting %s", _zip) try: os.remove(_zip) i += 1 except OSError: logging.warning(Ta('Deleting %s failed!'), latin1(_zip)) brokenzip = '%s.1' % _zip if os.path.exists(brokenzip): logging.info("Deleting %s", brokenzip) try: os.remove(brokenzip) i += 1 except OSError: logging.warning(Ta('Deleting %s failed!'), latin1(brokenzip)) return unzip_failed except: msg = sys.exc_info()[1] nzo.fail_msg = T('Unpacking failed, %s') % msg logging.error(Ta('Error "%s" while running unzip() on %s'), msg, latin1(nzo.final_name)) return True def ZIP_Extract(zipfile, extraction_path, one_folder): """ Unzip single zip set 'zipfile' to 'extraction_path' """ if one_folder or cfg.flat_unpack(): option = '-j' # Unpack without folders else: option = '-qq' # Dummy option command = ['%s' % ZIP_COMMAND, '-o', '-qq', option, '-Pnone', '%s' % zipfile, '-d%s' % extraction_path] stup, need_shell, command, creationflags = build_command(command) p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, creationflags=creationflags) output = p.stdout.read() ret = p.wait() return ret #------------------------------------------------------------------------------ # PAR2 Functions #------------------------------------------------------------------------------ def par2_repair(parfile_nzf, nzo, workdir, setname, single): """ Try to repair a set, return readd or correctness """ #set the current nzo status to "Repairing". Used in History parfile = os.path.join(workdir, parfile_nzf.filename) old_dir_content = os.listdir(workdir) used_joinables = () joinables = () used_par2 = () setpars = pars_of_set(workdir, setname) result = readd = False nzo.status = Status.QUICK_CHECK nzo.set_action_line(T('Repair'), T('Quick Checking')) qc_result = QuickCheck(setname, nzo) if qc_result and cfg.quick_check(): logging.info("Quick-check for %s is OK, skipping repair", setname) nzo.set_unpack_info('Repair', T('[%s] Quick Check OK') % unicoder(setname), set=setname) pars = setpars result = True if not result: flag_file(workdir, QCHECK_FILE, True) nzo.status = Status.REPAIRING result = False readd = False try: nzo.set_action_line(T('Repair'), T('Starting Repair')) logging.info('Scanning "%s"', parfile) joinables, zips, rars, ts = build_filelists(workdir, None, check_rar=False) finished, readd, pars, datafiles, used_joinables, used_par2 = PAR_Verify(parfile, parfile_nzf, nzo, setname, joinables, single=single) if finished: result = True logging.info('Par verify finished ok on %s!', parfile) # Remove this set so we don't try to check it again nzo.remove_parset(parfile_nzf.setname) else: if qc_result: logging.warning('Par verify failed on %s, while QuickCheck succeeded!', parfile) else: logging.info('Par verify failed on %s!', parfile) if not readd: # Failed to repair -> remove this set nzo.remove_parset(parfile_nzf.setname) return readd, False except: msg = sys.exc_info()[1] nzo.fail_msg = T('Repairing failed, %s') % msg logging.error(Ta('Error %s while running par2_repair on set %s'), msg, latin1(setname)) logging.info("Traceback: ", exc_info = True) return readd, result try: if cfg.enable_par_cleanup(): new_dir_content = os.listdir(workdir) for path in new_dir_content: if os.path.splitext(path)[1] == '.1' and path not in old_dir_content: try: path = os.path.join(workdir, path) logging.info("Deleting %s", path) os.remove(path) except: logging.warning(Ta('Deleting %s failed!'), latin1(path)) path = os.path.join(workdir, setname + '.par2') path2 = os.path.join(workdir, setname + '.PAR2') if os.path.exists(path): try: logging.info("Deleting %s", path) os.remove(path) except: logging.warning(Ta('Deleting %s failed!'), latin1(path)) if os.path.exists(path2): try: logging.info("Deleting %s", path2) os.remove(path2) except: logging.warning(Ta('Deleting %s failed!'), latin1(path2)) if os.path.exists(parfile): try: logging.info("Deleting %s", parfile) os.remove(parfile) except OSError: logging.warning(Ta('Deleting %s failed!'), latin1(parfile)) deletables = [] for f in pars: if f in setpars: deletables.append(os.path.join(workdir, f)) deletables.extend(used_joinables) deletables.extend(used_par2) for filepath in deletables: if filepath in joinables: joinables.remove(filepath) if os.path.exists(filepath): logging.info("Deleting %s", filepath) try: os.remove(filepath) except OSError: logging.warning(Ta('Deleting %s failed!'), latin1(filepath)) except: msg = sys.exc_info()[1] nzo.fail_msg = T('Repairing failed, %s') % msg logging.error(Ta('Error "%s" while running par2_repair on set %s'), msg, latin1(setname)) return readd, result _RE_BLOCK_FOUND = re.compile('File: "([^"]+)" - found \d+ of \d+ data blocks from "([^"]+)"') _RE_IS_MATCH_FOR = re.compile('File: "([^"]+)" - is a match for "([^"]+)"') _RE_LOADING_PAR2 = re.compile('Loading "([^"]+)"\.') _RE_LOADED_PAR2 = re.compile('Loaded (\d+) new packets') def PAR_Verify(parfile, parfile_nzf, nzo, setname, joinables, classic=False, single=False): """ Run par2 on par-set """ if cfg.never_repair(): cmd = 'v' else: cmd = 'r' retry_classic = False used_joinables = [] used_par2 = [] extra_par2_name = None #set the current nzo status to "Verifying...". Used in History nzo.status = Status.VERIFYING start = time() classic = classic or not cfg.par2_multicore() logging.debug('Par2-classic = %s', classic) import sabnzbd.assembler if (sabnzbd.assembler.GetMD5Hashes(parfile, True)[1] and not classic) or not PAR2C_COMMAND: if cfg.par_option(): command = [str(PAR2_COMMAND), cmd, str(cfg.par_option().strip()), parfile] else: command = [str(PAR2_COMMAND), cmd, parfile] classic = not PAR2C_COMMAND else: command = [str(PAR2C_COMMAND), cmd, parfile] classic = True # Append the wildcard for this set wildcard = '%s*' % os.path.join(os.path.split(parfile)[0], setname) if single or len(globber(wildcard, None)) < 2: # Support bizarre naming conventions wildcard = os.path.join(os.path.split(parfile)[0], '*') if sabnzbd.WIN32 or sabnzbd.DARWIN: command.append(wildcard) else: flist = [item for item in globber(wildcard, None) if os.path.isfile(item)] command.extend(flist) stup, need_shell, command, creationflags = build_command(command) logging.debug('Starting par2: %s', command) lines = [] try: p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, creationflags=creationflags) proc = p.stdout if p.stdin: p.stdin.close() # Set up our variables pars = [] datafiles = [] renames = {} linebuf = '' finished = 0 readd = False verifynum = 1 verifytotal = 0 verified = 0 # Loop over the output, whee while 1: char = proc.read(1) if not char: break # Line not complete yet if char not in ('\n', '\r'): linebuf += char continue line = linebuf.strip() linebuf = '' # Skip empty lines if line == '': continue if 'Repairing:' not in line: lines.append(line) if extra_par2_name and line.startswith('Loading:') and line.endswith('%'): continue if extra_par2_name and line.startswith('Loaded '): m = _RE_LOADED_PAR2.search(line) if m and int(m.group(1)) > 0: used_par2.append(os.path.join(nzo.downpath, extra_par2_name)) extra_par2_name = None continue extra_par2_name = None if line.startswith('Invalid option specified'): msg = T('[%s] PAR2 received incorrect options, check your Config->Switches settings') % unicoder(setname) nzo.set_unpack_info('Repair', msg, set=setname) nzo.status = Status.FAILED elif line.startswith('All files are correct'): msg = T('[%s] Verified in %s, all files correct') % (unicoder(setname), format_time_string(time() - start)) nzo.set_unpack_info('Repair', msg, set=setname) logging.info('Verified in %s, all files correct', format_time_string(time() - start)) finished = 1 elif line.startswith('Repair is required'): msg = T('[%s] Verified in %s, repair is required') % (unicoder(setname), format_time_string(time() - start)) nzo.set_unpack_info('Repair', msg, set=setname) logging.info('Verified in %s, repair is required', format_time_string(time() - start)) start = time() verified = 1 elif line.startswith('Loading "'): # Found an extra par2 file. Only the next line will tell whether it's usable m = _RE_LOADING_PAR2.search(line) if m and m.group(1).lower().endswith('.par2'): extra_par2_name = m.group(1) elif line.startswith('Main packet not found') or 'The recovery file does not exist' in line: ## Initialparfile probably didn't decode properly, logging.info(Ta('Main packet not found...')) extrapars = parfile_nzf.extrapars logging.info("Extra pars = %s", extrapars) ## Look for the smallest par2file block_table = {} for nzf in extrapars: if not nzf.completed: block_table[int_conv(nzf.blocks)] = nzf if block_table: nzf = block_table[min(block_table.keys())] logging.info("Found new par2file %s", nzf.filename) ## Move from extrapar list to files to be downloaded nzo.add_parfile(nzf) extrapars.remove(nzf) ## Now set new par2 file as primary par2 nzo.partable[setname] = nzf nzf.extrapars= extrapars parfile_nzf = [] ## mark for readd readd = True else: msg = T('Invalid par2 files, cannot verify or repair') nzo.fail_msg = msg msg = u'[%s] %s' % (unicoder(setname), msg) nzo.set_unpack_info('Repair', msg, set=setname) nzo.status = Status.FAILED elif line.startswith('You need'): chunks = line.split() needed_blocks = int(chunks[2]) logging.info('Need to fetch %s more blocks, checking blocks', needed_blocks) avail_blocks = 0 extrapars = parfile_nzf.extrapars block_table = {} for nzf in extrapars: # Don't count extrapars that are completed already if nzf.completed: continue blocks = int_conv(nzf.blocks) avail_blocks += blocks if blocks not in block_table: block_table[blocks] = [] block_table[blocks].append(nzf) logging.info('%s blocks available', avail_blocks) force = False if (avail_blocks < needed_blocks) and (avail_blocks > 0): # Tell SAB that we always have enough blocks, so that # it will try to load all pars anyway msg = T('Repair failed, not enough repair blocks (%s short)') % str(int(needed_blocks - avail_blocks)) nzo.fail_msg = msg msg = u'[%s] %s' % (unicoder(setname), msg) nzo.set_unpack_info('Repair', msg, set=setname) nzo.status = Status.FETCHING needed_blocks = avail_blocks force = True if avail_blocks >= needed_blocks: added_blocks = 0 readd = True while added_blocks < needed_blocks: block_size = min(block_table.keys()) extrapar_list = block_table[block_size] if extrapar_list: new_nzf = extrapar_list.pop() nzo.add_parfile(new_nzf) if new_nzf in extrapars: extrapars.remove(new_nzf) added_blocks += block_size else: block_table.pop(block_size) logging.info('Added %s blocks to %s', added_blocks, nzo.final_name) if not force: msg = T('Fetching %s blocks...') % str(added_blocks) nzo.status = Status.FETCHING nzo.set_action_line(T('Fetching'), msg) else: msg = T('Repair failed, not enough repair blocks (%s short)') % str(needed_blocks) nzo.fail_msg = msg msg = u'[%s] %s' % (unicoder(setname), msg) nzo.set_unpack_info('Repair', msg, set=setname) nzo.status = Status.FAILED elif line.startswith('Repair is possible'): start = time() nzo.set_action_line(T('Repairing'), '%2d%%' % (0)) elif line.startswith('Repairing:'): chunks = line.split() per = float(chunks[-1][:-1]) nzo.set_action_line(T('Repairing'), '%2d%%' % per) nzo.status = Status.REPAIRING elif line.startswith('Repair complete'): msg = T('[%s] Repaired in %s') % (unicoder(setname), format_time_string(time() - start)) nzo.set_unpack_info('Repair', msg, set=setname) logging.info('Repaired in %s', format_time_string(time() - start)) finished = 1 elif line.startswith('File:') and line.find('data blocks from') > 0: # Find out if a joinable file has been used for joining for jn in joinables: if line.find(os.path.split(jn)[1]) > 0: used_joinables.append(jn) break # Special case of joined RAR files, the "of" and "from" must both be RAR files # This prevents the joined rars files from being seen as an extra rar-set m = _RE_BLOCK_FOUND.search(line) if m and '.rar' in m.group(1).lower() and '.rar' in m.group(2).lower(): workdir = os.path.split(parfile)[0] used_joinables.append(os.path.join(workdir, m.group(1))) elif 'Could not write' in line and 'at offset 0:' in line and not classic: # Hit a bug in par2-tbb, retry with par2-classic retry_classic = True elif ' cannot be renamed to ' in line: if not classic and sabnzbd.WIN32: # Hit a bug in par2-tbb, retry with par2-classic retry_classic = True else: msg = unicoder(line.strip()) nzo.fail_msg = msg msg = u'[%s] %s' % (unicoder(setname), msg) nzo.set_unpack_info('Repair', msg, set=setname) nzo.status = Status.FAILED # File: "oldname.rar" - is a match for "newname.rar". elif 'is a match for' in line: m = _RE_IS_MATCH_FOR.search(line) if m: old_name = m.group(1) new_name = m.group(2) logging.debug('PAR2 will rename "%s" to "%s"', old_name, new_name) renames[new_name] = old_name elif 'No details available for recoverable file' in line: msg = unicoder(line.strip()) nzo.fail_msg = msg msg = u'[%s] %s' % (unicoder(setname), msg) nzo.set_unpack_info('Repair', msg, set=setname) nzo.status = Status.FAILED elif not verified: if line.startswith('Verifying source files'): nzo.set_action_line(T('Verifying'), '01/%02d' % verifytotal) nzo.status = Status.VERIFYING elif line.startswith('Scanning:'): pass else: # Loading parity files m = LOADING_RE.match(line) if m: pars.append(m.group(1)) continue # Target files m = TARGET_RE.match(line) if m: if verifytotal == 0 or verifynum < verifytotal: verifynum += 1 nzo.set_action_line(T('Verifying'), '%02d/%02d' % (verifynum, verifytotal)) nzo.status = Status.VERIFYING datafiles.append(m.group(1)) continue # Verify done m = re.match(r'There are (\d+) recoverable files', line) if m: verifytotal = int(m.group(1)) p.wait() except WindowsError, err: if err[0] == '87' and not classic: # Hit a bug in par2-tbb, retry with par2-classic retry_classic = True else: raise WindowsError(err) logging.debug('PAR2 output was\n%s', '\n'.join(lines)) # If successful, add renamed files to the collection if finished and renames: previous = load_data(RENAMES_FILE, nzo.workpath, remove=False) for name in previous or {}: renames[name] = previous[name] save_data(renames, RENAMES_FILE, nzo.workpath) if retry_classic: logging.debug('Retry PAR2-joining with par2-classic') return PAR_Verify(parfile, parfile_nzf, nzo, setname, joinables, classic=True, single=single) else: return finished, readd, pars, datafiles, used_joinables, used_par2 #------------------------------------------------------------------------------- def fix_env(): """ OSX: Return copy of environment without PYTHONPATH and PYTHONHOME other: return None """ if sabnzbd.DARWIN: env = os.environ.copy() if 'PYTHONPATH' in env: del env['PYTHONPATH'] if 'PYTHONHOME' in env: del env['PYTHONHOME'] return env else: return None def build_command(command): """ Prepare list from running an external program """ if not sabnzbd.WIN32: if IONICE_COMMAND and cfg.ionice().strip(): lst = cfg.ionice().split() lst.reverse() for arg in lst: command.insert(0, arg) command.insert(0, IONICE_COMMAND) if NICE_COMMAND and cfg.nice().strip(): lst = cfg.nice().split() lst.reverse() for arg in lst: command.insert(0, arg) command.insert(0, NICE_COMMAND) need_shell = False stup = None creationflags = 0 else: need_shell = os.path.splitext(command[0])[1].lower() not in ('.exe', '.com') stup = subprocess.STARTUPINFO() stup.dwFlags = STARTF_USESHOWWINDOW stup.wShowWindow = SW_HIDE creationflags = IDLE_PRIORITY_CLASS # Work-around for bug in Python's Popen function, # scripts with spaces in the path don't work. if need_shell and ' ' in command[0]: command[0] = win32api.GetShortPathName(command[0]) if need_shell: command = list2cmdline(command) return stup, need_shell, command, creationflags # Sort the various RAR filename formats properly :\ def rar_sort(a, b): """ Define sort method for rar file names """ aext = a.split('.')[-1] bext = b.split('.')[-1] if aext == 'rar' and bext == 'rar': return cmp(a, b) elif aext == 'rar': return -1 elif bext == 'rar': return 1 else: return cmp(a, b) # Sort the various PAR filename formats properly :\ def par_sort(a, b): """ Define sort method for par2 file names """ aext = a.lower().split('.')[-1] bext = b.lower().split('.')[-1] if aext == bext: return cmp(a, b) elif aext == 'par2': return -1 elif bext == 'par2': return 1 def build_filelists(workdir, workdir_complete, check_rar=True): """ Build filelists, if workdir_complete has files, ignore workdir. Optionally test content to establish RAR-ness """ joinables, zips, rars, filelist = ([], [], [], []) if workdir_complete: for root, dirs, files in os.walk(workdir_complete): for _file in files: if '.AppleDouble' not in root and '.DS_Store' not in root: filelist.append(os.path.join(root, _file)) if workdir and not filelist: for root, dirs, files in os.walk(workdir): for _file in files: if '.AppleDouble' not in root and '.DS_Store' not in root: filelist.append(os.path.join(root, _file)) if check_rar: joinables = [f for f in filelist if SPLITFILE_RE.search(f) and not is_rarfile(f)] else: joinables = [f for f in filelist if SPLITFILE_RE.search(f)] zips = [f for f in filelist if ZIP_RE.search(f)] rars = [f for f in filelist if RAR_RE.search(f)] ts = [f for f in filelist if TS_RE.search(f) and f not in joinables] logging.debug("build_filelists(): joinables: %s", joinables) logging.debug("build_filelists(): zips: %s", zips) logging.debug("build_filelists(): rars: %s", rars) logging.debug("build_filelists(): ts: %s", ts) return joinables, zips, rars, ts def QuickCheck(set, nzo): """ Check all on-the-fly md5sums of a set """ md5pack = nzo.md5packs.get(set) if md5pack is None: return False result = False nzf_list = nzo.finished_files for file in md5pack: if sabnzbd.misc.on_cleanup_list(file, False): result = True continue found = False for nzf in nzf_list: if file == nzf.filename: found = True if (nzf.md5sum is not None) and nzf.md5sum == md5pack[file]: logging.debug('Quick-check of file %s OK', file) result = True else: logging.info('Quick-check of file %s failed!', file) return False # When any file fails, just stop break if not found: logging.info('Cannot Quick-check missing file %s!', file) return False # Missing file is failure return result def pars_of_set(wdir, setname): """ Return list of par2 files (pathless) matching the set """ list = [] for file in os.listdir(wdir): m = FULLVOLPAR2_RE.search(file) if m and m.group(1) == setname and m.group(2): list.append(file) return list def add_s(i): """ Return an "s" when 'i' > 1 """ if i > 1: return 's' else: return '' def unrar_check(rar): """ Return True if correct version of unrar is found """ if rar: try: version = run_simple(rar) except: return False m = re.search("RAR\s(\d+)\.(\d+)\s+.*Alexander Roshal", version) if m: return (int(m.group(1)), int(m.group(2))) >= (3, 80) return False #------------------------------------------------------------------------------- def sfv_check(sfv_path): """ Verify files using SFV file, input: full path of sfv, file are assumed to be relative to sfv returns: List of failing files or [] when all is OK """ failed = [] try: fp = open(sfv_path, 'r') except: logging.info('Cannot open SFV file %s', sfv_path) failed.append(unicoder(sfv_path)) return failed root = os.path.split(sfv_path)[0] for line in fp: line = line.strip('\n\r ') if line and line[0] != ';': x = line.rfind(' ') if x > 0: filename = platform_encode(line[:x].strip()) checksum = line[x:].strip() path = os.path.join(root, filename) if os.path.exists(path): if crc_check(path, checksum): logging.debug('File %s passed SFV check', path) else: logging.info('File %s did not pass SFV check', latin1(path)) failed.append(unicoder(filename)) else: logging.info('File %s missing in SFV check', latin1(path)) failed.append(unicoder(filename)) fp.close() return failed def crc_check(path, target_crc): """ Return True if file matches CRC """ try: fp = open(path, 'rb') except: return False crc = binascii.crc32('') while 1: data = fp.read(4096) if not data: break crc = binascii.crc32(data, crc) fp.close() crc = '%08x' % (crc & 0xffffffff,) return crc.lower() == target_crc.lower() #------------------------------------------------------------------------------- def analyse_show(name): """ Do a quick SeasonSort check and return basic facts """ job = SeriesSorter(None, name, None, None) job.match(force=True) if job.is_match(): job.get_values() info = job.show_info return info.get('show_name', ''), \ info.get('season_num', ''), \ info.get('episode_num', ''), \ info.get('ep_name', '') def pre_queue(name, pp, cat, script, priority, size, groups): """ Run pre-queue script (if any) and process results """ def fix(p): if not p or str(p).lower() == 'none': return '' else: return UNTRANS(str(p)) values = [1, name, pp, cat, script, priority, None] script_path = make_script_path(cfg.pre_script()) if script_path: command = [script_path, name, fix(pp), fix(cat), fix(script), fix(priority), str(size), ' '.join(groups)] command.extend(analyse_show(name)) stup, need_shell, command, creationflags = build_command(command) env = fix_env() logging.info('Running pre-queue script %s', command) try: p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, env=env, creationflags=creationflags) except: logging.debug("Failed script %s, Traceback: ", script_path, exc_info = True) return values output = p.stdout.read() ret = p.wait() if ret == 0: n = 0 for line in output.split('\n'): line = line.strip('\r\n \'"') if n < len(values) and line: values[n] = TRANS(line) n += 1 if int_conv(values[0]) < 1: logging.info('Pre-Q refuses %s', name) else: logging.info('Pre-Q accepts %s', name) return values #------------------------------------------------------------------------------ def list2cmdline(lst): """ convert list to a cmd.exe-compatible command string """ nlst = [] for arg in lst: if not arg: nlst.append('""') elif (' ' in arg) or ('\t' in arg) or ('&' in arg) or ('|' in arg) or (';' in arg) or (',' in arg): nlst.append('"%s"' % arg) else: nlst.append(arg) return ' '.join(nlst) #------------------------------------------------------------------------------ # Work-around for the failure of Python2.5 on Windows to support IPV6 with HTTPS def get_from_url(url, timeout=None): """ Retrieve URL and return content `timeout` sets non-standard timeout and skips when on Windows """ if 'https:' in url and sabnzbd.WIN32 and sys.version_info < (2,6) and sabnzbd.newsunpack.CURL_COMMAND: command = [sabnzbd.newsunpack.CURL_COMMAND, "-k", url] stup, need_shell, command, creationflags = build_command(command) p = subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=stup, creationflags=creationflags) output = p.stdout.read() p.wait() else: import urllib2 if sys.version_info < (2, 6): timeout = 0 try: if timeout: s = urllib2.urlopen(url, timeout=timeout) else: s = urllib2.urlopen(url) output = s.read() except: output = None return output #------------------------------------------------------------------------------ def run_simple(cmd): """ Run simple external command and return output """ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) txt = p.stdout.read() p.wait() return txt SABnzbd-0.7.20/sabnzbd/newswrapper.py0000644000000000000000000003563612433712602017614 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.newswrapper """ import errno import socket from threading import Thread from nntplib import NNTPPermanentError import time import logging import sabnzbd from sabnzbd.constants import * import sabnzbd.cfg try: from OpenSSL import SSL _ssl = SSL WantReadError = _ssl.WantReadError del SSL HAVE_SSL = True except ImportError: _ssl = None HAVE_SSL = False # Dummy class so this exception is ignored by clients without ssl installed class WantReadError(Exception): def __init__(self, value): self.parameter = value def __str__(self): return repr(self.parameter) import threading _RLock = threading.RLock del threading import select socket.setdefaulttimeout(DEF_TIMEOUT) #------------------------------------------------------------------------------ # getaddrinfo() can be very slow. In some situations this can lead # to delayed starts and timeouts on connections. # Because of this, the results will be cached in the server object. def _retrieve_info(server): """ Async attempt to run getaddrinfo() for specified server """ info = GetServerParms(server.host, server.port) if info is None: server.bad_cons += server.threads else: server.bad_cons = 0 (server.info, server.request) = (info, False) sabnzbd.downloader.Downloader.do.wakeup() def request_server_info(server): """ Launch async request to resolve server address """ if not server.request: server.request = True Thread(target=_retrieve_info, args=(server,)).start() def GetServerParms(host, port): """ Return processed getaddrinfo() for server """ try: int(port) except: port = 119 opt = sabnzbd.cfg.ipv6_servers() try: # Standard IPV4 or IPV6 ips = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM) if opt == 2 or (_EXTERNAL_IPV6 and opt == 1): # IPv6 reachable and allowed, or forced by user return ips else: # IPv6 unreachable or not allowed by user return [ip for ip in ips if ':' not in ip[4][0]] except: if opt == 2 or (_EXTERNAL_IPV6 and opt == 1): try: # Try IPV6 explicitly return socket.getaddrinfo(host, port, socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_IP, socket.AI_CANONNAME) except: # Nothing found! pass return None def con(sock, host, port, sslenabled, write_fds, nntp): assert isinstance(nntp, NNTP) try: sock.connect((host, port)) sock.setblocking(0) if sslenabled and _ssl: while True: try: sock.do_handshake() break except WantReadError: select.select([sock], [], [], 1.0) # Now it's safe to add the socket to the list of active sockets. # 'write_fds' is an attribute of the Downloader singleton. # This direct access is needed to prevent multi-threading sync problems. if write_fds is not None: write_fds[sock.fileno()] = nntp.nw except socket.error, e: try: # socket.error can either return a string or a tuple if isinstance(e, tuple): (_errno, strerror) = e else: # Are we safe to hardcode the ETIMEDOUT error? (_errno, strerror) = (errno.ETIMEDOUT, str(e)) e = (_errno, strerror) #expected, do nothing if _errno == errno.EINPROGRESS: pass finally: nntp.error(e) except _ssl.Error, e: nntp.error(e) class NNTP(object): def __init__(self, host, port, info, sslenabled, nw, user=None, password=None, block=False, write_fds=None): assert isinstance(nw, NewsWrapper) self.host = host self.port = port self.nw = nw self.blocking = block self.error_msg = None if not info: if block: info = GetServerParms(host, port) else: raise socket.error(errno.EADDRNOTAVAIL, "Address not available - Check for internet or DNS problems") af, socktype, proto, canonname, sa = info[0] if sslenabled and _ssl: # Some users benefit from SSLv2 not being capped. ssl_type = sabnzbd.cfg.ssl_type.get() if ssl_type == 'v2': ctx = _ssl.Context(_ssl.SSLv2_METHOD) elif ssl_type == 'v3': ctx = _ssl.Context(_ssl.SSLv3_METHOD) else: ctx = _ssl.Context(_ssl.SSLv23_METHOD) self.sock = SSLConnection(ctx, socket.socket(af, socktype, proto)) elif sslenabled and not _ssl: logging.error(Ta('Error importing OpenSSL module. Connecting with NON-SSL')) self.sock = socket.socket(af, socktype, proto) else: self.sock = socket.socket(af, socktype, proto) try: # Windows must do the connection in a seperate thread due to non-blocking issues # If the server wants to be blocked (for testing) then use the linux route if not block: Thread(target=con, args=(self.sock, self.host, self.port, sslenabled, write_fds, self)).start() else: # if blocking (server test) only wait for 4 seconds during connect until timeout if block: self.sock.settimeout(10) self.sock.connect((self.host, self.port)) if not block: self.sock.setblocking(0) if sslenabled and _ssl: while True: try: self.sock.do_handshake() break except WantReadError: select.select([self.sock], [], [], 1.0) except socket.error, e: try: # socket.error can either return a string or a tuple if isinstance(e, tuple): (_errno, strerror) = e else: # Are we safe to hardcode the ETIMEDOUT error? (_errno, strerror) = (errno.ETIMEDOUT, str(e)) e = (_errno, strerror) #expected, do nothing if _errno == errno.EINPROGRESS: pass finally: self.error(e) except _ssl.Error, e: self.error(e) def error(self, error): if 'SSL23_GET_SERVER_HELLO' in str(error): error = 'This server does not allow SSL on this port' msg = "Failed to connect: %s" % (str(error)) msg = "%s %s@%s:%s" % (msg, self.nw.thrdnum, self.host, self.port) self.error_msg = msg if self.blocking: raise socket.error(errno.ECONNREFUSED, msg) else: logging.info(msg) self.nw.server.warning = msg class NewsWrapper(object): def __init__(self, server, thrdnum, block=False): self.server = server self.thrdnum = thrdnum self.blocking = block self.timeout = None self.article = None self.data = '' self.lines = [] self.nntp = None self.recv = None self.connected = False self.user_sent = False self.pass_sent = False self.group = None self.user_ok = False self.pass_ok = False self.force_login = False def init_connect(self, write_fds): self.nntp = NNTP(self.server.hostip, self.server.port, self.server.info, self.server.ssl, self, self.server.username, self.server.password, self.blocking, write_fds) self.recv = self.nntp.sock.recv self.timeout = time.time() + self.server.timeout def finish_connect(self, code): if not (self.server.username or self.server.password or self.force_login): self.connected = True self.user_sent = True self.user_ok = True self.pass_sent = True self.pass_ok = True if code == '501' and self.user_sent: # Server asked for username, we sent empty one, # but it doesn't accept code = '481' self.user_ok = True self.pass_sent = True if code == '480': self.force_login = True self.connected = False self.user_sent = False self.user_ok = False self.pass_sent = False self.pass_ok = False if code in ('400', '502'): raise NNTPPermanentError(self.lines[0]) elif not self.user_sent: command = 'authinfo user %s\r\n' % (self.server.username) self.nntp.sock.sendall(command) self.user_sent = True elif not self.user_ok: if code == '381': self.user_ok = True elif code == '281': # No login required self.user_ok = True self.pass_sent = True self.pass_ok = True self.connected = True if self.user_ok and not self.pass_sent: command = 'authinfo pass %s\r\n' % (self.server.password) self.nntp.sock.sendall(command) self.pass_sent = True elif self.user_ok and not self.pass_ok: if code != '281': # Assume that login failed (code 481 or other) raise NNTPPermanentError(self.lines[0]) else: self.connected = True self.timeout = time.time() + self.server.timeout def body(self, precheck): self.timeout = time.time() + self.server.timeout if precheck: if self.server.have_stat: command = 'STAT <%s>\r\n' % (self.article.article) else: command = 'HEAD <%s>\r\n' % (self.article.article) elif self.server.have_body: command = 'BODY <%s>\r\n' % (self.article.article) else: command = 'ARTICLE <%s>\r\n' % (self.article.article) self.nntp.sock.sendall(command) def send_group(self, group): self.timeout = time.time() + self.server.timeout command = 'GROUP %s\r\n' % (group) self.nntp.sock.sendall(command) def recv_chunk(self, block=False): """ Receive data, return #bytes, done, skip """ self.timeout = time.time() + self.server.timeout while 1: try: chunk = self.recv(32768) break except WantReadError: # SSL connections will block until they are ready. # Either ignore the connection until it responds # Or wait in a loop until it responds if block: #time.sleep(0.0001) continue else: return (0, False, True) self.data += chunk new_lines = self.data.split('\r\n') # See if incorrect newline-only was used # Do this as a special case to prevent using extra memory # for normal articles if len(new_lines) == 1 and '\r' not in self.data: new_lines = self.data.split('\n') self.data = new_lines.pop() self.lines.extend(new_lines) if self.lines and self.lines[-1] == '.': self.lines = self.lines[1:-1] return (len(chunk), True, False) else: return (len(chunk), False, False) def soft_reset(self): self.timeout = None self.article = None self.data = '' self.lines = [] def hard_reset(self, wait=True, quit=True): if self.nntp: try: if quit: self.nntp.sock.sendall('QUIT\r\n') time.sleep(0.1) self.nntp.sock.close() except: pass self.__init__(self.server, self.thrdnum) # Wait before re-using this newswrapper if wait: # Reset due to error condition, use server timeout self.timeout = time.time() + self.server.timeout else: # Reset for internal reasons, just wait 5 sec self.timeout = time.time() + 5 def terminate(self, quit=False): """ Close connection and remove nntp object """ if self.nntp: try: if quit: self.nntp.sock.sendall('QUIT\r\n') time.sleep(0.1) self.nntp.sock.close() except: pass del self.nntp class SSLConnection(object): def __init__(self, *args): self._ssl_conn = apply(_ssl.Connection, args) self._lock = _RLock() for f in ('get_context', 'pending', 'send', 'write', 'recv', 'read', 'renegotiate', 'bind', 'listen', 'connect', 'accept', 'setblocking', 'fileno', 'shutdown', 'close', 'get_cipher_list', 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', 'makefile', 'get_app_data', 'set_app_data', 'state_string', 'sock_shutdown', 'get_peer_certificate', 'want_read', 'want_write', 'set_connect_state', 'set_accept_state', 'connect_ex', 'sendall', 'do_handshake', 'settimeout'): exec """def %s(self, *args): self._lock.acquire() try: return apply(self._ssl_conn.%s, args) finally: self._lock.release()\n""" % (f, f) def test_ipv6(): """ Check if external IPv6 addresses are reachable """ # Use google.com to test IPv6 access try: info = socket.getaddrinfo('www.google.com', 80, socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_IP, socket.AI_CANONNAME) except: return False try: af, socktype, proto, canonname, sa = info[0] sock = socket.socket(af, socktype, proto) sock.settimeout(6) sock.connect(sa[0:2]) sock.close() return True except: return False _EXTERNAL_IPV6 = test_ipv6() SABnzbd-0.7.20/sabnzbd/newzbin.py0000644000000000000000000003134612433712602016705 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.newzbin - newzbin2.es support functions """ import httplib import urllib import time import logging import re import Queue import socket try: socket.ssl _HAVE_SSL = True except: _HAVE_SSL = False from threading import * import sabnzbd from sabnzbd.constants import BOOKMARK_FILE_NAME from sabnzbd.decorators import synchronized from sabnzbd.misc import cat_to_opts, sanitize_foldername, bad_fetch, cat_convert, format_source_url from sabnzbd.encoding import name_fixer import sabnzbd.newswrapper import sabnzbd.cfg as cfg import sabnzbd.growler as growler ################################################################################ # DirectNZB support ################################################################################ _gFailures = 0 def _warn_user(msg): """ Warn user if too many soft newzbin errors occurred """ global _gFailures _gFailures += 1 if _gFailures > 5: logging.warning(msg) _gFailures = 0 else: logging.debug(msg) def _access_ok(): global _gFailures _gFailures = 0 class MSGIDGrabber(Thread): """ Thread for msgid-grabber queue """ do = None # Link to instance of thread def __init__(self): from sabnzbd.nzbqueue import NzbQueue Thread.__init__(self) self.queue = Queue.Queue() for tup in NzbQueue.do.get_msgids(): self.queue.put(tup) self.shutdown = False MSGIDGrabber.do = self def grab(self, msgid, nzo, when=None): ''' Add job to the waiting queue, 'when' gives delay in seconds ''' if when: nzo.wait = time.time() + when self.queue.put((msgid, nzo)) def stop(self): ''' Force stop of 'run' ''' self.shutdown = True # Put None on the queue to get 'run' out of the queue-wait self.queue.put((None, None)) def run(self): """ Process the queue (including waits and retries) """ from sabnzbd.nzbqueue import NzbQueue self.shutdown = False while not self.shutdown: time.sleep(5) (msgid, nzo) = self.queue.get() if self.shutdown or not msgid: break if nzo.wait and nzo.wait > time.time(): self.grab(msgid, nzo) continue logging.debug("Popping msgid %s", msgid) filename, data, newzbin_cat, nzo_info = _grabnzb(msgid) if filename and data: filename = name_fixer(filename) pp = nzo.pp script = nzo.script cat = nzo.cat if cat == '*' or not cat: cat = cat_convert(newzbin_cat) priority = nzo.priority nzbname = nzo.custom_name cat, pp, script, priority = cat_to_opts(cat, pp, script, priority) try: sabnzbd.nzbqueue.insert_future_nzo(nzo, filename, msgid, data, pp=pp, script=script, cat=cat, priority=priority, nzbname=nzbname, nzo_info=nzo_info) nzo.url = format_source_url(str(msgid)) except: logging.error(Ta('Failed to update newzbin job %s'), msgid) logging.info("Traceback: ", exc_info = True) NzbQueue.do.remove(nzo.nzo_id, False) msgid = None else: if filename: self.grab(msgid, nzo, float(filename)) else: # Fatal error, give up on this one bad_fetch(nzo, msgid, msg=nzo_info, retry=True) msgid = None if msgid: growler.send_notification(T('NZB added to queue'), filename, 'download') logging.debug('Stopping MSGIDGrabber') def _grabnzb(msgid): """ Grab one msgid from newzbin """ msg = '' retry = (60, None, None, None) nzo_info = {'msgid': msgid} logging.info('Fetching NZB for Newzbin report #%s', msgid) headers = {'User-agent' : 'SABnzbd+/%s' % sabnzbd.version.__version__} # Connect to Newzbin try: if _HAVE_SSL: conn = httplib.HTTPSConnection(cfg.newzbin_url()) else: conn = httplib.HTTPConnection(cfg.newzbin_url()) postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'reportid': msgid } postdata = urllib.urlencode(postdata) headers['Content-type'] = 'application/x-www-form-urlencoded' fetchurl = '/api/dnzb/' conn.request('POST', fetchurl, postdata, headers) response = conn.getresponse() # Save debug info if we have to data = response.read() except: _warn_user('Problem accessing Newzbin server, wait 1 min.') logging.info("Traceback: ", exc_info = True) return retry # Get the filename rcode = response.getheader('X-DNZB-RCode') rtext = response.getheader('X-DNZB-RText') try: nzo_info['more_info'] = response.getheader('X-DNZB-MoreInfo') except: # Only some reports will generate a moreinfo header pass if not (rcode or rtext): logging.error(T('Newzbin server changed its protocol')) return retry # Official return codes: # 200 = OK, NZB content follows # 400 = Bad Request, please supply all parameters # (this generally means reportid or fileid is missing; missing user/pass gets you a 401) # 401 = Unauthorised, check username/password? # 402 = Payment Required, not Premium # 404 = Not Found, data doesn't exist? # (only working for reportids, see Technical Limitations) # 450 = Try Later, wait seconds for counter to reset # (for an explanation of this, see DNZB Rate Limiting) # 500 = Internal Server Error, please report to Administrator # 503 = Service Unavailable, site is currently down if rcode in ('500', '503'): _warn_user('Newzbin has a server problem (%s, %s), wait 5 min.' % (rcode, rtext)) return retry _access_ok() if rcode == '450': wait_re = re.compile('wait (\d+) seconds') try: wait = int(wait_re.findall(rtext)[0]) except: wait = 60 if wait > 60: wait = 60 logging.debug("Newzbin says we should wait for %s sec", wait) return int(wait+1), None, None, None if rcode in ('402'): msg = Ta('You have no credit on your Newzbin account') return None, None, None, msg if rcode in ('401'): msg = Ta('Unauthorised, check your newzbin username/password') return None, None, None, msg if rcode in ('400', '404'): msg = Ta('Newzbin report %s not found') % msgid return None, None, None, msg if rcode != '200': msg = Ta('Newzbin gives undocumented error code (%s, %s)') % (rcode, rtext) return 60, None, None, msg # Process data report_name = response.getheader('X-DNZB-Name') report_cat = response.getheader('X-DNZB-Category') if not (report_name and report_cat): msg = Ta('Newzbin server fails to give info for %s') % msgid return 60, None, None, msg # sanitize report_name newname = sanitize_foldername(report_name) if len(newname) > 80: newname = newname[0:79].strip('. ') newname += ".nzb" logging.info('Successfully fetched report %s - %s (cat=%s) (%s)', msgid, report_name, report_cat, newname) return (newname, data, report_cat, nzo_info) ################################################################################ # BookMark support ################################################################################ BOOK_LOCK = Lock() class Bookmarks(object): """ Get list of bookmarks from www.newzbin2.es """ do = None # Link to instance def __init__(self): self.bookmarks = sabnzbd.load_admin(BOOKMARK_FILE_NAME) if not self.bookmarks: self.bookmarks = [] self.__busy = False Bookmarks.do = self @synchronized(BOOK_LOCK) def run(self, delete=None, force=False): if not (cfg.newzbin_bookmarks() or force): return if not (cfg.newzbin_username() and cfg.newzbin_password()): return headers = { 'User-Agent': 'SABnzbd+/%s' % sabnzbd.__version__, } # Connect to Newzbin try: if _HAVE_SSL: conn = httplib.HTTPSConnection(cfg.newzbin_url()) else: conn = httplib.HTTPConnection(cfg.newzbin_url()) if delete: logging.debug('Trying to delete Newzbin bookmark %s', delete) postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'action': 'delete', \ 'reportids' : delete } else: logging.info('Fetching Newzbin bookmarks') postdata = { 'username': cfg.newzbin_username(), 'password': cfg.newzbin_password(), 'action': 'fetch'} postdata = urllib.urlencode(postdata) headers['Content-type'] = 'application/x-www-form-urlencoded' fetchurl = '/api/bookmarks/' conn.request('POST', fetchurl, postdata, headers) response = conn.getresponse() except: _warn_user('Problem accessing Newzbin server.') logging.info("Traceback: ", exc_info = True) return data = response.read() # Get the status rcode = str(response.status) # Official return codes: # 200 = OK, NZB content follows # 204 = No content # 400 = Bad Request, please supply all parameters # (this generally means reportid or fileid is missing; missing user/pass gets you a 401) # 401 = Unauthorised, check username/password? # 402 = Payment Required, not Premium # 403 = Forbidden (incorrect auth) # 500 = Internal Server Error, please report to Administrator # 503 = Service Unavailable, site is currently down if rcode not in ('500', '503'): _access_ok() if rcode == '204': logging.debug("No bookmarks set") elif rcode in ('401', '403'): logging.warning(Ta('Unauthorised, check your newzbin username/password')) elif rcode in ('402'): logging.warning(Ta('You have no credit on your Newzbin account')) elif rcode in ('500', '503'): _warn_user('Newzbin has a server problem (%s).' % rcode) elif rcode == '200': if delete: if data.startswith('1'): logging.info('Deleted newzbin bookmark %s', delete) if delete in self.bookmarks: self.bookmarks.remove(delete) else: if delete in self.bookmarks: logging.warning(Ta('Could not delete newzbin bookmark %s'), delete) else: for line in data.split('\n'): try: msgid, size, text = line.split('\t', 2) except: msgid = size = text = None if msgid and (msgid not in self.bookmarks): self.bookmarks.append(msgid) logging.info("Found new bookmarked msgid %s (%s)", msgid, text) sabnzbd.add_msgid(int(msgid), None, None, priority=None) else: logging.error(Ta('Newzbin gives undocumented error code (%s)'), rcode) self._save() self.__busy = False @synchronized(BOOK_LOCK) def save(self): ''' Save queued newzbin bookmarks to disk (semaphored) ''' self._save() def _save(self): ''' Save queued newzbin bookmarks to disk ''' sabnzbd.save_admin(self.bookmarks, BOOKMARK_FILE_NAME) def bookmarksList(self): ''' Return list of newzbin bookmarks ''' return self.bookmarks def del_bookmark(self, msgid): if cfg.newzbin_unbookmark(): self.run(str(msgid)) SABnzbd-0.7.20/sabnzbd/nzbqueue.py0000644000000000000000000010707512433712602017072 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.nzbqueue - nzb queue """ import os import logging import time import datetime import sabnzbd from sabnzbd.trylist import TryList from sabnzbd.nzbstuff import NzbObject from sabnzbd.misc import exit_sab, cat_to_opts, \ get_admin_path, remove_all, globber from sabnzbd.panic import panic_queue import sabnzbd.database as database from sabnzbd.decorators import NZBQUEUE_LOCK, synchronized, synchronized_CV from sabnzbd.constants import QUEUE_FILE_NAME, QUEUE_VERSION, FUTURE_Q_FOLDER, JOB_ADMIN, \ LOW_PRIORITY, NORMAL_PRIORITY, HIGH_PRIORITY, TOP_PRIORITY, \ REPAIR_PRIORITY, STOP_PRIORITY, VERIFIED_FILE, \ PNFO_BYTES_FIELD, PNFO_BYTES_LEFT_FIELD, Status import sabnzbd.cfg as cfg from sabnzbd.articlecache import ArticleCache import sabnzbd.downloader from sabnzbd.assembler import Assembler, file_has_articles import sabnzbd.growler as growler from sabnzbd.encoding import latin1, platform_encode from sabnzbd.bpsmeter import BPSMeter #------------------------------------------------------------------------------- class NzbQueue(TryList): """ Singleton NzbQueue """ do = None def __init__(self): TryList.__init__(self) self.__top_only = False #cfg.top_only() self.__top_nzo = None self.__nzo_list = [] self.__nzo_table = {} NzbQueue.do = self def read_queue(self, repair): """ Read queue from disk, supporting repair modes 0 = no repairs 1 = use existing queue, add missing "incomplete" folders 2 = Discard all queue admin, reconstruct from "incomplete" folders """ nzo_ids = [] if repair < 2: # Read the queue from the saved files data = sabnzbd.load_admin(QUEUE_FILE_NAME) if data: try: queue_vers, nzo_ids, dummy = data if not queue_vers == QUEUE_VERSION: nzo_ids = [] logging.error(Ta('Incompatible queuefile found, cannot proceed')) if not repair: panic_queue(os.path.join(cfg.cache_dir.get_path(), QUEUE_FILE_NAME)) exit_sab(2) except ValueError: nzo_ids = [] logging.error(Ta('Error loading %s, corrupt file detected'), os.path.join(cfg.cache_dir.get_path(), QUEUE_FILE_NAME)) if not repair: return # First handle jobs in the queue file folders = [] for nzo_id in nzo_ids: folder, _id = os.path.split(nzo_id) # Try as normal job path = get_admin_path(bool(folder), folder, False) nzo = sabnzbd.load_data(_id, path, remove=False) if not nzo: # Try as future job path = get_admin_path(bool(folder), folder, True) nzo = sabnzbd.load_data(_id, path) if nzo: self.add(nzo, save=False, quiet=True) folders.append(folder) # Scan for any folders in "incomplete" that are not yet in the queue if repair: self.scan_jobs(not folders) # Handle any lost future jobs for path in globber(os.path.join(cfg.admin_dir.get_path(), FUTURE_Q_FOLDER)): path, nzo_id = os.path.split(path) if nzo_id not in self.__nzo_table: nzo = sabnzbd.load_data(nzo_id, path, remove=True) if nzo: self.add(nzo, save=True) def scan_jobs(self, all=False, action=True): """ Scan "incomplete" for mssing folders, 'all' is True: Include active folders 'action' is True, do the recovery action returns list of orphaned folders """ result = [] # Folders from the download queue if all: registered = [] else: registered = [nzo.work_name for nzo in self.__nzo_list] # Retryable folders from History items = sabnzbd.proxy_build_history()[0] # Anything waiting or active or retryable is a known item registered.extend([platform_encode(os.path.basename(item['path'])) \ for item in items if item['retry'] or item['loaded'] or item['status'] == Status.QUEUED]) # Repair unregistered folders for folder in globber(cfg.download_dir.get_path()): if os.path.isdir(folder) and os.path.basename(folder) not in registered: if action: logging.info('Repairing job %s', folder) self.repair_job(folder) result.append(os.path.basename(folder)) else: if action: logging.info('Skipping repair for job %s', folder) return result def repair_job(self, folder, new_nzb=None): """ Reconstruct admin for a single job folder, optionally with new NZB """ def all_verified(path): """ Return True when all sets have been successfully verified """ verified = sabnzbd.load_data(VERIFIED_FILE, path, remove=False) or {'x':False} return not bool([True for x in verified if not verified[x]]) nzo_id = None name = os.path.basename(folder) path = os.path.join(folder, JOB_ADMIN) if hasattr(new_nzb, 'filename'): filename = new_nzb.filename else: filename = '' if not filename: if not all_verified(path): filename = globber(path, '*.gz') if len(filename) > 0: logging.debug('Repair job %s by reparsing stored NZB', latin1(name)) nzo_id = sabnzbd.add_nzbfile(filename[0], pp=None, script=None, cat=None, priority=None, nzbname=name, reuse=True)[1] else: logging.debug('Repair job %s without stored NZB', latin1(name)) nzo = NzbObject(name, 0, pp=None, script=None, nzb='', cat=None, priority=None, nzbname=name, reuse=True) self.add(nzo) nzo_id = nzo.nzo_id else: remove_all(path, '*.gz') logging.debug('Repair job %s with new NZB (%s)', latin1(name), latin1(filename)) nzo_id = sabnzbd.add_nzbfile(new_nzb, pp=None, script=None, cat=None, priority=None, nzbname=name, reuse=True)[1] return nzo_id def send_back(self, nzo): """ Send back job to queue after successful pre-check """ try: nzb_path = globber(nzo.workpath, '*.gz')[0] except: logging.debug('Failed to find NZB file after pre-check (%s)', nzo.nzo_id) return from sabnzbd.dirscanner import ProcessSingleFile res, nzo_ids = ProcessSingleFile(nzo.work_name + '.nzb', nzb_path, reuse=True) if res == 0 and nzo_ids: nzo = self.replace_in_q(nzo, nzo_ids[0]) # Reset reuse flag to make pause/abort on encryption possible nzo.reuse = False @synchronized(NZBQUEUE_LOCK) def replace_in_q(self, nzo, nzo_id): """ Replace nzo by new in at the same spot in the queue, destroy nzo """ try: new_nzo = self.get_nzo(nzo_id) pos = self.__nzo_list.index(new_nzo) targetpos = self.__nzo_list.index(nzo) self.__nzo_list[targetpos] = new_nzo self.__nzo_list.pop(pos) del self.__nzo_table[nzo.nzo_id] del nzo return new_nzo except: logging.error('Failed to restart NZB after pre-check (%s)', nzo.nzo_id) logging.info("Traceback: ", exc_info = True) return nzo @synchronized(NZBQUEUE_LOCK) def save(self, save_nzo=None): """ Save queue, all nzo's or just the specified one """ logging.info("Saving queue") nzo_ids = [] # Aggregate nzo_ids and save each nzo for nzo in self.__nzo_list: if nzo.new_caching: nzo_ids.append(os.path.join(nzo.work_name, nzo.nzo_id)) else: nzo_ids.append(nzo.nzo_id) if save_nzo is None or nzo is save_nzo: sabnzbd.save_data(nzo, nzo.nzo_id, nzo.workpath) if not nzo.futuretype: nzo.save_to_disk() sabnzbd.save_admin((QUEUE_VERSION, nzo_ids, []), QUEUE_FILE_NAME) @synchronized(NZBQUEUE_LOCK) def set_top_only(self, value): self.__top_only = value @synchronized(NZBQUEUE_LOCK) def generate_future(self, msg, pp=None, script=None, cat=None, url=None, priority=NORMAL_PRIORITY, nzbname=None): """ Create and return a placeholder nzo object """ future_nzo = NzbObject(msg, 0, pp, script, None, True, cat=cat, url=url, priority=priority, nzbname=nzbname, status=Status.GRABBING) self.add(future_nzo) return future_nzo @synchronized(NZBQUEUE_LOCK) def insert_future(self, future, filename, msgid, data, pp=None, script=None, cat=None, priority=NORMAL_PRIORITY, nzbname=None, nzo_info=None): """ Refresh a placeholder nzo with an actual nzo """ assert isinstance(future, NzbObject) if nzo_info is None: nzo_info = {} nzo_id = future.nzo_id if nzo_id in self.__nzo_table: try: sabnzbd.remove_data(nzo_id, future.workpath) logging.info("Regenerating item: %s", nzo_id) r, u, d = future.repair_opts if not r is None: pp = sabnzbd.opts_to_pp(r, u, d) scr = future.script if scr is None: scr = script categ = future.cat if categ is None: categ = cat categ, pp, script, priority = cat_to_opts(categ, pp, script, priority) # Remember old priority old_prio = future.priority try: future.__init__(filename, msgid, pp, scr, nzb=data, futuretype=False, cat=categ, priority=priority, nzbname=nzbname, nzo_info=nzo_info) future.nzo_id = nzo_id self.save(future) except ValueError: self.remove(nzo_id, False) except TypeError: self.remove(nzo_id, False) # Make sure the priority is changed now that we know the category if old_prio != priority: future.priority = None self.set_priority(future.nzo_id, priority) if cfg.auto_sort(): self.sort_by_avg_age() self.reset_try_list() except: logging.error(Ta('Error while adding %s, removing'), nzo_id) logging.info("Traceback: ", exc_info = True) self.remove(nzo_id, False) else: logging.info("Item %s no longer in queue, omitting", nzo_id) @synchronized(NZBQUEUE_LOCK) def change_opts(self, nzo_ids, pp): for nzo_id in [item.strip() for item in nzo_ids.split(',')]: if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].set_pp(pp) @synchronized(NZBQUEUE_LOCK) def change_script(self, nzo_ids, script): for nzo_id in [item.strip() for item in nzo_ids.split(',')]: if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].script = script @synchronized(NZBQUEUE_LOCK) def change_cat(self, nzo_ids, cat, explicit_priority=None): for nzo_id in [item.strip() for item in nzo_ids.split(',')]: if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] nzo.cat, pp, nzo.script, prio = cat_to_opts(cat) nzo.set_pp(pp) if explicit_priority is None: self.set_priority(nzo_id, prio) @synchronized(NZBQUEUE_LOCK) def change_name(self, nzo_id, name, password=None): if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] if not nzo.futuretype: nzo.set_final_name_pw(name, password) else: # Reset url fetch wait time nzo.wait = None @synchronized(NZBQUEUE_LOCK) def get_nzo(self, nzo_id): if nzo_id in self.__nzo_table: return self.__nzo_table[nzo_id] else: return None @synchronized(NZBQUEUE_LOCK) def add(self, nzo, save=True, quiet=False): assert isinstance(nzo, NzbObject) if not nzo.nzo_id: nzo.nzo_id = sabnzbd.get_new_id('nzo', nzo.workpath, self.__nzo_table) # If no files are to be downloaded anymore, send to postproc if not nzo.files and not nzo.futuretype: self.end_job(nzo) return '' # Reset try_lists nzo.reset_try_list() self.reset_try_list() if nzo.nzo_id: nzo.deleted = False priority = nzo.priority self.__nzo_table[nzo.nzo_id] = nzo if priority > HIGH_PRIORITY: #Top and repair priority items are added to the top of the queue self.__nzo_list.insert(0, nzo) elif priority == LOW_PRIORITY: self.__nzo_list.append(nzo) else: #for high priority we need to add the item at the bottom #of any other high priority items above the normal priority #for normal priority we need to add the item at the bottom #of the normal priority items above the low priority if self.__nzo_list: pos = 0 added = False for position in self.__nzo_list: if position.priority < priority: self.__nzo_list.insert(pos, nzo) added = True break pos += 1 if not added: #if there are no other items classed as a lower priority #then it will be added to the bottom of the queue self.__nzo_list.append(nzo) else: #if the queue is empty then simple append the item to the bottom self.__nzo_list.append(nzo) if save: self.save(nzo) if not (quiet or nzo.status in ('Fetching',)): growler.send_notification(T('NZB added to queue'), nzo.filename, 'download') if cfg.auto_sort(): self.sort_by_avg_age() return nzo.nzo_id @synchronized(NZBQUEUE_LOCK) def remove(self, nzo_id, add_to_history = True, save=True, cleanup=True, keep_basic=False, del_files=False): if nzo_id in self.__nzo_table: nzo = self.__nzo_table.pop(nzo_id) nzo.deleted = True self.__nzo_list.remove(nzo) sabnzbd.remove_data(nzo_id, nzo.workpath) if add_to_history: # Create the history DB instance history_db = database.get_history_handle() # Add the nzo to the database. Only the path, script and time taken is passed # Other information is obtained from the nzo history_db.add_history_db(nzo, '', '', 0, '', '') history_db.close() elif cleanup: self.cleanup_nzo(nzo, keep_basic, del_files) if save: self.save(nzo) @synchronized(NZBQUEUE_LOCK) def remove_multiple(self, nzo_ids, del_files=False): for nzo_id in nzo_ids: self.remove(nzo_id, add_to_history = False, save = False, keep_basic=not del_files, del_files=del_files) # Save with invalid nzo_id, to that only queue file is saved self.save('x') @synchronized(NZBQUEUE_LOCK) def remove_all(self): lst = [] for nzo_id in self.__nzo_table: lst.append(nzo_id) for nzo_id in lst: nzo = self.__nzo_table.pop(nzo_id) nzo.deleted = True self.__nzo_list.remove(nzo) sabnzbd.remove_data(nzo_id, nzo.workpath) self.cleanup_nzo(nzo) del lst self.save() @synchronized(NZBQUEUE_LOCK) def remove_nzf(self, nzo_id, nzf_id): if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] nzf = nzo.get_nzf_by_id(nzf_id) if nzf: post_done = nzo.remove_nzf(nzf) if post_done: if nzo.finished_files: self.end_job(nzo) else: self.remove(nzo_id, add_to_history = False, keep_basic=False) @synchronized(NZBQUEUE_LOCK) def pause_multiple_nzo(self, nzo_ids): for nzo_id in nzo_ids: self.pause_nzo(nzo_id) @synchronized(NZBQUEUE_LOCK) def pause_nzo(self, nzo_id): if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] nzo.pause() logging.debug("Paused nzo: %s", nzo_id) @synchronized(NZBQUEUE_LOCK) def resume_multiple_nzo(self, nzo_ids): for nzo_id in nzo_ids: self.resume_nzo(nzo_id) @synchronized(NZBQUEUE_LOCK) def resume_nzo(self, nzo_id): if nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] nzo.resume() nzo.reset_all_try_lists() logging.debug("Resumed nzo: %s", nzo_id) self.reset_try_list() @synchronized(NZBQUEUE_LOCK) def switch(self, item_id_1, item_id_2): try: # Allow an index as second parameter, easier for some skins i = int(item_id_2) item_id_2 = self.__nzo_list[i].nzo_id except: pass try: nzo1 = self.__nzo_table[item_id_1] nzo2 = self.__nzo_table[item_id_2] except KeyError: # One or both jobs missing return (-1, 0) #get the priorities of the two items nzo1_priority = nzo1.priority nzo2_priority = nzo2.priority try: #get the item id of the item below to use in priority changing item_id_3 = self.__nzo_list[i+1].nzo_id #if there is an item below the id1 and id2 then we need that too #to determine whether to change the priority nzo3 = self.__nzo_table[item_id_3] nzo3_priority = nzo3.priority #if id1 is surrounded by items of a different priority then change it's pririty to match if nzo2_priority != nzo1_priority and nzo3_priority != nzo1_priority or nzo2_priority > nzo1_priority: nzo1.priority = nzo2_priority except: nzo1.priority = nzo2_priority item_id_pos1 = -1 item_id_pos2 = -1 for i in xrange(len(self.__nzo_list)): if item_id_1 == self.__nzo_list[i].nzo_id: item_id_pos1 = i elif item_id_2 == self.__nzo_list[i].nzo_id: item_id_pos2 = i if (item_id_pos1 > -1) and (item_id_pos2 > -1): item = self.__nzo_list[item_id_pos1] del self.__nzo_list[item_id_pos1] self.__nzo_list.insert(item_id_pos2, item) return (item_id_pos2, nzo1.priority) # If moving failed/no movement took place return (-1, nzo1.priority) @synchronized(NZBQUEUE_LOCK) def get_position(self, nzb_id): for i in xrange(len(self.__nzo_list)): if nzb_id == self.__nzo_list[i].nzo_id: return i return -1 @synchronized(NZBQUEUE_LOCK) def move_up_bulk(self, nzo_id, nzf_ids): if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].move_up_bulk(nzf_ids) @synchronized(NZBQUEUE_LOCK) def move_top_bulk(self, nzo_id, nzf_ids): if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].move_top_bulk(nzf_ids) @synchronized(NZBQUEUE_LOCK) def move_down_bulk(self, nzo_id, nzf_ids): if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].move_down_bulk(nzf_ids) @synchronized(NZBQUEUE_LOCK) def move_bottom_bulk(self, nzo_id, nzf_ids): if nzo_id in self.__nzo_table: self.__nzo_table[nzo_id].move_bottom_bulk(nzf_ids) @synchronized(NZBQUEUE_LOCK) def sort_by_avg_age(self, reverse=False): logging.info("Sorting by average date...(reversed:%s)", reverse) self.__nzo_list = sort_queue_function(self.__nzo_list, _nzo_date_cmp, reverse) @synchronized(NZBQUEUE_LOCK) def sort_by_name(self, reverse=False): logging.info("Sorting by name...(reversed:%s)", reverse) self.__nzo_list = sort_queue_function(self.__nzo_list, _nzo_name_cmp, reverse) @synchronized(NZBQUEUE_LOCK) def sort_by_size(self, reverse=False): logging.info("Sorting by size...(reversed:%s)", reverse) self.__nzo_list = sort_queue_function(self.__nzo_list, _nzo_size_cmp, reverse) @synchronized(NZBQUEUE_LOCK) def sort_queue(self, field, reverse=None): if isinstance(reverse, str): if reverse.lower() == 'desc': reverse = True else: reverse = False if reverse is None: reverse = False if field.lower() == 'name': self.sort_by_name(reverse) elif field.lower() == 'size' or field.lower() == 'bytes': self.sort_by_size(reverse) elif field.lower() == 'avg_age': self.sort_by_avg_age(reverse) else: logging.debug("Sort: %s not recognised", field) def __set_priority(self, nzo_id, priority): """ Sets the priority on the nzo and places it in the queue at the approrioate position """ try: priority = int(priority) nzo = self.__nzo_table[nzo_id] nzo_id_pos1 = -1 pos = -1 # If priority == STOP_PRIORITY, then send to queue if priority == STOP_PRIORITY: self.end_job(nzo) return # Get the current position in the queue for i in xrange(len(self.__nzo_list)): if nzo_id == self.__nzo_list[i].nzo_id: nzo_id_pos1 = i break # Don't change priority and order if priority is the same as asked if priority == self.__nzo_list[nzo_id_pos1].priority: return nzo_id_pos1 nzo.priority = priority nzo.save_to_disk() if nzo_id_pos1 != -1: del self.__nzo_list[nzo_id_pos1] if priority == TOP_PRIORITY: #A top priority item (usually a completed download fetching pars) #is added to the top of the queue self.__nzo_list.insert(0, nzo) pos = 0 elif priority == LOW_PRIORITY: pos = len(self.__nzo_list) self.__nzo_list.append(nzo) else: # for high priority we need to add the item at the bottom #of any other high priority items above the normal priority # for normal priority we need to add the item at the bottom #of the normal priority items above the low priority if self.__nzo_list: p = 0 added = False for position in self.__nzo_list: if position.priority < priority: self.__nzo_list.insert(p, nzo) pos = p added = True break p += 1 if not added: #if there are no other items classed as a lower priority #then it will be added to the bottom of the queue pos = len(self.__nzo_list) self.__nzo_list.append(nzo) else: #if the queue is empty then simple append the item to the bottom self.__nzo_list.append(nzo) pos = 0 return pos except: return -1 @synchronized(NZBQUEUE_LOCK) def set_priority(self, nzo_ids, priority): try: n = -1 for nzo_id in [item.strip() for item in nzo_ids.split(',')]: n = self.__set_priority(nzo_id, priority) return n except: return -1 @synchronized(NZBQUEUE_LOCK) def reset_try_lists(self, nzf = None, nzo = None): if nzf: nzf.reset_try_list() if nzo: nzo.reset_try_list() self.reset_try_list() @synchronized(NZBQUEUE_LOCK) def reset_all_try_lists(self): for nzo in self.__nzo_list: nzo.reset_all_try_lists() self.reset_try_list() @synchronized(NZBQUEUE_LOCK) def has_articles_for(self, server): ''' Check whether there are any pending articles for the downloader ''' if not self.__nzo_list: return False elif self.__top_only: for nzo in self.__nzo_list: # Ignore any items that are in a paused or grabbing state if nzo.status not in (Status.PAUSED, Status.GRABBING): return not nzo.server_in_try_list(server) else: return not self.server_in_try_list(server) @synchronized(NZBQUEUE_LOCK) def has_forced_items(self): ''' Check if the queue contains any Forced Priority items to download while paused ''' for nzo in self.__nzo_list: if nzo.priority == TOP_PRIORITY and nzo.status not in (Status.PAUSED, Status.GRABBING): return True return False @synchronized(NZBQUEUE_LOCK) def get_article(self, server): if self.__top_only: if self.__nzo_list: for nzo in self.__nzo_list: if nzo.status not in (Status.PAUSED, Status.GRABBING): article = nzo.get_article(server) if article: return article else: for nzo in self.__nzo_list: # Don't try to get an article if server is in try_list of nzo if not nzo.server_in_try_list(server) and nzo.status not in (Status.PAUSED, Status.GRABBING): article = nzo.get_article(server) if article: return article # No articles for this server, block server (until reset issued) self.add_to_try_list(server) @synchronized(NZBQUEUE_LOCK) def register_article(self, article, found=True): nzf = article.nzf nzo = nzf.nzo if nzf.deleted: logging.debug("Discarding article %s, no longer in queue", article.article) return file_done, post_done, reset = nzo.remove_article(article, found) filename = nzf.filename if reset: self.reset_try_list() if file_done: if nzo.next_save is None or time.time() > nzo.next_save: sabnzbd.save_data(nzo, nzo.nzo_id, nzo.workpath) BPSMeter.do.save() if nzo.save_timeout is None: nzo.next_save = None else: nzo.next_save = time.time() + nzo.save_timeout if not nzo.precheck: _type = nzf.type # Only start decoding if we have a filename and type if filename and _type: Assembler.do.process((nzo, nzf)) else: if file_has_articles(nzf): logging.warning(Ta('%s -> Unknown encoding'), filename) if post_done: self.end_job(nzo) def end_job(self, nzo): """ Send NZO to the post-processing queue """ if self.actives(grabs=False) < 2 and cfg.autodisconnect(): # This was the last job, close server connections if sabnzbd.downloader.Downloader.do: sabnzbd.downloader.Downloader.do.disconnect() # Notify assembler to call postprocessor if not nzo.deleted: nzo.deleted = True if nzo.precheck: nzo.save_to_disk() # Check result enough, ratio = nzo.check_quality() if enough: # Enough data present, do real download workdir = nzo.downpath self.cleanup_nzo(nzo, keep_basic=True) self.send_back(nzo) return else: # Not enough data, let postprocessor show it as failed pass Assembler.do.process((nzo, None)) @synchronized(NZBQUEUE_LOCK) def actives(self, grabs=True): """ Return amount of non-paused jobs, optionally with 'grabbing' items """ n = 0 for nzo in self.__nzo_list: # Ignore any items that are paused if grabs and nzo.status == Status.GRABBING: n += 1 elif nzo.status not in (Status.PAUSED, Status.GRABBING): n += 1 return n @synchronized(NZBQUEUE_LOCK) def queue_info(self, for_cli=False, max_jobs=0): bytes_left = 0 bytes = 0 q_size = 0 pnfo_list = [] n = 0 for nzo in self.__nzo_list: if not max_jobs or n < max_jobs: pnfo = nzo.gather_info(for_cli = for_cli) pnfo_list.append(pnfo) if nzo.status != 'Paused': bytes += pnfo[PNFO_BYTES_FIELD] bytes_left += pnfo[PNFO_BYTES_LEFT_FIELD] q_size += 1 elif nzo.status != 'Paused': b, b_left = nzo.total_and_remaining() bytes += b bytes_left += b_left q_size += 1 n += 1 return (bytes, bytes_left, pnfo_list, q_size) @synchronized(NZBQUEUE_LOCK) def remaining(self): """ Return bytes left in the queue by non-paused items """ bytes_left = 0 for nzo in self.__nzo_list: if nzo.status != 'Paused': bytes_left += nzo.remaining() return bytes_left @synchronized(NZBQUEUE_LOCK) def is_empty(self): empty = True for nzo in self.__nzo_list: if not nzo.futuretype and nzo.status != 'Paused': empty = False break return empty @synchronized(NZBQUEUE_LOCK) def cleanup_nzo(self, nzo, keep_basic=False, del_files=False): nzo.purge_data(keep_basic, del_files) ArticleCache.do.purge_articles(nzo.saved_articles) @synchronized(NZBQUEUE_LOCK) def stop_idle_jobs(self): """ Detect jobs that have zero files left and send them to post processing """ empty = [] for nzo in self.__nzo_list: if not nzo.futuretype and not nzo.files and nzo.status not in (Status.PAUSED, Status.GRABBING): empty.append(nzo) for nzo in empty: self.end_job(nzo) def get_urls(self): """ Return list of future-types needing URL """ lst = [] for nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] if nzo.futuretype: url = nzo.url if nzo.futuretype and url.lower().startswith('http'): lst.append((url, nzo)) return lst def get_msgids(self): """ Return list of future-types needing msgid """ lst = [] for nzo_id in self.__nzo_table: nzo = self.__nzo_table[nzo_id] msgid = nzo.url if nzo.futuretype and (msgid.isdigit() or len(msgid)==5): lst.append((msgid, nzo)) return lst def __repr__(self): return "" #------------------------------------------------------------------------------- def _nzo_date_cmp(nzo1, nzo2): avg_date1 = nzo1.avg_date avg_date2 = nzo2.avg_date if avg_date1 is None and avg_date2 is None: return 0 if avg_date1 is None: avg_date1 = datetime.datetime.now() elif avg_date2 is None: avg_date2 = datetime.datetime.now() return cmp(avg_date1, avg_date2) def _nzo_name_cmp(nzo1, nzo2): return cmp(nzo1.final_name.lower(), nzo2.final_name.lower()) def _nzo_size_cmp(nzo1, nzo2): return cmp(nzo1.bytes, nzo2.bytes) def sort_queue_function(nzo_list, method, reverse): ultra_high_priority = [nzo for nzo in nzo_list if nzo.priority == REPAIR_PRIORITY] super_high_priority = [nzo for nzo in nzo_list if nzo.priority == TOP_PRIORITY] high_priority = [nzo for nzo in nzo_list if nzo.priority == HIGH_PRIORITY] normal_priority = [nzo for nzo in nzo_list if nzo.priority == NORMAL_PRIORITY] low_priority = [nzo for nzo in nzo_list if nzo.priority == LOW_PRIORITY] ultra_high_priority.sort(cmp=method, reverse=reverse) super_high_priority.sort(cmp=method, reverse=reverse) high_priority.sort(cmp=method, reverse=reverse) normal_priority.sort(cmp=method, reverse=reverse) low_priority.sort(cmp=method, reverse=reverse) new_list = ultra_high_priority new_list.extend(super_high_priority) new_list.extend(high_priority) new_list.extend(normal_priority) new_list.extend(low_priority) # Make sure any left-over jobs enter the new list for item in nzo_list: if item not in new_list: new_list.append(item) return new_list #------------------------------------------------------------------------------- # Synchronized wrappers @synchronized_CV def add_nzo(nzo): return NzbQueue.do.add(nzo) @synchronized_CV def insert_future_nzo(future_nzo, filename, msgid, data, pp=None, script=None, cat=None, priority=NORMAL_PRIORITY, nzbname=None, nzo_info=None): if nzo_info is None: nzo_info = {} NzbQueue.do.insert_future(future_nzo, filename, msgid, data, pp=pp, script=script, cat=cat, priority=priority, nzbname=nzbname, nzo_info=nzo_info) @synchronized_CV def set_priority(nzo_ids, priority): return NzbQueue.do.set_priority(nzo_ids, priority) @synchronized_CV def get_nzo(nzo_id): return NzbQueue.do.get_nzo(nzo_id) @synchronized_CV def sort_queue(field, reverse=False): NzbQueue.do.sort_queue(field, reverse) @synchronized_CV @synchronized(NZBQUEUE_LOCK) def repair_job(folder, new_nzb): return NzbQueue.do.repair_job(folder, new_nzb) @synchronized_CV @synchronized(NZBQUEUE_LOCK) def scan_jobs(all=False, action=True): return NzbQueue.do.scan_jobs(all, action) SABnzbd-0.7.20/sabnzbd/nzbstuff.py0000644000000000000000000020117012433712602017064 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.nzbstuff - misc """ # Standard Library import os import time import re import logging import datetime import xml.sax import xml.sax.handler import xml.sax.xmlreader try: from cStringIO import StringIO except ImportError: from StringIO import StringIO # SABnzbd modules import sabnzbd from sabnzbd.constants import sample_match, GIGI, ATTRIB_FILE, JOB_ADMIN, \ DEFAULT_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY, \ HIGH_PRIORITY, PAUSED_PRIORITY, TOP_PRIORITY, DUP_PRIORITY, REPAIR_PRIORITY, \ RENAMES_FILE, Status from sabnzbd.misc import to_units, cat_to_opts, cat_convert, sanitize_foldername, \ get_unique_path, get_admin_path, remove_all, format_source_url, \ sanitize_filename, globber, sanitize_foldername, int_conv, \ set_permissions import sabnzbd.cfg as cfg from sabnzbd.trylist import TryList from sabnzbd.encoding import unicoder, platform_encode, latin1, name_fixer from sabnzbd.rating import Rating __all__ = ['Article', 'NzbFile', 'NzbObject'] # Name potterns RE_NEWZBIN = re.compile(r"msgid_(\w+) (.+)(\.nzb)$", re.I) RE_NORMAL = re.compile(r"(.+)(\.nzb)", re.I) SUBJECT_FN_MATCHER = re.compile(r'"([^"]*)"') RE_SAMPLE = re.compile(sample_match, re.I) PROBABLY_PAR2_RE = re.compile(r'(.*)\.vol(\d*)\+(\d*)\.par2', re.I) REJECT_PAR2_RE = re.compile(r'\.par2\.\d+', re.I) # Reject duplicate par2 files RE_NORMAL_NAME = re.compile(r'\.\w{2,5}$') # Test reasonably sized extension at the end ################################################################################ # Article # ################################################################################ ArticleMapper = ( # Pickle name Internal name ('article', 'article'), ('art_id', 'art_id'), ('bytes', 'bytes'), ('partnum', 'partnum'), ('nzf', 'nzf') ) class Article(TryList): """ Representation of one article """ def __init__ (self, article, bytes, partnum, nzf): TryList.__init__(self) self.fetcher = None self.allow_fill_server = False self.article = article self.art_id = None self.bytes = bytes self.partnum = partnum self.tries = 0 # Try count self.nzf = nzf def get_article(self, server): """ Return article when appropriate for specified server """ if server.fillserver and (not self.allow_fill_server) and sabnzbd.active_primaries(): return None if not self.fetcher and not self.server_in_try_list(server): self.fetcher = server self.tries += 1 if sabnzbd.LOG_ALL: logging.debug('Article-try = %s', self.tries) return self return None def get_art_id(self): """ Return unique article storage name, create if needed """ if not self.art_id: self.art_id = sabnzbd.get_new_id("article", self.nzf.nzo.workpath) return self.art_id def __getstate__(self): """ Save to pickle file, translating attributes """ dict_ = {} for tup in ArticleMapper: dict_[tup[0]] = self.__dict__[tup[1]] return dict_ def __setstate__(self, dict_): """ Load from pickle file, translating attributes """ for tup in ArticleMapper: try: self.__dict__[tup[1]] = dict_[tup[0]] except KeyError: # Handle new attributes self.__dict__[tup[1]] = None TryList.__init__(self) self.fetcher = None self.allow_fill_server = False self.tries = 0 def __repr__(self): return "" % \ (self.article, self.bytes, self.partnum, self.art_id) ################################################################################ # NzbFile # ################################################################################ NzbFileMapper = ( # Pickle name Internal name ('_NzbFile__date', 'date'), ('_NzbFile__subject', 'subject'), ('_NzbFile__filename', 'filename'), ('_NzbFile__type', 'type'), ('_NzbFile__ispar2file', 'is_par2'), ('_NzbFile__vol', 'vol'), ('_NzbFile__blocks', 'blocks'), ('_NzbFile__setname', 'setname'), ('_NzbFile__extrapars', 'extrapars'), ('_NzbFile__initial_article', 'initial_article'), ('_NzbFile__articles', 'articles'), ('_NzbFile__decodetable', 'decodetable'), ('_NzbFile__bytes', 'bytes'), ('_NzbFile__bytes_left', 'bytes_left'), ('_NzbFile__article_count', 'article_count'), ('nzo', 'nzo'), ('nzf_id', 'nzf_id'), ('deleted', 'deleted'), ('valid', 'valid'), ('import_finished', 'import_finished'), ('md5sum', 'md5sum'), ('valid', 'valid'), ('completed', 'completed') ) class NzbFile(TryList): """ Representation of one file consisting of multiple articles """ def __init__(self, date, subject, article_db, bytes, nzo): """ Setup object """ TryList.__init__(self) self.date = date self.subject = subject self.filename = None self.type = None self.filename = name_extractor(subject) self.is_par2 = False self.vol = None self.blocks = None self.setname = None self.extrapars = None self.initial_article = None self.articles = [] self.decodetable = {} self.bytes = bytes self.bytes_left = bytes self.article_count = 0 self.nzo = nzo self.nzf_id = sabnzbd.get_new_id("nzf", nzo.workpath) self.deleted = False self.completed = False self.valid = False self.import_finished = False self.md5sum = None self.valid = bool(article_db) if self.valid and self.nzf_id: sabnzbd.save_data(article_db, self.nzf_id, nzo.workpath) def finish_import(self): """ Load the article objects from disk """ logging.debug("Finishing import on %s", self.subject) article_db = sabnzbd.load_data(self.nzf_id, self.nzo.workpath, remove=False) if article_db: for partnum in article_db: art_id = article_db[partnum][0] bytes = article_db[partnum][1] article = Article(art_id, bytes, partnum, self) self.articles.append(article) self.decodetable[partnum] = article # Look for article with lowest number self.initial_article = self.decodetable[self.lowest_partnum] self.import_finished = True def remove_article(self, article, found): """ Handle completed article, possibly end of file """ if article in self.articles: self.articles.remove(article) if found: self.bytes_left -= article.bytes reset = False if article.partnum == self.lowest_partnum and self.articles: # Issue reset self.initial_article = None self.reset_try_list() reset = True done = True if self.articles: done = False return (done, reset) def set_par2(self, setname, vol, blocks): """ Designate this this file as a par2 file """ self.is_par2 = True self.setname = setname self.vol = vol self.blocks = int(blocks) def get_article(self, server): """ Get next article to be downloaded """ if self.initial_article: article = self.initial_article.get_article(server) if article: return article else: for article in self.articles: article = article.get_article(server) if article: return article self.add_to_try_list(server) def reset_all_try_lists(self): """ Clear all lists of visited servers """ for art in self.articles: art.reset_try_list() self.reset_try_list() @property def completed(self): """ Is this file completed? """ return self.import_finished and not bool(self.articles) @property def lowest_partnum(self): """ Get lowest article number of this file """ return min(self.decodetable) def remove_admin(self): """ Remove article database from disk (sabnzbd_nzf_)""" try: os.remove(os.path.join(self.nzo.workpath, self.nzf_id)) except: pass def __getstate__(self): """ Save to pickle file, translating attributes """ dict_ = {} for tup in NzbFileMapper: dict_[tup[0]] = self.__dict__[tup[1]] return dict_ def __setstate__(self, dict_): """ Load from pickle file, translating attributes """ for tup in NzbFileMapper: try: self.__dict__[tup[1]] = dict_[tup[0]] except KeyError: # Handle new attributes self.__dict__[tup[1]] = None TryList.__init__(self) def __repr__(self): return "" % (self.filename, self.type) ################################################################################ # NzbParser # ################################################################################ class NzbParser(xml.sax.handler.ContentHandler): """ Forgiving parser for NZB's """ def __init__ (self, nzo, remove_samples=False): self.nzo = nzo assert isinstance(self.nzo, NzbObject) self.in_nzb = False self.in_file = False self.in_groups = False self.in_group = False self.in_segments = False self.in_segment = False self.in_head = False self.in_meta = False self.meta_type = '' self.meta_types = {} self.meta_content = [] self.filename = '' self.avg_age = 0 self.valids = 0 self.skipped_files = 0 self.nzf_list = [] self.groups = [] self.filter = remove_samples self.now = time.time() def startDocument(self): pass def startElement(self, name, attrs): if name == 'segment' and self.in_nzb and self.in_file and self.in_segments: try: self.seg_bytes = int(attrs.get('bytes')) self.article_nr = int(attrs.get('number')) except ValueError: return self.article_id = [] self.file_bytes += self.seg_bytes self.in_segment = True elif name == 'segments' and self.in_nzb and self.in_file: self.in_segments = True elif name == 'file' and self.in_nzb: subject = attrs.get('subject', '').strip() self.filename = subject if self.filter and RE_SAMPLE.search(subject): logging.info('Skipping sample file %s', subject) else: self.in_file = True if isinstance(subject, unicode): subject = subject.encode('latin-1', 'replace') self.fileSubject = subject try: self.file_date = int(attrs.get('date')) except: # NZB has non-standard timestamp, assume now self.file_date = self.now self.article_db = {} self.file_bytes = 0 elif name == 'group' and self.in_nzb and self.in_file and self.in_groups: self.in_group = True self.group_name = [] elif name == 'groups' and self.in_nzb and self.in_file: self.in_groups = True elif name == 'head' and self.in_nzb: self.in_head = True elif name == 'meta' and self.in_nzb and self.in_head: self.in_meta = True meta_type = attrs.get('type') if meta_type: self.meta_type = meta_type.lower() self.meta_content = [] elif name == 'nzb': self.in_nzb = True def characters (self, content): if self.in_group: self.group_name.append(content) elif self.in_segment: self.article_id.append(content) elif self.in_meta: self.meta_content.append(content) def endElement(self, name): if name == 'group' and self.in_group: group = str(''.join(self.group_name)) if group not in self.groups: self.groups.append(group) self.in_group = False elif name == 'segment' and self.in_segment: partnum = self.article_nr segm = str(''.join(self.article_id)) if partnum in self.article_db: if segm != self.article_db[partnum][0]: msg = 'Duplicate part %s, but different ID-s (%s // %s)' % (partnum, self.article_db[partnum][0], segm) logging.info(msg) self.nzo.inc_log('dup_art_log', msg) else: logging.info("Skipping duplicate article (%s)", segm) else: self.article_db[partnum] = (segm, self.seg_bytes) self.in_segment = False elif name == 'groups' and self.in_groups: self.in_groups = False elif name == 'segments' and self.in_segments: self.in_segments = False elif name == 'file' and self.in_file: # Create an NZF self.in_file = False if not self.article_db: logging.warning(Ta('File %s is empty, skipping'), self.filename) return try: tm = datetime.datetime.fromtimestamp(self.file_date) except: tm = datetime.datetime.fromtimestamp(self.now) self.file_date = self.now nzf = NzbFile(tm, self.filename, self.article_db, self.file_bytes, self.nzo) if nzf.valid and nzf.nzf_id: logging.info('File %s added to queue', self.filename) self.nzo.files.append(nzf) self.nzo.files_table[nzf.nzf_id] = nzf self.nzo.bytes += nzf.bytes self.avg_age += self.file_date self.valids += 1 self.nzf_list.append(nzf) else: logging.info('Error importing %s, skipping', self.filename) if nzf.nzf_id: sabnzbd.remove_data(nzf.nzf_id, self.nzo.workpath) self.skipped_files += 1 elif name == 'head': self.in_head = False elif name == 'meta': self.in_meta = False if self.meta_type: if self.meta_type not in self.meta_types: self.meta_types[self.meta_type] = [] self.meta_types[self.meta_type].append(''.join(self.meta_content)) elif name == 'nzb': self.in_nzb = False def endDocument(self): """ End of the file """ self.nzo.groups = self.groups self.nzo.meta = self.meta_types logging.debug('META-DATA = %s', self.nzo.meta) files = max(1, self.valids) self.nzo.avg_stamp = self.avg_age / files self.nzo.avg_date = datetime.datetime.fromtimestamp(self.avg_age / files) if self.skipped_files: logging.warning(Ta('Failed to import %s files from %s'), self.skipped_files, self.nzo.filename) ################################################################################ # NzbObject # ################################################################################ NzbObjectMapper = ( # Pickle name Internal name ('_NzbObject__filename', 'filename'), # Original NZB name ('_NzbObject__dirname', 'work_name'), ('_NzbObject__original_dirname', 'final_name'), ('_NzbObject__created', 'created'), ('_NzbObject__bytes', 'bytes'), ('_NzbObject__bytes_downloaded', 'bytes_downloaded'), ('_NzbObject__repair', 'repair'), ('_NzbObject__unpack', 'unpack'), ('_NzbObject__delete', 'delete'), ('_NzbObject__script', 'script'), ('_NzbObject__msgid', 'msgid'), ('_NzbObject__cat', 'cat'), ('_NzbObject__url', 'url'), ('_NzbObject__group', 'groups'), ('_NzbObject__avg_date', 'avg_date'), ('_NzbObject__dirprefix', 'dirprefix'), ('_NzbObject__partable', 'partable'), ('_NzbObject__extrapars', 'extrapars'), ('md5packs', 'md5packs'), ('_NzbObject__files', 'files'), ('_NzbObject__files_table', 'files_table'), ('_NzbObject__finished_files', 'finished_files'), ('_NzbObject__status', 'status'), ('_NzbObject__avg_bps_freq', 'avg_bps_freq'), ('_NzbObject__avg_bps_total', 'avg_bps_total'), ('_NzbObject__priority', 'priority'), ('_NzbObject__dupe_table', 'dupe_table'), ('saved_articles', 'saved_articles'), ('nzo_id', 'nzo_id'), ('futuretype', 'futuretype'), ('deleted', 'deleted'), ('parsed', 'parsed'), ('action_line', 'action_line'), ('unpack_info', 'unpack_info'), ('fail_msg', 'fail_msg'), ('nzo_info', 'nzo_info'), ('extra1', 'custom_name'), # Job name set by API &nzbname ('extra2', 'password'), # Password for rar files ('extra3', 'next_save'), # Earliest next save time of NZO ('extra4', 'save_timeout'), # Save timeout for this NZO ('extra5', 'new_caching'), # New style caching ('extra6', 'encrypted'), # Encrypted RAR file encountered ('duplicate', 'duplicate'), # Was detected as a duplicate ('oversized', 'oversized'), # Was detected as oversized ('create_group_folder', 'create_group_folder'), ('precheck', 'precheck'), ('incomplete', 'incomplete'), # Was detected as incomplete ('reuse', 'reuse'), ('meta', 'meta'), # Meta-date from 1.1 type NZB ('unwanted_ext', 'unwanted_ext'), ('rating_filtered', 'rating_filtered') # Has passed through ratings filter ) class NzbObject(TryList): def __init__(self, filename, msgid, pp, script, nzb = None, futuretype = False, cat = None, url=None, priority=NORMAL_PRIORITY, nzbname=None, status="Queued", nzo_info=None, reuse=False, dup_check=True): TryList.__init__(self) filename = platform_encode(filename) nzbname = platform_encode(nzbname) if pp is None: r = u = d = None else: r, u, d = sabnzbd.pp_to_opts(pp) self.filename = filename # Original filename if nzbname and nzb: work_name = nzbname # Use nzbname if set and only for non-future slot else: work_name = filename # If non-future: create safe folder name stripped from ".nzb" and junk if nzb and work_name and work_name.lower().endswith('.nzb'): dname, ext = os.path.splitext(work_name) # Used for folder name for final unpack if ext.lower() == '.nzb': work_name = dname work_name, password = scan_password(work_name) if not work_name: work_name = filename if nzb and work_name and not reuse: work_name = sanitize_foldername(work_name) self.work_name = work_name self.final_name = work_name self.meta = {} self.created = False # dirprefixes + work_name created self.bytes = 0 # Original bytesize self.bytes_downloaded = 0 # Downloaded byte self.repair = r # True if we want to repair this set self.unpack = u # True if we want to unpack this set self.delete = d # True if we want to delete this set self.script = script # External script for this set self.msgid = '0' # Newzbin msgid self.cat = cat # Newzbin category if url: self.url = str(url) # Either newzbin-id or source URL else: self.url = filename self.groups = [] self.avg_date = datetime.datetime.fromtimestamp(0.0) self.avg_stamp = 0.0 # Avg age in seconds (calculated from avg_age) self.dirprefix = [] self.partable = {} # Holds one parfile-name for each set self.extrapars = {} # Holds the extra parfile names for all sets self.md5packs = {} # Holds the md5pack for each set self.files = [] # List of all NZFs self.files_table = {} # Dictionary of NZFs indexed using NZF_ID self.finished_files = [] # List of al finished NZFs #the current status of the nzo eg: #Queued, Downloading, Repairing, Unpacking, Failed, Complete self.status = status self.avg_bps_freq = 0 self.avg_bps_total = 0 try: priority = int(priority) except: priority = DEFAULT_PRIORITY self.priority = priority self.dupe_table = {} self.saved_articles = [] self.nzo_id = None self.futuretype = futuretype self.deleted = False self.parsed = False self.duplicate = False self.oversized = False self.precheck = False self.incomplete = False self.unwanted_ext = 0 self.rating_filtered = 0 self.reuse = reuse if self.status == Status.QUEUED and not reuse: self.precheck = cfg.pre_check() if self.precheck: self.status = Status.CHECKING # Store one line responses for filejoin/par2/unrar/unzip here for history display self.action_line = '' # Store the results from various filejoin/par2/unrar/unzip stages self.unpack_info = {} # Stores one line containing the last failure self.fail_msg = '' # Stores various info about the nzo to be if nzo_info: self.nzo_info = nzo_info else: self.nzo_info = {} # Temporary store for custom foldername - needs to be stored because of url/newzbin fetching self.custom_name = nzbname self.password = password self.next_save = None self.save_timeout = None self.new_caching = True self.encrypted = 0 self.wait = None self.pp_active = False # Signals active post-processing (not saved) self.create_group_folder = cfg.create_group_folders() # Remove leading msgid_dddd and trailing .nzb self.work_name, self.msgid = split_filename(self.work_name) if msgid: self.msgid = msgid if nzb is None: # This is a slot for a future NZB, ready now return # Apply conversion option to final folder if cfg.replace_dots() and ' ' not in self.final_name: logging.info('Replacing dots with spaces in %s', self.final_name) self.final_name = self.final_name.replace('.',' ') if cfg.replace_spaces(): logging.info('Replacing spaces with underscores in %s', self.final_name) self.final_name = self.final_name.replace(' ','_') # Determine "incomplete" folder wdir = os.path.join(cfg.download_dir.get_path(), self.work_name) adir = os.path.join(wdir, JOB_ADMIN) # Duplicate checking, needs to be done before the backup duplicate = (not reuse) and nzb and dup_check and sabnzbd.backup_exists(filename) \ and priority != REPAIR_PRIORITY if reuse: remove_all(adir, 'SABnzbd_nz?_*') remove_all(adir, 'SABnzbd_article_*') else: wdir = get_unique_path(wdir, create_dir=True) set_permissions(wdir) adir = os.path.join(wdir, JOB_ADMIN) if not os.path.exists(adir): os.mkdir(adir) dummy, self.work_name = os.path.split(wdir) self.created = True # Must create a lower level XML parser because we must # disable the reading of the DTD file from newzbin.com # by setting "feature_external_ges" to 0. if nzb and '' not in nzb: logging.warning(Ta('Incomplete NZB file %s'), filename) else: logging.warning(Ta('Invalid NZB file %s, skipping (reason=%s, line=%s)'), filename, err.getMessage(), err.getLineNumber()) except Exception, err: self.incomplete = True logging.warning(Ta('Invalid NZB file %s, skipping (reason=%s, line=%s)'), filename, err, 0) if self.incomplete: if cfg.allow_incomplete_nzb(): self.pause() else: self.purge_data() raise ValueError sabnzbd.backup_nzb(filename, nzb) sabnzbd.save_compressed(adir, filename, nzb) if not self.files and not reuse: self.purge_data(keep_basic=False) if cfg.warn_empty_nzb(): mylog = logging.warning else: mylog = logging.info if self.url: mylog(Ta('Empty NZB file %s') + ' [%s]', filename, self.url) else: mylog(Ta('Empty NZB file %s'), filename) raise ValueError if cat is None: for metacat in self.meta.get('category', ()): metacat = cat_convert(metacat) if metacat: cat = metacat break if cat is None: for grp in self.groups: cat = cat_convert(grp) if cat: break if cfg.create_group_folders(): self.dirprefix.append(self.group) # Pickup backed-up attributes when re-using if reuse: cat, pp, script, priority, name, self.url = get_attrib_file(self.workpath, 6) self.set_final_name_pw(name) # Determine category and find pp/script values self.cat, pp_tmp, self.script, self.priority = cat_to_opts(cat, pp, script, priority) self.repair, self.unpack, self.delete = sabnzbd.pp_to_opts(pp_tmp) # Run user pre-queue script if needed if not reuse: accept, name, pp, cat, script, priority, group = \ sabnzbd.proxy_pre_queue(self.final_name_pw_clean, pp, cat, script, priority, self.bytes, self.groups) accept = int_conv(accept) try: pp = int(pp) except: pp = None try: priority = int(priority) except: priority = None if accept < 1: self.purge_data() raise TypeError if name: self.set_final_name_pw(name) if group: self.groups = [str(group)] # Re-evaluate results from pre-queue script self.cat, pp, self.script, self.priority = cat_to_opts(cat, pp, script, priority) self.repair, self.unpack, self.delete = sabnzbd.pp_to_opts(pp) else: accept = 1 # Pause job when above size limit limit = cfg.size_limit.get_int() if not reuse and abs(limit) > 0.5 and self.bytes > limit: logging.info('Job too large, forcing low prio and paused (%s)', self.work_name) self.pause() self.oversized = True self.priority = LOW_PRIORITY if duplicate and cfg.no_dupes() == 1: if cfg.warn_dupl_jobs(): logging.warning(Ta('Ignoring duplicate NZB "%s"'), filename) self.purge_data(keep_basic=False) raise TypeError if duplicate or self.priority == DUP_PRIORITY: if cfg.warn_dupl_jobs(): logging.warning(Ta('Pausing duplicate NZB "%s"'), filename) self.duplicate = True self.pause() self.priority = NORMAL_PRIORITY if self.priority == PAUSED_PRIORITY: self.pause() self.priority = NORMAL_PRIORITY if reuse: self.check_existing_files(wdir) if cfg.auto_sort(): self.files.sort(cmp=nzf_cmp_date) else: self.files.sort(cmp=nzf_cmp_name) # In the hunt for Unwanted Extensions: # The file with the unwanted extension often is in the first or the last rar file # So put the last rar immediatly after the first rar file so that it gets detected early if cfg.unwanted_extensions() and not cfg.auto_sort(): # ... only useful if there are unwanted extensions defined and there is no sorting on date logging.debug('Unwanted Extension: putting last rar after first rar') nzfposcounter = firstrarpos = lastrarpos = 0 for nzf in self.files: nzfposcounter += 1 if '.rar' in str(nzf): # a NZF found with '.rar' in the name if firstrarpos == 0: # this is the first .rar found, so remember this position firstrarpos = nzfposcounter lastrarpos = nzfposcounter lastrarnzf = nzf # The NZF itself if firstrarpos != lastrarpos: # at least two different .rar's found logging.debug('Unwanted Extension: First rar at %s, Last rar at %s',firstrarpos, lastrarpos) logging.debug('Unwanted Extension: Last rar is %s', str(lastrarnzf)) try: self.files.remove(lastrarnzf) # first remove. NB: remove() does searches for lastrarnzf self.files.insert(firstrarpos,lastrarnzf) # ... and only then add after position firstrarpos except: logging.debug('The lastrar swap did not go well') # Set nzo save-delay to 6 sec per GB with a max of 5 min self.save_timeout = min(6.0 * float(self.bytes) / GIGI, 300.0) def check_for_dupe(self, nzf): filename = nzf.filename dupe = False if filename in self.dupe_table: old_nzf = self.dupe_table[filename] if nzf.article_count <= old_nzf.article_count: dupe = True if not dupe: self.dupe_table[filename] = nzf return dupe def update_avg_kbs(self, bps): if bps: self.avg_bps_total += bps / 1024 self.avg_bps_freq += 1 def remove_nzf(self, nzf): if nzf in self.files: self.files.remove(nzf) self.finished_files.append(nzf) nzf.import_finished = True nzf.deleted = True return not bool(self.files) def reset_all_try_lists(self): for nzf in self.files: nzf.reset_all_try_lists() self.reset_try_list() def postpone_pars(self, nzf, parset): """ Move all vol-par files matching 'parset' to the extrapars table """ self.partable[parset] = nzf self.extrapars[parset] = [] nzf.extrapars = self.extrapars[parset] lparset = parset.lower() for xnzf in self.files[:]: name = xnzf.filename or platform_encode(xnzf.subject) # Move only when not current NZF and filename was extractable from subject if name and nzf is not xnzf: head, vol, block = analyse_par2(name) if head and matcher(lparset, head.lower()): xnzf.set_par2(parset, vol, block) self.extrapars[parset].append(xnzf) if not self.precheck: self.files.remove(xnzf) def handle_par2(self, nzf, file_done): """ Check if file is a par2 and build up par2 collection """ fn = nzf.filename if fn: # We have a real filename now fn = fn.strip() lfn = fn.lower() if not nzf.is_par2: head, vol, block = analyse_par2(fn) ## Is a par2file and repair mode activated if head and (self.repair or cfg.allow_streaming()): ## Skip if mini-par2 is not complete and there are more par2 files if not block and nzf.bytes_left and self.extrapars.get(head): return nzf.set_par2(head, vol, block) ## Already got a parfile for this set? if head in self.partable: nzf.extrapars = self.extrapars[head] ## Set the smallest par2file as initialparfile ## But only do this if our last initialparfile ## isn't already done (e.g two small parfiles) if nzf.blocks < self.partable[head].blocks \ and self.partable[head] in self.files: self.partable[head].reset_try_list() self.files.remove(self.partable[head]) self.extrapars[head].append(self.partable[head]) self.partable[head] = nzf ## This file either has more blocks, ## or initialparfile is already decoded else: if file_done: if nzf in self.files: self.files.remove(nzf) if nzf not in self.extrapars[head]: self.extrapars[head].append(nzf) else: nzf.reset_try_list() ## No par2file in this set yet, set this as ## initialparfile else: self.postpone_pars(nzf, head) ## Is not a par2file or nothing to do else: pass ## No filename in seg 1? Probably not uu or yenc encoded ## Set subject as filename else: nzf.filename = nzf.subject def remove_article(self, article, found): nzf = article.nzf file_done, reset = nzf.remove_article(article, found) if file_done: self.remove_nzf(nzf) if not self.reuse and cfg.fail_hopeless() and not self.check_quality(99)[0]: #set the nzo status to return "Queued" self.status = Status.QUEUED self.set_download_report() self.fail_msg = T('Aborted, cannot be completed') self.set_unpack_info('Download', self.fail_msg, unique=False) logging.debug('Abort job "%s", due to impossibility to complete it', self.final_name_pw_clean) return True, True, True if reset: self.reset_try_list() if file_done: self.handle_par2(nzf, file_done) post_done = False if not self.files: post_done = True #set the nzo status to return "Queued" self.status = Status.QUEUED self.set_download_report() return (file_done, post_done, reset) def check_existing_files(self, wdir): """ Check if downloaded files already exits, for these set NZF to complete """ # Get a list of already present files files = [os.path.basename(f) for f in globber(wdir) if os.path.isfile(f)] # Substitute renamed files renames = sabnzbd.load_data(RENAMES_FILE, self.workpath, remove=True) if renames: for name in renames: if name in files: files.remove(name) files.append(renames[name]) # Looking for the longest name first, minimizes the chance on a mismatch files.sort(lambda x, y: len(y) - len(x)) nzfs = self.files[:] # The NZFs should be tried shortest first, to improve the chance on a proper match nzfs.sort(lambda x, y: len(x.subject) - len(y.subject)) # Flag files from NZB that already exist as finished for filename in files[:]: for nzf in nzfs: subject = sanitize_filename(latin1(nzf.subject)) if (nzf.filename == filename) or (subject == filename) or (filename in subject): nzf.filename = filename nzf.completed = True nzf.bytes_left = 0 self.handle_par2(nzf, file_done=True) self.remove_nzf(nzf) nzfs.remove(nzf) files.remove(filename) break try: # Create an NZF for each remaining existing file for filename in files: tup = os.stat(os.path.join(wdir, filename)) tm = datetime.datetime.fromtimestamp(tup.st_mtime) nzf = NzbFile(tm, '"%s"' % filename, [], tup.st_size, self) self.files.append(nzf) self.files_table[nzf.nzf_id] = nzf self.bytes += nzf.bytes nzf.filename = filename nzf.completed = True nzf.bytes_left = 0 self.handle_par2(nzf, file_done=True) self.remove_nzf(nzf) logging.info('File %s added to job', filename) except: logging.debug('Bad NZB handling') logging.info("Traceback: ", exc_info = True) @property def pp(self): if self.repair is None: return None else: return sabnzbd.opts_to_pp(self.repair, self.unpack, self.delete) def set_pp(self, value): self.repair, self.unpack, self.delete = sabnzbd.pp_to_opts(value) self.save_to_disk() @property def final_name_pw(self): prefix = '' if self.duplicate: prefix = Ta('DUPLICATE') + ' / ' #: Queue indicator for duplicate job if self.encrypted and self.status == 'Paused': prefix += Ta('ENCRYPTED') + ' / ' #: Queue indicator for encrypted job if self.oversized and self.status == 'Paused': prefix += Ta('TOO LARGE') + ' / ' #: Queue indicator for oversized job if self.incomplete and self.status == 'Paused': prefix += Ta('INCOMPLETE') + ' / ' #: Queue indicator for incomplete NZB if self.unwanted_ext and self.status == 'Paused': prefix += Ta('UNWANTED') + ' / ' #: Queue indicator for unwanted extensions if self.rating_filtered and self.status == 'Paused': prefix += Ta('FILTERED') + ' / ' #: Queue indicator for filtered if isinstance(self.wait, float): dif = int(self.wait - time.time() + 0.5) if dif > 0: prefix += Ta('WAIT %s sec') % dif + ' / ' #: Queue indicator for waiting URL fetch if self.password: return '%s%s/%s' % (name_fixer(prefix), self.final_name, self.password) else: return '%s%s' % (name_fixer(prefix), self.final_name) @property def final_name_pw_clean(self): if self.password: return '%s/%s' % (self.final_name, self.password) else: return self.final_name def set_final_name_pw(self, name, password=None): if isinstance(name, str): if password is not None: name = platform_encode(name) self.password = platform_encode(password) else: name, self.password = scan_password(platform_encode(name)) self.final_name = sanitize_foldername(name) self.save_to_disk() def pause(self): self.status = 'Paused' # Prevent loss of paused state when terminated if self.nzo_id: sabnzbd.save_data(self, self.nzo_id, self.workpath) def resume(self): self.status = Status.QUEUED if self.encrypted: # If user resumes after encryption warning, no more auto-pauses self.encrypted = 2 if self.rating_filtered: # If user resumes after filtered warning, no more auto-pauses self.rating_filtered = 2 # If user resumes after warning, reset duplicate/oversized/incomplete/unwanted indicators self.duplicate = False self.oversized = False self.incomplete = False if self.unwanted_ext: # If user resumes after "unwanted" warning, no more auto-pauses self.unwanted_ext = 2 def add_parfile(self, parfile): if parfile not in self.files: self.files.append(parfile) if parfile.extrapars and parfile in parfile.extrapars: parfile.extrapars.remove(parfile) def remove_parset(self, setname): self.partable.pop(setname) __re_quick_par2_check = re.compile('\.par2\W*', re.I) def check_quality(self, req_ratio=0): """ Determine amount of articles present on servers and return (gross available, nett) bytes """ need = 0L pars = 0L short = 0L anypars = False for nzf_id in self.files_table: nzf = self.files_table[nzf_id] assert isinstance(nzf, NzbFile) if nzf.deleted: short += nzf.bytes_left if self.__re_quick_par2_check.search(nzf.subject): pars += nzf.bytes anypars = True else: need += nzf.bytes have = need + pars - short ratio = float(have) / float(max(1, need)) if anypars: enough = ratio * 100.0 >= (req_ratio or float(cfg.req_completion_rate())) else: enough = have >= need logging.debug('Download Quality: enough=%s, have=%s, need=%s, ratio=%s', enough, have, need, ratio) return enough, ratio def set_download_report(self): if self.avg_bps_total and self.bytes_downloaded and self.avg_bps_freq: #get the deltatime since the download started avg_bps = self.avg_bps_total / self.avg_bps_freq timecompleted = datetime.timedelta(seconds=self.bytes_downloaded / (avg_bps*1024)) seconds = timecompleted.seconds #find the total time including days totaltime = (timecompleted.days/86400) + seconds self.nzo_info['download_time'] = totaltime #format the total time the download took, in days, hours, and minutes, or seconds. complete_time = format_time_string(seconds, timecompleted.days) msg1 = T('Downloaded in %s at an average of %sB/s') % (complete_time, to_units(avg_bps*1024, dec_limit=1)) bad = self.nzo_info.get('bad_art_log', []) miss = self.nzo_info.get('missing_art_log', []) killed = self.nzo_info.get('killed_art_log', []) dups = self.nzo_info.get('dup_art_log', []) msg2 = msg3 = msg4 = msg5 = '' if bad: msg2 = ('
    ' + T('%s articles were malformed')) % len(bad) if miss: msg3 = ('
    ' + T('%s articles were missing')) % len(miss) if dups: msg4 = ('
    ' + T('%s articles had non-matching duplicates')) % len(dups) if killed: msg5 = ('
    ' + T('%s articles were removed')) % len(killed) msg = ''.join((msg1, msg2, msg3, msg4, msg5, )) self.set_unpack_info('Download', msg, unique=True) if self.url: self.set_unpack_info('Source', format_source_url(self.url), unique=True) def inc_log(self, log, txt): """ Append string txt to nzo_info element "log" """ try: self.nzo_info[log].append(txt) except: self.nzo_info[log] = [txt] def get_article(self, server): article = None nzf_remove_list = [] for nzf in self.files: assert isinstance(nzf, NzbFile) if nzf.deleted: logging.debug('Skipping existing file %s', nzf.filename or nzf.subject) else: # Don't try to get an article if server is in try_list of nzf if not nzf.server_in_try_list(server): if not nzf.import_finished: # Only load NZF when it's a primary server # or when it's a backup server without active primaries if server.fillserver ^ sabnzbd.active_primaries(): nzf.finish_import() # Still not finished? Something went wrong... if not nzf.import_finished: logging.error(Ta('Error importing %s'), nzf) nzf_remove_list.append(nzf) continue else: continue article = nzf.get_article(server) if article: break # Remove all files for which admin could not be read for nzf in nzf_remove_list: nzf.deleted = True nzf.completed = True self.files.remove(nzf) # If cleanup emptied the active files list, end this job if nzf_remove_list and not self.files: sabnzbd.NzbQueue.do.end_job(self) if not article: # No articles for this server, block for next time self.add_to_try_list(server) return article def move_top_bulk(self, nzf_ids): self.cleanup_nzf_ids(nzf_ids) if nzf_ids: target = range(len(nzf_ids)) while 1: self.move_up_bulk(nzf_ids, cleanup = False) pos_nzf_table = self.build_pos_nzf_table(nzf_ids) keys = pos_nzf_table.keys() keys.sort() if target == keys: break def move_bottom_bulk(self, nzf_ids): self.cleanup_nzf_ids(nzf_ids) if nzf_ids: target = range(len(self.files)-len(nzf_ids), len(self.files)) while 1: self.move_down_bulk(nzf_ids, cleanup = False) pos_nzf_table = self.build_pos_nzf_table(nzf_ids) keys = pos_nzf_table.keys() keys.sort() if target == keys: break def move_up_bulk(self, nzf_ids, cleanup = True): if cleanup: self.cleanup_nzf_ids(nzf_ids) if nzf_ids: pos_nzf_table = self.build_pos_nzf_table(nzf_ids) while pos_nzf_table: pos = min(pos_nzf_table) nzf = pos_nzf_table.pop(pos) if pos > 0: tmp_nzf = self.files[pos-1] if tmp_nzf.nzf_id not in nzf_ids: self.files[pos-1] = nzf self.files[pos] = tmp_nzf def move_down_bulk(self, nzf_ids, cleanup = True): if cleanup: self.cleanup_nzf_ids(nzf_ids) if nzf_ids: pos_nzf_table = self.build_pos_nzf_table(nzf_ids) while pos_nzf_table: pos = max(pos_nzf_table) nzf = pos_nzf_table.pop(pos) if pos < len(self.files)-1: tmp_nzf = self.files[pos+1] if tmp_nzf.nzf_id not in nzf_ids: self.files[pos+1] = nzf self.files[pos] = tmp_nzf # Determine if rating information (including site identifier so rating can be updated) # is present in metadata and if so store it def update_rating(self): if cfg.rating_enable(): try: def _get_first_meta(type): values = self.meta.get('x-oznzb-rating-' + type, None) or self.meta.get('x-rating-' + type, None) return values[0] if values else None rating_types = ['video', 'videocnt', 'audio', 'audiocnt', 'voteup' ,'votedown', \ 'spam', 'confirmed-spam', 'passworded', 'confirmed-passworded'] fields = {} for k in rating_types: fields[k] = _get_first_meta(k) Rating.do.add_rating(_get_first_meta('id'), self.nzo_id, self.meta.get('x-rating-host'), fields) except: pass ## end nzo.Mutators ####################################################### ########################################################################### @property def workpath(self): """ Return the full path for my job-admin folder (or old style cache) """ return get_admin_path(self.new_caching, self.work_name, self.futuretype) @property def downpath(self): """ Return the full path for my download folder """ return os.path.join(cfg.download_dir.get_path(), self.work_name) @property def group(self): if self.groups: return self.groups[0] else: return None def purge_data(self, keep_basic=False, del_files=False): """ Remove all admin info, 'keep_basic' preserves attribs and nzb """ wpath = self.workpath for nzf in self.files: sabnzbd.remove_data(nzf.nzf_id, wpath) for _set in self.extrapars: for nzf in self.extrapars[_set]: sabnzbd.remove_data(nzf.nzf_id, wpath) for nzf in self.finished_files: sabnzbd.remove_data(nzf.nzf_id, wpath) if self.new_caching and not self.futuretype: if keep_basic: remove_all(wpath, 'SABnzbd_nz?_*') remove_all(wpath, 'SABnzbd_article_*') else: remove_all(wpath, recursive=True) if del_files: remove_all(self.downpath, recursive=True) else: try: os.rmdir(self.downpath) except: pass def remaining(self): """ Return remaining bytes """ bytes_left = 0 for nzf in self.files: bytes_left += nzf.bytes_left return bytes_left def total_and_remaining(self): """ Return total and remaining bytes """ bytes = 0 bytes_left = 0 for nzf in self.files: bytes += nzf.bytes bytes_left += nzf.bytes_left return bytes, bytes_left def gather_info(self, for_cli = False): bytes_left_all = 0 active_files = [] queued_files = [] finished_files = [] for nzf in self.finished_files: bytes = nzf.bytes filename = nzf.filename if not filename: filename = nzf.subject date = nzf.date if for_cli: date = time.mktime(date.timetuple()) finished_files.append((0, bytes, filename, date)) for nzf in self.files: bytes_left = nzf.bytes_left bytes = nzf.bytes filename = nzf.filename if not filename: filename = nzf.subject date = nzf.date if for_cli: date = time.mktime(date.timetuple()) bytes_left_all += bytes_left active_files.append((bytes_left, bytes, filename, date, nzf.nzf_id)) for _set in self.extrapars: for nzf in self.extrapars[_set]: bytes_left = nzf.bytes_left bytes = nzf.bytes filename = nzf.filename if not filename: filename = nzf.subject date = nzf.date if for_cli: date = time.mktime(date.timetuple()) queued_files.append((_set, bytes_left, bytes, filename, date)) avg_date = self.avg_date if for_cli: avg_date = time.mktime(avg_date.timetuple()) return (self.repair, self.unpack, self.delete, self.script, self.nzo_id, self.final_name_pw, {}, self.msgid, self.cat, self.url, bytes_left_all, self.bytes, avg_date, finished_files, active_files, queued_files, self.status, self.priority, len(self.nzo_info.get('missing_art_log', [])) ) def get_nzf_by_id(self, nzf_id): if nzf_id in self.files_table: return self.files_table[nzf_id] def set_unpack_info(self, key, msg, set='', unique=False): ''' Builds a dictionary containing the stage name (key) and a message If set is present, it will overwrite any other messages from the set of the same stage If unique is present, it will only have a single line message ''' found = False # Unique messages allow only one line per stage(key) if not unique: if not self.unpack_info.has_key(key): self.unpack_info[key] = [] # If set is present, look for previous message from that set and replace if set: set = unicoder('[%s]' % set) for x in xrange(len(self.unpack_info[key])): if set in self.unpack_info[key][x]: self.unpack_info[key][x] = msg found = True if not found: self.unpack_info[key].append(msg) else: self.unpack_info[key] = [msg] def set_action_line(self, action=None, msg=None): if action and msg: self.action_line = '%s: %s' % (action, msg) else: self.action_line = '' @property def repair_opts(self): return self.repair, self.unpack, self.delete def save_to_disk(self): """ Save job's admin to disk """ self.save_attribs() if self.nzo_id: sabnzbd.save_data(self, self.nzo_id, self.workpath) def save_attribs(self): set_attrib_file(self.workpath, (self.cat, self.pp, self.script, self.priority, self.final_name_pw_clean, self.url)) def build_pos_nzf_table(self, nzf_ids): pos_nzf_table = {} for nzf_id in nzf_ids: if nzf_id in self.files_table: nzf = self.files_table[nzf_id] pos = self.files.index(nzf) pos_nzf_table[pos] = nzf return pos_nzf_table def cleanup_nzf_ids(self, nzf_ids): for nzf_id in nzf_ids[:]: if nzf_id in self.files_table: if self.files_table[nzf_id] not in self.files: nzf_ids.remove(nzf_id) else: nzf_ids.remove(nzf_id) def __getstate__(self): """ Save to pickle file, translating attributes """ dict_ = {} for tup in NzbObjectMapper: dict_[tup[0]] = self.__dict__[tup[1]] return dict_ def __setstate__(self, dict_): """ Load from pickle file, translating attributes """ for tup in NzbObjectMapper: try: self.__dict__[tup[1]] = dict_[tup[0]] except KeyError: # Handle new attributes self.__dict__[tup[1]] = None self.pp_active = False self.avg_stamp = time.mktime(self.avg_date.timetuple()) self.wait = None if self.meta is None: self.meta = {} TryList.__init__(self) def __repr__(self): return "" % self.filename #------------------------------------------------------------------------------- def nzf_get_filename(nzf): """ Return filename, if the filename not set, try the the full subject line instead. Can produce non-ideal results """ name = nzf.filename if not name: name = nzf.subject if not name: name = '' return name.lower() def get_ext_list(): """ Return priority extenstion list, with extensions starting with a period """ exts = [] for ext in cfg.prio_sort_list(): ext = ext.strip() if not ext.startswith('.'): ext = '.' + ext exts.append(ext) return exts def ext_on_list(name, lst): """ Return True if `name` contains any extension in `lst` """ for ext in lst: if name.rfind(ext) >= 0: return True return False def nzf_cmp_date(nzf1, nzf2): """ Compare files based on date, but give vol-par files preference. Wrapper needed, because `cmp` function doesn't handle extra parms. """ return nzf_cmp_name(nzf1, nzf2, name=False) RE_RAR = re.compile(r'(\.rar|\.r\d\d|\.s\d\d|\.t\d\d|\.u\d\d|\.v\d\d)$', re.I) def nzf_cmp_name(nzf1, nzf2, name=True): # The comparison will sort .par2 files to the top of the queue followed by .rar files, # they will then be sorted by name. name1 = nzf_get_filename(nzf1) name2 = nzf_get_filename(nzf2) # Determine vol-pars is_par1 = '.vol' in name1 and '.par2' in name1 is_par2 = '.vol' in name2 and '.par2' in name2 # mini-par2 in front if not is_par1 and name1.endswith('.par2'): return -1 if not is_par2 and name2.endswith('.par2'): return 1 # vol-pars go to the back if is_par1 and not is_par2: return 1 if is_par2 and not is_par1: return -1 # Anything with a priority extention goes first ext_list = get_ext_list() if ext_list: onlist1 = ext_on_list(name1, ext_list) onlist2 = ext_on_list(name2, ext_list) if onlist1 and not onlist2: return -1 if onlist2 and not onlist1: return 1 if name: # Prioritise .rar files above any other type of file (other than vol-par) # Useful for nzb streaming m1 = RE_RAR.search(name1) m2 = RE_RAR.search(name2) if m1 and not (is_par2 or m2): return -1 elif m2 and not (is_par1 or m1): return 1 # Force .rar to come before 'r00' if m1 and m1.group(1) == '.rar': name1 = name1.replace('.rar', '.r//') if m2 and m2.group(1) == '.rar': name2 = name2.replace('.rar', '.r//') return cmp(name1, name2) else: # Do date comparision return cmp(nzf1.date, nzf2.date) #------------------------------------------------------------------------------- def split_filename(name): """ Isolate newzbin msgid from filename and remove ".nzb" Return (nice-name, msg-id) """ name = name.strip() if name.find('://') < 0: m = RE_NEWZBIN.match(name) if (m): return m.group(2).rstrip('.').strip(), m.group(1) m = RE_NORMAL.match(name) if (m): return m.group(1).rstrip('.').strip(), "" else: return name.strip(), "" return "", "" else: return name.strip(), "" def format_time_string(seconds, days=0): """ Given seconds and days, return formatted day/hour/min/sec string """ def unit(n, single): if n == 1: return n, Tx(single) else: return n, Tx(single + 's') try: seconds = int(seconds) except ValueError: seconds = 0 completestr = '' if days: completestr += '%s %s ' % unit(days, 'day') if (seconds/3600) >= 1: completestr += '%s %s ' % unit(seconds/3600, 'hour') seconds -= (seconds/3600)*3600 if (seconds/60) >= 1: completestr += '%s %s ' % unit(seconds/60, 'minute') seconds -= (seconds/60)*60 if seconds > 0: completestr += '%s %s ' % unit(seconds, 'second') else: completestr += '%s %s' % unit(0, 'second') return completestr.strip() def scan_password(name): """ Get password (if any) from the title """ if 'http://' in name or 'https://' in name: return name, None braces = name.find('{{') if braces < 0: braces = len(name) slash = name.find('/') # Look for name/password, but make sure that '/' comes before any {{ if slash >= 0 and slash < braces and not 'password=' in name: return name[:slash].strip('. '), name[slash+1:] # Look for "name password=password" pw = name.find('password=') if pw >= 0: return name[:pw].strip('. '), name[pw+9:] # Look for name{{password}} if braces < len(name) and name.endswith('}}'): return name[:braces].strip('. '), name[braces+2:len(name)-2] # Look again for name/password if slash >= 0: return name[:slash].strip('. '), name[slash+1:] # No password found return name, None def get_attrib_file(path, size): """ Read job's attributes from file """ attribs = [] path = os.path.join(path, ATTRIB_FILE) try: f = open(path, 'r') except: return [None for n in xrange(size)] for n in xrange(size): line = f.readline().strip('\r\n ') if line: if line.lower() == 'none': line = None try: line = int(line) except: pass attribs.append(line) else: attribs.append(None) f.close() return attribs def set_attrib_file(path, attribs): """ Write job's attributes to file """ path = os.path.join(path, ATTRIB_FILE) try: f = open(path, 'w') except: return for item in attribs: f.write('%s\n' % item) f.close() def analyse_par2(name): """ Check if file is a par2-file and determine vol/block return head, vol, block head is empty when not a par2 file """ head = None vol = block = 0 if name and not REJECT_PAR2_RE.search(name): m = PROBABLY_PAR2_RE.search(name) if m: head = m.group(1) vol = m.group(2) block = m.group(3) elif name.lower().find('.par2') > 0: head = os.path.splitext(name)[0].strip() else: head = None return head, vol, block def name_extractor(subject): """ Try to extract a file name from a subject line, return `subject` if in doubt """ result = subject for name in re.findall(SUBJECT_FN_MATCHER, subject): name = name.strip(' "') if name and RE_NORMAL_NAME.search(name): result = name return platform_encode(result) def matcher(pattern, txt): """ Return True if `pattern` is sufficiently equal to `txt` """ if txt.endswith(pattern): txt = txt[:txt.rfind(pattern)].strip() return (not txt) or txt.endswith('"') else: return False SABnzbd-0.7.20/sabnzbd/osxmenu.py0000644000000000000000000010112012433712602016713 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.osxmenu - OSX Top Menu """ import objc from Foundation import * from AppKit import * from PyObjCTools import AppHelper from objc import YES, NO, nil import os import subprocess from threading import Thread import cherrypy import Cheetah.DummyTransaction import sys import time import logging import sabnzbd import sabnzbd.cfg from sabnzbd.constants import * from sabnzbd.misc import get_filename, get_ext, diskfree, to_units from sabnzbd.panic import launch_a_browser import sabnzbd.growler as growler from sabnzbd.api import fast_queue from sabnzbd.nzbqueue import NzbQueue import sabnzbd.config as config import sabnzbd.scheduler as scheduler import sabnzbd.downloader import sabnzbd.dirscanner as dirscanner from sabnzbd.bpsmeter import BPSMeter from sabnzbd.newzbin import Bookmarks from sabnzbd.database import get_history_handle from sabnzbd.encoding import unicoder status_icons = {'idle':'../Resources/sab_idle.tiff','pause':'../Resources/sab_pause.tiff','clicked':'../Resources/sab_clicked.tiff'} start_time = NSDate.date() debug = 0 class SABnzbdDelegate(NSObject): icons = {} status_bar = None osx_icon = True history_db = None def awakeFromNib(self): #Status Bar iniatilize #if (debug == 1) : NSLog("[osx] awake") self.buildMenu() #Timer for updating menu self.timer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_(start_time, 3.0, self, 'updateAction:', None, True) NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode) NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSEventTrackingRunLoopMode) # NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSModalPanelRunLoopMode) self.timer.fire() def buildMenu(self): #logging.info("building menu") status_bar = NSStatusBar.systemStatusBar() self.status_item = status_bar.statusItemWithLength_(NSVariableStatusItemLength) for i in status_icons.keys(): self.icons[i] = NSImage.alloc().initByReferencingFile_(status_icons[i]) if sabnzbd.DARWIN_YS: # Support for Yosemite Dark Mode self.icons[i].setTemplate_(YES) self.status_item.setImage_(self.icons['idle']) self.status_item.setAlternateImage_(self.icons['clicked']) self.status_item.setHighlightMode_(1) self.status_item.setToolTip_('SABnzbd') self.status_item.setEnabled_(YES) if (debug == 1) : NSLog("[osx] menu 1 building") #Wait for SABnzbd Initialisation #cherrypy.engine.wait(cherrypy.process.wspbus.states.STARTED) # Wait for translated texts to be loaded while not sabnzbd.WEBUI_READY and not sabnzbd.SABSTOP: time.sleep(0.5) if (debug == 1) : NSLog("[osx] language file not loaded, waiting") #Variables self.state = "Idle" try: self.speed = sabnzbd.downloader.Downloader.do.get_limit() except: self.speed = 0 self.version_notify = 1 self.status_removed = 0 if (debug == 1) : NSLog("[osx] menu 2 initialization") #Menu construction self.menu = NSMenu.alloc().init() try: menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_("Dummy", '', '') menu_item.setHidden_(YES) self.isLeopard = 1 except: self.isLeopard = 0 if (debug == 1) : NSLog("[osx] menu 3 construction") #Warnings Item self.warnings_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Warnings'), 'openBrowserAction:', '') if self.isLeopard: self.warnings_menu_item.setHidden_(YES) else: self.warnings_menu_item.setEnabled_(NO) self.warnings_menu_item.setRepresentedObject_("connections/") self.menu.addItem_(self.warnings_menu_item) if (debug == 1) : NSLog("[osx] menu 4 warning added") #State Item self.state_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Idle'), 'openBrowserAction:', '') self.state_menu_item.setRepresentedObject_("") self.menu.addItem_(self.state_menu_item) if (debug == 1) : NSLog("[osx] menu 5 state added") #Config Item menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Configuration'), 'openBrowserAction:', '') menu_item.setRepresentedObject_("config/general/") menu_item.setAlternate_(YES) menu_item.setKeyEquivalentModifierMask_(NSAlternateKeyMask) self.menu.addItem_(menu_item) if (debug == 1) : NSLog("[osx] menu 6 config added") #Queue Item self.queue_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Queue'), 'openBrowserAction:', '') self.queue_menu_item.setRepresentedObject_("") self.menu.addItem_(self.queue_menu_item) if (debug == 1) : NSLog("[osx] menu 7 queue added") #Purge Queue Item self.purgequeue_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Purge Queue'), 'purgeAction:', '') self.purgequeue_menu_item.setRepresentedObject_("queue") self.purgequeue_menu_item.setAlternate_(YES) self.purgequeue_menu_item.setKeyEquivalentModifierMask_(NSAlternateKeyMask) self.menu.addItem_(self.purgequeue_menu_item) if (debug == 1) : NSLog("[osx] menu 8 purge queue added") #History Item self.history_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('History'), 'openBrowserAction:', '') self.history_menu_item.setRepresentedObject_("") self.menu.addItem_(self.history_menu_item) if (debug == 1) : NSLog("[osx] menu 9 history added") #Purge History Item self.purgehistory_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Purge History'), 'purgeAction:', '') self.purgehistory_menu_item.setRepresentedObject_("history") self.purgehistory_menu_item.setAlternate_(YES) self.purgehistory_menu_item.setKeyEquivalentModifierMask_(NSAlternateKeyMask) self.menu.addItem_(self.purgehistory_menu_item) if (debug == 1) : NSLog("[osx] menu 10 purge history added") self.separator_menu_item = NSMenuItem.separatorItem() self.menu.addItem_(self.separator_menu_item) #Limit Speed Item & Submenu self.speed_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Limit Speed'), '', '') self.menu_speed = NSMenu.alloc().init() speeds ={ 0 : T('None'), 50 :'50 KB/s' , 100 : '100 KB/s', 200 : '200 KB/s' , 300 : '300 KB/s' , 400 : '400 KB/s', 500 :'500 KB/s' , 600 : '600 KB/s', 700 : '700 KB/s' , 800 : '800 KB/s' , 900 : '900 KB/s', 1000 :'1000 KB/s' , 1500 : '1500 KB/s', 2000 : '2000 KB/s' , 3000 : '3000 KB/s' } for speed in sorted(speeds.keys()): menu_speed_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('%s' % (speeds[speed]), 'speedlimitAction:', '') menu_speed_item.setRepresentedObject_("%s" % (speed)) self.menu_speed.addItem_(menu_speed_item) self.speed_menu_item.setSubmenu_(self.menu_speed) self.menu.addItem_(self.speed_menu_item) if (debug == 1) : NSLog("[osx] menu 11 limit speed added") #Pause Item & Submenu self.pause_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Pause'), 'pauseAction:', '') self.pause_menu_item.setRepresentedObject_('0') self.menu_pause = NSMenu.alloc().init() for i in range(6): menu_pause_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_("%s %s" % ((i+1)*10,T('min.')), 'pauseAction:', '') menu_pause_item.setRepresentedObject_("%s" % ((i+1)*10)) self.menu_pause.addItem_(menu_pause_item) self.pause_menu_item.setSubmenu_(self.menu_pause) self.menu.addItem_(self.pause_menu_item) if (debug == 1) : NSLog("[osx] menu 12 pause added") #Resume Item self.resume_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Resume'), 'resumeAction:', '') if self.isLeopard: self.resume_menu_item.setHidden_(YES) else: self.resume_menu_item.setEnabled_(NO) self.menu.addItem_(self.resume_menu_item) if (debug == 1) : NSLog("[osx] menu 13 resume added") #Newzbin Item self.newzbin_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Get Newzbin Bookmarks'), 'getNewzbinBookmarksAction:', '') if self.isLeopard: self.newzbin_menu_item.setHidden_(YES) else: self.newzbin_menu_item.setEnabled_(NO) self.menu.addItem_(self.newzbin_menu_item) if (debug == 1) : NSLog("[osx] menu 14 newzbin added") #Watched folder Item self.watched_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Scan watched folder'), 'watchedFolderAction:', '') if self.isLeopard: self.watched_menu_item.setHidden_(YES) else: self.watched_menu_item.setEnabled_(NO) self.menu.addItem_(self.watched_menu_item) self.separator2_menu_item = NSMenuItem.separatorItem() self.menu.addItem_(self.separator2_menu_item) if (debug == 1) : NSLog("[osx] menu 14 watched folder added") #Complete Folder Item self.completefolder_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Complete Folder') + '\t\t\t', 'openFolderAction:', '') self.completefolder_menu_item.setRepresentedObject_(sabnzbd.cfg.complete_dir.get_path()) self.menu.addItem_(self.completefolder_menu_item) #Incomplete Folder Item self.incompletefolder_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Incomplete Folder') + '\t\t', 'openFolderAction:', '') self.incompletefolder_menu_item.setRepresentedObject_(sabnzbd.cfg.download_dir.get_path()) self.menu.addItem_(self.incompletefolder_menu_item) if (debug == 1) : NSLog("[osx] menu 15 folder added") self.menu.addItem_(NSMenuItem.separatorItem()) #About Item (TO FIX) #menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('About SABnzbd', 'aboutAction:', '') #self.menu.addItem_(menu_item) # Set diagnostic menu self.diagnostic_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Troubleshoot'), '', '') self.menu_diagnostic = NSMenu.alloc().init() diag_items = ((T('Restart'), 'restartAction:'), (T('Restart') + ' - 127.0.0.1:8080', 'restartSafeHost:'), (T('Restart without login'), 'restartNoLogin:') ) for item in diag_items: menu_diag_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(item[0], item[1], '') menu_diag_item.setRepresentedObject_(item[0]) self.menu_diagnostic.addItem_(menu_diag_item) self.diagnostic_menu_item.setSubmenu_(self.menu_diagnostic) self.menu.addItem_(self.diagnostic_menu_item) if (debug == 1) : NSLog("[osx] menu 16 Diagnostic added") #Quit Item menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Quit'), 'terminate:', '') self.menu.addItem_(menu_item) if (debug == 1) : NSLog("[osx] menu 16 quit added") #Add menu to Status Item self.status_item.setMenu_(self.menu) if (debug == 1) : NSLog("[osx] menu 18 menu added") def updateAction_(self, notification): try: self.osx_icon = sabnzbd.cfg.osx_menu() if self.osx_icon: if self.status_removed == 1: self.buildMenu() if self.serverUpdate(): self.warningsUpdate() self.queueUpdate() self.historyUpdate() self.stateUpdate() self.iconUpdate() self.pauseUpdate() self.speedlimitUpdate() self.versionUpdate() self.newzbinUpdate() self.diskspaceUpdate() self.watchedUpdate() else: if self.status_removed == 0: status_bar = NSStatusBar.systemStatusBar() status_bar.removeStatusItem_(self.status_item) self.status_removed = 1 status_bar = None self.status_item = None except : logging.info("[osx] Exception %s" % (sys.exc_info()[0])) def queueUpdate(self): try: qnfo = NzbQueue.do.queue_info(max_jobs=10) pnfo_list = qnfo[QNFO_PNFO_LIST_FIELD] bytesleftprogess = 0 bpsnow = BPSMeter.do.get_bps() self.info = "" self.menu_queue = NSMenu.alloc().init() if len(pnfo_list): menu_queue_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Queue First 10 Items'), '', '') self.menu_queue.addItem_(menu_queue_item) self.menu_queue.addItem_(NSMenuItem.separatorItem()) for pnfo in pnfo_list: filename = unicoder(pnfo[PNFO_FILENAME_FIELD]) msgid = pnfo[PNFO_MSGID_FIELD] bytesleft = pnfo[PNFO_BYTES_LEFT_FIELD] / MEBI bytesleftprogess += pnfo[PNFO_BYTES_LEFT_FIELD] bytes = pnfo[PNFO_BYTES_FIELD] / MEBI nzo_id = pnfo[PNFO_NZO_ID_FIELD] timeleft = self.calc_timeleft(bytesleftprogess, bpsnow) job = "%s\t(%d/%d MB) %s" % (filename, bytesleft, bytes, timeleft) menu_queue_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(job, '', '') self.menu_queue.addItem_(menu_queue_item) self.info = "%d nzb(s)\t( %d / %d MB )" % (qnfo[QNFO_Q_SIZE_LIST_FIELD],(qnfo[QNFO_BYTES_LEFT_FIELD] / MEBI), (qnfo[QNFO_BYTES_FIELD] / MEBI)) else: menu_queue_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Empty'), '', '') self.menu_queue.addItem_(menu_queue_item) self.queue_menu_item.setSubmenu_(self.menu_queue) except : logging.info("[osx] queueUpdate Exception %s" % (sys.exc_info()[0])) def historyUpdate(self): try: # Fetch history items if not self.history_db: self.history_db = sabnzbd.database.get_history_handle() items, fetched_items, total_items = self.history_db.fetch_history(0,10,None) self.menu_history = NSMenu.alloc().init() self.failedAttributes = { NSForegroundColorAttributeName:NSColor.redColor(), NSFontAttributeName:NSFont.menuFontOfSize_(14.0) } menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('History Last 10 Items'), '', '') self.menu_history.addItem_(menu_history_item) self.menu_history.addItem_(NSMenuItem.separatorItem()) if fetched_items: for history in items: #logging.info("[osx] history : %s" % (history)) job = "%s" % (history['name']) path = "" if os.path.isdir(history['storage']) or os.path.isfile(history['storage']): if os.path.isfile(history['storage']): path = os.path.dirname(history['storage']) else: path = history['storage'] if path: menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(job, 'openFolderAction:', '') else: menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(job, '', '') if history['status'] != Status.COMPLETED: jobfailed = NSAttributedString.alloc().initWithString_attributes_(job, self.failedAttributes) menu_history_item.setAttributedTitle_(jobfailed) menu_history_item.setRepresentedObject_("%s" % (path)) self.menu_history.addItem_(menu_history_item) else: menu_history_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(T('Empty'), '', '') self.menu_history.addItem_(menu_history_item) self.history_menu_item.setSubmenu_(self.menu_history) except : logging.info("[osx] historyUpdate Exception %s" % (sys.exc_info()[0])) def warningsUpdate(self): try: warnings = sabnzbd.GUIHANDLER.count() if warnings: warningsAttributes = { NSForegroundColorAttributeName: NSColor.redColor(), NSFontAttributeName: NSFont.menuFontOfSize_(14.0) } warningsTitle = NSAttributedString.alloc().initWithString_attributes_( "%s : %s" % (T('Warnings'),warnings), warningsAttributes) self.warnings_menu_item.setAttributedTitle_(warningsTitle) if self.isLeopard: self.warnings_menu_item.setHidden_(NO) else: self.warnings_menu_item.setEnabled_(YES) else: self.warnings_menu_item.setTitle_("%s : 0" % (T('Warnings'))) if self.isLeopard: self.warnings_menu_item.setHidden_(YES) else: self.warnings_menu_item.setEnabled_(NO) except : logging.info("[osx] warningsUpdate Exception %s" % (sys.exc_info()[0])) def stateUpdate(self): try: paused, bytes_left, bpsnow, time_left = fast_queue() if paused: self.state = T('Paused') if sabnzbd.scheduler.pause_int() != "0": self.setMenuTitle("\n\n%s\n" % (sabnzbd.scheduler.pause_int())) else: self.setMenuTitle("") elif bytes_left > 0: self.state = "" speed = to_units(bpsnow, dec_limit=1) # "10.1 MB/s" doesn't fit, remove space char if 'M' in speed and len(speed) > 5: speed = speed.replace(' ', '') time_left = (bpsnow>10 and time_left) or "------" statusbarText = "\n\n%s\n%sB/s\n" % (time_left, speed) if sabnzbd.SABSTOP: statusbarText = "..." if not sabnzbd.cfg.osx_speed(): statusbarText = "" self.setMenuTitle(statusbarText) else: self.state = T('Idle') self.setMenuTitle("") if self.state != "" and self.info != "": self.state_menu_item.setTitle_("%s - %s" % (self.state,self.info)) if self.info == "": self.state_menu_item.setTitle_("%s" % (self.state)) else: self.state_menu_item.setTitle_("%s" % (self.info)) except : logging.info("[osx] stateUpdate Exception %s" % (sys.exc_info()[0])) def iconUpdate(self): try: if sabnzbd.downloader.Downloader.do.paused: self.status_item.setImage_(self.icons['pause']) else: self.status_item.setImage_(self.icons['idle']) except : logging.info("[osx] iconUpdate Exception %s" % (sys.exc_info()[0])) def pauseUpdate(self): try: if sabnzbd.downloader.Downloader.do.paused: if self.isLeopard: self.resume_menu_item.setHidden_(NO) self.pause_menu_item.setHidden_(YES) else: self.resume_menu_item.setEnabled_(YES) self.pause_menu_item.setEnabled_(NO) else: if self.isLeopard: self.resume_menu_item.setHidden_(YES) self.pause_menu_item.setHidden_(NO) else: self.resume_menu_item.setEnabled_(NO) self.pause_menu_item.setEnabled_(YES) except : logging.info("[osx] pauseUpdate Exception %s" % (sys.exc_info()[0])) def speedlimitUpdate(self): try: speed = int(sabnzbd.downloader.Downloader.do.get_limit()) if self.speed != speed : self.speed = speed speedsValues = self.menu_speed.numberOfItems() for i in range(speedsValues): menuitem = self.menu_speed.itemAtIndex_(i) if speed == int(menuitem.representedObject()): menuitem.setState_(NSOnState) else: menuitem.setState_(NSOffState) except : logging.info("[osx] speedlimitUpdate Exception %s" % (sys.exc_info()[0])) def versionUpdate(self): try: if sabnzbd.NEW_VERSION and self.version_notify: #logging.info("[osx] New Version : %s" % (sabnzbd.NEW_VERSION)) new_release, new_rel_url = sabnzbd.NEW_VERSION.split(';') growler.send_notification("SABnzbd","%s : %s" % (T('New release available'), new_release), 'other') self.version_notify = 0 except : logging.info("[osx] versionUpdate Exception %s" % (sys.exc_info()[0])) def watchedUpdate(self): try: if sabnzbd.cfg.dirscan_dir(): if self.isLeopard: self.watched_menu_item.setHidden_(NO) else: self.watched_menu_item.setEnabled_(YES) else: if self.isLeopard: self.watched_menu_item.setHidden_(YES) else: self.watched_menu_item.setEnabled_(NO) except : logging.info("[osx] watchedUpdate Exception %s" % (sys.exc_info()[0])) def newzbinUpdate(self): try: if sabnzbd.cfg.newzbin_username() and sabnzbd.cfg.newzbin_password(): if self.isLeopard: self.newzbin_menu_item.setHidden_(NO) else: self.newzbin_menu_item.setEnabled_(YES) else: if self.isLeopard: self.newzbin_menu_item.setHidden_(YES) else: self.newzbin_menu_item.setEnabled_(NO) except : logging.info("[osx] newzbinUpdate Exception %s" % (sys.exc_info()[0])) def serverUpdate(self): try: if not config.get_servers(): self.state_menu_item.setTitle_(T('Go to wizard')) hide=YES alternate=NO value=0 else: hide=NO alternate=YES value=1 if self.isLeopard: self.speed_menu_item.setHidden_(hide) self.resume_menu_item.setHidden_(hide) self.pause_menu_item.setHidden_(hide) self.newzbin_menu_item.setHidden_(hide) self.watched_menu_item.setHidden_(hide) self.purgequeue_menu_item.setAlternate_(alternate) self.purgequeue_menu_item.setHidden_(hide) self.queue_menu_item.setHidden_(hide) self.purgehistory_menu_item.setAlternate_(alternate) self.purgehistory_menu_item.setHidden_(hide) self.history_menu_item.setHidden_(hide) self.separator_menu_item.setHidden_(hide) self.separator2_menu_item.setHidden_(hide) self.completefolder_menu_item.setHidden_(hide) self.incompletefolder_menu_item.setHidden_(hide) else: self.speed_menu_item.setEnabled_(alternate) self.resume_menu_item.setEnabled_(alternate) self.pause_menu_item.setEnabled_(alternate) self.newzbin_menu_item.setEnabled_(alternate) self.watched_menu_item.setEnabled_(alternate) self.purgequeue_menu_item.setAlternate_(alternate) self.purgequeue_menu_item.setEnabled_(alternate) self.queue_menu_item.setEnabled_(alternate) self.purgehistory_menu_item.setAlternate_(alternate) self.purgehistory_menu_item.setEnabled_(alternate) self.history_menu_item.setEnabled_(alternate) self.separator_menu_item.setEnabled_(alternate) self.separator2_menu_item.setEnabled_(alternate) self.completefolder_menu_item.setEnabled_(alternate) self.incompletefolder_menu_item.setEnabled_(alternate) return value except : logging.info("[osx] configUpdate Exception %s" % (sys.exc_info()[0])) return 0 def diskspaceUpdate(self): try: self.completefolder_menu_item.setTitle_("%s%.2f GB" % (T('Complete Folder') + '\t\t\t',diskfree(sabnzbd.cfg.complete_dir.get_path()))) self.incompletefolder_menu_item.setTitle_("%s%.2f GB" % (T('Incomplete Folder') + '\t\t',diskfree(sabnzbd.cfg.download_dir.get_path()))) except: logging.info("[osx] diskspaceUpdate Exception %s" % (sys.exc_info()[0])) def setMenuTitle(self,text): try: style = NSMutableParagraphStyle.new() style.setParagraphStyle_(NSParagraphStyle.defaultParagraphStyle()) style.setAlignment_(NSCenterTextAlignment) style.setLineSpacing_(0.0) style.setMaximumLineHeight_(9.0) style.setParagraphSpacing_(-3.0) #Trying to change color of title to white when menu is open TO FIX if self.menu.highlightedItem(): #logging.info("Menu Clicked") titleColor = NSColor.highlightColor() else: #logging.info("Menu Not Clicked") titleColor = NSColor.blackColor() titleAttributes = { NSBaselineOffsetAttributeName : 5.0, NSFontAttributeName: NSFont.menuFontOfSize_(9.0), NSParagraphStyleAttributeName: style #,NSForegroundColorAttributeName: titleColor } title = NSAttributedString.alloc().initWithString_attributes_(text, titleAttributes) self.status_item.setAttributedTitle_(title) except : logging.info("[osx] setMenuTitle Exception %s" % (sys.exc_info()[0])) def calc_timeleft(self, bytesleft, bps): """ Calculate the time left in the format HH:MM:SS """ try: totalseconds = int(bytesleft / bps) minutes, seconds = divmod(totalseconds, 60) hours, minutes = divmod(minutes, 60) if minutes <10: minutes = '0%s' % minutes if seconds <10: seconds = '0%s' % seconds return '%s:%s:%s' % (hours, minutes, seconds) except: return '0:00:00' def openBrowserAction_(self, sender): if sender.representedObject: link = sender.representedObject() else: link = "" launch_a_browser(sabnzbd.BROWSER_URL, True) def speedlimitAction_(self, sender): #logging.info("[osx] speed limit to %s" % (sender.representedObject())) speed = int(sender.representedObject()) if speed != self.speed: sabnzbd.downloader.Downloader.do.limit_speed(speed) self.speedlimitUpdate() def purgeAction_(self, sender): mode = sender.representedObject() #logging.info("[osx] purge %s" % (mode)) if mode == "queue": NzbQueue.do.remove_all() elif mode == "history": if not self.history_db: self.history_db = sabnzbd.database.get_history_handle() self.history_db.remove_history() def pauseAction_(self, sender): minutes = int(sender.representedObject()) #logging.info("[osx] pause for %s" % (minutes)) if minutes: scheduler.plan_resume(minutes) else: sabnzbd.downloader.Downloader.do.pause() def resumeAction_(self, sender): scheduler.plan_resume(0) def getNewzbinBookmarksAction_(self, sender): Bookmarks.do.run(force=True) def watchedFolderAction_(self, sender): sabnzbd.dirscanner.dirscan() def openFolderAction_(self, sender): folder2open = sender.representedObject() if isinstance(folder2open, unicode): folder2open = folder2open.encode("utf-8") if (debug == 1) : NSLog("[osx] %@",folder2open ) os.system('open "%s"' % folder2open) # def aboutAction_(self, sender): # app = NSApplication.sharedApplication() # app.orderFrontStandardAboutPanel_(nil) def restartAction_(self, sender): self.setMenuTitle("\n\n%s\n"% (T('Stopping...'))) sabnzbd.halt() cherrypy.engine.restart() self.setMenuTitle("\n\n%s\n"% (T('Stopping...'))) def restartSafeHost_(self, sender): sabnzbd.cfg.cherryhost.set('127.0.0.1') sabnzbd.cfg.cherryport.set('8080') sabnzbd.cfg.https_port.set('8090') sabnzbd.cfg.enable_https.set(False) sabnzbd.config.save_config() self.setMenuTitle("\n\n%s\n"% (T('Stopping...'))) sabnzbd.halt() cherrypy.engine.restart() self.setMenuTitle("\n\n%s\n"% (T('Stopping...'))) def restartNoLogin_(self, sender): sabnzbd.cfg.username.set('') sabnzbd.cfg.password.set('') sabnzbd.config.save_config() self.setMenuTitle("\n\n%s\n"% (T('Stopping...'))) sabnzbd.halt() cherrypy.engine.restart() self.setMenuTitle("\n\n%s\n"% (T('Stopping...'))) def application_openFiles_(self, nsapp, filenames): #logging.info('[osx] file open') #logging.info('[osx] file : %s' % (filenames)) for name in filenames : logging.info('[osx] receiving from OSX : %s' % name) if os.path.exists(name): fn = get_filename(name) #logging.info('[osx] filename : %s' % (fn)) if fn: if get_ext(name) in ('.zip', '.rar'): #logging.info('[osx] archive') dirscanner.ProcessArchiveFile(fn, name, keep=True) elif get_ext(name) in ('.nzb', '.gz'): #logging.info('[osx] nzb') dirscanner.ProcessSingleFile(fn, name, keep=True) #logging.info('opening done') def applicationShouldTerminate_(self, sender): logging.info('[osx] application terminating') self.setMenuTitle("\n\n%s\n"% (T('Stopping...'))) self.status_item.setHighlightMode_(NO) self.osx_icon = False logging.info('[osx] application stopping daemon') sabnzbd.halt() cherrypy.engine.exit() sabnzbd.SABSTOP = True try: growler.send_notification('SABnzbd', T('SABnzbd shutdown finished'), growler.NOTIFICATION['other']) except AttributeError: # Fails for the OSX binary pass logging.info('Leaving SABnzbd') sys.stderr.flush() sys.stdout.flush() return NSTerminateNow #------------------------------------------------------------------------------ def notify(notificationName, message): """ Send a notification to the OS (OSX-only) """ if sabnzbd.FOUNDATION: pool = Foundation.NSAutoreleasePool.alloc().init() nc = Foundation.NSDistributedNotificationCenter.defaultCenter() nc.postNotificationName_object_(notificationName, message) del pool SABnzbd-0.7.20/sabnzbd/panic.py0000644000000000000000000002127712433712602016325 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.panic - Send panic message to the browser """ import os import logging import webbrowser import tempfile import sabnzbd import sabnzbd.cfg as cfg PANIC_NONE = 0 PANIC_PORT = 1 PANIC_TEMPL = 2 PANIC_QUEUE = 3 PANIC_FWALL = 4 PANIC_OTHER = 5 PANIC_XPORT = 6 PANIC_SQLITE = 7 PANIC_HOST = 8 def MSG_BAD_NEWS(): return r''' ''' + Ta('Problem with') + ''' %s %s

    %s %s

     

    %s

    %s
    ''' def MSG_BAD_FWALL(): return Ta(r''' SABnzbd is not compatible with some software firewalls.
    %s
    Sorry, but we cannot solve this incompatibility right now.
    Please file a complaint at your firewall supplier.

    ''') def MSG_BAD_PORT(): return Ta(r''' SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but it is not available.
    Some other software uses the port or SABnzbd is already running.

    Please restart SABnzbd with a different port number.''') + \ '''

    %s
        %s --server %s:%s

    ''' + \ Ta(r'If you get this error message again, please try a different number.
    ') def MSG_ILL_PORT(): return Ta(r''' SABnzbd needs a free tcp/ip port for its internal web server.
    Port %s on %s was tried , but the account used for SABnzbd has no permission to use it.
    On OSX and Linux systems, normal users must use ports above 1023.

    Please restart SABnzbd with a different port number.''') + \ '''

    %s
        %s --server %s:%s

    ''' + \ Ta(r'If you get this error message again, please try a different number.
    ') def MSG_BAD_HOST(): return Ta(r''' SABnzbd needs a valid host address for its internal web server.
    You have specified an invalid address.
    Safe values are localhost and 0.0.0.0

    Please restart SABnzbd with a proper host address.''') + \ '''

    %s
        %s --server %s:%s

    ''' def MSG_BAD_QUEUE(): return Ta(r''' SABnzbd detected saved data from an other SABnzbd version
    but cannot re-use the data of the other program.

    You may want to finish your queue first with the other program.

    After that, start this program with the "--clean" option.
    This will erase the current queue and history!
    SABnzbd read the file "%s".''') + \ '''

    %s
        %s --clean

    ''' def MSG_BAD_TEMPL(): return Ta(r''' SABnzbd cannot find its web interface files in %s.
    Please install the program again.

    ''') def MSG_OTHER(): return Ta('SABnzbd detected a fatal error:') + '
    %s

    %s
    ' def MSG_OLD_QUEUE(): return Ta(r''' SABnzbd detected a Queue and History from an older (0.4.x) release.

    Both queue and history will be ignored and may get lost!

    You may choose to stop SABnzbd and finish the queue with the older program.

    Click OK to proceed to SABnzbd''') + \ ('''

    ''' % Ta('OK')) def MSG_SQLITE(): return Ta(r''' SABnzbd detected that the file sqlite3.dll is missing.

    Some poorly designed virus-scanners remove this file.
    Please check your virus-scanner, try to re-install SABnzbd and complain to your virus-scanner vendor.

    ''') def panic_message(panic, a=None, b=None): """Create the panic message from templates """ if sabnzbd.WIN32: os_str = Ta('Press Startkey+R and type the line (example):') prog_path = '"%s"' % sabnzbd.MY_FULLNAME else: os_str = Ta('Open a Terminal window and type the line (example):') prog_path = sabnzbd.MY_FULLNAME if panic == PANIC_PORT: newport = int(b) + 1 newport = "%s" % newport msg = MSG_BAD_PORT() % (b, a, os_str, prog_path, a, newport) elif panic == PANIC_XPORT: if int(b) < 1023: newport = 1024 else: newport = int(b) + 1 newport = "%s" % newport msg = MSG_ILL_PORT() % (b, a, os_str, prog_path, a, newport) elif panic == PANIC_TEMPL: msg = MSG_BAD_TEMPL() % a elif panic == PANIC_QUEUE: msg = MSG_BAD_QUEUE() % (a, os_str, prog_path) elif panic == PANIC_FWALL: if a: msg = MSG_BAD_FWALL() % Ta('It is likely that you are using ZoneAlarm on Vista.
    ') else: msg = MSG_BAD_FWALL() % "
    " elif panic == PANIC_SQLITE: msg = MSG_SQLITE() elif panic == PANIC_HOST: msg = MSG_BAD_HOST() % (os_str, prog_path, 'localhost', b) else: msg = MSG_OTHER() % (a, b) msg = MSG_BAD_NEWS() % (sabnzbd.MY_NAME, sabnzbd.__version__, sabnzbd.MY_NAME, sabnzbd.__version__, msg, Ta('Program did not start!')) if sabnzbd.WIN_SERVICE: sabnzbd.WIN_SERVICE.ErrLogger('Panic exit', msg) if (not cfg.autobrowser()) or sabnzbd.DAEMON: return msgfile, url = tempfile.mkstemp(suffix='.html') os.write(msgfile, msg) os.close(msgfile) return url def panic_fwall(vista): launch_a_browser(panic_message(PANIC_FWALL, vista)) def panic_port(host, port): launch_a_browser(panic_message(PANIC_PORT, host, port)) def panic_host(host, port): launch_a_browser(panic_message(PANIC_HOST, host, port)) def panic_xport(host, port): launch_a_browser(panic_message(PANIC_XPORT, host, port)) logging.error(Ta('You have no permisson to use port %s'), port) def panic_queue(name): launch_a_browser(panic_message(PANIC_QUEUE, name, 0)) def panic_tmpl(name): launch_a_browser(panic_message(PANIC_TEMPL, name, 0)) def panic_sqlite(name): launch_a_browser(panic_message(PANIC_SQLITE, name, 0)) def panic_old_queue(): msg = MSG_OLD_QUEUE() return MSG_BAD_NEWS() % (sabnzbd.MY_NAME, sabnzbd.__version__, sabnzbd.MY_NAME, sabnzbd.__version__, msg, '') def panic(reason, remedy=""): print "\n%s:\n %s\n%s" % (Ta('Fatal error'), reason, remedy) launch_a_browser(panic_message(PANIC_OTHER, reason, remedy)) def launch_a_browser(url, force=False): """Launch a browser pointing to the URL """ if not force and not cfg.autobrowser() or sabnzbd.DAEMON: return if '::1' in url and not '[::1]' in url: # Get around ideosyncrasy in Python runtime url = url.replace('::1', '[::1]') if cfg.enable_https() and not cfg.https_port.get_int(): # Must use https, because http is not available url = url.replace('http:', 'https:') logging.info("Lauching browser with %s", url) try: if url and not url.startswith('http'): url = 'file:///%s' % url webbrowser.open(url, 2, 1) except: logging.warning(Ta('Cannot launch the browser, probably not found')) logging.info("Traceback: ", exc_info = True) def error_page_401(status, message, traceback, version): """ Custom handler for 401 error """ title = T('Access denied') body = T('Error %s: You need to provide a valid username and password.') % status return r''' %s

    %s ''' % (title, body) def error_page_404(status, message, traceback, version): """ Custom handler for 404 error, redirect to main page """ import cherrypy return r'''
    ''' % cherrypy.wsgiserver.REDIRECT_URL SABnzbd-0.7.20/sabnzbd/postproc.py0000644000000000000000000007764112433712602017112 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.postproc - threaded post-processing of jobs """ #------------------------------------------------------------------------------ import os import Queue import logging import sabnzbd import urllib import time import re from sabnzbd.newsunpack import unpack_magic, par2_repair, external_processing, sfv_check from threading import Thread from sabnzbd.misc import real_path, get_unique_path, create_dirs, move_to_path, \ make_script_path, sanitize_and_trim_path, \ on_cleanup_list, renamer, remove_dir, remove_all, globber, \ set_permissions, cleanup_empty_directories from sabnzbd.tvsort import Sorter from sabnzbd.constants import REPAIR_PRIORITY, TOP_PRIORITY, POSTPROC_QUEUE_FILE_NAME, \ POSTPROC_QUEUE_VERSION, sample_match, JOB_ADMIN, Status, VERIFIED_FILE from sabnzbd.encoding import TRANS, unicoder from sabnzbd.newzbin import Bookmarks from sabnzbd.rating import Rating import sabnzbd.emailer as emailer import sabnzbd.dirscanner as dirscanner import sabnzbd.downloader import sabnzbd.config as config import sabnzbd.cfg as cfg import sabnzbd.nzbqueue import sabnzbd.database as database import sabnzbd.growler as growler #------------------------------------------------------------------------------ class PostProcessor(Thread): """ PostProcessor thread, designed as Singleton """ do = None # Link to instance of the thread def __init__ (self, queue=None, history_queue=None): """ Initialize, optionally passing existing queue """ Thread.__init__(self) # This history queue is simply used to log what active items to display in the web_ui if history_queue: self.history_queue = history_queue else: self.load() if self.history_queue is None: self.history_queue = [] if queue: self.queue = queue else: self.queue = Queue.Queue() for nzo in self.history_queue: self.process(nzo) self.__stop = False self.paused = False PostProcessor.do = self self.__busy = False # True while a job is being processed def save(self): """ Save postproc queue """ logging.info("Saving postproc queue") sabnzbd.save_admin((POSTPROC_QUEUE_VERSION, self.history_queue), POSTPROC_QUEUE_FILE_NAME) def load(self): """ Save postproc queue """ self.history_queue = [] logging.info("Loading postproc queue") data = sabnzbd.load_admin(POSTPROC_QUEUE_FILE_NAME) if data is None: return try: version, history_queue = data if POSTPROC_QUEUE_VERSION != version: logging.warning(Ta('Failed to load postprocessing queue: Wrong version (need:%s, found:%s)'), POSTPROC_QUEUE_VERSION, version) if isinstance(history_queue, list): self.history_queue = [nzo for nzo in history_queue if os.path.exists(nzo.downpath)] except: logging.info('Corrupt %s file, discarding', POSTPROC_QUEUE_FILE_NAME) logging.info("Traceback: ", exc_info = True) def delete(self, nzo_id, del_files=False): """ Remove a job from the post processor queue """ for nzo in self.history_queue: if nzo.nzo_id == nzo_id: self.remove(nzo) nzo.purge_data(keep_basic=True, del_files=del_files) logging.info('Removed job %s from postproc queue', nzo.work_name) nzo.work_name = '' # Mark as deleted job break def process(self, nzo): """ Push on finished job in the queue """ if nzo not in self.history_queue: self.history_queue.append(nzo) self.queue.put(nzo) self.save() def remove(self, nzo): """ Remove given nzo from the queue """ try: self.history_queue.remove(nzo) except: nzo_id = getattr(nzo, 'nzo_id', 'unknown id') logging.error(Ta('Failed to remove nzo from postproc queue (id)') + ' ' + nzo_id) logging.info('Traceback: ', exc_info = True) self.save() def stop(self): """ Stop thread after finishing running job """ self.__stop = True self.queue.put(None) self.save() def empty(self): """ Return True if pp queue is empty """ return self.queue.empty() and not self.__busy def get_queue(self): """ Return list of NZOs that still need to be processed """ return [nzo for nzo in self.history_queue if nzo.work_name] def get_path(self, nzo_id): """ Return download path for given nzo_id or None when not found """ for nzo in self.history_queue: if nzo.nzo_id == nzo_id: return nzo.downpath return None def run(self): """ Actual processing """ check_eoq = False while not self.__stop: self.__busy = False if self.paused: time.sleep(5) continue try: nzo = self.queue.get(timeout=1) except Queue.Empty: if check_eoq: check_eoq = False handle_empty_queue() continue else: nzo = self.queue.get() ## Stop job if not nzo: continue ## Job was already deleted. if not nzo.work_name: check_eoq = True continue ## Flag NZO as being processed nzo.pp_active = True ## Pause downloader, if users wants that if cfg.pause_on_post_processing(): sabnzbd.downloader.Downloader.do.wait_for_postproc() self.__busy = True process_job(nzo) self.remove(nzo) check_eoq = True ## Allow download to proceed sabnzbd.downloader.Downloader.do.resume_from_postproc() #end PostProcessor class #------------------------------------------------------------------------------ def process_job(nzo): """ Process one job """ assert isinstance(nzo, sabnzbd.nzbstuff.NzbObject) start = time.time() # keep track of whether we can continue all_ok = True # keep track of par problems par_error = False # keep track of any unpacking errors unpack_error = False # Signal empty download, for when 'empty_postproc' is enabled empty = False nzb_list = [] # These need to be initialised incase of a crash workdir_complete = '' postproc_time = 0 script_log = '' script_line = '' crash_msg = '' ## Get the job flags nzo.save_attribs() flag_repair, flag_unpack, flag_delete = nzo.repair_opts # Normalize PP if flag_delete: flag_unpack = True if flag_unpack: flag_repair = True # Get the NZB name filename = nzo.final_name msgid = nzo.msgid if cfg.allow_streaming() and not (flag_repair or flag_unpack or flag_delete): # After streaming, force +D nzo.set_pp(3) nzo.status = Status.FAILED nzo.save_attribs() all_ok = False if nzo.fail_msg: # Special case: aborted due to too many missing data nzo.status = Status.FAILED nzo.save_attribs() all_ok = False par_error = True unpack_error = 1 try: # Get the folder containing the download result workdir = nzo.downpath tmp_workdir_complete = None # if no files are present (except __admin__), fail the job if all_ok and len(globber(workdir)) < 2: if nzo.precheck: enough, ratio = nzo.check_quality() req_ratio = float(cfg.req_completion_rate()) / 100.0 # Make sure that rounded ratio doesn't equal required ratio # when it is actually below required if (ratio < req_ratio) and (req_ratio - ratio) < 0.001: ratio = req_ratio - 0.001 emsg = '%.1f%%' % (ratio * 100.0) emsg2 = '%.1f%%' % float(cfg.req_completion_rate()) emsg = T('Download might fail, only %s of required %s available') % (emsg, emsg2) else: emsg = T('Download failed - Out of your server\'s retention?') empty = True nzo.fail_msg = emsg nzo.set_unpack_info('Fail', emsg) nzo.status = Status.FAILED # do not run unpacking or parity verification flag_repair = flag_unpack = False all_ok = cfg.empty_postproc() and empty if not all_ok: par_error = True unpack_error = 1 script = nzo.script cat = nzo.cat logging.info('Starting PostProcessing on %s' + \ ' => Repair:%s, Unpack:%s, Delete:%s, Script:%s, Cat:%s', filename, flag_repair, flag_unpack, flag_delete, script, cat) ## Par processing, if enabled if all_ok and flag_repair: par_error, re_add = parring(nzo, workdir) if re_add: # Try to get more par files return False ## Check if user allows unsafe post-processing if flag_repair and cfg.safe_postproc(): all_ok = all_ok and not par_error # Set complete dir to workdir in case we need to abort workdir_complete = workdir dirname = nzo.final_name marker_file = None if all_ok: one_folder = False ## Determine class directory if cfg.create_group_folders(): complete_dir = addPrefixes(cfg.complete_dir.get_path(), nzo.dirprefix) complete_dir = create_dirs(complete_dir) else: catdir = config.get_categories(cat).dir() if catdir.endswith('*'): catdir = catdir.strip('*') one_folder = True complete_dir = real_path(cfg.complete_dir.get_path(), catdir) ## TV/Movie/Date Renaming code part 1 - detect and construct paths if cfg.enable_meta(): file_sorter = Sorter(nzo, cat) else: file_sorter = Sorter(None, cat) complete_dir = file_sorter.detect(dirname, complete_dir) if file_sorter.sort_file: one_folder = False complete_dir = sanitize_and_trim_path(complete_dir) if one_folder: workdir_complete = create_dirs(complete_dir) else: workdir_complete = get_unique_path(os.path.join(complete_dir, dirname), create_dir=True) marker_file = set_marker(workdir_complete) if not workdir_complete or not os.path.exists(workdir_complete): crash_msg = T('Cannot create final folder %s') % unicoder(os.path.join(complete_dir, dirname)) raise IOError if cfg.folder_rename() and not one_folder: tmp_workdir_complete = prefix(workdir_complete, '_UNPACK_') try: renamer(workdir_complete, tmp_workdir_complete) except: pass # On failure, just use the original name else: tmp_workdir_complete = workdir_complete newfiles = [] ## Run Stage 2: Unpack if flag_unpack: if all_ok: #set the current nzo status to "Extracting...". Used in History nzo.status = Status.EXTRACTING logging.info("Running unpack_magic on %s", filename) unpack_error, newfiles = unpack_magic(nzo, workdir, tmp_workdir_complete, flag_delete, one_folder, (), (), (), ()) logging.info("unpack_magic finished on %s", filename) else: nzo.set_unpack_info('Unpack', T('No post-processing because of failed verification')) if cfg.safe_postproc(): all_ok = all_ok and not unpack_error if all_ok: ## Move any (left-over) files to destination nzo.status = Status.MOVING nzo.set_action_line(T('Moving'), '...') for root, dirs, files in os.walk(workdir): if not root.endswith(JOB_ADMIN): for file_ in files: path = os.path.join(root, file_) new_path = path.replace(workdir, tmp_workdir_complete) ok, new_path = move_to_path(path, new_path) newfiles.append(new_path) if not ok: nzo.set_unpack_info('Unpack', T('Failed moving %s to %s') % (unicoder(path), unicoder(new_path))) all_ok = False break ## Set permissions right set_permissions(tmp_workdir_complete) if all_ok and marker_file: del_marker(os.path.join(tmp_workdir_complete, marker_file)) remove_from_list(marker_file, newfiles) if all_ok: ## Remove files matching the cleanup list cleanup_list(tmp_workdir_complete, True) ## Check if this is an NZB-only download, if so redirect to queue ## except when PP was Download-only if flag_repair: nzb_list = nzb_redirect(tmp_workdir_complete, nzo.final_name, nzo.pp, script, cat, priority=nzo.priority) else: nzb_list = None if nzb_list: nzo.set_unpack_info('Download', T('Sent %s to queue') % unicoder(nzb_list)) cleanup_empty_directories(tmp_workdir_complete) else: cleanup_list(tmp_workdir_complete, False) script_output = '' script_ret = 0 if not nzb_list: ## Give destination its final name if cfg.folder_rename() and tmp_workdir_complete and not one_folder: if all_ok: try: newfiles = rename_and_collapse_folder(tmp_workdir_complete, workdir_complete, newfiles) except: logging.error(Ta('Error renaming "%s" to "%s"'), tmp_workdir_complete, workdir_complete) logging.info('Traceback: ', exc_info = True) # Better disable sorting because filenames are all off now file_sorter.sort_file = None else: workdir_complete = tmp_workdir_complete.replace('_UNPACK_', '_FAILED_') workdir_complete = get_unique_path(workdir_complete, n=0, create_dir=False) if empty: job_result = -1 else: job_result = int(par_error) + int(bool(unpack_error))*2 if cfg.ignore_samples() > 0: remove_samples(workdir_complete) ## TV/Movie/Date Renaming code part 2 - rename and move files to parent folder if all_ok and file_sorter.sort_file: if newfiles: file_sorter.rename(newfiles, workdir_complete) workdir_complete, ok = file_sorter.move(workdir_complete) else: workdir_complete, ok = file_sorter.rename_with_ext(workdir_complete) if not ok: nzo.set_unpack_info('Unpack', T('Failed to move files')) all_ok = False ## Run the user script script_path = make_script_path(script) if (all_ok or not cfg.safe_postproc()) and (not nzb_list) and script_path: #set the current nzo status to "Ext Script...". Used in History nzo.status = Status.RUNNING nzo.set_action_line(T('Running script'), unicoder(script)) nzo.set_unpack_info('Script', T('Running user script %s') % unicoder(script), unique=True) script_log, script_ret = external_processing(script_path, workdir_complete, nzo.filename, msgid, dirname, cat, nzo.group, job_result, nzo.nzo_info.get('failure', '')) script_line = get_last_line(script_log) if script_log: script_output = nzo.nzo_id if script_line: nzo.set_unpack_info('Script', unicoder(script_line), unique=True) else: nzo.set_unpack_info('Script', T('Ran %s') % unicoder(script), unique=True) else: script = "" script_line = "" script_ret = 0 ## Email the results if (not nzb_list) and cfg.email_endjob(): if (cfg.email_endjob() == 1) or (cfg.email_endjob() == 2 and (unpack_error or par_error)): emailer.endjob(dirname, msgid, cat, all_ok, workdir_complete, nzo.bytes_downloaded, nzo.fail_msg, nzo.unpack_info, script, TRANS(script_log), script_ret) if script_output: # Can do this only now, otherwise it would show up in the email if script_ret: script_ret = 'Exit(%s) ' % script_ret else: script_ret = '' if script_line: nzo.set_unpack_info('Script', u'%s%s (%s)' % (script_ret, unicoder(script_line), urllib.quote(script_output), T('More')), unique=True) else: nzo.set_unpack_info('Script', u'%s%s' % (script_ret, urllib.quote(script_output), T('View script output')), unique=True) ## Cleanup again, including NZB files if all_ok: cleanup_list(workdir_complete, False) ## Remove newzbin bookmark, if any if msgid and all_ok: Bookmarks.do.del_bookmark(msgid) elif all_ok and isinstance(nzo.url, str): sabnzbd.proxy_rm_bookmark(nzo.url) ## Force error for empty result all_ok = all_ok and not empty ## Update indexer with results if cfg.rating_enable(): if nzo.encrypted > 0: Rating.do.update_auto_flag(nzo.nzo_id, Rating.FLAG_ENCRYPTED) if empty: hosts = map(lambda s: s.host, sabnzbd.downloader.Downloader.do.nzo_servers(nzo)) if not hosts: hosts = [None] for host in hosts: Rating.do.update_auto_flag(nzo.nzo_id, Rating.FLAG_EXPIRED, host) ## Show final status in history if all_ok: growler.send_notification(T('Download Completed'), filename, 'complete') nzo.status = Status.COMPLETED else: growler.send_notification(T('Download Failed'), filename, 'complete') nzo.status = Status.FAILED except: logging.error(Ta('Post Processing Failed for %s (%s)'), filename, crash_msg) if not crash_msg: logging.info("Traceback: ", exc_info = True) crash_msg = T('see logfile') nzo.fail_msg = T('PostProcessing was aborted (%s)') % unicoder(crash_msg) growler.send_notification(T('Download Failed'), filename, 'complete') nzo.status = Status.FAILED par_error = True all_ok = False if cfg.email_endjob(): emailer.endjob(dirname, msgid, cat, all_ok, workdir_complete, nzo.bytes_downloaded, nzo.fail_msg, nzo.unpack_info, '', '', 0) if all_ok: # If the folder only contains one file OR folder, have that as the path # Be aware that series/generic/date sorting may move a single file into a folder containing other files workdir_complete = one_file_or_folder(workdir_complete) workdir_complete = os.path.normpath(workdir_complete) # Log the overall time taken for postprocessing postproc_time = int(time.time() - start) # Create the history DB instance history_db = database.get_history_handle() # Add the nzo to the database. Only the path, script and time taken is passed # Other information is obtained from the nzo history_db.add_history_db(nzo, workdir_complete, nzo.downpath, postproc_time, script_log, script_line) # The connection is only used once, so close it here history_db.close() ## Clean up the NZO try: logging.info('Cleaning up %s (keep_basic=%s)', filename, str(not all_ok)) sabnzbd.nzbqueue.NzbQueue.do.cleanup_nzo(nzo, keep_basic=not all_ok) except: logging.error(Ta('Cleanup of %s failed.'), nzo.final_name) logging.info("Traceback: ", exc_info = True) ## Remove download folder if all_ok: try: if os.path.exists(workdir): logging.debug('Removing workdir %s', workdir) remove_all(workdir, recursive=True) except: logging.error(Ta('Error removing workdir (%s)'), workdir) logging.info("Traceback: ", exc_info = True) # Use automatic retry link on par2 errors and encrypted/bad RARs if par_error or unpack_error in (2, 3): try_alt_nzb(nzo) return True #------------------------------------------------------------------------------ def parring(nzo, workdir): """ Perform par processing. Returns: (par_error, re_add) """ assert isinstance(nzo, sabnzbd.nzbstuff.NzbObject) filename = nzo.final_name growler.send_notification(T('Post-processing'), nzo.final_name, 'pp') logging.info('Par2 check starting on %s', filename) ## Get verification status of sets verified = sabnzbd.load_data(VERIFIED_FILE, nzo.workpath, remove=False) or {} ## Collect the par files if nzo.partable: par_table = nzo.partable.copy() else: par_table = {} repair_sets = par_table.keys() re_add = False par_error = False single = len(repair_sets) == 1 if repair_sets: for setname in repair_sets: if cfg.ignore_samples() > 0 and 'sample' in setname.lower(): continue if not verified.get(setname, False): logging.info("Running repair on set %s", setname) parfile_nzf = par_table[setname] if os.path.exists(os.path.join(nzo.downpath, parfile_nzf.filename)) or parfile_nzf.extrapars: need_re_add, res = par2_repair(parfile_nzf, nzo, workdir, setname, single=single) re_add = re_add or need_re_add if not res and not need_re_add and cfg.sfv_check(): res = try_sfv_check(nzo, workdir, setname) verified[setname] = res else: continue par_error = par_error or not res else: logging.info("No par2 sets for %s", filename) nzo.set_unpack_info('Repair', T('[%s] No par2 sets') % unicoder(filename)) if cfg.sfv_check(): par_error = not try_sfv_check(nzo, workdir, '') verified[''] = not par_error if re_add: logging.info('Readded %s to queue', filename) if nzo.priority != TOP_PRIORITY: nzo.priority = REPAIR_PRIORITY sabnzbd.nzbqueue.add_nzo(nzo) sabnzbd.downloader.Downloader.do.resume_from_postproc() sabnzbd.save_data(verified, VERIFIED_FILE, nzo.workpath) logging.info('Par2 check finished on %s', filename) return par_error, re_add def try_sfv_check(nzo, workdir, setname): """ Attempt to verify set using SFV file Return True if verified, False when failed When setname is '', all SFV files will be used, otherwise only the matching one When setname is '' and no SFV files are found, True is returned """ # Get list of SFV names; shortest name first, minimizes the chance on a mismatch sfvs = globber(workdir, '*.sfv') sfvs.sort(lambda x, y: len(x) - len(y)) par_error = False found = False for sfv in sfvs: if setname.lower() in os.path.basename(sfv).lower(): found = True nzo.set_unpack_info('Repair', T('Trying SFV verification')) failed = sfv_check(sfv) if failed: msg = T('Some files failed to verify against "%s"') % unicoder(os.path.basename(sfv)) msg += '; ' msg += '; '.join(failed) nzo.set_unpack_info('Repair', msg) par_error = True else: nzo.set_unpack_info('Repair', T('Verified successfully using SFV files')) if setname: break return (found or not setname) and not par_error #------------------------------------------------------------------------------ def addPrefixes(path, dirprefix): """ Add list of prefixes as sub folders to path '/my/path' and ['a', 'b', 'c'] will give '/my/path/a/b/c' """ for folder in dirprefix: if not folder: continue if not path: break basepath = os.path.basename(os.path.abspath(path)) if folder != basepath.lower(): path = os.path.join(path, folder) return path def handle_empty_queue(): """ Check if empty queue calls for action """ if sabnzbd.nzbqueue.NzbQueue.do.actives() == 0: sabnzbd.save_state() logging.info("Queue has finished, launching: %s (%s)", \ sabnzbd.QUEUECOMPLETEACTION, sabnzbd.QUEUECOMPLETEARG) if sabnzbd.QUEUECOMPLETEARG: sabnzbd.QUEUECOMPLETEACTION(sabnzbd.QUEUECOMPLETEARG) else: Thread(target=sabnzbd.QUEUECOMPLETEACTION).start() sabnzbd.change_queue_complete_action(cfg.queue_complete(), new=False) def cleanup_list(wdir, skip_nzb): """ Remove all files whose extension matches the cleanup list, optionally ignoring the nzb extension """ if cfg.cleanup_list(): try: files = os.listdir(wdir) except: files = () for file in files: path = os.path.join(wdir, file) if os.path.isdir(path): cleanup_list(path, skip_nzb) else: if on_cleanup_list(file, skip_nzb): try: logging.info("Removing unwanted file %s", path) os.remove(path) except: logging.error(Ta('Removing %s failed'), path) logging.info("Traceback: ", exc_info = True) if files: try: remove_dir(wdir) except: pass def prefix(path, pre): """ Apply prefix to last part of path '/my/path' and 'hi_' will give '/my/hi_path' """ p, d = os.path.split(path) return os.path.join(p, pre + d) def nzb_redirect(wdir, nzbname, pp, script, cat, priority): """ Check if this job contains only NZB files, if so send to queue and remove if on CleanList Returns list of processed NZB's """ files = [] for root, dirs, names in os.walk(wdir): for name in names: files.append(os.path.join(root, name)) for file_ in files: if os.path.splitext(file_)[1].lower() != '.nzb': return None # For multiple NZBs, cannot use the current job name if len(files) != 1: nzbname = None # Process all NZB files for file_ in files: dirscanner.ProcessSingleFile(os.path.split(file_)[1], file_, pp, script, cat, priority=priority, keep=False, dup_check=False, nzbname=nzbname) return files def one_file_or_folder(folder): """ If the dir only contains one file or folder, join that file/folder onto the path """ if os.path.exists(folder) and os.path.isdir(folder): cont = os.listdir(folder) if len(cont) == 1: folder = os.path.join(folder, cont[0]) folder = one_file_or_folder(folder) return folder def get_last_line(txt): """ Return last non-empty line of a text, trim to 150 max """ lines = txt.split('\n') n = len(lines) - 1 while n >= 0 and not lines[n].strip('\r\t '): n = n - 1 line = lines[n].strip('\r\t ') if len(line) >= 150: line = line[:147] + '...' return line def remove_samples(path): """ Remove all files that match the sample pattern """ RE_SAMPLE = re.compile(sample_match, re.I) for root, dirs, files in os.walk(path): for file_ in files: if RE_SAMPLE.search(file_): path = os.path.join(root, file_) try: logging.info("Removing unwanted sample file %s", path) os.remove(path) except: logging.error(Ta('Removing %s failed'), path) logging.info("Traceback: ", exc_info = True) #------------------------------------------------------------------------------ def rename_and_collapse_folder(oldpath, newpath, files): """ Rename folder, collapsing when there's just a single subfolder oldpath --> newpath OR oldpath/subfolder --> newpath Modify list of filenames accordingly """ orgpath = oldpath items = globber(oldpath) if len(items) == 1: folder_path = items[0] folder = os.path.split(folder_path)[1] if os.path.isdir(folder_path) and folder not in ('VIDEO_TS', 'AUDIO_TS'): logging.info('Collapsing %s', os.path.join(newpath, folder)) oldpath = folder_path oldpath = os.path.normpath(oldpath) newpath = os.path.normpath(newpath) files = [os.path.normpath(f).replace(oldpath, newpath) for f in files] renamer(oldpath, newpath) try: remove_dir(orgpath) except: pass return files #------------------------------------------------------------------------------ def set_marker(folder): """ Set marker file and return name """ name = cfg.marker_file() if name: path = os.path.join(folder, name) logging.debug('Create marker file %s', path) try: fp = open(path, 'w') fp.close() except: logging.info('Cannot create marker file %s', path) logging.info("Traceback: ", exc_info = True) name = None return name def del_marker(path): """ Remove marker file """ if path and os.path.exists(path): logging.debug('Removing marker file %s', path) try: os.remove(path) except: logging.info('Cannot remove marker file %s', path) logging.info("Traceback: ", exc_info = True) def remove_from_list(name, lst): if name: for n in xrange(len(lst)): if lst[n].endswith(name): logging.debug('Popping %s', lst[n]) lst.pop(n) return def try_alt_nzb(nzo): """ Try to get a new NZB if available """ url = nzo.nzo_info.get('failure') if url and cfg.new_nzb_on_failure(): sabnzbd.add_url(url, nzo.pp, nzo.script, nzo.cat, nzo.priority) SABnzbd-0.7.20/sabnzbd/powersup.py0000644000000000000000000001702712433712602017115 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.powersup - System power management support """ import os import subprocess import logging import time from sabnzbd.encoding import latin1 #------------------------------------------------------------------------------ # Power management for Windows def win_hibernate(): """ Hibernate Windows system, returns after wakeup """ try: subprocess.Popen("rundll32 powrprof.dll,SetSuspendState Hibernate") time.sleep(10) except: logging.error(Ta('Failed to hibernate system')) logging.info("Traceback: ", exc_info = True) def win_standby(): """ Standby Windows system, returns after wakeup """ try: subprocess.Popen("rundll32 powrprof.dll,SetSuspendState Standby") time.sleep(10) except: logging.error(Ta('Failed to standby system')) logging.info("Traceback: ", exc_info = True) def win_shutdown(): """ Shutdown Windows system, never returns """ try: import win32security import win32api import ntsecuritycon flags = ntsecuritycon.TOKEN_ADJUST_PRIVILEGES | ntsecuritycon.TOKEN_QUERY htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags) id_ = win32security.LookupPrivilegeValue(None, ntsecuritycon.SE_SHUTDOWN_NAME) newPrivileges = [(id_, ntsecuritycon.SE_PRIVILEGE_ENABLED)] win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges) win32api.InitiateSystemShutdown("", "", 30, 1, 0) finally: os._exit(0) #------------------------------------------------------------------------------ # Power management for OSX def osx_shutdown(): """ Shutdown OSX system, never returns """ try: subprocess.call(['osascript', '-e', 'tell app "System Events" to shut down']) except: logging.error(Ta('Error while shutting down system')) logging.info("Traceback: ", exc_info = True) os._exit(0) def osx_standby(): """ Make OSX system sleep, returns after wakeup """ try: subprocess.call(['osascript', '-e','tell app "System Events" to sleep']) time.sleep(10) except: logging.error(Ta('Failed to standby system')) logging.info("Traceback: ", exc_info = True) def osx_hibernate(): """ Make OSX system sleep, returns after wakeup """ osx_standby() #------------------------------------------------------------------------------ # Power management for linux. # # Requires DBus plus either HAL [1] or the more modern ConsoleKit [2] and # DeviceKit(-power) [3]. HAL will eventually be deprecated but older systems # might still use it. # [1] http://people.freedesktop.org/~hughsient/temp/dbus-interface.html # [2] http://www.freedesktop.org/software/ConsoleKit/doc/ConsoleKit.html # [3] http://hal.freedesktop.org/docs/DeviceKit-power/ # # Original code was contributed by Marcel de Vries # try: import dbus HAVE_DBUS = True except ImportError: HAVE_DBUS = False def _get_sessionproxy(): """ Return (proxy-object, interface), (None, None) if not available """ name = 'org.freedesktop.PowerManagement' path = '/org/freedesktop/PowerManagement' interface = 'org.freedesktop.PowerManagement' try: bus = dbus.SessionBus() return bus.get_object(name, path), interface except dbus.exceptions.DBusException: return None, None def _get_systemproxy(method): """ Return (proxy-object, interface, pinterface), (None, None, None) if not available """ if method == 'ConsoleKit': name = 'org.freedesktop.ConsoleKit' path = '/org/freedesktop/ConsoleKit/Manager' interface = 'org.freedesktop.ConsoleKit.Manager' pinterface = None elif method == 'DeviceKit': name = 'org.freedesktop.DeviceKit.Power' path = '/org/freedesktop/DeviceKit/Power' interface = 'org.freedesktop.DeviceKit.Power' pinterface = 'org.freedesktop.DBus.Properties' elif method == 'UPower': name = 'org.freedesktop.UPower' path = '/org/freedesktop/UPower' interface = 'org.freedesktop.UPower' pinterface = 'org.freedesktop.DBus.Properties' try: bus = dbus.SystemBus() return bus.get_object(name, path), interface, pinterface except dbus.exceptions.DBusException, msg: logging.info('DBus not reachable (%s)', msg) return None, None, None def linux_shutdown(): """ Make Linux system shutdown, never returns """ if not HAVE_DBUS: os._exit(0) proxy, interface = _get_sessionproxy() if proxy: if proxy.CanShutdown(): proxy.Shutdown(dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy('ConsoleKit') if proxy: if proxy.CanStop(dbus_interface=interface): try: proxy.Stop(dbus_interface=interface) except dbus.exceptions.DBusException, msg: logging.info('Received a DBus exception %s', latin1(msg)) else: logging.info('DBus does not support Stop (shutdown)') os._exit(0) def linux_hibernate(): """ Make Linux system go into hibernate, returns after wakeup """ if not HAVE_DBUS: return proxy, interface = _get_sessionproxy() if proxy: if proxy.CanHibernate(): proxy.Hibernate(dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy('UPower') if not proxy: proxy, interface, pinterface = _get_systemproxy('DeviceKit') if proxy: if proxy.Get(interface, 'can-hibernate', dbus_interface=pinterface): try: proxy.Hibernate(dbus_interface=interface) except dbus.exceptions.DBusException, msg: logging.info('Received a DBus exception %s', latin1(msg)) else: logging.info('DBus does not support Hibernate') time.sleep(10) def linux_standby(): """ Make Linux system go into standby, returns after wakeup """ if not HAVE_DBUS: return proxy, interface = _get_sessionproxy() if proxy: if proxy.CanSuspend(): proxy.Suspend(dbus_interface=interface) else: proxy, interface, pinterface = _get_systemproxy('UPower') if not proxy: proxy, interface, pinterface = _get_systemproxy('DeviceKit') if proxy: if proxy.Get(interface, 'can-suspend', dbus_interface=pinterface): try: proxy.Suspend(dbus_interface=interface) except dbus.exceptions.DBusException, msg: logging.info('Received a DBus exception %s', latin1(msg)) else: logging.info('DBus does not support Suspend (standby)') time.sleep(10) SABnzbd-0.7.20/sabnzbd/rating.py0000644000000000000000000002636012433712602016515 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.rating - Rating support functions """ import httplib import urllib import time import logging import copy import socket try: socket.ssl _HAVE_SSL = True except: _HAVE_SSL = False from threading import * import sabnzbd from sabnzbd.decorators import synchronized from sabnzbd.misc import OrderedSetQueue import sabnzbd.cfg as cfg RATING_URL = "/releaseRatings/releaseRatings.php" RATING_LOCK = RLock() _g_warnings = 0 def _warn(msg): global _g_warnings _g_warnings += 1 if _g_warnings < 3: logging.warning(msg) def _reset_warn(): global _g_warnings _g_warnings = 0 class NzbRating(object): def __init__(self): self.avg_video = 0 self.avg_video_cnt = 0 self.avg_audio = 0 self.avg_audio_cnt = 0 self.avg_vote_up = 0 self.avg_vote_down = 0 self.user_video = None self.user_audio = None self.user_vote = None self.user_flag = {} self.auto_flag = {} self.changed = 0 class NzbRatingV2(NzbRating): def __init__(self): super(NzbRatingV2, self).__init__() self.avg_spam_cnt = 0 self.avg_spam_confirm = False self.avg_encrypted_cnt = 0 self.avg_encrypted_confirm = False def to_v2(self, rating): self.__dict__.update(rating.__dict__) return self class Rating(Thread): VERSION = 2 VOTE_UP = 1 VOTE_DOWN = 2 FLAG_OK = 0 FLAG_SPAM = 1 FLAG_ENCRYPTED = 2 FLAG_EXPIRED = 3 FLAG_OTHER = 4 FLAG_COMMENT = 5 CHANGED_USER_VIDEO = 0x01 CHANGED_USER_AUDIO = 0x02 CHANGED_USER_VOTE = 0x04 CHANGED_USER_FLAG = 0x08 CHANGED_AUTO_FLAG = 0x10 do = None def __init__(self): Rating.do = self self.shutdown = False self.queue = OrderedSetQueue() try: (self.version, self.ratings, self.nzo_indexer_map) = sabnzbd.load_admin("Rating.sab") if self.version == 1: ratings = {} for k, v in self.ratings.iteritems(): ratings[k] = NzbRatingV2().to_v2(v) self.ratings = ratings self.version = 2 if (self.version != Rating.VERSION): raise Exception() except: self.version = Rating.VERSION self.ratings = {} self.nzo_indexer_map = {} Thread.__init__(self) if not _HAVE_SSL: logging.warning('Ratings server requires secure connection') self.stop() def stop(self): self.shutdown = True self.queue.put(None) # Unblock queue def run(self): self.shutdown = False while not self.shutdown: time.sleep(1) if not cfg.rating_enable(): continue indexer_id = self.queue.get() try: if indexer_id and not self._send_rating(indexer_id): for i in range(0, 60): if self.shutdown: break time.sleep(1) self.queue.put(indexer_id) except: pass logging.debug('Stopping ratings') @synchronized(RATING_LOCK) def save(self): if self.ratings and self.nzo_indexer_map: sabnzbd.save_admin((self.version, self.ratings, self.nzo_indexer_map), "Rating.sab") # The same file may be uploaded multiple times creating a new nzo_id each time @synchronized(RATING_LOCK) def add_rating(self, indexer_id, nzo_id, host, fields): if indexer_id and nzo_id and (len(fields) == 10): logging.debug('Add rating (%s, %s: %s, %s, %s, %s)', indexer_id, nzo_id, fields['video'], fields['audio'], fields['voteup'], fields['votedown']) try: rating = self.ratings.get(indexer_id, NzbRatingV2()) if fields['video'] and fields['videocnt']: rating.avg_video = int(float(fields['video'])) rating.avg_video_cnt = int(float(fields['videocnt'])) if fields['audio'] and fields['audiocnt']: rating.avg_audio = int(float(fields['audio'])) rating.avg_audio_cnt = int(float(fields['audiocnt'])) if fields['voteup']: rating.avg_vote_up = int(float(fields['voteup'])) if fields['votedown']: rating.avg_vote_down = int(float(fields['votedown'])) if fields['spam']: rating.avg_spam_cnt = int(float(fields['spam'])) if fields['confirmed-spam']: rating.avg_spam_confirm = (fields['confirmed-spam'].lower() == 'yes') if fields['passworded']: rating.avg_encrypted_cnt = int(float(fields['passworded'])) if fields['confirmed-passworded']: rating.avg_encrypted_confirm = (fields['confirmed-passworded'].lower() == 'yes') rating.host = host[0] if host and isinstance(host, list) else host self.ratings[indexer_id] = rating self.nzo_indexer_map[nzo_id] = indexer_id except: pass @synchronized(RATING_LOCK) def update_user_rating(self, nzo_id, video, audio, vote, flag, flag_detail = None): logging.debug('Updating user rating (%s: %s, %s, %s, %s)', nzo_id, video, audio, vote, flag) if nzo_id not in self.nzo_indexer_map: logging.warning('indexer id (%s) not found for ratings file', nzo_id) return indexer_id = self.nzo_indexer_map[nzo_id] rating = self.ratings[indexer_id] if video: rating.user_video = int(video) rating.avg_video = int((rating.avg_video_cnt * rating.avg_video + rating.user_video) / (rating.avg_video_cnt + 1)) rating.changed = rating.changed | Rating.CHANGED_USER_VIDEO if audio: rating.user_audio = int(audio) rating.avg_audio = int((rating.avg_audio_cnt * rating.avg_audio + rating.user_audio) / (rating.avg_audio_cnt + 1)) rating.changed = rating.changed | Rating.CHANGED_USER_AUDIO if flag: rating.user_flag = { 'val': int(flag), 'detail': flag_detail } rating.changed = rating.changed | Rating.CHANGED_USER_FLAG if vote and not rating.user_vote: rating.user_vote = int(vote) rating.changed = rating.changed | Rating.CHANGED_USER_VOTE if rating.user_vote == Rating.VOTE_UP: rating.avg_vote_up += 1 else: rating.avg_vote_down += 1 self.queue.put(indexer_id) @synchronized(RATING_LOCK) def update_auto_flag(self, nzo_id, flag, flag_detail = None): if not flag or not cfg.rating_enable() or not cfg.rating_feedback() or (nzo_id not in self.nzo_indexer_map): return logging.debug('Updating auto flag (%s: %s)', nzo_id, flag) indexer_id = self.nzo_indexer_map[nzo_id] rating = self.ratings[indexer_id] rating.auto_flag = { 'val': int(flag), 'detail': flag_detail } rating.changed = rating.changed | Rating.CHANGED_AUTO_FLAG self.queue.put(indexer_id) @synchronized(RATING_LOCK) def get_rating_by_nzo(self, nzo_id): if nzo_id not in self.nzo_indexer_map: return None return copy.copy(self.ratings[self.nzo_indexer_map[nzo_id]]) @synchronized(RATING_LOCK) def _get_rating_by_indexer(self, indexer_id): return copy.copy(self.ratings[indexer_id]) def _flag_request(self, val, flag_detail, auto): if val == Rating.FLAG_SPAM: return {'m': 'rs', 'auto': auto} if val == Rating.FLAG_ENCRYPTED: return {'m': 'rp', 'auto': auto} if val == Rating.FLAG_EXPIRED: expired_host = flag_detail if flag_detail and len(flag_detail) > 0 else 'Other' return {'m': 'rpr', 'pr': expired_host, 'auto': auto} if (val == Rating.FLAG_OTHER) and flag_detail and len(flag_detail) > 0: return {'m': 'o', 'r': flag_detail} if (val == Rating.FLAG_COMMENT) and flag_detail and len(flag_detail) > 0: return {'m': 'rc', 'r': flag_detail} def _send_rating(self, indexer_id): logging.debug('Updating indexer rating (%s)', indexer_id) api_key = cfg.rating_api_key() rating_host = cfg.rating_host() if not api_key: return True requests = [] _headers = {'User-agent' : 'SABnzbd+/%s' % sabnzbd.version.__version__, 'Content-type': 'application/x-www-form-urlencoded'} rating = self._get_rating_by_indexer(indexer_id) # Requesting info here ensures always have latest information even on retry if hasattr(rating, 'host') and rating.host: rating_host = rating.host if not rating_host: return True if rating.changed & Rating.CHANGED_USER_VIDEO: requests.append({'m': 'r', 'r': 'videoQuality', 'rn': rating.user_video}) if rating.changed & Rating.CHANGED_USER_AUDIO: requests.append({'m': 'r', 'r': 'audioQuality', 'rn': rating.user_audio}) if rating.changed & Rating.CHANGED_USER_VOTE: up_down = 'up' if rating.user_vote == Rating.VOTE_UP else 'down' requests.append({'m': 'v', 'v': up_down, 'r': 'overall'}) if rating.changed & Rating.CHANGED_USER_FLAG: requests.append(self._flag_request(rating.user_flag.get('val'), rating.user_flag.get('detail'), 0)) if rating.changed & Rating.CHANGED_AUTO_FLAG: requests.append(self._flag_request(rating.auto_flag.get('val'), rating.auto_flag.get('detail'), 1)) try: conn = httplib.HTTPSConnection(rating_host) for request in filter(lambda r: r is not None, requests): request['apikey'] = api_key request['i'] = indexer_id conn.request('POST', RATING_URL, urllib.urlencode(request), headers = _headers) response = conn.getresponse() response.read() if response.status == httplib.UNAUTHORIZED: _warn('Ratings server unauthorized user') return False elif response.status != httplib.OK: _warn('Ratings server failed to process request (%s, %s)' % (response.status, response.reason)) return False self.ratings[indexer_id].changed = self.ratings[indexer_id].changed & ~rating.changed _reset_warn() return True except: _warn('Problem accessing ratings server: %s' % rating_host) return False SABnzbd-0.7.20/sabnzbd/rss.py0000644000000000000000000006065612433712602016046 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.rss - rss client functionality """ import re import logging import time import threading import urllib import os import sabnzbd from sabnzbd.constants import * from sabnzbd.decorators import synchronized import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.misc import cat_convert, sanitize_foldername, wildcard_to_re, cat_to_opts, match_str import sabnzbd.emailer as emailer from sabnzbd.encoding import latin1, unicoder, xml_name import sabnzbd.utils.feedparser as feedparser __RSS = None # Global pointer to RSS-scanner instance ################################################################################ # Wrapper functions # ################################################################################ def init(): global __RSS __RSS = RSSQueue() def stop(): global __RSS if __RSS: __RSS.stop() try: __RSS.join() except: pass def del_feed(feed): global __RSS if __RSS: __RSS.delete(feed) def run_feed(feed, download, ignoreFirst=False, force=False, readout=True): global __RSS if __RSS: return __RSS.run_feed(feed, download, ignoreFirst, force=force, readout=readout) def show_result(feed): global __RSS if __RSS: return __RSS.show_result(feed) def flag_downloaded(feed, id): global __RSS if __RSS: __RSS.flag_downloaded(feed, id) def lookup_url(feed, id): global __RSS if __RSS: return __RSS.lookup_url(feed, id) def run_method(): global __RSS if __RSS: return __RSS.run() else: return None def next_run(t=None): global __RSS if __RSS: if t: __RSS.next_run = t else: return __RSS.next_run else: return time.time() def save(): global __RSS if __RSS: __RSS.save() def clear_feed(feed): global __RSS if __RSS: __RSS.clear_feed(feed) def clear_downloaded(feed): global __RSS if __RSS: __RSS.clear_downloaded(feed) ################################################################################ def notdefault(item): """ Return True if not 'Default'/'*'/'' """ return bool(item) and str(item).lower() not in ('default', '*', '', str(DEFAULT_PRIORITY)) def ListUris(): """ Return list of all RSS uris """ uris = [] for uri in config.get_rss(): uris.append(uri) return uris def convert_filter(text): """ Return compiled regex. If string starts with re: it's a real regex else quote all regex specials, replace '*' by '.*' """ text = text.strip().lower() if text.startswith('re:'): txt = text[3:].strip() else: txt = wildcard_to_re(text) try: return re.compile(txt, re.I) except: logging.debug('Could not compile regex: %s', text) return None _EXPIRE_SEC = 3*24*3600 # 3 days def remove_obsolete(jobs, new_jobs): """ Expire G/B links that are not in new_jobs (mark them 'X') Expired links older than 3 days are removed from 'jobs' """ now = time.time() limit = now - _EXPIRE_SEC olds = jobs.keys() for old in olds: tm = jobs[old]['time'] if old not in new_jobs: if jobs[old].get('status', ' ')[0] in ('G', 'B'): jobs[old]['status'] = 'X' if jobs[old]['status'] == 'X' and tm < limit: logging.debug("Purging link %s", old) del jobs[old] LOCK = threading.RLock() class RSSQueue(object): def __init__(self): def check_str(p): return p is None or p == '' or isinstance(p, str) def check_int(p): try: int(p) return True except: return False self.jobs = {} self.next_run = time.time() try: defined = config.get_rss().keys() feeds = sabnzbd.load_admin(RSS_FILE_NAME) if type(feeds) == type({}): for feed in feeds: if feed not in defined: logging.debug('Dropping obsolete data for feed "%s"', feed) continue self.jobs[feed] = {} for link in feeds[feed]: data = feeds[feed][link] if type(data) == type([]): # Convert previous list-based store to dictionary new = {} try: new['status'] = data[0] new['title'] = data[1] new['url'] = data[2] new['cat'] = data[3] new['pp'] = data[4] new['script'] = data[5] new['time'] = data[6] new['prio'] = str(NORMAL_PRIORITY) new['rule'] = 0 self.jobs[feed][link] = new except IndexError: del new else: # Consistency check on data try: item = feeds[feed][link] if not isinstance(item, dict) or not isinstance(item.get('title'), unicode): raise IndexError if item.get('status', ' ')[0] not in ('D', 'G', 'B', 'X'): item['status'] = 'X' if not isinstance(item.get('url'), unicode): item['url'] = '' item['url'] = item['url'].replace('www.newzbin.com', cfg.newzbin_url()) if not check_str(item.get('cat')): item['cat'] = '' if not check_str(item.get('orgcat')): item['orgcat'] = '' if not check_str(item.get('pp')): item['pp'] = '3' if not check_str(item.get('script')): item['script'] = 'None' if not check_str(item.get('prio')): item['prio'] = '-100' if not check_int(item.get('rule', 0)): item['rule'] = 0 if not isinstance(item.get('time'), float): item['time'] = time.time() if not check_int(item.get('order', 0)): item.get['order'] = 0 self.jobs[feed][link] = item except (KeyError, IndexError): logging.info('Incorrect entry in %s detected, discarding %s', RSS_FILE_NAME, item) remove_obsolete(self.jobs[feed], self.jobs[feed].keys()) except IOError: logging.debug('Cannot read file %s', RSS_FILE_NAME) # jobs is a NAME-indexed dictionary # Each element is link-indexed dictionary # Each element is another dictionary: # status : 'D', 'G', 'B', 'X' (downloaded, good-match, bad-match, obsolete) # '*' added means: from the initial batch # '-' added to 'D' means downloaded, but not displayed anymore # title : Title # url : URL or MsgId # cat : category # orgcat : category as read from feed # pp : pp # script : script # prio : priority # time : timestamp (used for time-based clean-up) # order : order in the RSS feed self.shutdown = False def stop(self): self.shutdown = True @synchronized(LOCK) def run_feed(self, feed=None, download=False, ignoreFirst=False, force=False, readout=True): """ Run the query for one URI and apply filters """ self.shutdown = False def dup_title(title): """ Check if this title was in this or other feeds Return matching feed name """ title = title.lower() for fd in self.jobs: for lk in self.jobs[fd]: item = self.jobs[fd][lk] if item.get('status', ' ')[0] == 'D' and \ item.get('title', '').lower() == title: return fd return '' if not feed: return 'No such feed' newlinks = [] new_downloads = [] # Preparations, get options try: feeds = config.get_rss()[feed] except KeyError: logging.error(Ta('Incorrect RSS feed description "%s"'), feed) logging.info("Traceback: ", exc_info = True) return T('Incorrect RSS feed description "%s"') % feed uri = feeds.uri() defCat = feeds.cat() if not notdefault(defCat): defCat = None defPP = feeds.pp() if not notdefault(defPP): defPP = None defScript = feeds.script() if not notdefault(defScript): defScript = None defPrio = feeds.priority() if not notdefault(defPrio): defPrio = None # Preparations, convert filters to regex's regexes = [] reTypes = [] reCats = [] rePPs = [] rePrios = [] reScripts = [] reEnabled = [] for filter in feeds.filters(): reCat = filter[0] if defCat in ('', '*'): reCat = None reCats.append(reCat) rePPs.append(filter[1]) reScripts.append(filter[2]) reTypes.append(filter[3]) regexes.append(convert_filter(filter[4])) rePrios.append(filter[5]) reEnabled.append(filter[6] != '0') regcount = len(regexes) # Set first if this is the very first scan of this URI first = (feed not in self.jobs) and ignoreFirst # Add sabnzbd's custom User Agent feedparser.USER_AGENT = 'SABnzbd+/%s' % sabnzbd.version.__version__ # Check for nzbs.org if 'nzbs.org/' in uri and not ('&dl=1' in uri): uri += '&dl=1' # Read the RSS feed msg = None entries = None if readout: uri = uri.replace(' ', '%20') logging.debug("Running feedparser on %s", uri) d = feedparser.parse(uri.replace('feed://', 'http://')) logging.debug("Done parsing %s", uri) if not d: msg = Ta('Failed to retrieve RSS from %s: %s') % (uri, '?') logging.info(msg) return unicoder(msg) status = d.get('status', 999) if status in (401, 402, 403): msg = Ta('Do not have valid authentication for feed %s') % feed logging.info(msg) return unicoder(msg) if status >= 500 and status <=599: msg = Ta('Server side error (server code %s); could not get %s on %s') % (status, feed, uri) logging.info(msg) return unicoder(msg) entries = d.get('entries') if 'bozo_exception' in d and not entries: msg = Ta('Failed to retrieve RSS from %s: %s') % (uri, xml_name(str(d['bozo_exception']))) logging.info(msg) return unicoder(msg) if not entries: msg = Ta('RSS Feed %s was empty') % uri logging.info(msg) if feed not in self.jobs: self.jobs[feed] = {} jobs = self.jobs[feed] if readout: if not entries: return unicoder(msg) else: entries = jobs.keys() # Sort in the order the jobs came from the feed entries.sort(lambda x, y: jobs[x].get('order', 0) - jobs[y].get('order', 0)) order = 0 # Filter out valid new links for entry in entries: if self.shutdown: return if readout: try: link, category = _get_link(uri, entry) except (AttributeError, IndexError): link = None category = '' logging.info(Ta('Incompatible feed') + ' ' + uri) logging.info("Traceback: ", exc_info = True) return T('Incompatible feed') category = latin1(category) # Make sure only latin-1 encodable characters occur atitle = latin1(entry.title) title = unicoder(atitle) else: link = entry category = jobs[link].get('orgcat', '') if category in ('', '*'): category = None atitle = latin1(jobs[link].get('title', '')) title = unicoder(atitle) if link: # Make sure spaces are quoted in the URL link = link.strip().replace(' ','%20') newlinks.append(link) if link in jobs: jobstat = jobs[link].get('status', ' ')[0] else: jobstat = 'N' if jobstat in 'NGB' or (jobstat == 'X' and readout): # Match this title against all filters logging.debug('Trying title %s', atitle) result = False myCat = defCat myPP = defPP myScript = defScript myPrio = defPrio n = 0 # Match against all filters until an postive or negative match for n in xrange(regcount): if reEnabled[n]: if category and reTypes[n] == 'C': found = re.search(regexes[n], category) if not found: logging.debug("Filter rejected on rule %d", n) result = False break else: if regexes[n]: found = re.search(regexes[n], title) else: found = False if reTypes[n] == 'M' and not found: logging.debug("Filter rejected on rule %d", n) result = False break if found and reTypes[n] == 'A': logging.debug("Filter matched on rule %d", n) result = True break if found and reTypes[n] == 'R': logging.debug("Filter rejected on rule %d", n) result = False break if len(reCats): if notdefault(reCats[n]): myCat = reCats[n] elif category and not defCat: myCat = cat_convert(category) if myCat: myCat, catPP, catScript, catPrio = cat_to_opts(myCat) else: myCat = catPP = catScript = catPrio = None if notdefault(rePPs[n]): myPP = rePPs[n] elif not (reCats[n] or category): myPP = catPP if notdefault(reScripts[n]): myScript = reScripts[n] elif not (notdefault(reCats[n]) or category): myScript = catScript if rePrios[n] not in (str(DEFAULT_PRIORITY), ''): myPrio = rePrios[n] elif not ((rePrios[n] != str(DEFAULT_PRIORITY)) or category): myPrio = catPrio if cfg.no_dupes() and dup_title(title): if cfg.no_dupes() == 1: logging.info("Ignoring duplicate job %s", atitle) continue else: myPrio = DUP_PRIORITY act = download and not first if link in jobs: act = act and not jobs[link].get('status', '').endswith('*') act = act or force star = first or jobs[link].get('status', '').endswith('*') else: star = first if result: _HandleLink(jobs, link, title, 'G', category, myCat, myPP, myScript, act, star, order, priority=myPrio, rule=str(n)) if act: new_downloads.append(title) else: _HandleLink(jobs, link, title, 'B', category, myCat, myPP, myScript, False, star, order, priority=myPrio, rule=str(n)) order += 1 # Send email if wanted and not "forced" if new_downloads and cfg.email_rss() and not force: emailer.rss_mail(feed, new_downloads) remove_obsolete(jobs, newlinks) return '' def run(self): """ Run all the URI's and filters """ if not sabnzbd.PAUSED_ALL: active = False if self.next_run < time.time(): self.next_run = time.time() + cfg.rss_rate.get() * 60 feeds = config.get_rss() for feed in feeds.keys(): try: if feeds[feed].enable.get(): logging.info('Starting scheduled RSS read-out for "%s"', feed) active = True self.run_feed(feed, download=True, ignoreFirst=True) # Wait 15 seconds, else sites may get irritated for x in xrange(15): if self.shutdown: return else: time.sleep(1.0) except KeyError: # Feed must have been deleted pass if active: self.save() logging.info('Finished scheduled RSS read-outs') @synchronized(LOCK) def show_result(self, feed): if feed in self.jobs: try: return self.jobs[feed] except: return {} else: return {} @synchronized(LOCK) def save(self): sabnzbd.save_admin(self.jobs, sabnzbd.RSS_FILE_NAME) @synchronized(LOCK) def delete(self, feed): if feed in self.jobs: del self.jobs[feed] @synchronized(LOCK) def flag_downloaded(self, feed, id): if feed in self.jobs: lst = self.jobs[feed] for link in lst: if lst[link].get('url', '') == id: lst[link]['status'] = 'D' @synchronized(LOCK) def lookup_url(self, feed, url): if url and feed in self.jobs: lst = self.jobs[feed] for link in lst: if lst[link].get('url') == url: return lst[link] return None @synchronized(LOCK) def clear_feed(self, feed): # Remove any previous references to this feed name, and start fresh if feed in self.jobs: del self.jobs[feed] @synchronized(LOCK) def clear_downloaded(self, feed): # Mark downloaded jobs, so that they won't be displayed any more. if feed in self.jobs: for item in self.jobs[feed]: if self.jobs[feed][item]['status'] == 'D': self.jobs[feed][item]['status'] = 'D-' RE_NEWZBIN = re.compile(r'(newz)(bin|xxx|bin2|xxx2)\.[\w]+/browse/post/(\d+)', re.I) def _HandleLink(jobs, link, title, flag, orgcat, cat, pp, script, download, star, order, priority=NORMAL_PRIORITY, rule=0): """ Process one link """ if script == '': script = None if pp == '': pp = None jobs[link] = {} jobs[link]['order'] = order jobs[link]['orgcat'] = orgcat if special_rss_site(link): nzbname = None else: nzbname = title m = RE_NEWZBIN.search(link) if m and m.group(1).lower() == 'newz' and m.group(2) and m.group(3): if download: jobs[link]['status'] = 'D' jobs[link]['title'] = title logging.info("Adding %s (%s) to queue", m.group(3), title) sabnzbd.add_msgid(m.group(3), pp=pp, script=script, cat=cat, priority=priority, nzbname=nzbname) else: if star: jobs[link]['status'] = flag + '*' else: jobs[link]['status'] = flag jobs[link]['title'] = title jobs[link]['url'] = m.group(3) jobs[link]['cat'] = cat jobs[link]['pp'] = pp jobs[link]['script'] = script jobs[link]['prio'] = str(priority) else: if download: jobs[link]['status'] = 'D' jobs[link]['title'] = title logging.info("Adding %s (%s) to queue", link, title) sabnzbd.add_url(link, pp=pp, script=script, cat=cat, priority=priority, nzbname=nzbname) else: if star: jobs[link]['status'] = flag + '*' else: jobs[link]['status'] = flag jobs[link]['title'] = title jobs[link]['url'] = link jobs[link]['cat'] = cat jobs[link]['pp'] = pp jobs[link]['script'] = script jobs[link]['prio'] = str(priority) jobs[link]['time'] = time.time() jobs[link]['rule'] = rule def _get_link(uri, entry): """ Retrieve the post link from this entry Returns (link, category) """ link = None category = '' uri = uri.lower() if 'newzbin.' in uri or 'newzxxx.' in uri or 'newzbin2.' in uri or 'newzxxx2.' in uri: link = entry.link if not (link and '/post/' in link.lower()): # Use alternative link link = entry.links[0].href else: # Try standard link first link = entry.link if not link: link = entry.links[0].href if encl_sites(uri, link): try: link = entry.enclosures[0]['href'] except: pass if link and 'http' in link.lower(): try: category = entry.cattext except: try: category = entry.category except: try: # nzb.su category = entry.tags[0]['term'] except: try: # nzbmatrix.com category = entry.description except: category = '' return link, category else: logging.warning(Ta('Empty RSS entry found (%s)'), link) return None, '' def special_rss_site(url): """ Return True if url describes an RSS site with odd titles """ return cfg.rss_filenames() or match_str(url, cfg.rss_odd_titles()) _ENCL_SITES = ('nzbindex.nl', 'nzbindex.com', 'animeusenet.org', 'nzbclub.com') def encl_sites(url, link): """ Return True if url or link matches sites that use enclosures """ for site in _ENCL_SITES: if site in url or (link and site in link): return True return False SABnzbd-0.7.20/sabnzbd/sabtray.py0000644000000000000000000001143412433712602016672 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabtray.py - Systray icon for SABnzbd on Windows, contributed by Jan Schejbal """ import logging from time import sleep import sabnzbd from sabnzbd.panic import launch_a_browser import sabnzbd.api as api import sabnzbd.scheduler as scheduler from sabnzbd.downloader import Downloader import sabnzbd.cfg as cfg from sabnzbd.constants import MEBI from sabnzbd.misc import to_units import os import cherrypy from sabnzbd.utils.systrayiconthread import SysTrayIconThread # contains the tray icon, which demands its own thread class SABTrayThread(SysTrayIconThread): sabicons = { 'default': 'icons/sabnzbd16.ico', 'green': 'icons/sabnzbd16green.ico', 'pause': 'icons/sabnzbd16paused.ico' } def __init__(self): # Wait for translated texts to be loaded while not sabnzbd.WEBUI_READY: sleep(0.2) logging.debug('language file not loaded, waiting') self.sabpaused = False self.counter = 0 text = "SABnzbd" menu_options = ( (T('Show interface'), None, self.browse), (T('Open complete folder'), None, self.opencomplete), (T('Troubleshoot'), None, ((T('Restart'), None, self.restart), (T('Restart without login'), None, self.nologin), (T('Restart') + ' - 127.0.0.1:8080', None, self.defhost))), (T('Pause') + '/' + T('Resume'), None, self.pauseresume), (T('Shutdown'), None, self.shutdown), ) SysTrayIconThread.__init__(self, self.sabicons['default'], text, menu_options, None, 0, "SabTrayIcon") # called every few ms by SysTrayIconThread def doUpdates(self): """ Update menu info, once every 10 calls """ self.counter += 1 if self.counter > 10: self.sabpaused, bytes_left, bpsnow, time_left = api.fast_queue() mb_left = to_units(bytes_left, dec_limit=1) speed = to_units(bpsnow, dec_limit=1) if self.sabpaused: self.hover_text = T('Paused') self.icon = self.sabicons['pause'] elif bytes_left > 0: self.hover_text = "%sB/s %s: %sB (%s)" % (speed, T('Remaining'), mb_left, time_left) self.icon = self.sabicons['green'] else: self.hover_text = T('Idle') self.icon = self.sabicons['default'] self.refresh_icon() self.counter = 0 if sabnzbd.SABSTOP: self.terminate = True # menu handler def opencomplete(self, icon): try: os.startfile(cfg.complete_dir.get_path()) except WindowsError: pass # menu handler def browse(self, icon): launch_a_browser(sabnzbd.BROWSER_URL, True) # menu handler def pauseresume(self, icon): if self.sabpaused: self.resume() else: self.pause() # menu handler def restart(self, icon): self.hover_text = T('Restart') sabnzbd.halt() cherrypy.engine.restart() # menu handler def nologin(self, icon): sabnzbd.cfg.username.set('') sabnzbd.cfg.password.set('') sabnzbd.config.save_config() self.hover_text = T('Restart') sabnzbd.halt() cherrypy.engine.restart() # menu handler def defhost(self, icon): sabnzbd.cfg.cherryhost.set('127.0.0.1') sabnzbd.cfg.enable_https.set(False) sabnzbd.config.save_config() self.hover_text = T('Restart') sabnzbd.halt() cherrypy.engine.restart() # menu handler - adapted from interface.py def shutdown(self, icon): self.hover_text = T('Shutdown') sabnzbd.halt() cherrypy.engine.exit() sabnzbd.SABSTOP = True # adapted from interface.py def pause(self): scheduler.plan_resume(0) Downloader.do.pause() # adapted from interface.py def resume(self): scheduler.plan_resume(0) sabnzbd.unpause_all() SABnzbd-0.7.20/sabnzbd/scheduler.py0000644000000000000000000003366312433712602017213 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2011 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.scheduler - Event Scheduler """ #------------------------------------------------------------------------------ import random import logging import time import sabnzbd.utils.kronos as kronos import sabnzbd.rss as rss from sabnzbd.newzbin import Bookmarks import sabnzbd.downloader import sabnzbd.dirscanner import sabnzbd.misc import sabnzbd.config as config import sabnzbd.cfg as cfg from sabnzbd.postproc import PostProcessor __SCHED = None # Global pointer to Scheduler instance RSSTASK_MINUTE = random.randint(0, 59) SCHEDULE_GUARD_FLAG = False PP_PAUSE_EVENT = False def schedule_guard(): """ Set flag for scheduler restart """ global SCHEDULE_GUARD_FLAG SCHEDULE_GUARD_FLAG = True def pp_pause(): PostProcessor.do.paused = True def pp_resume(): PostProcessor.do.paused = False def pp_pause_event(): return PP_PAUSE_EVENT def init(): """ Create the scheduler and set all required events """ global __SCHED reset_guardian() __SCHED = kronos.ThreadedScheduler() rss_planned = False for schedule in cfg.schedules(): arguments = [] argument_list = None try: m, h, d, action_name = schedule.split() except: m, h, d, action_name, argument_list = schedule.split(None, 4) if argument_list: arguments = argument_list.split() action_name = action_name.lower() try: m = int(m) h = int(h) except: logging.warning(Ta('Bad schedule %s at %s:%s'), action_name, m, h) continue if d.isdigit(): d = [int(i) for i in d] else: d = range(1, 8) if action_name == 'resume': action = scheduled_resume arguments = [] elif action_name == 'pause': action = sabnzbd.downloader.Downloader.do.pause arguments = [] elif action_name == 'pause_all': action = sabnzbd.pause_all arguments = [] elif action_name == 'shutdown': action = sabnzbd.shutdown_program arguments = [] elif action_name == 'restart': action = sabnzbd.restart_program arguments = [] elif action_name == 'pause_post': action = pp_pause elif action_name == 'resume_post': action = pp_resume elif action_name == 'speedlimit' and arguments != []: action = sabnzbd.downloader.Downloader.do.limit_speed elif action_name == 'enable_server' and arguments != []: action = sabnzbd.enable_server elif action_name == 'disable_server' and arguments != []: action = sabnzbd.disable_server elif action_name == 'scan_folder': action = sabnzbd.dirscanner.dirscan elif action_name == 'rss_scan': action = rss.run_method rss_planned = True elif action_name == 'remove_failed': action = sabnzbd.api.history_remove_failed else: logging.warning(Ta('Unknown action: %s'), action_name) continue logging.debug("scheduling %s(%s) on days %s at %02d:%02d", action_name, arguments, d, h, m) __SCHED.add_daytime_task(action, action_name, d, None, (h, m), kronos.method.sequential, arguments, None) # Set Guardian interval to 30 seconds __SCHED.add_interval_task(sched_guardian, "Guardian", 15, 30, kronos.method.sequential, None, None) # Set RSS check interval if not rss_planned: interval = cfg.rss_rate() delay = random.randint(0, interval-1) logging.debug("Scheduling RSS interval task every %s min (delay=%s)", interval, delay) sabnzbd.rss.next_run(time.time() + delay * 60) __SCHED.add_interval_task(rss.run_method, "RSS", delay*60, interval*60, kronos.method.sequential, None, None) __SCHED.add_single_task(rss.run_method, 'RSS', 15, kronos.method.sequential, None, None) if cfg.version_check(): # Check for new release, once per week on random time m = random.randint(0, 59) h = random.randint(0, 23) d = (random.randint(1, 7), ) logging.debug("Scheduling VersionCheck on day %s at %s:%s", d[0], h, m) __SCHED.add_daytime_task(sabnzbd.misc.check_latest_version, 'VerCheck', d, None, (h, m), kronos.method.sequential, [], None) if False: #cfg.newzbin_bookmarks(): interval = cfg.bookmark_rate() delay = random.randint(0, interval-1) logging.debug("Scheduling Bookmark interval task every %s min (delay=%s)", interval, delay) __SCHED.add_interval_task(Bookmarks.do.run, 'Bookmarks', delay*60, interval*60, kronos.method.sequential, None, None) __SCHED.add_single_task(Bookmarks.do.run, 'Bookmarks', 20, kronos.method.sequential, None, None) action, hour, minute = sabnzbd.bpsmeter.BPSMeter.do.get_quota() if action: logging.info('Setting schedule for quota check daily at %s:%s', hour, minute) __SCHED.add_daytime_task(action, 'quota_reset', range(1, 8), None, (hour, minute), kronos.method.sequential, [], None) logging.info('Setting schedule for midnight BPS reset') __SCHED.add_daytime_task(sabnzbd.bpsmeter.midnight_action, 'midnight_bps', range(1, 8), None, (0, 0), kronos.method.sequential, [], None) # Subscribe to special schedule changes cfg.newzbin_bookmarks.callback(schedule_guard) cfg.bookmark_rate.callback(schedule_guard) cfg.rss_rate.callback(schedule_guard) def start(): """ Start the scheduler """ global __SCHED if __SCHED: logging.debug('Starting scheduler') __SCHED.start() def restart(force=False): """ Stop and start scheduler """ global __PARMS, SCHEDULE_GUARD_FLAG if force: SCHEDULE_GUARD_FLAG = True else: if SCHEDULE_GUARD_FLAG: SCHEDULE_GUARD_FLAG = False stop() analyse(sabnzbd.downloader.Downloader.do.paused) init() start() def stop(): """ Stop the scheduler, destroy instance """ global __SCHED if __SCHED: logging.debug('Stopping scheduler') try: __SCHED.stop() except IndexError: pass del __SCHED __SCHED = None def abort(): """ Emergency stop, just set the running attribute false """ global __SCHED if __SCHED: logging.debug('Terminating scheduler') __SCHED.running = False def sort_schedules(all_events, now=None): """ Sort the schedules, based on order of happening from now `all_events=True`: Return an event for each active day `all_events=False`: Return only first occurring event of the week `now` : for testing: simulated localtime() """ day_min = 24 * 60 week_min = 7 * day_min events = [] now = now or time.localtime() now_hm = now[3] * 60 + now[4] now = now[6] * day_min + now_hm for schedule in cfg.schedules(): parms = None try: m, h, dd, action, parms = schedule.split(None, 4) except: try: m, h, dd, action = schedule.split(None, 3) except: continue # Bad schedule, ignore action = action.strip() if dd == '*': dd = '1234567' if not dd.isdigit(): continue # Bad schedule, ignore for d in dd: then = (int(d) - 1) * day_min + int(h) * 60 + int(m) dif = then - now if all_events and dif < 0: # Expired event will occur again after a week dif = dif + week_min events.append((dif, action, parms, schedule)) if not all_events: break events.sort(lambda x, y: x[0] - y[0]) return events def analyse(was_paused=False): """ Determine what pause/resume state we would have now. """ global PP_PAUSE_EVENT PP_PAUSE_EVENT = False paused = None paused_all = False pause_post = False speedlimit = None servers = {} for ev in sort_schedules(all_events=True): logging.debug('Schedule check result = %s', ev) action = ev[1] try: value = ev[2] except: value = None if action == 'pause': paused = True elif action == 'pause_all': paused_all = True PP_PAUSE_EVENT = True elif action == 'resume': paused = False paused_all = False elif action == 'pause_post': pause_post = True PP_PAUSE_EVENT = True elif action == 'resume_post': pause_post = False PP_PAUSE_EVENT = True elif action == 'speedlimit' and value!=None: speedlimit = int(ev[2]) elif action == 'enable_server': try: servers[value] = 1 except: logging.warning(Ta('Schedule for non-existing server %s'), value) elif action == 'disable_server': try: servers[value] = 0 except: logging.warning(Ta('Schedule for non-existing server %s'), value) if not was_paused: if paused_all: sabnzbd.pause_all() else: sabnzbd.unpause_all() sabnzbd.downloader.Downloader.do.set_paused_state(paused or paused_all) PostProcessor.do.paused = pause_post if speedlimit: sabnzbd.downloader.Downloader.do.limit_speed(speedlimit) for serv in servers: try: item = config.get_config('servers', serv) value = servers[serv] if bool(item.enable()) != bool(value): item.enable.set(value) sabnzbd.downloader.Downloader.do.init_server(serv, serv) except: pass config.save_config() #------------------------------------------------------------------------------ # Support for single shot pause (=delayed resume) __PAUSE_END = None # Moment when pause will end def scheduled_resume(): """ Scheduled resume, only when no oneshot resume is active """ global __PAUSE_END if __PAUSE_END is None: sabnzbd.unpause_all() def __oneshot_resume(when): """ Called by delayed resume schedule Only resumes if call comes at the planned time """ global __PAUSE_END if __PAUSE_END != None and (when > __PAUSE_END-5) and (when < __PAUSE_END+55): __PAUSE_END = None logging.debug('Resume after pause-interval') sabnzbd.unpause_all() else: logging.debug('Ignoring cancelled resume') def plan_resume(interval): """ Set a scheduled resume after the interval """ global __SCHED, __PAUSE_END if interval > 0: __PAUSE_END = time.time() + (interval * 60) logging.debug('Schedule resume at %s', __PAUSE_END) __SCHED.add_single_task(__oneshot_resume, '', interval*60, kronos.method.sequential, [__PAUSE_END], None) sabnzbd.downloader.Downloader.do.pause() else: __PAUSE_END = None sabnzbd.unpause_all() def pause_int(): """ Return minutes:seconds until pause ends """ global __PAUSE_END if __PAUSE_END is None: return "0" else: val = __PAUSE_END - time.time() if val < 0: sign = '-' val = abs(val) else: sign = '' min = int(val / 60L) sec = int(val - min*60) return "%s%d:%02d" % (sign, min, sec) def pause_check(): """ Unpause when time left is negative, compensate for missed schedule """ global __PAUSE_END if __PAUSE_END is not None and (__PAUSE_END - time.time()) < 0: __PAUSE_END = None logging.debug('Force resume, negative timer') sabnzbd.unpause_all() #------------------------------------------------------------------------------ def plan_server(action, parms, interval): """ Plan to re-activate server after "interval" minutes """ __SCHED.add_single_task(action, '', interval*60, kronos.method.sequential, parms, None) #------------------------------------------------------------------------------ def force_rss(): """ Add a one-time RSS scan, one second from now """ __SCHED.add_single_task(rss.run_method, 'RSS', 1, kronos.method.sequential, None, None) #------------------------------------------------------------------------------ # Scheduler Guarding system # Each check sets the guardian flag False # Each succesful scheduled check sets the flag # If 4 consequetive checks fail, the sheduler is assumed to have crashed __SCHED_GUARDIAN = False __SCHED_GUARDIAN_CNT = 0 def reset_guardian(): global __SCHED_GUARDIAN, __SCHED_GUARDIAN_CNT __SCHED_GUARDIAN = False __SCHED_GUARDIAN_CNT = 0 def sched_guardian(): global __SCHED_GUARDIAN, __SCHED_GUARDIAN_CNT __SCHED_GUARDIAN = True def sched_check(): global __SCHED_GUARDIAN, __SCHED_GUARDIAN_CNT if not __SCHED_GUARDIAN: __SCHED_GUARDIAN_CNT += 1 return __SCHED_GUARDIAN_CNT < 4 reset_guardian() return True SABnzbd-0.7.20/sabnzbd/skintext.py0000644000000000000000000014755212433712602017111 0ustar00usergroup00000000000000#!/usr/bin/python -OO # -*- coding: UTF-8 -*- # Copyright 2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.skintext - Language strings used in the templates """ SKIN_TEXT = { # Special texts 'stage-download' : TT('Download'), #: Queue status "download" 'stage-repair' : TT('Repair'), #: PP phase "repair" 'stage-filejoin' : TT('Join files'), #: PP phase "filejoin" 'stage-unpack' : TT('Unpack'), #: PP phase "unpack" 'stage-script' : TT('Script'), #: PP phase "script" 'stage-source' : TT('Source'), #: PP Source of the NZB (path or URL) 'stage-fail' : TT('Failure'), #: PP Failure message 'post-Completed' : TT('Completed'), #: PP status 'post-Failed' : TT('Failed'), #: PP status 'post-Queued' : TT('Waiting'), #: Queue and PP status 'post-Paused' : TT('Paused'), #: PP status 'post-Repairing' : TT('Repairing...'), #: PP status 'post-Extracting' : TT('Extracting...'), #: PP status 'post-Moving' : TT('Moving...'), #: PP status 'post-Running' : TT('Running script...'), #: PP status 'post-Fetching' : TT('Fetching extra blocks...'), #: PP status 'post-QuickCheck' : TT('Quick Check...'), #: PP status 'post-Verifying' : TT('Verifying...'), #: PP status 'post-Downloading' : TT('Downloading'), #: Pseudo-PP status, in reality used for Queue-status 'post-Grabbing' : TT('Get NZB'), #: Pseudo-PP status, in reality used for Grabbing status 'post-Checking' : TT('Checking'), #: PP status 'sch-frequency' : TT('Frequency'), #: #: Config->Scheduler 'sch-action' : TT('Action'), #: #: Config->Scheduler 'sch-arguments' : TT('Arguments'), #: #: Config->Scheduler 'sch-task' : TT('Task'), #: #: Config->Scheduler 'sch-disable_server' : TT('disable server'), #: #: Config->Scheduler 'sch-enable_server' : TT('enable server'), #: #: Config->Scheduler 'sch-resume' : TT('Resume'), #: #: Config->Scheduler 'sch-pause' : TT('Pause'), #: #: Config->Scheduler 'sch-shutdown' : TT('Shutdown'), #: #: Config->Scheduler 'sch-restart' : TT('Restart'), #: #: Config->Scheduler 'sch-speedlimit' : TT('Speedlimit'), #: #: Config->Scheduler 'sch-pause_all' : TT('Pause All'), #: #: Config->Scheduler 'sch-pause_post' : TT('Pause post-processing'), #: #: Config->Scheduler 'sch-resume_post' : TT('Resume post-processing'), #: #: Config->Scheduler 'sch-scan_folder' : TT('Scan watched folder'), #: #: Config->Scheduler 'sch-rss_scan' : TT('Read RSS feeds'), #: #: Config->Scheduler 'sch-remove_failed' : TT('Remove failed jobs'), #: Config->Scheduler # General texts 'default' : TT('Default'), #: Default value, used in dropdown menus 'none' : TT('None'), #: No value, used in dropdown menus 'KBs' : TT('KB/s'), #: Speed indicator kilobytes/sec 'MB' : TT('MB'), #: Megabytes 'GB' : TT('GB'), #: Gigabytes 'hour' : TT('hour'), #: One hour 'hours' : TT('hours'), #: Multiple hours 'minute' : TT('min'), #: One minute 'minutes' : TT('mins'), #: Multiple minutes 'second' : TT('sec'), #: One second 'seconds' : TT('seconds'), #: Multiple seconds 'day' : TT('day'), 'days' : TT('days'), 'week' : TT('week'), 'month' : TT('Month'), 'year' : TT('Year'), 'daily' : TT('Daily'), 'monday' : TT('Monday'), 'tuesday' : TT('Tuesday'), 'wednesday' : TT('Wednesday'), 'thursday' : TT('Thursday'), 'friday' : TT('Friday'), 'saturday' : TT('Saturday'), 'sunday' : TT('Sunday'), 'day-of-month' : TT('Day of month'), 'thisWeek' : TT('This week'), 'thisMonth' : TT('This month'), 'today' : TT('Today'), 'total' : TT('Total'), 'on' : TT('on'), 'off' : TT('off'), 'parameters' : TT('Parameters'), #: Config: startup parameters of SABnzbd 'pythonVersion' : TT('Python Version'), 'homePage' : TT('Home page'), #: Home page of the SABnzbd project 'source' : TT('Source'), #: Where to find the SABnzbd sourcecode 'or' : TT('or'), #: Used in "IRC or IRC-Webaccess" 'host' : TT('Host'), 'comment' : TT('Comment'), 'send' : TT('Send'), 'cancel' : TT('Cancel'), 'other' : TT('Other'), 'report' : TT('Report'), 'video' : TT('Video'), 'audio' : TT('Audio'), 'notUsed' : TT('Not used'), 'orLess' : TT('or less'), # General template elements 'signOn' : TT('The automatic usenet download tool'), #: SABnzbd's theme line 'button-save' : TT('Save'), #: "Save" button 'queued' : TT('Queued'), #: "Queued" used to show amount of jobs 'button-back' : TT('Back'), #: Generic "Back" button 'button-x' : TT('X'), #: Generic "Delete" button, short form 'confirm' : TT('Are you sure?'), #: Used in confirmation popups 'delFiles' : TT('Delete all downloaded files?'), #: Used in confirmation popups # Header 'menu-home' : TT('Home'), #: Main menu item 'menu-queue' : TT('Queue'), #: Main menu item 'menu-history' : TT('History'), #: Main menu item 'menu-config' : TT('Config'), #: Main menu item 'menu-cons' : TT('Status'), #: Main menu item 'menu-help' : TT('Help'), #: Main menu item 'menu-wiki' : TT('Wiki'), #: Main menu item 'menu-forums' : TT('Forum'), #: Main menu item 'menu-irc' : TT('IRC'), #: Main menu item 'cmenu-general' : TT('General'), #: Main menu item 'cmenu-folders' : TT('Folders'), #: Main menu item 'cmenu-switches' : TT('Switches'), #: Main menu item 'cmenu-servers' : TT('Servers'), #: Main menu item 'cmenu-scheduling' : TT('Scheduling'), #: Main menu item 'cmenu-rss' : TT('RSS'), #: Main menu item 'cmenu-notif' : TT('Notifications'), #: Main menu item 'cmenu-email' : TT('Email'), #: Main menu item 'cmenu-newzbin' : TT('Index Sites'), #: Main menu item 'cmenu-cat' : TT('Categories'), #: Main menu item 'cmenu-sorting' : TT('Sorting'), #: Main menu item 'cmenu-special' : TT('Special'), #: Main menu item # Footer 'ft-download' : TT('Download Dir'), # Used in Footer 'ft-complete' : TT('Complete Dir'), # Used in Footer 'ft-speed' : TT('Download speed'), # Used in Footer 'ft-queued' : TT('Queued'), # Used in Footer 'ft-paused' : TT('PAUSED'), # Used in Footer 'ft-buffer@2' : TT('Cached %s articles (%s)'), # Used in Footer 'ft-sysload' : TT('Sysload'), # Used in Footer 'ft-warning' : TT('WARNINGS'), # Used in Footer 'ft-newRelease@1' : TT('New release %s available at'), # Used in Footer # Main page 'addNewJobs' : TT('Add new downloads'), 'shutdownOK?' : TT('Are you sure you want to shutdown SABnzbd?'), 'link-shutdown' : TT('Shutdown'), 'link-pause' : TT('Pause'), 'link-resume' : TT('Resume'), 'button-add' : TT('Add'), 'add' : TT('Add'), 'reportId' : TT('Report-id'), 'addFile' : TT('Add File'), 'category' : TT('Category'), 'pp' : TT('Processing'), 'script' : TT('Script'), 'priority' : TT('Priority'), 'pp-none' : TT('Download'), 'pp-repair' : TT('+Repair'), 'pp-unpack' : TT('+Unpack'), 'pp-delete' : TT('+Delete'), 'pp-n' : TT(' '), 'pp-r' : TT('R'), 'pp-u' : TT('U'), 'pp-d' : TT('D'), 'pr-force' : TT('Force'), 'pr-repair' : TT('Repair'), 'pr-normal' : TT('Normal'), 'pr-high' : TT('High'), 'pr-low' : TT('Low'), 'pr-paused' : TT('Paused'), 'pr-stop' : TT('Stop'), 'enterURL' : TT('Enter URL'), 'enterID' : TT(' or Report ID'), # Queue page 'link-sortByName' : TT('Sort by name'), #: Queue page button 'link-sortByAge' : TT('Sort by age'), #: Queue page button 'link-sortBySize' : TT('Sort by size'), #: Queue page button 'link-hideFiles' : TT('Hide files'), #: Queue page button 'link-showFiles' : TT('Show files'), #: Queue page button 'onQueueFinish' : TT('On queue finish'), #: Queue page selection menu 'shutdownPc' : TT('Shutdown PC'), #: Queue page end-of-queue action 'standbyPc' : TT('Standby PC'), #: Queue page end-of-queue action 'hibernatePc' : TT('Hibernate PC'), #: Queue page end-of-queue action 'shutdownSab' : TT('Shutdown SABnzbd'), #: Queue page end-of-queue action 'speedLimit' : TT('Speed Limit'), #: Queue page selection menu or entry box 'pauseFor' : TT('Pause for'), #: Queue page button or entry box 'mode' : TT('Processing'), #: Queue page table column header 'order' : TT('Order'), #: Queue page table column header 'name' : TT('Name'), #: Queue page table column header 'remainTotal' : TT('Remain/Total'), #: Queue page table column header 'eta' : TT('ETA'), #: Queue page table column header, "estimated time of arrival" 'age' : TT('AGE'), #: Queue page table column header, "age of the NZB" 'button-del' : TT('Del'), #: Queue page table, "Delete" button 'button-resume' : TT('Resume'), #: Queue page button 'button-pause' : TT('Pause'), #: Queue page button 'button-retry' : TT('Retry'), #: Queue page button 'eoq-actions' : TT('Actions'), #: Queue end-of-queue selection box 'eoq-scripts' : TT('Scripts'), #: Queue page table, script selection menu 'purgeQueue' : TT('Purge Queue'), #: Queue page button 'purgeQueueConf' : TT('Delete all items from the queue?'), #: Confirmation popup 'purgeNZBs' : TT('Purge NZBs'), #: Queue page button 'purgeNZBs-Files' : TT('Purge NZBs & Delete Files'), #: Queue page button 'removeNZB' : TT('Remove NZB'), #: Queue page button 'removeNZB-Files' : TT('Remove NZB & Delete Files'), #: Queue page button 'AofB' : TT('of'), #: Queue page, as in "4G *of* 10G" 'missingArt': TT('Missing articles'), #: Caption for missing articles in Queue 'quota-left' : TT('Quota left'), #: Remaining quota (displayed in Queue) 'manual' : TT('manual'), #: Manual reset of quota 'link-resetQuota' : TT('Reset Quota now'), # History page 'purgeHist' : TT('Purge History'), #: History page button 'purgeHistFailed' : TT('Purge Failed History'), #: History page button 'purgeHistConf' : TT('Delete all completed items from History?'), #: Confirmation popup 'purgeHistFailedConf' : TT('Delete all failed items from History?'), #: Confirmation popup 'hideDetails' : TT('Hide details'), #: Button/link hiding History job details 'showDetails' : TT('Show details'), #: Button/link showing History job details 'sizeHist' : TT('History Size'), #: History: amount of downloaded data 'showFailedHis' : TT('Show Failed'), #: Button or link showing only failed History jobs. DON'T MAKE THIS VERY LONG! 'showAllHis' : TT('Show All'), #: Button or link showing all History jobs 'completed' : TT('Completed'), #: History: job status 'size' : TT('Size'), #: History table header 'status' : TT('Status'), #: History table header 'purgeFailed' : TT('Purge Failed NZBs'), #: Button to delete all failed jobs in History 'purgeFailed-Files' : TT('Purge Failed NZBs & Delete Files'), #: Button to delete all failed jobs in History, including files 'purgeCompl' : TT('Purge Completed NZBs'), #: Button to delete all completed jobs in History 'opt-extra-NZB' : TT('Optional Supplemental NZB'), #: Button to add NZB to failed job in History 'msg-path' : TT('Path'), #: Path as displayed in History details 'spam' : TT('Virus/spam'), 'encrypted' : TT('Passworded'), 'expired' : TT('Out of retention'), 'otherProblem' : TT('Other problem'), # Connections page 'link-forceDisc' : TT('Force Disconnect'), #: Status page button 'askTestEmail' : TT('This will send a test email to your account.'), 'link-showLog' : TT('Show Logging'), #: Status page button 'link-showWeblog' : TT('Show Weblogging'), #: Status page button 'link-testEmail' : TT('Test Email'), #: Status page button 'logging' : TT('Logging'), #: Status page selection menu 'log-errWarn' : TT('Errors/Warning'), #: Status page table header 'log-info' : TT('+ Info'), #: Status page logging selection value 'log-debug' : TT('+ Debug'), #: Status page logging selection value 'connections' : TT('Connections'), #: Status page tab header 'thread' : TT('Thread'), #: Status page, server threads 'emailResult' : TT('Email Test Result'), #: Status page, title for email test result 'lastWarnings' : TT('Latest Warnings'), #: Status page, table header 'clearWarnings' : TT('clear'), #: Status page button 'server-blocked' : TT('Unblock'), #: Status page button 'article-id' : TT('Article identifier'), #: Status page, article identifier 'file-set' : TT('File set'), #: Status page, par-set that article belongs to 'warn-when' : TT('When'), #: Status page, table column header, when error occured 'warn-type' : TT('Type'), #: Status page, table column header, type of message 'warning' : TT('Warning'), #: Status page, table column header, actual message 'warnings' : TT('Warnings'), #: Footer: indicator of warnings 'enabled' : TT('Enabled'), #: Status page, indicator that server is enabled # Configuration 'configuration' : TT('Configuration'), 'confgFile' : TT('Config File'), 'cache' : TT('Used cache'), #: Main config page, how much cache is in use 'explain-Restart' : TT('This will restart SABnzbd.
    Use it when you think the program has a stability problem.
    Downloading will be paused before the restart and resume afterwards.'), 'button-restart' : TT('Restart'), 'explain-orphans' : TT('There are orphaned jobs in the download folder.
    You can choose to delete them (including files) or send them back to the queue.'), 'button-repair' : TT('Repair'), 'explain-Repair' : TT('The "Repair" button will restart SABnzbd and do a complete
    reconstruction of the queue content, preserving already downloaded files.
    This will modify the queue order.'), #'explain-Shutdown' : TT('This will end the SABnzbd process.
    You will be unable to access SABnzbd and no downloading will take place until the service is started again.'), 'version' : TT('Version'), 'uptime' : TT('Uptime'), 'backup' : TT('Backup'), #: Indicates that server is Backup server in Status page 'oznzb' : TT('OZnzb'), # Config->General 'generalConfig' : TT('General configuration'), 'restartRequired' : TT('Changes will require a SABnzbd restart!'), 'webServer' : TT('SABnzbd Web Server'), 'opt-host' : TT('SABnzbd Host'), 'explain-host' : TT('Host SABnzbd should listen on.'), 'opt-port' : TT('SABnzbd Port'), 'explain-port' : TT('Port SABnzbd should listen on.'), 'opt-web_dir' : TT('Web Interface'), 'explain-web_dir' : TT('Choose a skin.'), 'opt-web_dir2' : TT('Secondary Web Interface'), 'explain-web_dir2' : TT('Activate an alternative skin.'), 'webAuth' : TT('Web server authentication'), 'opt-web_username' : TT('SABnzbd Username'), 'explain-web_username' : TT('Optional authentication username.'), 'opt-web_password' : TT('SABnzbd Password'), 'explain-web_password' : TT('Optional authentication password.'), 'httpsSupport' : TT('HTTPS Support'), 'opt-enable_https' : TT('Enable HTTPS'), 'opt-notInstalled' : TT('not installed'), 'explain-enable_https' : TT('Enable accessing the interface from a HTTPS address.'), 'opt-https_port' : TT('HTTPS Port'), 'explain-https_port' : TT('If empty, the standard port will only listen to HTTPS.'), 'opt-https_cert' : TT('HTTPS Certificate'), 'explain-https_cert' : TT('File name or path to HTTPS Certificate.'), 'opt-https_key' : TT('HTTPS Key'), 'explain-https_key' : TT('File name or path to HTTPS Key.'), 'opt-https_chain' : TT('HTTPS Chain Certifcates'), 'explain-https_chain' : TT('File name or path to HTTPS Chain.'), 'tuning' : TT('Tuning'), 'opt-refresh_rate' : TT('Queue auto refresh interval:'), 'explain-refresh_rate' : TT('Refresh interval of the queue web-interface page(sec, 0= none).'), 'opt-rss_rate' : TT('RSS Checking Interval'), 'explain-rss_rate' : TT('Checking interval (in minutes, at least 15). Not active when you use the Scheduler!'), 'opt-bandwidth_limit' : TT('Download Speed Limit'), 'explain-bandwidth_limit' : TT('Download rate limit (in KB/s - kilobytes per second).'), 'opt-cache_limitstr' : TT('Article Cache Limit'), 'explain-cache_limitstr' : TT('Cache articles in memory to reduce disk access.
    In bytes, optionally follow with K,M,G. For example: "64M" or "128M"'), 'opt-cleanup_list' : TT('Cleanup List'), 'explain-cleanup_list' : TT('List of file extensions that should be deleted after download.
    For example: .nfo or .nfo, .sfv'), 'button-saveChanges' : TT('Save Changes'), 'opt-language' : TT('Language'), 'explain-language' : TT('Select a web interface language.'), 'opt-apikey' : TT('API Key'), 'explain-apikey' : TT('This key will give 3rd party programs full access to SABnzbd.'), 'opt-nzbkey' : TT('NZB Key'), 'explain-nzbkey' : TT('This key will allow 3rd party programs to add NZBs to SABnzbd.'), 'button-apikey' : TT('Generate New Key'), 'opt-disableApikey' : TT('Disable API-key'), 'explain-disableApikey' : TT('Do not require the API key.'), 'explain-disableApikeyWarn' : TT('USE AT YOUR OWN RISK!'), 'qr-code' : TT('QR Code'), #: Button to show QR code of APIKEY 'explain-qr-code' : TT('API Key QR Code'), #: Explanation for QR code of APIKEY # Config->Folders 'folderConfig' : TT('Folder configuration'), 'explain-folderConfig' : TT('NOTE: Folders will be created automatically when Saving. You may use absolute paths to save outside of the default folders.'), 'userFolders' : TT('User Folders'), 'in' : TT('In'), 'opt-download_dir' : TT('Temporary Download Folder'), 'explain-download_dir' : TT('Location to store unprocessed downloads.
    Can only be changed when queue is empty.'), 'opt-download_free' : TT('Minimum Free Space for Temporary Download Folder'), 'explain-download_free' : TT('Auto-pause when free space is beneath this value.
    In bytes, optionally follow with K,M,G,T. For example: "800M" or "8G"'), 'opt-complete_dir' : TT('Completed Download Folder'), 'explain-complete_dir' : TT('Location to store finished, fully processed downloads.
    Can be overruled by user-defined categories.'), 'opt-permissions' : TT('Permissions for completed downloads'), 'explain-permissions' : TT('Set permissions pattern for completed files/folders.
    In octal notation. For example: "755" or "777"'), 'opt-dirscan_dir' : TT('Watched Folder'), 'explain-dirscan_dir' : TT('Folder to monitor for .nzb files.
    Also scans .zip .rar and .tar.gz archives for .nzb files.'), 'opt-dirscan_speed' : TT('Watched Folder Scan Speed'), 'explain-dirscan_speed' : TT('Number of seconds between scans for .nzb files.'), 'opt-script_dir' : TT('Post-Processing Scripts Folder'), 'explain-script_dir' : TT('Folder containing user scripts for post-processing.'), 'opt-email_dir' : TT('Email Templates Folder'), 'explain-email_dir' : TT('Folder containing user-defined email templates.'), 'opt-password_file' : TT('Password file'), 'explain-password_file' : TT('File containing all passwords to be tried on encrypted RAR files.'), 'systemFolders' : TT('System Folders'), 'opt-admin_dir' : TT('Administrative Folder'), 'explain-admin_dir1' : TT('Location for queue admin and history database.
    Can only be changed when queue is empty.'), 'explain-admin_dir2' : TT('Data will not be moved. Requires SABnzbd restart!'), 'opt-log_dir' : TT('Log Folder'), 'explain-log_dir' : TT('Location of log files for SABnzbd.
    Requires SABnzbd restart!'), 'opt-nzb_backup_dir' : TT('.nzb Backup Folder'), 'explain-nzb_backup_dir' : TT('Location where .nzb files will be stored.'), 'base-folder' : TT('Default Base Folder'), # Config->Switches 'switchesConfig' : TT('Switches configuration'), 'processingSwitches' : TT('Processing Switches'), 'opt-quick_check' : TT('Enable Quick Check'), 'explain-quick_check' : TT('Skip par2 checking when files are 100% valid.'), 'opt-enable_unrar' : TT('Enable Unrar'), 'explain-enable_unrar' : TT('Enable built-in unrar functionality.'), 'opt-enable_unzip' : TT('Enable Unzip'), 'explain-enable_unzip' : TT('Enable built-in unzip functionality.'), 'opt-enable_filejoin' : TT('Enable Filejoin'), 'explain-enable_filejoin' : TT('Join files ending in .001, .002 etc. into one file.'), 'opt-enable_tsjoin' : TT('Enable TS Joining'), 'explain-ts_join' : TT('Join files ending in .001.ts, .002.ts etc. into one file.'), 'opt-enable_par_cleanup' : TT('Enable Par Cleanup'), 'explain-enable_par_cleanup' : TT('Cleanup par files (if verifiying/repairing succeded).'), 'opt-fail_on_crc' : TT('Fail on yEnc CRC Errors'), 'explain-fail_on_crc' : TT('When article has a CRC error, try to get it from another server.'), 'opt-top_only' : TT('Only Get Articles for Top of Queue'), 'explain-top_only' : TT('Enable for less memory usage. Disable to prevent slow jobs from blocking the queue.'), 'opt-safe_postproc' : TT('Post-Process Only Verified Jobs'), 'explain-safe_postproc' : TT('Only perform post-processing on jobs that passed all PAR2 checks.'), 'opt-pause_on_pwrar' : TT('Action when encrypted RAR is downloaded'), 'explain-pause_on_pwrar' : TT('In case of "Pause", you\'ll need to set a password and resume the job.'), 'opt-no_dupes' : TT('Detect Duplicate Downloads'), 'explain-no_dupes' : TT('Detect identically named NZB files (requires NZB backup option) and duplicate titles across RSS feeds.'), 'opt-action_on_unwanted_extensions' : TT('Action when unwanted extension detected'), 'explain-action_on_unwanted_extensions' : TT('Action when an unwanted extension is detected in RAR files'), 'opt-unwanted_extensions' : TT('Unwanted extensions'), 'explain-unwanted_extensions' : TT('List all unwanted extensions. For example: exe or exe, com'), 'nodupes-off' : TT('Off'), #: Three way switch for duplicates 'nodupes-ignore' : TT('Discard'), #: Three way switch for duplicates 'nodupes-pause' : TT('Pause'), #: Three way switch for duplicates 'abort' : TT('Abort'), #: Three way switch for encrypted posts 'opt-sfv_check' : TT('Enable SFV-based checks'), 'explain-sfv_check' : TT('Do an extra verification based on SFV files.'), 'opt-unpack_check' : TT('Check result of unpacking'), 'explain-unpack_check' : TT('Check result of unpacking (needs to be off for some file systems).'), 'opt-folder_rename' : TT('Enable folder rename'), 'explain-folder_rename' : TT('Use temporary names during post processing. Disable when your system doesn\'t handle that properly.'), 'opt-dirscan_opts' : TT('Default Post-Processing'), 'explain-dirscan_opts' : TT('Used when no post-processing is defined by the category.'), 'opt-dirscan_script' : TT('Default User Script'), 'explain-dirscan_script' : TT('Used when no user script is defined by the category.'), 'opt-pre_script' : TT('Pre-queue user script'), 'explain-pre_script' : TT('Used before an NZB enters the queue.'), 'opt-dirscan_priority' : TT('Default Priority'), 'explain-dirscan_priority' : TT('Used when no priority is defined by the category.'), 'opt-par2_multicore' : TT('Enable MultiCore Par2'), 'explain-par2_multicore' : TT('Read the Wiki Help on this!'), 'opt-par_option' : TT('Extra PAR2 Parameters'), 'explain-par_option' : TT('Read the Wiki Help on this!'), 'opt-nice' : TT('Nice Parameters'), 'explain-nice' : TT('Read the Wiki Help on this!'), 'opt-ionice' : TT('IONice Parameters'), 'explain-ionice' : TT('Read the Wiki Help on this!'), 'otherSwitches' : TT('Other Switches'), 'opt-auto_disconnect' : TT('Disconnect on Empty Queue'), 'explain-auto_disconnect' : TT('Disconnect from Usenet server(s) when queue is empty or paused.'), 'opt-send_group' : TT('Send Group'), 'explain-send_group' : TT('Send group command before requesting articles.'), 'opt-auto_sort' : TT('Sort by Age'), 'explain-auto_sort' : TT('Automatically sort items by (average) age.'), 'opt-check_new_rel' : TT('Check for New Release'), 'explain-check_new_rel' : TT('Weekly check for new SABnzbd release.'), 'also-test' : TT('Also test releases'), #: Pick list for weekly test for new releases 'opt-replace_spaces' : TT('Replace Spaces in Foldername'), 'explain-replace_spaces' : TT('Replace spaces with underscores in folder names.'), 'opt-replace_dots' : TT('Replace dots in Foldername'), 'explain-replace_dots' : TT('Replace dots with spaces in folder names.'), 'opt-replace_illegal' : TT('Replace Illegal Characters in Folder Names'), 'explain-replace_illegal' : TT('Replace illegal characters in folder names by equivalents (otherwise remove).'), 'opt-auto_browser' : TT('Launch Browser on Startup'), 'explain-auto_browser' : TT('Launch the default web browser when starting SABnzbd.'), 'opt-pause_on_post_processing' : TT('Pause Downloading During Post-Processing'), 'explain-pause_on_post_processing' : TT('Pauses downloading at the start of post processing and resumes when finished.'), 'opt-ignore_samples' : TT('Ignore Samples'), 'explain-ignore_samples' : TT('Filter out sample files (e.g. video samples).'), 'igsam-off' : TT('Off'), 'igsam-del' : TT('Delete after download'), 'igsam-not' : TT('Do not download'), 'opt-ssl_type' : TT('SSL type'), 'explain-ssl_type' : TT('Use V23 unless your provider requires otherwise!'), 'opt-ampm' : TT('Use 12 hour clock (AM/PM)'), 'explain-ampm' : TT('Show times in AM/PM notation (does not affect scheduler).'), 'swtag-general' : TT('General'), 'swtag-server' : TT('Server'), 'swtag-queue' : TT('Queue'), 'swtag-pp' : TT('Post processing'), 'swtag-naming' : TT('Naming'), 'swtag-quota' : TT('Quota'), 'swtag-indexing' : TT('Indexing'), 'opt-quota_size' : TT('Size'), #: Size of the download quota 'explain-quota_size' : TT('How much can be downloaded this month (K/M/G)'), 'opt-quota_day' : TT('Reset day'), #: Reset day of the download quota 'explain-quota_day' : TT('On which day of the month or week (1=Monday) does your ISP reset the quota? (Optionally with hh:mm)'), 'opt-quota_resume' : TT('Auto resume'), #: Auto-resume download on the reset day 'explain-quota_resume' : TT('Should downloading resume after the quota is reset?'), 'opt-quota_period' : TT('Quota period'), #: Does the quota get reset every day, week or month? 'explain-quota_period' : TT('Does the quota get reset each day, week or month?'), 'opt-pre_check' : TT('Check before download'), 'explain-pre_check' : TT('Try to predict successful completion before actual download (slower!)'), 'opt-max_art_tries' : TT('Maximum retries'), 'explain-max_art_tries' : TT('Maximum number of retries per server'), 'opt-max_art_opt' : TT('Only for optional servers'), 'explain-max_art_opt' : TT('Apply maximum retries only to optional servers'), 'opt-fail_hopeless' : TT('Abort jobs that cannot be completed'), 'explain-fail_hopeless' : TT('When during download it becomes clear that too much data is missing, abort the job'), 'opt-rating_enable' : TT('Enable OZnzb Integration'), 'explain-rating_enable' : TT('Enhanced functionality including ratings and extra status information is available when connected to OZnzb indexer.'), 'opt-rating_api_key' : TT('Site API Key'), 'explain-rating_api_key' : TT('This key provides identity to indexer. Refer to https://www.oznzb.com/profile.'), 'tip-rating_api_key' : TT('Refer to https://www.oznzb.com/profile'), 'opt-rating_feedback' : TT('Automatic Feedback'), 'explain-rating_feedback' : TT('Send automatically calculated validation results for downloads to indexer.'), 'opt-rating_filter_enable' : TT('Enable Filtering'), 'explain-rating_filter_enable' : TT('Action downloads according to filtering rules.'), 'opt-rating_filter_abort_if' : TT('Abort If'), 'opt-rating_filter_pause_if' : TT('Else Pause If'), 'opt-rating_filter_video' : TT('Video rating'), 'opt-rating_filter_audio' : TT('Audio rating'), 'opt-rating_filter_passworded' : TT('Passworded'), 'opt-rating_filter_spam' : TT('Spam'), 'opt-rating_filter_confirmed' : TT('Confirmed'), 'opt-rating_filter_downvoted' : TT('More thumbs down than up'), 'opt-rating_filter_keywords' : TT('Title keywords'), 'explain-rating_filter_keywords' : TT('Comma separated list'), # Config->Server 'configServer' : TT('Server configuration'), #: Caption 'defServer' : TT('Server definition'), # Caption 'addServer' : TT('Add Server'), #: Caption 'srv-host' : TT('Host'), #: Server hostname or IP 'srv-port' : TT('Port'), #: Server port 'srv-username' : TT('Username'), #: Server username 'srv-password' : TT('Password'), #: Server password 'srv-timeout' : TT('Timeout'), #: Server timeout 'srv-connections' : TT('Connections'), #: Server: amount of connections 'srv-retention' : TT('Retention time'), #: Server's retention time in days 'srv-ssl' : TT('SSL'), #: Server SSL tickbox 'srv-fillserver' : TT('Backup server'), #: Backup server tickbox 'srv-optional' : TT('Optional'), #: Server optional tickbox 'srv-enable' : TT('Enable'), #: Enable server tickbox 'button-addServer' : TT('Add Server'), #: Button: Add server 'button-delServer' : TT('Remove Server'), #: Button: Remove server 'button-testServer' : TT('Test Server'), #: Button: Test server 'button-clrServer' : TT('Clear Counters'), #: Button: Clear server's byte counters 'srv-testing' : TT('Testing server details...'), 'srv-testHint' : TT('Click below to test.'), 'srv-bandwidth' : TT('Bandwidth'), # Config->Scheduling 'configSchedule' : TT('Scheduling configuration'), 'addSchedule' : TT('Add Schedule'), 'sch-frequency' : TT('Frequency'), 'sch-action' : TT('Action'), 'sch-arguments' : TT('Arguments'), 'button-addSchedule' : TT('Add Schedule'), 'button-delSchedule' : TT('Remove'), 'currentSchedules' : TT('Current Schedules'), 'sch-resume' : TT('Resume'), 'sch-pause' : TT('Pause'), 'sch-shutdown' : TT('Shutdown'), 'sch-restart' : TT('Restart'), # Config->RSS 'configRSS' : TT('RSS Configuration'), 'newFeedURI' : TT('New Feed URL'), 'explain-RSS' : TT('The checkbox next to the feed name should be ticked for the feed to be enabled and be automatically checked for new items.
    When a feed is added, it will only pick up new items and not anything already in the RSS feed unless you press "Force Download".'), 'feed' : TT('Feed'), #: Config->RSS, tab header 'addFeed' : TT('Add Feed'), #: Config->RSS button 'button-delFeed' : TT('Delete Feed'),#: Config->RSS button 'button-preFeed' : TT('Read Feed'),#: Config->RSS button 'button-forceFeed' : TT('Force Download'),#: Config->RSS button 'rss-order' : TT('Order'), #: Config->RSS table column header 'rss-type' : TT('Type'), #: Config->RSS table column header 'rss-filter' : TT('Filter'), #: Config->RSS table column header 'rss-skip' : TT('Skip'), #: Config->RSS table column header 'rss-accept' : TT('Accept'), #: Config->RSS filter-type selection menu 'rss-reject' : TT('Reject'), #: Config->RSS filter-type selection menu 'rss-must' : TT('Requires'), #: Config->RSS filter-type selection menu 'rss-mustcat' : TT('RequiresCat'), #: Config->RSS filter-type selection menu 'rss-delFilter' : TT('X'), #: Config->RSS button "Delete filter" 'rss-matched' : TT('Matched'), #: Config->RSS section header 'rss-notMatched' : TT('Not Matched'), #: Config->RSS section header 'rss-done' : TT('Downloaded'), #: Config->RSS section header 'link-download' : TT('Download'), #: Config->RSS button "download item" 'tableFeeds' : TT('Feeds'), #: Tab title for Config->Feeds 'button-rssNow' : TT('Read All Feeds Now'), #: Config->RSS button 'feedSettings' : TT('Settings'), #: Tab title for Config->Feeds 'filters' : TT('Filters'), #: Tab title for Config->Feeds 'configEmail' : TT('Notifications'), #: Main Config page 'emailOptions' : TT('Email Options'), #: Section header 'opt-email_endjob' : TT('Email Notification On Job Completion'), 'email-never' : TT('Never'), #: When to send email 'email-always' : TT('Always'), #: When to send email 'email-errorOnly' : TT('Error-only'), #: When to send email 'opt-email_full' : TT('Disk Full Notifications'), 'explain-email_full' : TT('Send email when disk is full and SABnzbd is paused.'), 'opt-email_rss' : TT('Send RSS notifications'), 'explain-email_rss' : TT('Send email when an RSS feed adds jobs to the queue.'), 'emailAccount' : TT('Email Account Settings'), 'opt-email_server' : TT('SMTP Server'), 'explain-email_server' : TT('Set your ISP\'s server for outgoing email.'), 'opt-email_to' : TT('Email Recipient'), 'explain-email_to' : TT('Email address to send the email to.'), 'opt-email_from' : TT('Email Sender'), 'explain-email_from' : TT('Who should we say sent the email?'), 'opt-email_account' : TT('OPTIONAL Account Username'), 'explain-email_account' : TT('For authenticated email, account name.'), 'opt-email_pwd' : TT('OPTIONAL Account Password'), 'explain-email_pwd' : TT('For authenticated email, password.'), 'growlSettings' : TT('Notifications'), #: Section header 'opt-growl_enable' : TT('Enable Growl'), #: Don't translate "Growl" 'explain-growl_enable' : TT('Send notifications to Growl'), #: Don't translate "Growl" 'opt-growl_server' : TT('Server address'), #: Address of Growl server 'explain-growl_server' : TT('Only use for remote Growl server (host:port)'), #: Don't translate "Growl" 'opt-growl_password' : TT('Server password'), #: Growl server password 'explain-growl_password' : TT('Optional password for Growl server'), #: Don't translate "Growl" 'opt-ntfosd_enable' : TT('Enable NotifyOSD'), #: Don't translate "NotifyOSD" 'explain-ntfosd_enable' : TT('Send notifications to NotifyOSD'), #: Don't translate "NotifyOSD" 'opt-ncenter_enable' : TT('Notification Center'), 'explain-ncenter_enable' : TT('Send notifications to Notification Center'), 'opt-notify_classes' : TT('Notification classes'), 'explain-notify_classes' : TT('Enable classes of messages to be reported (none, one or multiple)'), 'testNotify' : TT('Test Notification'), # Config->Newzbin 'explain-newzbin' : TT('If you have an account at www.newzbin2.es, you can enter your account info here.
    This will unlock extra functionality.'), 'accountInfo' : TT('Account info'), 'opt-username_newzbin' : TT('Newzbin Username'), 'explain-username_newzbin' : TT('Set your account username here.'), 'opt-password_newzbin' : TT('Newzbin Password'), 'explain-password_newzbin' : TT('Set your account password here.'), 'newzbinBookmarks' : TT('Bookmark Processing'), 'opt-newzbin_bookmarks' : TT('Auto-Fetch Bookmarks'), 'explain-newzbin_bookmarks' : TT('Automatically retrieve jobs from your bookmarks.'), 'link-getBookmarks' : TT('Get Bookmarks Now'), 'link-HideBM' : TT('Hide Bookmarks'), 'link-ShowBM' : TT('Show Bookmarks'), 'opt-newzbin_unbookmark' : TT('Un-Bookmark If Download Complete'), 'explain-newzbin_unbookmark' : TT('Remove from bookmark list when download is complete.'), 'opt-bookmark_rate' : TT('Checking Interval'), 'explain-bookmark_rate' : TT('In minutes (at least 15 min).'), 'processedBM' : TT('Processed Bookmarks'), 'explain-nzbmatrix' : TT('If you have an account at www.nzbmatrix.com, you can enter your account info here.
    This is required if you want to use the RSS feeds of this site.'), 'opt-username_matrix' : TT('NzbMatrix Username'), 'explain-username_matrix' : TT('Set your account username here.'), 'opt-apikey_matrix' : TT('NzbMatrix API key'), 'explain-apikey_matrix' : TT('Set the NzbMatrix API key here.'), # Config->Cat 'configCat' : TT('User-defined categories'), 'explain-configCat' : TT('Defines post-processing and storage.'), 'explain-catTags' : TT('Use the "Groups / Indexer tags" column to map groups and tags to your categories.
    Wildcards are supported. Use commas to seperate terms.'), 'explain-catTags2' : TT('Ending the path with an asterisk * will prevent creation of job folders.'), 'explain-relFolder' : TT('Relative folders are based on'), 'catFolderPath' : TT('Folder/Path'), 'catTags' : TT('Groups / Indexer tags'), 'button-delCat' : TT('X'), # Config->Sorting 'configSort' : TT('Sorting configuration'), 'seriesSorting' : TT('Series Sorting'), 'opt-tvsort' : TT('Enable TV Sorting'), 'explain-tvsort' : TT('Enable sorting and renaming of episodes.'), 'sort-legenda' : TT('Pattern Key'), 'button-clear' : TT('Clear'), 'presetSort' : TT('Presets'), 'example' : TT('Example'), 'genericSort' : TT('Generic Sorting'), 'opt-movieSort' : TT('Enable Movie Sorting'), 'explain-movieSort' : TT('Enable generic sorting and renaming of files.'), 'opt-movieExtra' : TT('Keep loose downloads in extra folders'), 'explain-movieExtra' : TT('Enable if downloads are not put in their own folders.'), 'affectedCat' : TT('Affected Categories'), 'sort-meaning' : TT('Meaning'), 'sort-pattern' : TT('Pattern'), 'sort-result' : TT('Result'), 'button-Season1x05' : TT('1x05 Season Folder'), 'button-SeasonS01E05' : TT('S01E05 Season Folder'), 'button-Ep1x05' : TT('1x05 Episode Folder'), 'button-EpS01E05' : TT('S01E05 Episode Folder'), 'sort-title' : TT('Title'), 'movie-sp-name' : TT('Movie Name'), 'movie-dot-name' : TT('Movie.Name'), 'movie-us-name' : TT('Movie_Name'), 'show-name' : TT('Show Name'), 'show-sp-name' : TT('Show Name'), 'show-dot-name' : TT('Show.Name'), 'show-us-name' : TT('Show_Name'), 'show-seasonNum' : TT('Season Number'), 'show-epNum' : TT('Episode Number'), 'ep-name' : TT('Episode Name'), 'ep-sp-name' : TT('Episode Name'), 'ep-dot-name' : TT('Episode.Name'), 'ep-us-name' : TT('Episode_Name'), 'fileExt' : TT('File Extension'), 'extension' : TT('Extension'), 'partNumber' : TT('Part Number'), 'decade' : TT('Decade'), 'orgFilename' : TT('Original Filename'), 'orgDirname' : TT('Original Foldername'), 'lowercase' : TT('Lower Case'), 'TEXT' : TT('TEXT'), 'text' : TT('text'), 'sort-File' : TT('file'), 'sort-Folder' : TT('folder'), 'sortString' : TT('Sort String'), 'multiPartLabel' : TT('Multi-part label'), 'button-inFolders' : TT('In folders'), 'button-noFolders' : TT('No folders'), 'dateSorting' : TT('Date Sorting'), 'opt-dateSort' : TT('Enable Date Sorting'), 'explain-dateSort' : TT('Enable sorting and renaming of date named files.'), 'button-ShowNameF' : TT('Show Name folder'), 'button-YMF' : TT('Year-Month Folders'), 'button-DailyF' : TT('Daily Folders'), 'case-adjusted' : TT('case-adjusted'), #: Note for title expression in Sorting that does case adjustment 'sortResult' : TT('Processed Result'), # Config->Special 'explain-special' : TT('Rarely used options. For their meaning and explanation, click on the Help button to go to the Wiki page.
    ' 'Don\'t change these without checking the Wiki first, as some have serious side-effects.
    ' 'The default values are between parentheses.'), 'sptag-boolean' : TT('Switches'), 'sptag-entries' : TT('Values'), # NZO 'nzoDetails' : TT('Edit NZB Details'), #: Job details page 'nzoName' : TT('Name'), #: Job details page 'nzo-delete' : TT('Delete'), #: Job details page, delete button 'nzo-top' : TT('Top'), #: Job details page, move file to top 'nzo-up' : TT('Up'), #: Job details page, move file one place up 'nzo-down' : TT('Down'), #: Job details page, move file one place down 'nzo-bottom' : TT('Bottom'), #: Job details page, move file to bottom 'nzo-all' : TT('All'), #: Job details page, select all files 'nzo-none' : TT('None'), #: Job details page, select no files 'nzo-invert' : TT('Invert'), #: Job details page, invert file selection 'nzo-filename' : TT('Filename'), #: Job details page, filename column header 'nzo-subject' : TT('Subject'), #: Job details page, subject column header 'nzo-age' : TT('Age'), #: Job details page, file age column header 'nzo-selection' : TT('Selection'), #: Job details page, section header 'nzo-action' : TT('Action'), #: Job details page, section header #OSX Menu 'Mobile-confirm-delete' : TT('Are you sure you want to delete'), 'Mobile-button-refresh' : TT('Refresh'), 'Mobile-warnings' : TT('Warnings'), 'Mobile-button-options' : TT('Options'), 'Mobile-page' : TT('Page'), 'Mobile-button-prev' : TT('Prev'), 'Mobile-button-next' : TT('Next'), 'Mobile-button-first' : TT('First'), 'Mobile-button-last' : TT('Last'), 'Mobile-button-close' : TT('Close'), 'Mobile-button-pauseInterval' : TT('Set Pause Interval'), 'Mobile-sort' : TT('Sort'), 'Mobile-confirm-purgeQ' : TT('Purge the Queue?'), 'Mobile-button-purgeQ' : TT('Purge Queue'), 'Mobile-pauseInterval' : TT('Pause Interval'), 'Mobile-pause5m' : TT('Pause for 5 minutes'), 'Mobile-pause15m' : TT('Pause for 15 minutes'), 'Mobile-pause30m' : TT('Pause for 30 minutes'), 'Mobile-pause1h' : TT('Pause for 1 hour'), 'Mobile-pause3h' : TT('Pause for 3 hours'), 'Mobile-pause6h' : TT('Pause for 6 hours'), 'Mobile-pause12h' : TT('Pause for 12 hours'), 'Mobile-pause24h' : TT('Pause for 24 hours'), 'Mobile-sortAgeAsc' : TT('Sort by Age Oldest→Newest'), 'Mobile-sortAgeDesc' : TT('Sort by Age Newest→Oldest'), 'Mobile-sortNameAsc' : TT('Sort by Name A→Z'), 'Mobile-sortNameDesc' : TT('Sort by Name Z→A'), 'Mobile-sortSizeAsc' : TT('Sort by Size Smallest→Largest'), 'Mobile-sortSizeDesc' : TT('Sort by Size Largest→Smallest'), 'Mobile-rename' : TT('Rename'), 'Mobile-left' : TT('Left'), 'Mobile-confirm-purgeH' : TT('Purge the History?'), 'Mobile-button-purgeH' : TT('Purge History'), #Plush skin 'Plush-confirmWithoutSavingPrompt' : TT('Changes have not been saved, and will be lost.'), 'Plush-cmenu-scheduling' : TT('Scheduling'), 'Plush-confirm' : TT('Are you sure?'), 'Plush-openSourceURL' : TT('Open Source URL'), 'Plush-openInfoURL' : TT('Open Informational URL'), 'Plush-path' : TT('Path'), 'Plush-storage' : TT('Storage'), 'Plush-viewScriptLog' : TT('View Script Log'), 'Plush-prev' : TT('Prev'), 'Plush-next' : TT('Next'), 'Plush-confirmPurgeH' : TT('Purge the History?'), 'Plush-enableJavascript' : TT('You must enable JavaScript for Plush to function!'), 'Plush-addnzb' : TT('Add NZB'), 'Plush-button-refresh' : TT('Refresh'), 'Plush-options' : TT('Options'), 'Plush-plushoptions' : TT('Plush Options'), 'Plush-updateAvailable' : TT('Update Available!'), 'Plush-pause5m' : TT('Pause for 5 minutes'), 'Plush-pause15m' : TT('Pause for 15 minutes'), 'Plush-pause30m' : TT('Pause for 30 minutes'), 'Plush-pause1h' : TT('Pause for 1 hour'), 'Plush-pause3h' : TT('Pause for 3 hours'), 'Plush-pause6h' : TT('Pause for 6 hours'), 'Plush-pauseForPrompt' : TT('Pause for how many minutes?'), 'Plush-pauseFor' : TT('Pause for...'), 'Plush-multiOperations' : TT('Multi-Operations'), 'Plush-topMenu' : TT('Top Menu'), 'Plush-onQueueFinish' : TT('On Finish'), 'Plush-sort' : TT('Sort'), 'Plush-sortAgeAsc' : TT('Sort by Age (Oldest→Newest)'), 'Plush-sortAgeDesc' : TT('Sort by Age (Newest→Oldest)'), 'Plush-sortNameAsc' : TT('Sort by Name (A→Z)'), 'Plush-sortNameDesc' : TT('Sort by Name (Z→A)'), 'Plush-sortSizeAsc' : TT('Sort by Size (Smallest→Largest)'), 'Plush-sortSizeDesc' : TT('Sort by Size (Largest→Smallest)'), 'Plush-confirmPurgeQ' : TT('Purge the Queue?'), 'Plush-purge' : TT('Purge'), 'Plush-left' : TT('left'), 'Plush-maxSpeed' : TT('Max Speed'), #: Used in speed menu. Split in two lines if too long. 'Plush-nzo-range' : TT('Range'), 'Plush-reset' : TT('Reset'), 'Plush-applySelected' : TT('Apply to Selected'), 'Plush-page' : TT('page'), 'Plush-everything' : TT('Everything'), 'Plush-disabled' : TT('Disabled'), 'Plush-refreshRate' : TT('Refresh Rate'), 'Plush-containerWidth' : TT('Container Width'), 'Plush-confirmDeleteQueue' : TT('Confirm Queue Deletions'), 'Plush-confirmDeleteHistory' : TT('Confirm History Deletions'), 'Plush-explain-blockRefresh' : TT('This will prevent refreshing content when your mouse cursor is hovering over the queue.'), 'Plush-blockRefresh' : TT('Block Refreshes on Hover'), 'Plush-fetch' : TT('Fetch'), #: Fetch from URL button in "Add NZB" dialog box 'Plush-upload' : TT('Upload'), #: Upload button in "Add NZB" dialog box 'Plush-uploadTip' : TT('Upload: .nzb .rar .zip .gz'), 'Plush-addnzb-filename' : TT('Optionally specify a filename'), 'Plush-progress' : TT('Progress'), 'Plush-remaining' : TT('Remaining'), 'Plush-notEnoughSpace' : TT('Not enough disk space to complete downloads!'), 'Plush-freeSpace' : TT('Free Space'), 'Plush-freeSpaceTemp' : TT('Free (Temp)'), 'Plush-idle' : TT('IDLE'), 'Plush-downloads' : TT('Downloads'), 'Plush-tab-repair' : TT('Queue repair'), 'Plush-rss-delete' : TT('Delete'), 'Plush-rss-actions' : TT('Actions'), 'Plush-explain-rssActions' : TT('Read Feed will get the current feed content. Force Download will download all matching NZBs now.'), #smpl skin 'smpl-hourmin' : TT('Hour:Min'), 'smpl-purgehist' : TT('Delete Completed'), 'smpl-purgefailhistOK?' : TT('Delete the all failed items from the history?'), 'smpl-purgefailhist' : TT('Delete Failed'), 'smpl-links' : TT('Links'), 'smpl-size' : TT('Size'), 'smpl-path' : TT('Path'), 'smpl-numresults@3' : TT('Showing %s to %s out of %s results'), 'smpl-noresult' : TT('No results'), 'smpl-oneresult' : TT('Showing one result'), 'smpl-first' : TT('First'), 'smpl-previous' : TT('Prev'), 'smpl-next' : TT('Next'), 'smpl-last' : TT('Last'), 'smpl-pauseForPrompt' : TT('Pause for how many minutes?'), 'smpl-paused' : TT('Paused'), 'smpl-downloading' : TT('Downloading'), 'smpl-idle' : TT('Idle'), 'smpl-emailsent' : TT('Email Sent!'), 'smpl-notesent' : TT('Notification Sent!'), 'smpl-saving' : TT('Saving..'), 'smpl-saved' : TT('Saved'), 'smpl-failed' : TT('Failed'), 'smpl-speed' : TT('Speed'), 'smpl-toggleadd' : TT('Toggle Add NZB'), 'smpl-dualView1' : TT('DualView1'), 'smpl-dualView2' : TT('DualView2'), 'smpl-warnings' : TT('Warnings'), 'smpl-custom' : TT('Custom'), 'smpl-getbookmarks' : TT('Get Bookmarks'), 'smpl-restartOK?' : TT('Are you sure you want to restart SABnzbd?'), 'smpl-refreshr' : TT('Refresh rate'), 'smpl-purgeQueue' : TT('Delete All'), 'smpl-hideEdit' : TT('Hide Edit Options'), 'smpl-showEdit' : TT('Show Edit Options'), 'smpl-edit' : TT('Edit'), 'smpl-progress' : TT('Progress'), 'smpl-timeleft' : TT('Timeleft'), 'smpl-age' : TT('Age'), #Wizard 'wizard-quickstart' : TT('SABnzbd Quick-Start Wizard'), 'wizard-version' : TT('SABnzbd Version'), 'wizard-previous' : TT('Previous'), #: Button to go to previous Wizard page 'wizard-next' : TT('Next'), #: Button to go to next Wizard page 'wizard-access' : TT('Access'), #: Wizard step in which the web server is set 'wizard-access-anypc' : TT('I want SABnzbd to be viewable by any pc on my network.'), 'wizard-access-mypc' : TT('I want SABnzbd to be viewable from my pc only.'), 'wizard-access-pass' : TT('Password protect access to SABnzbd (recommended)'), 'wizard-access-https' : TT('Enable HTTPS access to SABnzbd.'), 'wizard-misc' : TT('Misc'), #: Wizard step 'wizard-misc-browser' : TT('Launch my internet browser with the SABnzbd page when the program starts.'), 'wizard-server' : TT('Server Details'), 'wizard-explain-server' : TT('Please enter in the details of your primary usenet provider.'), 'wizard-server-help' : TT('Help'), #: Wizard help link 'wizard-server-help1' : TT('In order to download from usenet you will require access to a provider. Your ISP may provide you with access, however a premium provider is recommended.'), 'wizard-server-help2' : TT('Don\'t have a usenet provider? We recommend trying %s.'), 'wizard-server-con-explain' : TT('The number of connections allowed by your provider'), 'wizard-server-con-eg' : TT('E.g. 8 or 20'), #: Wizard: examples of amount of connections 'wizard-server-ssl-explain' : TT('Select only if your provider allows SSL connections.'), 'wizard-server-text' : TT('Click to test the entered details.'), 'wizard-server-required' : TT('This field is required.'), 'wizard-server-number' : TT('Please enter a whole number.'), 'wizard-index-explain' : TT('If you are a member of newzbin or nzbmatrix, you may enter your username and password here so we can fetch their nzb\'s. This stage can be skipped if you don\'t use either services.'), 'wizard-index-bookmark' : TT('Automatically download bookmarked posts.'), 'wizard-optional' : TT('Optional'), #: As in "this item is optional" 'wizard-example' : TT('E.g.'), #: Abbreviation for "for example" 'wizard-button-testServer' : TT('Test Server'), #: Wizard step 'wizard-restarting' : TT('Restarting SABnzbd...'), #: Wizard step 'wizard-complete' : TT('Setup is now complete!'), #: Wizard step 'wizard-tip1' : TT('SABnzbd will now be running in the background.'), #: Wizard tip 'wizard-tip2' : TT('Closing any browser windows/tabs will NOT close SABnzbd.'), #: Wizard tip 'wizard-tip3' : TT('After SABnzbd has finished restarting you will be able to access it at the following location: %s'), #: Wizard tip 'wizard-tip4' : TT('It is recommended you right click and bookmark this location and use this bookmark to access SABnzbd when it is running in the background.'), #: Wizard tip 'wizard-tip-wiki' : TT('Further help can be found on our'), #: Will be appended with a wiki-link, adjust word order accordingly 'wizard-goto' : TT('Go to SABnzbd'), #: Wizard step 'wizard-step-one' : TT('Step One'), #: Wizard step 'wizard-step-two' : TT('Step Two'), #: Wizard step 'wizard-step-three' : TT('Step Three'), #: Wizard step 'wizard-step-four' : TT('Step Four'), #: Wizard step 'wizard-step-five' : TT('Step Five'), #: Wizard step 'wizard-port-eg' : TT('E.g. 119 or 563 for SSL'), #: Wizard port number examples 'wizard-exit' : TT('Exit SABnzbd'), #: Wizard EXIT button on first page 'wizard-start' : TT('Start Wizard'), #: Wizard START button on first page 'wizard-create-account' : TT('If you do not have an account it can be created at '), #Special 'yourRights' : TT(''' SABnzbd comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. It is licensed under the GNU GENERAL PUBLIC LICENSE Version 2 or (at your option) any later version. ''') } SABnzbd-0.7.20/sabnzbd/trylist.py0000644000000000000000000000425712433712602016744 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.trylist - trylist class """ import logging from threading import Lock import sabnzbd from sabnzbd.decorators import synchronized # TryList keeps track of which servers have been tried for # a specific article # TryList should be redefined as a new-style class. # However, this would break queue compatibility with # previous releases (despite the mapping done in nzbstuff). TRYLIST_LOCK = Lock() class TryList: def __init__(self): self.__try_list = [] @synchronized(TRYLIST_LOCK) def server_in_try_list(self, server): """ Return whether specified server has been tried """ return (server in self.__try_list) @synchronized(TRYLIST_LOCK) def add_to_try_list(self, server): """ Register server as having been tried already """ if server not in self.__try_list: if sabnzbd.LOG_ALL: logging.debug("Appending %s to %s.__try_list", server, self) self.__try_list.append(server) @synchronized(TRYLIST_LOCK) def remove_from_try_list(self, server): """ Server is no longer listed as tried """ if server in self.__try_list: if sabnzbd.LOG_ALL: logging.debug("Removing %s from %s.__try_list", server, self) self.__try_list.remove(server) @synchronized(TRYLIST_LOCK) def reset_try_list(self): """ Clean the list """ if self.__try_list: self.__try_list = [] SABnzbd-0.7.20/sabnzbd/tvsort.py0000644000000000000000000012745612433712602016602 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.tvsort - Sorting Functions Series Sorting - Sorting downloads into seasons & episodes Date sorting - Sorting downloads by a custom date matching Generic Sorting - Sorting large files by a custom matching """ import os import logging import re import sabnzbd from sabnzbd.misc import move_to_path, cleanup_empty_directories, get_unique_path, \ get_unique_filename, get_ext, renamer, sanitize_foldername from sabnzbd.constants import series_match, date_match, year_match, sample_match import sabnzbd.cfg as cfg from sabnzbd.encoding import titler, latin1 RE_SAMPLE = re.compile(sample_match, re.I) # Do not rename .vob files as they are usually DVD's EXCLUDED_FILE_EXTS = ('.vob', '.bin') LOWERCASE = ('the', 'of', 'and', 'at', 'vs', 'a', 'an', 'but', 'nor', 'for', 'on', \ 'so', 'yet') UPPERCASE = ('III', 'II', 'IV') REPLACE_AFTER = { '()': '', '..': '.', '__': '_', ' ': ' ', ' .%ext': '.%ext' } # Title() function messes up country names, so need to replace them instead COUNTRY_REP = ('(US)', '(UK)', '(EU)', '(CA)', '(YU)', '(VE)', '(TR)', '(CH)', \ '(SE)', '(ES)', '(KR)', '(ZA)', '(SK)', '(SG)', '(RU)', '(RO)', \ '(PR)', '(PT)', '(PL)', '(PH)', '(PK)', '(NO)', '(NG)', '(NZ)', \ '(NL)', '(MX)', '(MY)', '(MK)', '(KZ)', '(JP)', '(JM)', '(IT)', \ '(IL)', '(IE)', '(IN)', '(IS)', '(HU)', '(HK)', '(HN)', '(GR)', \ '(GH)', '(DE)', '(FR)', '(FI)', '(DK)', '(CZ)', '(HR)', '(CR)', \ '(CO)', '(CN)', '(CL)', '(BG)', '(BR)', '(BE)', '(AT)', '(AU)', \ '(AW)', '(AR)', '(AL)', '(AF)') _RE_ENDEXT = re.compile(r'\.%ext[{}]*$', re.I) _RE_ENDFN = re.compile(r'%fn[{}]*$', re.I) def ends_in_file(path): """ Return True when path ends with '.%ext' or '%fn' """ return bool(_RE_ENDEXT.search(path) or _RE_ENDFN.search(path)) def move_to_parent_folder(workdir): """ Move all in 'workdir' into 'workdir/..' """ # Determine 'folder'/.. workdir = os.path.abspath(os.path.normpath(workdir)) dest = os.path.normpath(os.path.join(workdir, '..')) # Check for DVD folders and stop if found for item in os.listdir(workdir): if item.lower() in ('video_ts', 'audio_ts', 'bdmv'): return workdir, True for root, dirs, files in os.walk(workdir): for _file in files: path = os.path.join(root, _file) new_path = path.replace(workdir, dest) ok, new_path = move_to_path(path, new_path) if not ok: return dest, False cleanup_empty_directories(workdir) return dest, True class Sorter(object): """ Generic Sorter class """ def __init__(self, nzo, cat): self.sorter = None self.type = None self.sort_file = False self.nzo = nzo self.cat = cat self.ext = '' def detect(self, dirname, complete_dir): """ Detect which kind of sort applies """ self.sorter = SeriesSorter(self.nzo, dirname, complete_dir, self.cat) if self.sorter.matched: complete_dir = self.sorter.get_final_path() self.type = 'tv' self.sort_file = True return complete_dir self.sorter = DateSorter(self.nzo, dirname, complete_dir, self.cat) if self.sorter.matched: complete_dir = self.sorter.get_final_path() self.type = 'date' self.sort_file = True return complete_dir self.sorter = GenericSorter(self.nzo, dirname, complete_dir, self.cat) if self.sorter.matched: complete_dir = self.sorter.get_final_path() self.type = 'movie' self.sort_file = True return complete_dir self.sort_file = False return complete_dir def rename(self, newfiles, workdir_complete): """ Rename files of the job """ if self.sorter.rename_or_not: self.sorter.rename(newfiles, workdir_complete) def rename_with_ext(self, workdir_complete): """ Special renamer for %ext """ if self.sorter.rename_or_not and '%ext' in workdir_complete and self.ext: # Replace %ext with extension newpath = workdir_complete.replace('%ext', self.ext) try: renamer(workdir_complete, newpath) except: return newpath, False return newpath, True else: return workdir_complete, True def move(self, workdir_complete): ok = True if self.type == 'movie': move_to_parent = True # check if we should leave the files inside an extra folder if cfg.movie_extra_folders(): #if there is a folder in the download, leave it in an extra folder move_to_parent = not check_for_folder(workdir_complete) if move_to_parent: workdir_complete, ok = move_to_parent_folder(workdir_complete) else: workdir_complete, ok = move_to_parent_folder(workdir_complete) if not ok: return workdir_complete, False path, part = os.path.split(workdir_complete) if '%fn' in part and self.sorter.fname: old = workdir_complete workdir_complete = os.path.join(path, part.replace('%fn', self.sorter.fname)) workdir_complete = get_unique_path(workdir_complete, create_dir=False) try: renamer(old, workdir_complete) except: logging.error(Ta('Cannot create directory %s'), workdir_complete) workdir_complete = old ok = False return workdir_complete, ok class SeriesSorter(object): """ Methods for Series Sorting """ def __init__(self, nzo, dirname, path, cat): self.matched = False self.original_dirname = dirname self.original_path = path self.nzo = nzo self.cat = cat self.sort_string = cfg.tv_sort_string() self.cats = cfg.tv_categories() self.filename_set = '' self.fname = '' # Value for %fn substitution in folders self.final_path = '' self.match_obj = None self.extras = None self.descmatch = None self.rename_or_not = False self.show_info = {} #Check if it is a TV show on init() self.match() def match(self, force=False): ''' Checks the regex for a match, if so set self.match to true ''' if force or (cfg.enable_tv_sorting() and cfg.tv_sort_string()): if force or (not self.cats) or (self.cat and self.cat.lower() in self.cats) or (not self.cat and 'None' in self.cats): #First check if the show matches TV episode regular expressions. Returns regex match object self.match_obj, self.extras = check_regexs(self.original_dirname, series_match) if self.match_obj: logging.debug("Found TV Show - Starting folder sort (%s)", self.original_dirname) self.matched = True def is_match(self): ''' Returns whether there was a match or not ''' return self.matched def get_final_path(self): """ Collect and construct all the variables such as episode name, show names """ if self.get_values(): # Get the final path path = self.construct_path() self.final_path = os.path.join(self.original_path, path) return self.final_path else: # Error Sorting return os.path.join(self.original_path, self.original_dirname) def get_multi_ep_naming(self, one, two, extras): ''' Returns a list of unique values joined into a string and seperated by - (ex:01-02-03-04) ''' extra_list = [one] extra2_list = [two] for extra in extras: if extra not in (extra_list, extra2_list): ep_no2 = extra.rjust(2,'0') extra_list.append(extra) extra2_list.append(ep_no2) one = '-'.join(extra_list) two = '-'.join(extra2_list) return (one, two) def get_shownames(self): ''' Get the show name from the match object and format it ''' # Get the formatted title and alternate title formats self.show_info['show_tname'], self.show_info['show_tname_two'], self.show_info['show_tname_three'] = get_titles(self.nzo, self.match_obj, self.original_dirname, True) self.show_info['show_name'], self.show_info['show_name_two'], self.show_info['show_name_three'] = get_titles(self.nzo, self.match_obj, self.original_dirname) def get_seasons(self): ''' Get the season number from the match object and format it ''' try: season = self.match_obj.group(1).strip('_') # season number except AttributeError: season = '1' # Provide alternatve formatting (0 padding) if season.lower() == 's': season2 = season else: try: season = str(int(season)) except: pass season2 = season.rjust(2,'0') self.show_info['season_num'] = season self.show_info['season_num_alt'] = season2 def get_episodes(self): ''' Get the episode numbers from the match object, format and join them ''' try: ep_no = self.match_obj.group(2) # episode number except AttributeError: ep_no = '1' # Store the original episode number # Provide alternatve formatting (0 padding) ep_no2 = ep_no.rjust(2,'0') try: ep_no = str(int(ep_no)) except: pass # Dual episode support if self.extras: ep_no, ep_no2 = self.get_multi_ep_naming(ep_no, ep_no2, self.extras) self.show_info['episode_num'] = ep_no self.show_info['episode_num_alt'] = ep_no2 def get_showdescriptions(self): ''' Get the show descriptions from the match object and format them ''' self.show_info['ep_name'], self.show_info['ep_name_two'], self.show_info['ep_name_three'] = get_descriptions(self.nzo, self.match_obj, self.original_dirname) def get_values(self): """ Collect and construct all the values needed for path replacement """ try: ## - Show Name self.get_shownames() ## - Season self.get_seasons() ## - Episode Number self.get_episodes() ## - Episode Name self.get_showdescriptions() return True except: logging.error(Ta('Error getting TV info (%s)'), self.original_dirname) logging.info("Traceback: ", exc_info = True) return False def construct_path(self): ''' Replaces the sort string with real values such as Show Name and Episode Number ''' sorter = self.sort_string.replace('\\', '/') mapping = [] if ends_in_file(sorter): extension = True sorter = sorter.replace('.%ext', '') else: extension = False # Replace Show name mapping.append(('%sn', self.show_info['show_tname'])) mapping.append(('%s.n', self.show_info['show_tname_two'])) mapping.append(('%s_n', self.show_info['show_tname_three'])) mapping.append(('%sN', self.show_info['show_name'])) mapping.append(('%s.N', self.show_info['show_name_two'])) mapping.append(('%s_N', self.show_info['show_name_three'])) # Replace season number mapping.append(('%s', self.show_info['season_num'])) mapping.append(('%0s', self.show_info['season_num_alt'])) # Original dir name mapping.append(('%dn', self.original_dirname)) # Replace episode names if self.show_info['ep_name']: mapping.append(('%en', self.show_info['ep_name'])) mapping.append(('%e.n', self.show_info['ep_name_two'])) mapping.append(('%e_n', self.show_info['ep_name_three'])) else: mapping.append(('%en', '')) mapping.append(('%e.n', '')) mapping.append(('%e_n', '')) # Replace episode number mapping.append(('%e', self.show_info['episode_num'])) mapping.append(('%0e', self.show_info['episode_num_alt'])) # Make sure unsupported %desc is removed mapping.append(('%desc', '')) # Replace elements path = path_subst(sorter, mapping) for key, name in REPLACE_AFTER.iteritems(): path = path.replace(key, name) # Lowercase all characters encased in {} path = to_lowercase(path) # Strip any extra ' ' '.' or '_' around foldernames path = strip_folders(path) # Split the last part of the path up for the renamer if extension: head, tail = os.path.split(path) self.filename_set = tail self.rename_or_not = True else: head = path return os.path.normpath(head) def rename(self, files, current_path): """ Rename for Series """ logging.debug("Renaming Series") largest = (None, None, 0) def to_filepath(f, current_path): if is_full_path(f): filepath = os.path.normpath(f) else: filepath = os.path.normpath(os.path.join(current_path, f)) return filepath # Create a generator of filepaths, ignore sample files and excluded files (vobs ect) filepaths = ((file, to_filepath(file, current_path)) for file in files if not RE_SAMPLE.search(file) \ and get_ext(file) not in EXCLUDED_FILE_EXTS) # Find the largest existing file for file, fp in filepaths: # If for some reason the file no longer exists, skip if not os.path.exists(fp): continue size = os.stat(fp).st_size f_file, f_fp, f_size = largest if size > f_size: largest = (file, fp, size) file, filepath, size = largest # >20MB if filepath and size > 20971520: self.fname, self.ext = os.path.splitext(os.path.split(file)[1]) newname = "%s%s" % (self.filename_set, self.ext) # Replace %fn with the original filename newname = newname.replace('%fn', self.fname) newpath = os.path.join(current_path, newname) # Replace %ext with extension newpath = newpath.replace('%ext', self.ext) try: logging.debug("Rename: %s to %s", filepath, newpath) renamer(filepath, newpath) except: logging.error("Failed to rename: %s to %s", current_path, newpath) logging.info("Traceback: ", exc_info = True) rename_similar(current_path, self.ext, self.filename_set, ()) else: logging.debug('Nothing to rename, %s', files) _RE_MULTIPLE = ( \ re.compile(r'cd\W?(\d+)\W?', re.I), # .cd1.avi re.compile(r'\w\W?([\w\d])[{}]*$', re.I), # blah1.avi blaha.avi re.compile(r'\w\W([\w\d])\W', re.I) # blah-1-ok.avi blah-a-ok.avi ) def check_for_multiple(files): """ Return list of files that looks like a multi-part post """ for regex in _RE_MULTIPLE: matched_files = check_for_sequence(regex, files) if matched_files: return matched_files return '' def check_for_sequence(regex, files): """ Return list of files that looks like a sequence, using 'regex' """ matches = {} prefix = None # Build up a dictionary of matches # The key is based off the match, ie {1:'blah-part1.avi'} for _file in files: name, ext = os.path.splitext(_file) match1 = regex.search(name) if match1: if not prefix or prefix == name[:match1.start()]: matches[match1.group(1)] = name+ext prefix = name[:match1.start()] # Don't do anything if only one or no files matched if len(matches.keys()) < 2: return {} key_prev = 0 passed = True alphabet = 'abcdefghijklmnopqrstuvwxyz' # Check the dictionary to see if the keys are in a numeric or alphabetic sequence for akey in sorted(matches.keys()): if akey.isdigit(): key = int(akey) elif akey in alphabet: key = alphabet.find(akey) + 1 else: passed = False if passed: if not key_prev: key_prev = key else: if key_prev + 1 == key: key_prev = key else: passed = False if passed: # convert {'b':'filename-b.avi'} to {'2', 'filename-b.avi'} item = matches.pop(akey) matches[str(key)] = item if passed: return matches else: return {} class GenericSorter(object): """ Methods for Generic Sorting """ def __init__(self, nzo, dirname, path, cat): self.matched = False self.original_dirname = dirname self.original_path = path self.sort_string = cfg.movie_sort_string() self.extra = cfg.movie_sort_extra() self.cats = cfg.movie_categories() self.cat = cat self.nzo = nzo self.filename_set = '' self.fname = '' # Value for %fn substitution in folders self.final_path = '' self.match_obj = None self.rename_or_not = False self.movie_info = {} # Check if we match the category in init() self.match() def match(self, force=False): """ Checks the category for a match, if so set self.match to true """ if force or (cfg.enable_movie_sorting() and self.sort_string): #First check if the show matches TV episode regular expressions. Returns regex match object if force or (self.cat and self.cat.lower() in self.cats) or (not self.cat and 'None' in self.cats): logging.debug("Movie Sorting - Starting folder sort (%s)", self.original_dirname) self.matched = True def get_final_path(self): """ Collect and construct all the variables such as episode name, show names """ if self.get_values(): # Get the final path path = self.construct_path() self.final_path = os.path.join(self.original_path, path) return self.final_path else: # Error Sorting return os.path.join(self.original_path, self.original_dirname) def get_values(self): """ Collect and construct all the values needed for path replacement """ ## - Get Year if self.nzo: year = self.nzo.nzo_info.get('year') or self.nzo.meta.get('year', (None,))[0] else: year = '' if year: year_m = None else: dirname = self.original_dirname.replace('_', ' ') RE_YEAR = re.compile(year_match, re.I) year_m = RE_YEAR.search(dirname) if year_m: # Find the last matched date # Keep year_m to use in get_titles year = RE_YEAR.findall(dirname)[-1][0] else: year = '' self.movie_info['year'] = year ## - Get Decades self.movie_info['decade'], self.movie_info['decade_two'] = get_decades(year) ## - Get Title self.movie_info['ttitle'], self.movie_info['ttitle_two'], self.movie_info['ttitle_three'] = get_titles(self.nzo, year_m, self.original_dirname, True) self.movie_info['title'], self.movie_info['title_two'], self.movie_info['title_three'] = get_titles(self.nzo, year_m, self.original_dirname) return True def construct_path(self): """ Return path reconstructed from orginal and sort expression """ sorter = self.sort_string.replace('\\', '/') mapping = [] if ends_in_file(sorter): extension = True sorter = sorter.replace(".%ext", '') else: extension = False # Replace title mapping.append(('%title', self.movie_info['title'])) mapping.append(('%.title', self.movie_info['title_two'])) mapping.append(('%_title', self.movie_info['title_three'])) # Replace title (short forms) mapping.append(('%t', self.movie_info['title'])) mapping.append(('%.t', self.movie_info['title_two'])) mapping.append(('%_t', self.movie_info['title_three'])) mapping.append(('%sn', self.movie_info['title'])) mapping.append(('%s.n', self.movie_info['title_two'])) mapping.append(('%s_n', self.movie_info['title_three'])) mapping.append(('%sN', self.movie_info['ttitle'])) mapping.append(('%s.N', self.movie_info['ttitle_two'])) mapping.append(('%s_N', self.movie_info['ttitle_three'])) # Replace year mapping.append(('%y', self.movie_info['year'])) # Replace decades mapping.append(('%decade', self.movie_info['decade'])) mapping.append(('%0decade', self.movie_info['decade_two'])) # Original dir name mapping.append(('%dn', self.original_dirname)) path = path_subst(sorter, mapping) for key, name in REPLACE_AFTER.iteritems(): path = path.replace(key, name) # Lowercase all characters encased in {} path = to_lowercase(path) # Strip any extra ' ' '.' or '_' around foldernames path = strip_folders(path) # Split the last part of the path up for the renamer if extension: head, tail = os.path.split(path) self.filename_set = tail self.rename_or_not = True else: head = path return os.path.normpath(head) def rename(self, _files, current_path): """ Rename for Generic files """ logging.debug("Renaming Generic file") def filter_files(_file, current_path): if is_full_path(_file): filepath = os.path.normpath(_file) else: filepath = os.path.normpath(os.path.join(current_path, _file)) if os.path.exists(filepath): size = os.stat(filepath).st_size if size >= cfg.movie_rename_limit.get_int() and not RE_SAMPLE.search(_file) \ and get_ext(_file) not in EXCLUDED_FILE_EXTS: return True return False # remove any files below the limit from this list files = [_file for _file in _files if filter_files(_file, current_path)] length = len(files) ## Single File Handling if length == 1: file = files[0] if is_full_path(file): filepath = os.path.normpath(file) else: filepath = os.path.normpath(os.path.join(current_path, file)) if os.path.exists(filepath): self.fname, ext = os.path.splitext(os.path.split(file)[1]) newname = "%s%s" % (self.filename_set, ext) newname = newname.replace('%fn', self.fname) newpath = os.path.join(current_path, newname) try: logging.debug("Rename: %s to %s", filepath, newpath) renamer(filepath, newpath) except: logging.error(Ta('Failed to rename: %s to %s'), filepath, newpath) logging.info("Traceback: ", exc_info = True) rename_similar(current_path, ext, self.filename_set, ()) ## Sequence File Handling # if there is more than one extracted file check for CD1/1/A in the title elif self.extra: matched_files = check_for_multiple(files) # rename files marked as in a set if matched_files: logging.debug("Renaming a series of generic files (%s)", matched_files) renamed = matched_files.values() for index, file in matched_files.iteritems(): filepath = os.path.join(current_path, file) renamed.append(filepath) self.fname, ext = os.path.splitext(os.path.split(file)[1]) name = '%s%s' % (self.filename_set, self.extra) name = name.replace('%1', str(index)).replace('%fn', self.fname) name = name + ext newpath = os.path.join(current_path, name) try: logging.debug("Rename: %s to %s", filepath, newpath) renamer(filepath, newpath) except: logging.error(Ta('Failed to rename: %s to %s'), filepath, newpath) logging.info("Traceback: ", exc_info = True) rename_similar(current_path, ext, self.filename_set, renamed) else: logging.debug("Movie files not in sequence %s", _files) class DateSorter(object): """ Methods for Date Sorting """ def __init__(self, nzo, dirname, path, cat): self.matched = False self.original_dirname = dirname self.original_path = path self.sort_string = cfg.date_sort_string() self.cats = cfg.date_categories() self.cat = cat self.nzo = nzo self.filename_set = '' self.fname = '' # Value for %fn substitution in folders self.match_obj = None self.rename_or_not = False self.date_type = None self.date_info = {} self.final_path = '' # Check if we match the category in init() self.match() def match(self, force=False): ''' Checks the category for a match, if so set self.matched to true ''' if force or (cfg.enable_date_sorting() and self.sort_string): #First check if the show matches TV episode regular expressions. Returns regex match object if force or (self.cat and self.cat.lower() in self.cats) or (not self.cat and 'None' in self.cats): self.match_obj, self.date_type = check_for_date(self.original_dirname, date_match) if self.match_obj: logging.debug("Date Sorting - Starting folder sort (%s)", self.original_dirname) self.matched = True def is_match(self): ''' Returns whether there was a match or not ''' return self.matched def get_final_path(self): """ Collect and construct all the variables such as episode name, show names """ if self.get_values(): # Get the final path path = self.construct_path() self.final_path = os.path.join(self.original_path, path) return self.final_path else: # Error Sorting return os.path.join(self.original_path, self.original_dirname) def get_values(self): """ Collect and construct all the values needed for path replacement """ if self.date_type == 1: #2008-10-16 self.date_info['year'] = self.match_obj.group(1) self.date_info['month'] = self.match_obj.group(2) self.date_info['date'] = self.match_obj.group(3) else: #10.16.2008 self.date_info['year'] = self.match_obj.group(3) self.date_info['month'] = self.match_obj.group(1) self.date_info['date'] = self.match_obj.group(2) self.date_info['month_two'] = self.date_info['month'].rjust(2,'0') self.date_info['date_two'] = self.date_info['date'].rjust(2,'0') ## - Get Decades self.date_info['decade'], self.date_info['decade_two'] = get_decades(self.date_info['year']) ## - Get Title self.date_info['ttitle'], self.date_info['ttitle_two'], self.date_info['ttitle_three'] = get_titles(self.nzo, self.match_obj, self.original_dirname, True) self.date_info['title'], self.date_info['title_two'], self.date_info['title_three'] = get_titles(self.nzo, self.match_obj, self.original_dirname) self.date_info['ep_name'], self.date_info['ep_name_two'], self.date_info['ep_name_three'] = get_descriptions(self.nzo, self.match_obj, self.original_dirname) return True def construct_path(self): """ Return path reconstructed from orginal and sort expression """ sorter = self.sort_string.replace('\\', '/') mapping = [] if ends_in_file(sorter): extension = True sorter = sorter.replace(".%ext", '') else: extension = False # Replace title mapping.append(('%title', self.date_info['title'])) mapping.append(('%.title', self.date_info['title_two'])) mapping.append(('%_title', self.date_info['title_three'])) mapping.append(('%t', self.date_info['title'])) mapping.append(('%.t', self.date_info['title_two'])) mapping.append(('%_t', self.date_info['title_three'])) mapping.append(('%sn', self.date_info['ttitle'])) mapping.append(('%s.n', self.date_info['ttitle_two'])) mapping.append(('%s_n', self.date_info['ttitle_three'])) mapping.append(('%sN', self.date_info['title'])) mapping.append(('%s.N', self.date_info['title_two'])) mapping.append(('%s_N', self.date_info['title_three'])) # Replace year mapping.append(('%year', self.date_info['year'])) mapping.append(('%y', self.date_info['year'])) if self.date_info['ep_name']: mapping.append(('%desc', self.date_info['ep_name'])) mapping.append(('%.desc', self.date_info['ep_name_two'])) mapping.append(('%_desc', self.date_info['ep_name_three'])) else: mapping.append(('%desc', '')) mapping.append(('%.desc', '')) mapping.append(('%_desc', '')) # Replace decades mapping.append(('%decade', self.date_info['decade'])) mapping.append(('%0decade', self.date_info['decade_two'])) # Replace month mapping.append(('%m', self.date_info['month'])) mapping.append(('%0m', self.date_info['month_two'])) # Replace date mapping.append(('%d', self.date_info['date'])) mapping.append(('%0d', self.date_info['date_two'])) path = path_subst(sorter, mapping) for key, name in REPLACE_AFTER.iteritems(): path = path.replace(key, name) # Lowercase all characters encased in {} path = to_lowercase(path) # Strip any extra ' ' '.' or '_' around foldernames path = strip_folders(path) # Split the last part of the path up for the renamer if extension: head, tail = os.path.split(path) self.filename_set = tail self.rename_or_not = True else: head = path return os.path.normpath(head) def rename(self, files, current_path): """ Renaming Date file """ logging.debug("Renaming Date file") #find the master file to rename for file in files: if is_full_path(file): filepath = os.path.normpath(file) else: filepath = os.path.normpath(os.path.join(current_path, file)) if os.path.exists(filepath): size = os.stat(filepath).st_size if size > cfg.movie_rename_limit.get_int(): if 'sample' not in file: self.fname, ext = os.path.splitext(os.path.split(file)[1]) newname = "%s%s" % (self.filename_set, ext) newname = newname.replace('%fn', self.fname) newpath = os.path.join(current_path, newname) if not os.path.exists(newpath): try: logging.debug("Rename: %s to %s", filepath, newpath) renamer(filepath, newpath) except: logging.error(Ta('Failed to rename: %s to %s'), current_path, newpath) logging.info("Traceback: ", exc_info = True) rename_similar(current_path, ext, self.filename_set, ()) break def path_subst(path, mapping): """ Replace the sort sting elements by real values. Non-elements are copied literally. path = the sort string mapping = array of tuples that maps all elements to their values """ # Added ugly hack to prevent %ext from being masked by %e newpath = [] plen = len(path) n = 0 while n < plen: result = path[n] if result == '%': for key, value in mapping: if path.startswith(key, n) and not path.startswith('%ext', n): n += len(key)-1 result = value break newpath.append(result) n += 1 return ''.join(newpath) def get_titles(nzo, match, name, titleing=False): ''' The title will be the part before the match Clean it up and title() it ''.title() isn't very good under python so this contains a lot of little hacks to make it better and for more control ''' if nzo: title = latin1(nzo.nzo_info.get('propername') or nzo.meta.get('propername', (None,))[0]) else: title = '' if not title: if match: name = name[:match.start()] # Replace .US. with (US) if cfg.tv_sort_countries() == 1: for rep in COUNTRY_REP: # (us) > (US) name = replace_word(name, rep.lower(), rep) # (Us) > (US) name = replace_word(name, titler(rep), rep) # .US. > (US) dotted_country = '.%s.' % (rep.strip('()')) name = replace_word(name, dotted_country, rep) # Remove .US. and (US) elif cfg.tv_sort_countries() == 2: for rep in COUNTRY_REP: # Remove (US) name = replace_word(name, rep, '') dotted_country = '.%s.' % (rep.strip('()')) # Remove .US. name = replace_word(name, dotted_country, '.') title = name.replace('.', ' ').replace('_', ' ') title = title.strip().strip('(').strip('_').strip('-').strip().strip('_') if titleing: title = titler(title) # title the show name so it is in a consistant letter case #title applied uppercase to 's Python bug? title = title.replace("'S", "'s") # Replace titled country names, (Us) with (US) and so on if cfg.tv_sort_countries() == 1: for rep in COUNTRY_REP: title = title.replace(titler(rep), rep) # Remove country names, ie (Us) elif cfg.tv_sort_countries() == 2: for rep in COUNTRY_REP: title = title.replace(titler(rep), '').strip() # Make sure some words such as 'and' or 'of' stay lowercased. for x in LOWERCASE: xtitled = titler(x) title = replace_word(title, xtitled, x) # Make sure some words such as 'III' or 'IV' stay uppercased. for x in UPPERCASE: xtitled = titler(x) title = replace_word(title, xtitled, x) # Make sure the first letter of the title is always uppercase if title: title = titler(title[0]) + title[1:] # The title with spaces replaced by dots dots = title.replace(" - ", "-").replace(' ','.').replace('_','.') dots = dots.replace('(', '.').replace(')','.').replace('..','.').rstrip('.') # The title with spaces replaced by underscores underscores = title.replace(' ','_').replace('.','_').replace('__','_').rstrip('_') return title, dots, underscores def replace_word(input, one, two): ''' Regex replace on just words ''' regex = re.compile(r'\W(%s)(\W|$)' % one, re.I) matches = regex.findall(input) if matches: for m in matches: input = input.replace(one, two) return input def get_descriptions(nzo, match, name): ''' If present, get a description from the nzb name. A description has to be after the matched item, seperated either like ' - Description' or '_-_Description' ''' if nzo: ep_name = latin1(nzo.nzo_info.get('episodename') or nzo.meta.get('episodename', (None,))[0]) else: ep_name = '' if not ep_name: if match: ep_name = name[match.end():] # Need to improve for multi ep support else: ep_name = name ep_name = ep_name.strip(' _.') if ep_name.startswith('-'): ep_name = ep_name.strip('- _.') if '.' in ep_name and ' ' not in ep_name: ep_name = ep_name.replace('.', ' ') ep_name = ep_name.replace('_', ' ') ep_name2 = ep_name.replace(" - ", "-").replace(" ", ".") ep_name3 = ep_name.replace(" ", "_") return ep_name, ep_name2, ep_name3 def get_decades(year): """ Return 4 digit and 2 digit decades given 'year' """ if year: try: decade = year[2:3]+'0' decade2 = year[:3]+'0' except: decade = '' decade2 = '' else: decade = '' decade2 = '' return decade, decade2 def check_for_folder(path): """ Return True if any folder is found in the tree at 'path' """ for root, dirs, files in os.walk(path): if dirs: return True return False _RE_LOWERCASE = re.compile(r'{([^{]*)}') def to_lowercase(path): ''' Lowercases any characters enclosed in {} ''' while True: m = _RE_LOWERCASE.search(path) if not m: break path = path[:m.start()] + m.group(1).lower() + path[m.end():] # just incase path = path.replace('{', '') path = path.replace('}', '') return path def strip_folders(path): """ Return 'path' without leading and trailing spaces and underscores in each element For Windows, also remove leading and trailing dots """ unc = sabnzbd.WIN32 and (path.startswith('//') or path.startswith('\\\\')) f = path.strip('/').split('/') # For path beginning with a slash, insert empty element to prevent loss if path.strip()[0] in '/\\': f.insert(0, '') def strip_all(x): """ Strip all leading/trailing underscores also dots for Windows """ x = x.strip().strip('_') if sabnzbd.WIN32: # OSX and Linux should keep dots, because leading dots are significant # while Windows cannot handle trailing dots x = x.strip('.') x = x.strip() return x path = os.path.normpath('/'.join([strip_all(x) for x in f])) if unc: return '\\' + path else: return path def rename_similar(folder, skip_ext, name, skipped_files): """ Rename all other files in the 'folder' hierarchy after 'name' and move them to the root of 'folder'. Files having extension 'skip_ext' will be moved, but not renamed. Don't touch files in list `skipped_files` """ logging.debug('Give files in set "%s" matching names.', name) folder = os.path.normpath(folder) skip_ext = skip_ext.lower() for root, dirs, files in os.walk(folder): for f in files: path = os.path.join(root, f) if path in skipped_files: continue org, ext = os.path.splitext(f) if ext.lower() == skip_ext: # Move file, but do not rename newpath = os.path.join(folder, f) else: # Move file and rename newname = "%s%s" % (name, ext) newname = newname.replace('%fn', org) newpath = os.path.join(folder, newname) if path != newpath: newpath = get_unique_filename(newpath) try: logging.debug("Rename: %s to %s", path, newpath) renamer(path, newpath) except: logging.error(Ta('Failed to rename similar file: %s to %s'), path, newpath) logging.info("Traceback: ", exc_info=True) cleanup_empty_directories(folder) def check_regexs(filename, matchers): """ Regular Expression match for a list of regexes Returns the MatchObject if a match is made This version checks for an additional match """ extras = [] for expressions in matchers: expression, extramatchers = expressions regex = re.compile(expression) match1 = regex.search(filename) if match1: for m in extramatchers: regex = re.compile(m) match2 = regex.findall(filename, match1.end()) if match2: for match in match2: if type(match) == type(()) and len(match) > 1: extras.append(match[1]) else: extras.append(match) break return match1, extras return None, None def check_for_date(filename, matcher): """ Regular Expression match for date based files Returns the MatchObject if a match is made """ x = 0 if matcher: for expression in matcher: regex = re.compile(expression) match1 = regex.search(filename) x += 1 if match1: return match1, x return None, 0 def is_full_path(file): """ Return True if path is absolute """ if file.startswith('\\') or file.startswith('/'): return True try: if file[1:3] == ':\\': return True except: pass return False def eval_sort(sorttype, expression, name=None, multipart=''): """ Preview a sort expression, to be used by API """ from sabnzbd.api import Ttemplate path = '' name = sanitize_foldername(name) if sorttype == 'series': name = name or ('%s S01E05 - %s [DTS]' % (Ttemplate('show-name'), Ttemplate('ep-name'))) sorter = sabnzbd.tvsort.SeriesSorter(None, name, path, 'tv') elif sorttype == 'generic': name = name or (Ttemplate('movie-sp-name') + ' (2009)') sorter = sabnzbd.tvsort.GenericSorter(None, name, path, 'tv') elif sorttype == 'date': name = name or (Ttemplate('show-name') + ' 2009-01-02') sorter = sabnzbd.tvsort.DateSorter(None, name, path, 'tv') else: return None sorter.sort_string = expression sorter.match(force=True) path = sorter.get_final_path() path = os.path.normpath(os.path.join(path, sorter.filename_set)) fname = Ttemplate('orgFilename') fpath = path if sorttype == 'generic' and '%1' in multipart: fname = fname + multipart.replace('%1', '1') fpath = fpath + multipart.replace('%1', '1') if '%fn' in path: path = path.replace('%fn', fname + '.avi') else: if sorter.rename_or_not: path = fpath + '.avi' else: if sabnzbd.WIN32: path += '\\' else: path += '/' return path SABnzbd-0.7.20/sabnzbd/urlgrabber.py0000644000000000000000000004060512433712602017356 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.urlgrabber - Queue for grabbing NZB files from websites """ import os import time import re import logging import Queue import urllib from threading import Thread import socket try: socket.ssl _PROTOCOL = 'https' except: _PROTOCOL = 'http' import sabnzbd import sabnzbd.misc as misc import sabnzbd.dirscanner as dirscanner from sabnzbd.nzbqueue import NzbQueue import sabnzbd.cfg as cfg _BAD_GZ_HOSTS = ('.zip', 'nzbsa.co.za', 'newshost.za.net') #------------------------------------------------------------------------------ class URLGrabber(Thread): do = None # Link to instance of the thread def __init__(self): Thread.__init__(self) self.queue = Queue.Queue() for tup in NzbQueue.do.get_urls(): url, nzo = tup self.queue.put((url, nzo)) self.shutdown = False URLGrabber.do = self def add(self, url, future_nzo, when=None): """ Add an URL to the URLGrabber queue, 'when' is seconds from now """ if when and future_nzo: future_nzo.wait = time.time() + when self.queue.put((url, future_nzo)) def rm_bookmark(self, url): """ Add removal request for nzbmatrix bookmark """ if 'nzbmatrix.com' in url and cfg.matrix_del_bookmark(): url = url.replace('download.php?', 'bookmarks.php?action=remove&') self.add(url, None) def stop(self): logging.info('URLGrabber shutting down') self.shutdown = True self.add(None, None) def run(self): logging.info('URLGrabber starting up') self.shutdown = False while not self.shutdown: # Don't pound the website! time.sleep(5.0) (url, future_nzo) = self.queue.get() if not url: # stop signal, go test self.shutdown continue if future_nzo and future_nzo.wait and future_nzo.wait > time.time(): # Requeue when too early and still active self.add(url, future_nzo) continue url = url.replace(' ', '') try: del_bookmark = not future_nzo if future_nzo: # If nzo entry deleted, give up try: deleted = future_nzo.deleted except AttributeError: deleted = True if deleted: logging.debug('Dropping URL %s, job entry missing', url) continue # Add nzbmatrix credentials if needed url, matrix_id = _matrix_url(url) # _grab_url cannot reside in a function, because the tempfile # would not survive the end of the function if del_bookmark: logging.info('Removing nzbmatrix bookmark %s', matrix_id) else: logging.info('Grabbing URL %s', url) if '.nzbsrus.' in url: opener = urllib.URLopener({}) else: opener = urllib.FancyURLopener({}) opener.prompt_user_passwd = None opener.addheaders = [] opener.addheader('User-Agent', 'SABnzbd+/%s' % sabnzbd.version.__version__) if not [True for item in _BAD_GZ_HOSTS if item in url]: opener.addheader('Accept-encoding','gzip') filename = None category = None length = 0 nzo_info = {} wait = 0 try: fn, header = opener.retrieve(url) except: fn = None if fn: for tup in header.items(): try: item = tup[0].lower() value = tup[1].strip() except: continue if item in ('category_id', 'x-dnzb-category'): category = value elif item in ('x-dnzb-moreinfo',): nzo_info['more_info'] = value elif item in ('x-dnzb-name',): filename = value if not filename.endswith('.nzb'): filename += '.nzb' elif item == 'x-dnzb-propername': nzo_info['propername'] = value elif item == 'x-dnzb-episodename': nzo_info['episodename'] = value elif item == 'x-dnzb-year': nzo_info['year'] = value elif item == 'x-dnzb-failure': nzo_info['failure'] = value elif item == 'x-dnzb-details': nzo_info['details'] = value elif item in ('content-length',): length = misc.int_conv(value) elif item == 'retry-after': # For NZBFinder wait = misc.int_conv(value) if not filename: for item in tup: if "filename=" in item: filename = item[item.index("filename=") + 9:].strip(';').strip('"') if matrix_id: fn, msg, retry, wait = _analyse_matrix(fn, matrix_id) if not fn: if retry: logging.info(msg) logging.debug('Retry nzbmatrix item %s after waiting %s sec', matrix_id, wait) self.add(url, future_nzo, wait) else: logging.error(msg) misc.bad_fetch(future_nzo, clean_matrix_url(url), msg, retry=True) continue category = get_matrix_category(url, category) if del_bookmark: # No retries of nzbmatrix bookmark removals continue else: if wait: # For sites that have a rate-limiting attribute msg = '' retry = True fn = None else: fn, msg, retry, wait = _analyse_others(fn, url) if not fn: if retry: logging.info('Retry URL %s', url) self.add(url, future_nzo, wait) else: misc.bad_fetch(future_nzo, url, msg, retry=True) continue if not filename: filename = os.path.basename(url) + '.nzb' pp = future_nzo.pp script = future_nzo.script cat = future_nzo.cat if (cat is None or cat == '*') and category: cat = misc.cat_convert(category) priority = future_nzo.priority nzbname = future_nzo.custom_name # Check if nzb file if os.path.splitext(filename)[1].lower() in ('.nzb', '.gz'): res, nzo_ids = dirscanner.ProcessSingleFile(filename, fn, pp=pp, script=script, cat=cat, priority=priority, \ nzbname=nzbname, nzo_info=nzo_info, url=future_nzo.url) if res == 0: NzbQueue.do.remove(future_nzo.nzo_id, add_to_history=False) else: if res == -2: logging.info('Incomplete NZB, retry after 5 min %s', url) when = 300 elif res == -1: # Error, but no reason to retry. Warning is already given NzbQueue.do.remove(future_nzo.nzo_id, add_to_history=False) continue else: logging.info('Unknown error fetching NZB, retry after 2 min %s', url) when = 120 self.add(url, future_nzo, when) # Check if a supported archive else: if dirscanner.ProcessArchiveFile(filename, fn, pp, script, cat, priority=priority, nzbname=nzbname, url=future_nzo.url)[0] == 0: NzbQueue.do.remove(future_nzo.nzo_id, add_to_history=False) else: # Not a supported filetype, not an nzb (text/html ect) try: os.remove(fn) except: pass logging.info('Unknown filetype when fetching NZB, retry after 30s %s', url) self.add(url, future_nzo, 30) except: logging.error('URLGRABBER CRASHED', exc_info=True) logging.debug("URLGRABBER Traceback: ", exc_info=True) #------------------------------------------------------------------------------- _RE_NZBMATRIX = re.compile(r'nzbmatrix\.com/(.*)[\?&]id=(\d+)', re.I) _RE_NZBXXX = re.compile(r'nzbxxx\.com/(.*)[\?&]id=(\d+)', re.I) _RE_NZBMATRIX_USER = re.compile(r'&username=([^&=]+)', re.I) _RE_NZBMATRIX_API = re.compile(r'&apikey=([^&=]+)', re.I) def _matrix_url(url): """ Patch up the url for nzbmatrix.com """ matrix_id = 0 m = _RE_NZBMATRIX.search(url) if not m: mx = _RE_NZBXXX.search(url) if m: site = 'nzbmatrix.com' user = urllib.quote_plus(cfg.matrix_username()) key = urllib.quote_plus(cfg.matrix_apikey()) elif mx: site = 'nzbxxx.com' user = urllib.quote_plus(cfg.xxx_username()) key = urllib.quote_plus(cfg.xxx_apikey()) m = mx if m: matrix_id = m.group(2) if not _RE_NZBMATRIX_USER.search(url) or not _RE_NZBMATRIX_API.search(url): url = '%s://api.%s/v1.1/download.php?id=%s&username=%s&apikey=%s' % \ (_PROTOCOL, site, matrix_id, user, key) return url, matrix_id def clean_matrix_url(url): ''' Return nzbmatrix url without user credentials ''' site = 'nzbmatrix.com' m = _RE_NZBMATRIX.search(url) if not m: m = _RE_NZBXXX.search(url) site = 'nzbxxx.com' if m: matrix_id = m.group(2) url = '%s://api.%s/v1.1/download.php?id=%s' % (_PROTOCOL, site, matrix_id) return url _RE_MATRIX_ERR = re.compile(r'please_wait[_ ]+(\d+)', re.I) def _analyse_matrix(fn, matrix_id): """ Analyse respons of nzbmatrix returns fn|None, error-message|None, retry, wait-seconds """ msg = '' wait = 0 if not fn: logging.debug('No response from nzbmatrix, retry after 60 sec') return None, msg, True, 60 try: f = open(fn, 'r') data = f.read(40).lower() f.close() except: logging.debug('Problem with tempfile %s from nzbmatrix, retry after 60 sec', fn) return None, msg, True, 60 # Check for an error response if data and ' # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.wizard - Wizard Webinterface """ import os import cherrypy from Cheetah.Template import Template import sabnzbd from sabnzbd.constants import * import sabnzbd.api from sabnzbd.lang import list_languages, set_language from sabnzbd.utils.servertests import test_nntp_server_dict from sabnzbd.api import Ttemplate import sabnzbd.interface import sabnzbd.config as config import sabnzbd.cfg as cfg #------------------------------------------------------------------------------ class Wizard(object): def __init__(self, web_dir, root, prim): self.__root = root # Get the path for the folder named wizard self.__web_dir = sabnzbd.WIZARD_DIR self.__prim = prim self.info = {'webdir': sabnzbd.WIZARD_DIR, 'steps':4, 'version':sabnzbd.__version__, 'T': T} @cherrypy.expose def index(self, **kwargs): """ Show the language selection page """ info = self.info.copy() info['num'] = '' info['number'] = 0 info['lang'] = cfg.language() info['languages'] = list_languages() info['T'] = Ttemplate if not os.path.exists(self.__web_dir): # If the wizard folder does not exist, simply load the normal page raise cherrypy.HTTPRedirect('') else: template = Template(file=os.path.join(self.__web_dir, 'index.html'), searchList=[info], compilerSettings=sabnzbd.interface.DIRECTIVES) return template.respond() @cherrypy.expose def exit(self, **kwargs): """ Stop SABnzbd """ yield "Initiating shutdown..." sabnzbd.halt() yield "
    SABnzbd-%s shutdown finished" % sabnzbd.__version__ cherrypy.engine.exit() sabnzbd.SABSTOP = True @cherrypy.expose def one(self, **kwargs): """ Accept language and show server page """ language = kwargs.get('lang') cfg.language.set(language) set_language(language) sabnzbd.api.clear_trans_cache() # Always setup Plush sabnzbd.interface.change_web_dir('Plush - Gold') info = self.info.copy() info['num'] = '» %s' % T('Step One') info['number'] = 1 info['session'] = cfg.api_key() info['language'] = cfg.language() info['T'] = Ttemplate info['have_ssl'] = bool(sabnzbd.newswrapper.HAVE_SSL) servers = config.get_servers() if not servers: info['host'] = '' info['port'] = '' info['username'] = '' info['password'] = '' info['connections'] = '' info['ssl'] = 0 else: for server in servers: # If there are multiple servers, just use the first enabled one s = servers[server] info['host'] = s.host() info['port'] = s.port() info['username'] = s.username() info['password'] = s.password.get_stars() info['connections'] = s.connections() info['ssl'] = s.ssl() if s.enable(): break template = Template(file=os.path.join(self.__web_dir, 'one.html'), searchList=[info], compilerSettings=sabnzbd.interface.DIRECTIVES) return template.respond() @cherrypy.expose def two(self, **kwargs): """ Accept server and show internal web server page """ # Save server details if kwargs: kwargs['enable'] = 1 sabnzbd.interface.handle_server(kwargs) # Create web server page info = self.info.copy() info['num'] = '» %s' % T('Step Two') info['number'] = 2 info['T'] = Ttemplate host = cfg.cherryhost() info['host'] = host # Allow special operation if host is not one of the defaults if host not in ('localhost','0.0.0.0'): info['custom_host'] = True else: info['custom_host'] = False info['have_ssl'] = bool(sabnzbd.newswrapper.HAVE_SSL) info['enable_https'] = cfg.enable_https() info['autobrowser'] = cfg.autobrowser() info['web_user'] = cfg.username() info['web_pass'] = cfg.password() template = Template(file=os.path.join(self.__web_dir, 'two.html'), searchList=[info], compilerSettings=sabnzbd.interface.DIRECTIVES) return template.respond() @cherrypy.expose def three(self, **kwargs): """ Accept webserver parms and show Indexer page """ if kwargs: if 'access' in kwargs: cfg.cherryhost.set(kwargs['access']) cfg.enable_https.set(kwargs.get('enable_https',0)) cfg.autobrowser.set(kwargs.get('autobrowser',0)) cfg.username.set(kwargs.get('web_user', '')) cfg.password.set(kwargs.get('web_pass', '')) if not cfg.username() or not cfg.password(): sabnzbd.interface.set_auth(cherrypy.config) config.save_config() # Create indexer page info = self.info.copy() info['num'] = '» %s' % T('Step Three') info['number'] = 3 info['T'] = Ttemplate info['rating_enable'] = cfg.rating_enable() info['rating_api_key'] = cfg.rating_api_key() template = Template(file=os.path.join(self.__web_dir, 'three.html'), searchList=[info], compilerSettings=sabnzbd.interface.DIRECTIVES) return template.respond() @cherrypy.expose def four(self, **kwargs): if kwargs: cfg.rating_enable.set(kwargs.get('rating_enable', 0)) cfg.rating_api_key.set(kwargs.get('rating_api_key', '')) config.save_config() # Show Restart screen info = self.info.copy() info['num'] = '» %s' % T('Step Four') info['number'] = 4 info['helpuri'] = 'http://wiki.sabnzbd.org/' info['session'] = cfg.api_key() info['access_url'], info['urls'] = self.get_access_info() info['T'] = Ttemplate template = Template(file=os.path.join(self.__web_dir, 'four.html'), searchList=[info], compilerSettings=sabnzbd.interface.DIRECTIVES) return template.respond() def get_access_info(self): ''' Build up a list of url's that sabnzbd can be accessed from ''' # Access_url is used to provide the user a link to sabnzbd depending on the host access_uri = 'localhost' cherryhost = cfg.cherryhost() if cherryhost == '0.0.0.0': import socket host = socket.gethostname() socks = [host] # Grab a list of all ips for the hostname try: addresses = socket.getaddrinfo(host, None) except: addresses = [] for addr in addresses: address = addr[4][0] # Filter out ipv6 addresses (should not be allowed) if ':' not in address and address not in socks: socks.append(address) if cherrypy.request.headers.has_key('host'): host = cherrypy.request.headers['host'] host = host.rsplit(':')[0] access_uri = host socks.insert(0, host) else: socks.insert(0, 'localhost') elif cherryhost == '::': import socket host = socket.gethostname() socks = [host] # Grab a list of all ips for the hostname addresses = socket.getaddrinfo(host, None) for addr in addresses: address = addr[4][0] # Only ipv6 addresses will work if ':' in address: address = '[%s]' % address if address not in socks: socks.append(address) if cherrypy.request.headers.has_key('host'): host = cherrypy.request.headers['host'] host = host.rsplit(':')[0] access_uri = host socks.insert(0, host) else: socks.insert(0, 'localhost') elif not cherryhost: import socket socks = [socket.gethostname()] access_uri = socket.gethostname() else: socks = [cherryhost] access_uri = cherryhost urls = [] for sock in socks: if sock: if cfg.enable_https(): url = 'https://%s:%s/sabnzbd/' % (sock, cfg.https_port()) else: url = 'http://%s:%s/sabnzbd/' % (sock, cfg.cherryport()) urls.append(url) if cfg.enable_https(): access_url = 'https://%s:%s/sabnzbd/' % (access_uri, cfg.https_port()) else: access_url = 'http://%s:%s/sabnzbd/' % (access_uri, cfg.cherryport()) return access_url, urls @cherrypy.expose def servertest(self, **kwargs): result, msg = test_nntp_server_dict(kwargs) return msg SABnzbd-0.7.20/sabnzbd/__init__.py0000644000000000000000000010333612433712602016767 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. from sabnzbd.version import __version__, __baseline__ __configversion__ = 18 __queueversion__ = 8 import os import logging import datetime import tempfile import cPickle, pickle import zipfile import glob import gzip import subprocess import time import cherrypy import sys from threading import RLock, Lock, Condition, Thread try: import sleepless except ImportError: sleepless = None #------------------------------------------------------------------------ # Determine platform flags WIN32 = DARWIN = DARWIN_INTEL = POSIX = FOUNDATION = WIN64 = False KERNEL32 = None if os.name == 'nt': WIN32 = True try: import ctypes KERNEL32 = ctypes.windll.LoadLibrary("Kernel32.dll") except: pass elif os.name == 'posix': ORG_UMASK = os.umask(18) os.umask(ORG_UMASK) POSIX = True import platform if platform.system().lower() == 'darwin': DARWIN = True try: import Foundation FOUNDATION = True except: pass if '86' in platform.machine(): DARWIN_INTEL = True if DARWIN: DARWIN_YS = [int(n) for n in platform.mac_ver()[0].split('.')] >= [10, 9] DARWIN_ML = [int(n) for n in platform.mac_ver()[0].split('.')] >= [10, 8] else: DARWIN_YS = DARWIN_ML = False #------------------------------------------------------------------------ from sabnzbd.nzbqueue import NzbQueue from sabnzbd.postproc import PostProcessor from sabnzbd.downloader import Downloader from sabnzbd.assembler import Assembler from sabnzbd.newzbin import Bookmarks, MSGIDGrabber from sabnzbd.rating import Rating import sabnzbd.misc as misc import sabnzbd.powersup as powersup from sabnzbd.dirscanner import DirScanner, ProcessArchiveFile, ProcessSingleFile from sabnzbd.urlgrabber import URLGrabber import sabnzbd.scheduler as scheduler import sabnzbd.rss as rss import sabnzbd.emailer as emailer from sabnzbd.articlecache import ArticleCache import sabnzbd.newsunpack import sabnzbd.encoding as encoding import sabnzbd.config as config from sabnzbd.bpsmeter import BPSMeter import sabnzbd.cfg as cfg import sabnzbd.database import sabnzbd.lang as lang import sabnzbd.api from sabnzbd.decorators import * from sabnzbd.constants import * LINUX_POWER = powersup.HAVE_DBUS START = datetime.datetime.now() MY_NAME = None MY_FULLNAME = None NEW_VERSION = None DIR_HOME = None DIR_APPDATA = None DIR_LCLDATA = None DIR_PROG = None DIR_INTERFACES = None DIR_LANGUAGE = None DIR_PID = None QUEUECOMPLETE = None #stores the nice name of the action QUEUECOMPLETEACTION = None #stores the name of the function to be called QUEUECOMPLETEARG = None #stores an extra arguments that need to be passed DAEMON = None LOGFILE = None WEBLOGFILE = None LOGHANDLER = None GUIHANDLER = None LOG_ALL = False AMBI_LOCALHOST = False WIN_SERVICE = None # Instance of our Win32 Service Class BROWSER_URL = None CMDLINE = '' # Rendering of original command line arguments WEB_DIR = None WEB_DIR2 = None WEB_DIRC = None WIZARD_DIR = None WEB_COLOR = None WEB_COLOR2 = None SABSTOP = False RESTART_REQ = False PAUSED_ALL = False OLD_QUEUE = False SCHED_RESTART = False # Set when restarted through scheduler WINTRAY = None # Thread for the Windows SysTray icon WEBUI_READY = False __INITIALIZED__ = False __SHUTTING_DOWN__ = False ################################################################################ # Table to map 0.5.x style language code to new style LANG_MAP = { 'de-de' : 'de', 'dk-da' : 'da', # Should have been "da-dk" 'fr-fr' : 'fr', 'nl-du' : 'nl', # Should have been "du-nl" 'no-no' : 'nb', # Norsk Bokmal 'sv-se' : 'sv', 'us-en' : 'en' # Should have been "en-us" } ################################################################################ # Signal Handler # ################################################################################ def sig_handler(signum = None, frame = None): global SABSTOP, WINTRAY if sabnzbd.WIN32 and type(signum) != type(None) and DAEMON and signum==5: # Ignore the "logoff" event when running as a Win32 daemon return True if type(signum) != type(None): logging.warning(Ta('Signal %s caught, saving and exiting...'), signum) try: save_state(flag=True) finally: if sabnzbd.WIN32: from util.apireg import del_connection_info del_connection_info() if sabnzbd.WINTRAY: sabnzbd.WINTRAY.terminate = True time.sleep(0.5) else: pid_file() SABSTOP = True os._exit(0) ################################################################################ # Initializing # ################################################################################ INIT_LOCK = Lock() def connect_db(thread_index): # Create a connection and store it in the current thread cherrypy.thread_data.history_db = sabnzbd.database.get_history_handle() @synchronized(INIT_LOCK) def initialize(pause_downloader = False, clean_up = False, evalSched=False, repair=0): global __INITIALIZED__, __SHUTTING_DOWN__,\ LOGFILE, WEBLOGFILE, LOGHANDLER, GUIHANDLER, AMBI_LOCALHOST, WAITEXIT, \ DAEMON, MY_NAME, MY_FULLNAME, NEW_VERSION, \ DIR_HOME, DIR_APPDATA, DIR_LCLDATA, DIR_PROG , DIR_INTERFACES, \ DARWIN, RESTART_REQ, OLD_QUEUE if __INITIALIZED__: return False __SHUTTING_DOWN__ = False ### Set global database connection for Web-UI threads cherrypy.engine.subscribe('start_thread', connect_db) ### Paused? pause_downloader = pause_downloader or cfg.start_paused() ### Clean-up, if requested if clean_up: # Old cache folder misc.remove_all(cfg.cache_dir.get_path(), '*.sab') misc.remove_all(cfg.cache_dir.get_path(), 'SABnzbd_*') # New admin folder misc.remove_all(cfg.admin_dir.get_path(), '*.sab') ### Optionally wait for "incomplete" to become online if cfg.wait_for_dfolder(): wait_for_download_folder() else: cfg.download_dir.set(cfg.download_dir(), create=True) cfg.download_dir.set_create(True) ### Set access rights for "incomplete" base folder misc.set_permissions(cfg.download_dir.get_path(), recursive=False) ### If dirscan_dir cannot be created, set a proper value anyway. ### Maybe it's a network path that's temporarily missing. path = cfg.dirscan_dir.get_path() if not os.path.exists(path): sabnzbd.misc.create_real_path(cfg.dirscan_dir.ident(), '', path, False) ### Set call backs for Config items cfg.cache_limit.callback(new_limit) cfg.cherryhost.callback(guard_restart) cfg.cherryport.callback(guard_restart) cfg.web_dir.callback(guard_restart) cfg.web_dir2.callback(guard_restart) cfg.web_color.callback(guard_restart) cfg.web_color2.callback(guard_restart) cfg.log_dir.callback(guard_restart) cfg.cache_dir.callback(guard_restart) cfg.https_port.callback(guard_restart) cfg.https_cert.callback(guard_restart) cfg.https_key.callback(guard_restart) cfg.enable_https.callback(guard_restart) cfg.bandwidth_limit.callback(guard_speedlimit) cfg.top_only.callback(guard_top_only) cfg.pause_on_post_processing.callback(guard_pause_on_pp) cfg.growl_server.callback(sabnzbd.growler.change_value) cfg.growl_password.callback(sabnzbd.growler.change_value) cfg.quota_size.callback(guard_quota_size) cfg.quota_day.callback(guard_quota_dp) cfg.quota_period.callback(guard_quota_dp) cfg.fsys_type.callback(guard_fsys_type) cfg.language.callback(sabnzbd.growler.reset_growl) ### Set Posix filesystem encoding sabnzbd.encoding.change_fsys(cfg.fsys_type()) ### Set cache limit if (sabnzbd.WIN32 or sabnzbd.DARWIN) and not cfg.cache_limit(): cfg.cache_limit.set('200M') ArticleCache.do.new_limit(cfg.cache_limit.get_int()) check_incomplete_vs_complete() ### Handle language upgrade from 0.5.x to 0.6.x cfg.language.set(LANG_MAP.get(cfg.language(), cfg.language())) ### Set language files lang.set_locale_info('SABnzbd', DIR_LANGUAGE) lang.set_language(cfg.language()) sabnzbd.api.clear_trans_cache() ### Check for old queue (when a new queue is not present) if not os.path.exists(os.path.join(cfg.cache_dir.get_path(), QUEUE_FILE_NAME)): OLD_QUEUE = bool(misc.globber(cfg.cache_dir.get_path(), QUEUE_FILE_TMPL % '?')) sabnzbd.change_queue_complete_action(cfg.queue_complete(), new=False) if check_repair_request(): repair = 2 pause_downloader = True else: # Check crash detection file #if load_admin(TERM_FLAG_FILE, remove=True): # Repair mode 2 is a bit over an over-reaction! pass # repair = 2 # Set crash detection file #save_admin(1, TERM_FLAG_FILE) ### ### Initialize threads ### Bookmarks() rss.init() paused = BPSMeter.do.read() PostProcessor() NzbQueue() Assembler() NzbQueue.do.read_queue(repair) Downloader(pause_downloader or paused) DirScanner() MSGIDGrabber() Rating() URLGrabber() scheduler.init() if evalSched: scheduler.analyse(pause_downloader) logging.info('All processes started') RESTART_REQ = False __INITIALIZED__ = True return True @synchronized(INIT_LOCK) def start(): global __INITIALIZED__ if __INITIALIZED__: logging.debug('Starting postprocessor') PostProcessor.do.start() logging.debug('Starting assembler') Assembler.do.start() logging.debug('Starting downloader') Downloader.do.start() scheduler.start() logging.debug('Starting dirscanner') DirScanner.do.start() MSGIDGrabber.do.start() Rating.do.start() logging.debug('Starting urlgrabber') URLGrabber.do.start() @synchronized(INIT_LOCK) def halt(): global __INITIALIZED__, __SHUTTING_DOWN__ if __INITIALIZED__: logging.info('SABnzbd shutting down...') __SHUTTING_DOWN__ = True rss.stop() Bookmarks.do.save() logging.debug('Stopping URLGrabber') URLGrabber.do.stop() try: URLGrabber.do.join() except: pass logging.debug('Stopping Newzbin-Grabber') MSGIDGrabber.do.stop() try: MSGIDGrabber.do.join() except: pass logging.debug('Stopping rating') Rating.do.stop() try: Rating.do.join() except: pass logging.debug('Stopping dirscanner') DirScanner.do.stop() try: DirScanner.do.join() except: pass ## Stop Required Objects ## logging.debug('Stopping downloader') sabnzbd.downloader.stop() logging.debug('Stopping assembler') Assembler.do.stop() try: Assembler.do.join() except: pass logging.debug('Stopping postprocessor') PostProcessor.do.stop() try: PostProcessor.do.join() except: pass ## Save State ## try: save_state(flag=True) except: logging.error('Fatal error at saving state', exc_info=True) # The Scheduler cannot be stopped when the stop was scheduled. # Since all warm-restarts have been removed, it's not longer # needed to stop the scheduler. # We must tell the scheduler to deactivate. scheduler.abort() logging.info('All processes stopped') __INITIALIZED__ = False ################################################################################ ## Misc Wrappers ## ################################################################################ def new_limit(): """ Callback for article cache changes """ ArticleCache.do.new_limit(cfg.cache_limit.get_int()) def guard_restart(): """ Callback for config options requiring a restart """ global RESTART_REQ sabnzbd.RESTART_REQ = True def guard_speedlimit(): """ Callback for change of bandwidth_limit, sets actual speed """ Downloader.do.limit_speed(cfg.bandwidth_limit()) def guard_top_only(): """ Callback for change of top_only option """ NzbQueue.do.set_top_only(cfg.top_only()) def guard_pause_on_pp(): """ Callback for change of pause-download-on-pp """ if cfg.pause_on_post_processing(): pass # Not safe to idle downloader, because we don't know # if post-processing is active now else: Downloader.do.resume_from_postproc() def guard_quota_size(): """ Callback for change of quota_size """ BPSMeter.do.change_quota() def guard_quota_dp(): """ Callback for change of quota_day or quota_period """ scheduler.restart(force=True) def guard_fsys_type(): """ Callback for change of file system naming type """ sabnzbd.encoding.change_fsys(cfg.fsys_type()) def add_msgid(msgid, pp=None, script=None, cat=None, priority=None, nzbname=None): """ Add NZB based on newzbin report number, attributes optional """ if pp and pp=="-1": pp = None if script and script.lower()=='default': script = None if cat and cat.lower()=='default': cat = None if cfg.newzbin_username() and cfg.newzbin_password(): logging.info('Fetching msgid %s from www.newzbin2.es', msgid) msg = T('fetching msgid %s from www.newzbin2.es') % msgid future_nzo = NzbQueue.do.generate_future(msg, pp, script, cat=cat, url=msgid, priority=priority, nzbname=nzbname) MSGIDGrabber.do.grab(msgid, future_nzo) else: logging.error(Ta('Error Fetching msgid %s from www.newzbin2.es - Please make sure your Username and Password are set'), msgid) def add_url(url, pp=None, script=None, cat=None, priority=None, nzbname=None): """ Add NZB based on a URL, attributes optional """ if 'http' not in url: return if pp and pp=="-1": pp = None if script and script.lower()=='default': script = None if cat and cat.lower()=='default': cat = None logging.info('Fetching %s', url) msg = T('Trying to fetch NZB from %s') % url future_nzo = NzbQueue.do.generate_future(msg, pp, script, cat, url=url, priority=priority, nzbname=nzbname) URLGrabber.do.add(url, future_nzo) def save_state(flag=False): """ Save all internal bookkeeping to disk """ ArticleCache.do.flush_articles() NzbQueue.do.save() BPSMeter.do.save() rss.save() Bookmarks.do.save() Rating.do.save() DirScanner.do.save() PostProcessor.do.save() #if flag: # # Remove crash detector # load_admin(TERM_FLAG_FILE, remove=True) def pause_all(): """ Pause all activities than cause disk access """ global PAUSED_ALL PAUSED_ALL = True Downloader.do.pause() logging.debug('PAUSED_ALL active') def unpause_all(): """ Resume all activcities """ global PAUSED_ALL PAUSED_ALL = False Downloader.do.resume() logging.debug('PAUSED_ALL inactive') ################################################################################ ## NZB_LOCK Methods ## ################################################################################ NZB_LOCK = Lock() @synchronized(NZB_LOCK) def backup_exists(filename): """ Return True if backup exists and no_dupes is set """ path = cfg.nzb_backup_dir.get_path() return path and sabnzbd.cfg.no_dupes() and \ os.path.exists(os.path.join(path, filename+'.gz')) def backup_nzb(filename, data): """ Backup NZB file """ path = cfg.nzb_backup_dir.get_path() if path: save_compressed(path, filename, data) @synchronized(NZB_LOCK) def save_compressed(folder, filename, data): """ Save compressed NZB file in folder """ # Need to go to the save folder to # prevent the pathname being embedded in the GZ file here = os.getcwd() os.chdir(folder) if filename.endswith('.nzb'): filename += '.gz' else: filename += '.nzb.gz' logging.info("Backing up %s", os.path.join(folder, filename)) try: f = gzip.GzipFile(filename, 'wb') f.write(data) f.flush() f.close() except: logging.error("Saving %s failed", os.path.join(folder, filename)) logging.info("Traceback: ", exc_info = True) os.chdir(here) ################################################################################ ## CV synchronized (notifies downloader) ## ################################################################################ @synchronized_CV def add_nzbfile(nzbfile, pp=None, script=None, cat=None, priority=NORMAL_PRIORITY, nzbname=None, reuse=False): """ Add disk-based NZB file, optional attributes, 'reuse' flag will suppress duplicate detection """ if pp and pp=="-1": pp = None if script and script.lower()=='default': script = None if cat and cat.lower()=='default': cat = None if isinstance(nzbfile, str): # File coming from queue repair filename = nzbfile keep = True else: # File coming from API/TAPI # Consider reception of Latin-1 names for non-Windows platforms # When an OSX/Unix server receives a file from Windows platform filename = encoding.special_fixer(nzbfile.filename) keep = False if not sabnzbd.WIN32: # If windows client sends file to Unix server backslashed may # be included, so convert these filename = filename.replace('\\', '/') filename = os.path.basename(filename) root, ext = os.path.splitext(filename) logging.info('Adding %s', filename) if isinstance(nzbfile, str): path = nzbfile else: try: f, path = tempfile.mkstemp(suffix=ext, text=False) os.write(f, nzbfile.value) os.close(f) except: logging.error(Ta('Cannot create temp file for %s'), filename) logging.info("Traceback: ", exc_info = True) if ext.lower() in ('.zip', '.rar'): return ProcessArchiveFile(filename, path, pp, script, cat, priority=priority, nzbname=nzbname) else: return ProcessSingleFile(filename, path, pp, script, cat, priority=priority, nzbname=nzbname, keep=keep, reuse=reuse) ################################################################################ ## Unsynchronized methods ## ################################################################################ def enable_server(server): """ Enable server (scheduler only) """ try: config.get_config('servers', server).enable.set(1) except: logging.warning(Ta('Trying to set status of non-existing server %s'), server) return config.save_config() Downloader.do.update_server(server, server) def disable_server(server): """ Disable server (scheduler only) """ try: config.get_config('servers', server).enable.set(0) except: logging.warning(Ta('Trying to set status of non-existing server %s'), server) return config.save_config() Downloader.do.update_server(server, server) def system_shutdown(): """ Shutdown system after halting download and saving bookkeeping """ logging.info("Performing system shutdown") Thread(target=halt).start() while __INITIALIZED__: time.sleep(1.0) if sabnzbd.WIN32: powersup.win_shutdown() elif DARWIN: powersup.osx_shutdown() else: powersup.linux_shutdown() def system_hibernate(): """ Hibernate system """ logging.info("Performing system hybernation") if sabnzbd.WIN32: powersup.win_hibernate() elif DARWIN: powersup.osx_hibernate() else: powersup.linux_hibernate() def system_standby(): """ Standby system """ logging.info("Performing system standby") if sabnzbd.WIN32: powersup.win_standby() elif DARWIN: powersup.osx_standby() else: powersup.linux_standby() def shutdown_program(): """ Stop program after halting and saving """ logging.info("Performing sabnzbd shutdown") Thread(target=halt).start() while __INITIALIZED__: time.sleep(1.0) os._exit(0) def restart_program(): """ Restart program (used by scheduler) """ global SCHED_RESTART logging.info("Scheduled restart request") # Just set the stop flag, because stopping CherryPy from # the scheduler is not reliable cherrypy.engine.execv = SCHED_RESTART = True def change_queue_complete_action(action, new=True): """ Action or script to be performed once the queue has been completed Scripts are prefixed with 'script_' When "new" is False, check wether non-script actions are acceptable """ global QUEUECOMPLETE, QUEUECOMPLETEACTION, QUEUECOMPLETEARG _action = None _argument = None if 'script_' in action: #all scripts are labeled script_xxx _action = run_script _argument = action.replace('script_', '') elif new or cfg.queue_complete_pers.get(): if action == 'shutdown_pc': _action = system_shutdown elif action == 'hibernate_pc': _action = system_hibernate elif action == 'standby_pc': _action = system_standby elif action == 'shutdown_program': _action = shutdown_program else: action = None else: action = None if new: cfg.queue_complete.set(action or '') config.save_config() #keep the name of the action for matching the current select in queue.tmpl QUEUECOMPLETE = action QUEUECOMPLETEACTION = _action QUEUECOMPLETEARG = _argument def run_script(script): """ Run a user script (queue complete only) """ command = [os.path.join(cfg.script_dir.get_path(), script)] stup, need_shell, command, creationflags = sabnzbd.newsunpack.build_command(command) logging.info('Spawning external command %s', command) subprocess.Popen(command, shell=need_shell, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, startupinfo=stup, creationflags=creationflags) def empty_queues(): """ Return True if queues empty or non-existent """ global __INITIALIZED__ return (not __INITIALIZED__) or (PostProcessor.do.empty() and NzbQueue.do.is_empty()) def keep_awake(): """ If we still have work to do, keep Windows/OSX system awake """ if KERNEL32 or sleepless: if sabnzbd.cfg.keep_awake(): awake = False if not sabnzbd.downloader.Downloader.do.paused: if (not PostProcessor.do.empty()) or not NzbQueue.do.is_empty(): awake = True if KERNEL32: # set ES_SYSTEM_REQUIRED KERNEL32.SetThreadExecutionState(ctypes.c_int(0x00000001)) else: sleepless.keep_awake(u'SABnzbd is busy downloading and/or post-processing') if not awake and sleepless: sleepless.allow_sleep() def CheckFreeSpace(): """ Check if enough disk space is free, if not pause downloader and send email """ if cfg.download_free() and not sabnzbd.downloader.Downloader.do.paused: if misc.diskfree(cfg.download_dir.get_path()) < cfg.download_free.get_float() / GIGI: logging.warning(Ta('Too little diskspace forcing PAUSE')) # Pause downloader, but don't save, since the disk is almost full! Downloader.do.pause(save=False) emailer.diskfull() ################################################################################ # Data IO # ################################################################################ IO_LOCK = RLock() @synchronized(IO_LOCK) def get_new_id(prefix, folder, check_list=None): """ Return unique prefixed admin identifier within folder optionally making sure that id is not in the check_list. """ for n in xrange(10000): try: if not os.path.exists(folder): os.makedirs(folder) fd, path = tempfile.mkstemp('', 'SABnzbd_%s_' % prefix, folder) os.close(fd) head, tail = os.path.split(path) if not check_list or tail not in check_list: return tail except: logging.error(Ta('Failure in tempfile.mkstemp')) logging.info("Traceback: ", exc_info = True) # Cannot create unique id, crash the process raise IOError @synchronized(IO_LOCK) def save_data(data, _id, path, do_pickle = True, silent=False): """ Save data to a diskfile """ if not silent: logging.debug("Saving data for %s in %s", _id, path) path = os.path.join(path, _id) try: _f = open(path, 'wb') if do_pickle: if cfg.use_pickle(): pickler = pickle.Pickler(_f, 2) else: pickler = cPickle.Pickler(_f, 2) pickler.dump(data) _f.flush() _f.close() pickler.clear_memo() del pickler else: _f.write(data) _f.flush() _f.close() except: logging.error(Ta('Saving %s failed'), path) logging.info("Traceback: ", exc_info = True) @synchronized(IO_LOCK) def load_data(_id, path, remove=True, do_pickle=True, silent=False): """ Read data from disk file """ path = os.path.join(path, _id) if not os.path.exists(path): logging.info("%s missing", path) return None if not silent: logging.debug("Loading data for %s from %s", _id, path) try: _f = open(path, 'rb') if do_pickle: if cfg.use_pickle(): data = pickle.load(_f) else: data = cPickle.load(_f) else: data = _f.read() _f.close() if remove: os.remove(path) except: logging.error(Ta('Loading %s failed'), path) logging.info("Traceback: ", exc_info = True) return None return data @synchronized(IO_LOCK) def remove_data(_id, path): """ Remove admin file """ path = os.path.join(path, _id) try: if os.path.exists(path): os.remove(path) logging.info("%s removed", path) except: logging.info("Failed to remove %s", path) logging.info("Traceback: ", exc_info = True) @synchronized(IO_LOCK) def save_admin(data, _id, do_pickle=True): """ Save data in admin folder in specified format """ path = os.path.join(cfg.admin_dir.get_path(), _id) logging.info("Saving data for %s in %s", _id, path) try: _f = open(path, 'wb') if do_pickle: pickler = cPickle.Pickler(_f, 2) pickler.dump(data) _f.flush() _f.close() pickler.clear_memo() del pickler else: _f.write(data) _f.flush() _f.close() except: logging.error(Ta('Saving %s failed'), path) logging.info("Traceback: ", exc_info = True) @synchronized(IO_LOCK) def load_admin(_id, remove=False, do_pickle=True): """ Read data in admin folder in specified format """ path = os.path.join(cfg.admin_dir.get_path(), _id) logging.info("Loading data for %s from %s", _id, path) if not os.path.exists(path): logging.info("%s missing, trying old cache", path) path = os.path.join(cfg.cache_dir.get_path(), _id) if not os.path.exists(path): logging.info("%s missing", path) return None remove = True try: f = open(path, 'rb') if do_pickle: data = cPickle.load(f) else: data = f.read() f.close() if remove: os.remove(path) except: excepterror = str(sys.exc_info()[0]) logging.error(Ta('Loading %s failed with error %s'), path, excepterror) logging.info("Traceback: ", exc_info = True) return None return data def pp_to_opts(pp): """ Convert numeric processinf options to (repair, unpack, delete) """ # Convert the pp to an int pp = sabnzbd.interface.int_conv(pp) if pp == 0 : return (False, False, False) if pp == 1 : return (True, False, False) if pp == 2 : return (True, True, False) return (True, True, True) def opts_to_pp(repair, unpack, delete): """ Convert (repair, unpack, delete) to numeric process options """ if repair is None: return None pp = 0 if repair: pp = 1 if unpack: pp = 2 if delete: pp = 3 return pp def request_repair(): """ Request a full repair on next restart """ path = os.path.join(cfg.admin_dir.get_path(), REPAIR_REQUEST) try: f = open(path, 'w') f.write('\n') f.close() except: pass def check_repair_request(): """ Return True if repair request found, remove afterwards """ path = os.path.join(cfg.admin_dir.get_path(), REPAIR_REQUEST) if os.path.exists(path): try: os.remove(path) except: pass return True return False def SimpleRarExtract(rarfile, fn): """ Wrapper for call to newsunpack, required to avoid circular imports """ return sabnzbd.newsunpack.SimpleRarExtract(rarfile, fn) def check_all_tasks(): """ Check every task and restart safe ones, else restart program Return True when everything is under control """ if __SHUTTING_DOWN__ or not __INITIALIZED__: return True # Non-restartable threads, require program restart if not sabnzbd.PostProcessor.do.isAlive(): logging.info('Restarting because of crashed postprocessor') return False if not Downloader.do.isAlive(): logging.info('Restarting because of crashed downloader') return False if not Assembler.do.isAlive(): logging.info('Restarting because of crashed assembler') return False # Kick the downloader, in case it missed the semaphore Downloader.do.wakeup() # Make sure the right servers are active Downloader.do.check_timers() # Restartable threads if not DirScanner.do.isAlive(): logging.info('Restarting crashed dirscanner') DirScanner.do.__init__() if not URLGrabber.do.isAlive(): logging.info('Restarting crashed urlgrabber') URLGrabber.do.__init__() if not MSGIDGrabber.do.isAlive(): logging.info('Restarting crashed newzbin') MSGIDGrabber.do.__init__() if not Rating.do.isAlive(): logging.info('Restarting crashed rating') Rating.do.__init__() if not sabnzbd.scheduler.sched_check(): logging.info('Restarting crashed scheduler') sabnzbd.scheduler.init() sabnzbd.downloader.Downloader.do.unblock_all() # Check one-shot pause sabnzbd.scheduler.pause_check() # Check (and terminate) idle jobs sabnzbd.nzbqueue.NzbQueue.do.stop_idle_jobs() return True def pid_file(pid_path=None, pid_file= None, port=0): """ Create or remove pid file """ global DIR_PID if not sabnzbd.WIN32: if pid_path and pid_path.startswith('/'): DIR_PID = os.path.join(pid_path, 'sabnzbd-%s.pid' % port) elif pid_file and pid_file.startswith('/'): DIR_PID = pid_file if DIR_PID: try: if port: f = open(DIR_PID, 'w') f.write('%d\n' % os.getpid()) f.close() else: os.remove(DIR_PID) except: logging.warning('Cannot access PID file %s', DIR_PID) def check_incomplete_vs_complete(): """ Make sure "incomplete" and "complete" are not identical """ complete = cfg.complete_dir.get_path() if misc.same_file(cfg.download_dir.get_path(), complete): if misc.real_path('X', cfg.download_dir()) == cfg.download_dir(): # Abs path, so set an abs path too cfg.download_dir.set(os.path.join(complete, 'incomplete')) else: cfg.download_dir.set('incomplete') def wait_for_download_folder(): """ Wait for download folder to become available """ while not cfg.download_dir.test_path(): logging.debug('Waiting for "incomplete" folder') time.sleep(2.0) # Required wrapper because nzbstuff.py cannot import downloader.py def active_primaries(): return sabnzbd.downloader.Downloader.do.active_primaries() def proxy_pre_queue(name, pp, cat, script, priority, size, groups): return sabnzbd.newsunpack.pre_queue(name, pp, cat, script, priority, size, groups) def proxy_build_history(): """ Proxy to let nzbqueue call api """ return sabnzbd.api.build_history() def proxy_rm_bookmark(url): """ Proxy to urlgrabber rm_bookmark """ return sabnzbd.urlgrabber.URLGrabber.do.rm_bookmark(url) SABnzbd-0.7.20/sabnzbd/utils/certgen.py0000644000000000000000000000551412433712602020016 0ustar00usergroup00000000000000# -*- coding: latin-1 -*- # # Copyright (C) Martin Sjgren and AB Strakt 2001, All rights reserved # Copyright (C) Jean-Paul Calderone 2008, All rights reserved # This file is licenced under the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 or later (aka LGPL v2.1) # Please see LGPL2.1.txt for more information """ Certificate generation module. """ from OpenSSL import crypto import time TYPE_RSA = crypto.TYPE_RSA TYPE_DSA = crypto.TYPE_DSA serial = int(time.time()) def createKeyPair(type, bits): """ Create a public/private key pair. Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA bits - Number of bits to use in the key Returns: The public/private key pair in a PKey object """ pkey = crypto.PKey() pkey.generate_key(type, bits) return pkey def createCertRequest(pkey, digest="md5", **name): """ Create a certificate request. Arguments: pkey - The key to associate with the request digest - Digestion method to use for signing, default is md5 **name - The name of the subject of the request, possible arguments are: C - Country name ST - State or province name L - Locality name O - Organization name OU - Organizational unit name CN - Common name emailAddress - E-mail address Returns: The certificate request in an X509Req object """ req = crypto.X509Req() subj = req.get_subject() for (key,value) in name.items(): setattr(subj, key, value) req.set_pubkey(pkey) req.sign(pkey, digest) return req def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), digest="md5"): """ Generate a certificate given a certificate request. Arguments: req - Certificate reqeust to use issuerCert - The certificate of the issuer issuerKey - The private key of the issuer serial - Serial number for the certificate notBefore - Timestamp (relative to now) when the certificate starts being valid notAfter - Timestamp (relative to now) when the certificate stops being valid digest - Digest method to use for signing, default is md5 Returns: The signed certificate in an X509 object """ cert = crypto.X509() cert.set_serial_number(serial) cert.gmtime_adj_notBefore(notBefore) cert.gmtime_adj_notAfter(notAfter) cert.set_issuer(issuerCert.get_subject()) cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.sign(issuerKey, digest) return cert SABnzbd-0.7.20/sabnzbd/utils/configobj.py0000644000000000000000000025414312433712602020333 0ustar00usergroup00000000000000# configobj.py # A config file reader/writer that supports nested sections in config files. # Copyright (C) 2005-2010 Michael Foord, Nicola Larosa # E-mail: fuzzyman AT voidspace DOT org DOT uk # nico AT tekNico DOT net # ConfigObj 4 # http://www.voidspace.org.uk/python/configobj.html # Released subject to the BSD License # Please see http://www.voidspace.org.uk/python/license.shtml # Scripts maintained at http://www.voidspace.org.uk/python/index.shtml # For information about bugfixes, updates and support, please join the # ConfigObj mailing list: # http://lists.sourceforge.net/lists/listinfo/configobj-develop # Comments, suggestions and bug reports welcome. from __future__ import generators import os import re import sys from codecs import BOM_UTF8, BOM_UTF16, BOM_UTF16_BE, BOM_UTF16_LE # imported lazily to avoid startup performance hit if it isn't used compiler = None # A dictionary mapping BOM to # the encoding to decode with, and what to set the # encoding attribute to. BOMS = { BOM_UTF8: ('utf_8', None), BOM_UTF16_BE: ('utf16_be', 'utf_16'), BOM_UTF16_LE: ('utf16_le', 'utf_16'), BOM_UTF16: ('utf_16', 'utf_16'), } # All legal variants of the BOM codecs. # TODO: the list of aliases is not meant to be exhaustive, is there a # better way ? BOM_LIST = { 'utf_16': 'utf_16', 'u16': 'utf_16', 'utf16': 'utf_16', 'utf-16': 'utf_16', 'utf16_be': 'utf16_be', 'utf_16_be': 'utf16_be', 'utf-16be': 'utf16_be', 'utf16_le': 'utf16_le', 'utf_16_le': 'utf16_le', 'utf-16le': 'utf16_le', 'utf_8': 'utf_8', 'u8': 'utf_8', 'utf': 'utf_8', 'utf8': 'utf_8', 'utf-8': 'utf_8', } # Map of encodings to the BOM to write. BOM_SET = { 'utf_8': BOM_UTF8, 'utf_16': BOM_UTF16, 'utf16_be': BOM_UTF16_BE, 'utf16_le': BOM_UTF16_LE, None: BOM_UTF8 } def match_utf8(encoding): return BOM_LIST.get(encoding.lower()) == 'utf_8' # Quote strings used for writing values squot = "'%s'" dquot = '"%s"' noquot = "%s" wspace_plus = ' \r\n\v\t\'"' tsquot = '"""%s"""' tdquot = "'''%s'''" # Sentinel for use in getattr calls to replace hasattr MISSING = object() __version__ = '4.7.2' try: any except NameError: def any(iterable): for entry in iterable: if entry: return True return False __all__ = ( '__version__', 'DEFAULT_INDENT_TYPE', 'DEFAULT_INTERPOLATION', 'ConfigObjError', 'NestingError', 'ParseError', 'DuplicateError', 'ConfigspecError', 'ConfigObj', 'SimpleVal', 'InterpolationError', 'InterpolationLoopError', 'MissingInterpolationOption', 'RepeatSectionError', 'ReloadError', 'UnreprError', 'UnknownType', 'flatten_errors', 'get_extra_values' ) DEFAULT_INTERPOLATION = 'configparser' DEFAULT_INDENT_TYPE = ' ' MAX_INTERPOL_DEPTH = 10 OPTION_DEFAULTS = { 'interpolation': True, 'raise_errors': False, 'list_values': True, 'create_empty': False, 'file_error': False, 'configspec': None, 'stringify': True, # option may be set to one of ('', ' ', '\t') 'indent_type': None, 'encoding': None, 'default_encoding': None, 'unrepr': False, 'write_empty_values': False, } def getObj(s): global compiler if compiler is None: import compiler s = "a=" + s p = compiler.parse(s) return p.getChildren()[1].getChildren()[0].getChildren()[1] class UnknownType(Exception): pass class Builder(object): def build(self, o): m = getattr(self, 'build_' + o.__class__.__name__, None) if m is None: raise UnknownType(o.__class__.__name__) return m(o) def build_List(self, o): return map(self.build, o.getChildren()) def build_Const(self, o): return o.value def build_Dict(self, o): d = {} i = iter(map(self.build, o.getChildren())) for el in i: d[el] = i.next() return d def build_Tuple(self, o): return tuple(self.build_List(o)) def build_Name(self, o): if o.name == 'None': return None if o.name == 'True': return True if o.name == 'False': return False # An undefined Name raise UnknownType('Undefined Name') def build_Add(self, o): real, imag = map(self.build_Const, o.getChildren()) try: real = float(real) except TypeError: raise UnknownType('Add') if not isinstance(imag, complex) or imag.real != 0.0: raise UnknownType('Add') return real+imag def build_Getattr(self, o): parent = self.build(o.expr) return getattr(parent, o.attrname) def build_UnarySub(self, o): return -self.build_Const(o.getChildren()[0]) def build_UnaryAdd(self, o): return self.build_Const(o.getChildren()[0]) _builder = Builder() def unrepr(s): if not s: return s return _builder.build(getObj(s)) class ConfigObjError(SyntaxError): """ This is the base class for all errors that ConfigObj raises. It is a subclass of SyntaxError. """ def __init__(self, message='', line_number=None, line=''): self.line = line self.line_number = line_number SyntaxError.__init__(self, message) class NestingError(ConfigObjError): """ This error indicates a level of nesting that doesn't match. """ class ParseError(ConfigObjError): """ This error indicates that a line is badly written. It is neither a valid ``key = value`` line, nor a valid section marker line. """ class ReloadError(IOError): """ A 'reload' operation failed. This exception is a subclass of ``IOError``. """ def __init__(self): IOError.__init__(self, 'reload failed, filename is not set.') class DuplicateError(ConfigObjError): """ The keyword or section specified already exists. """ class ConfigspecError(ConfigObjError): """ An error occured whilst parsing a configspec. """ class InterpolationError(ConfigObjError): """Base class for the two interpolation errors.""" class InterpolationLoopError(InterpolationError): """Maximum interpolation depth exceeded in string interpolation.""" def __init__(self, option): InterpolationError.__init__( self, 'interpolation loop detected in value "%s".' % option) class RepeatSectionError(ConfigObjError): """ This error indicates additional sections in a section with a ``__many__`` (repeated) section. """ class MissingInterpolationOption(InterpolationError): """A value specified for interpolation was missing.""" def __init__(self, option): msg = 'missing option "%s" in interpolation.' % option InterpolationError.__init__(self, msg) class UnreprError(ConfigObjError): """An error parsing in unrepr mode.""" class InterpolationEngine(object): """ A helper class to help perform string interpolation. This class is an abstract base class; its descendants perform the actual work. """ # compiled regexp to use in self.interpolate() _KEYCRE = re.compile(r"%\(([^)]*)\)s") _cookie = '%' def __init__(self, section): # the Section instance that "owns" this engine self.section = section def interpolate(self, key, value): # short-cut if not self._cookie in value: return value def recursive_interpolate(key, value, section, backtrail): """The function that does the actual work. ``value``: the string we're trying to interpolate. ``section``: the section in which that string was found ``backtrail``: a dict to keep track of where we've been, to detect and prevent infinite recursion loops This is similar to a depth-first-search algorithm. """ # Have we been here already? if (key, section.name) in backtrail: # Yes - infinite loop detected raise InterpolationLoopError(key) # Place a marker on our backtrail so we won't come back here again backtrail[(key, section.name)] = 1 # Now start the actual work match = self._KEYCRE.search(value) while match: # The actual parsing of the match is implementation-dependent, # so delegate to our helper function k, v, s = self._parse_match(match) if k is None: # That's the signal that no further interpolation is needed replacement = v else: # Further interpolation may be needed to obtain final value replacement = recursive_interpolate(k, v, s, backtrail) # Replace the matched string with its final value start, end = match.span() value = ''.join((value[:start], replacement, value[end:])) new_search_start = start + len(replacement) # Pick up the next interpolation key, if any, for next time # through the while loop match = self._KEYCRE.search(value, new_search_start) # Now safe to come back here again; remove marker from backtrail del backtrail[(key, section.name)] return value # Back in interpolate(), all we have to do is kick off the recursive # function with appropriate starting values value = recursive_interpolate(key, value, self.section, {}) return value def _fetch(self, key): """Helper function to fetch values from owning section. Returns a 2-tuple: the value, and the section where it was found. """ # switch off interpolation before we try and fetch anything ! save_interp = self.section.main.interpolation self.section.main.interpolation = False # Start at section that "owns" this InterpolationEngine current_section = self.section while True: # try the current section first val = current_section.get(key) if val is not None and not isinstance(val, Section): break # try "DEFAULT" next val = current_section.get('DEFAULT', {}).get(key) if val is not None and not isinstance(val, Section): break # move up to parent and try again # top-level's parent is itself if current_section.parent is current_section: # reached top level, time to give up break current_section = current_section.parent # restore interpolation to previous value before returning self.section.main.interpolation = save_interp if val is None: raise MissingInterpolationOption(key) return val, current_section def _parse_match(self, match): """Implementation-dependent helper function. Will be passed a match object corresponding to the interpolation key we just found (e.g., "%(foo)s" or "$foo"). Should look up that key in the appropriate config file section (using the ``_fetch()`` helper function) and return a 3-tuple: (key, value, section) ``key`` is the name of the key we're looking for ``value`` is the value found for that key ``section`` is a reference to the section where it was found ``key`` and ``section`` should be None if no further interpolation should be performed on the resulting value (e.g., if we interpolated "$$" and returned "$"). """ raise NotImplementedError() class ConfigParserInterpolation(InterpolationEngine): """Behaves like ConfigParser.""" _cookie = '%' _KEYCRE = re.compile(r"%\(([^)]*)\)s") def _parse_match(self, match): key = match.group(1) value, section = self._fetch(key) return key, value, section class TemplateInterpolation(InterpolationEngine): """Behaves like string.Template.""" _cookie = '$' _delimiter = '$' _KEYCRE = re.compile(r""" \$(?: (?P\$) | # Two $ signs (?P[_a-z][_a-z0-9]*) | # $name format {(?P[^}]*)} # ${name} format ) """, re.IGNORECASE | re.VERBOSE) def _parse_match(self, match): # Valid name (in or out of braces): fetch value from section key = match.group('named') or match.group('braced') if key is not None: value, section = self._fetch(key) return key, value, section # Escaped delimiter (e.g., $$): return single delimiter if match.group('escaped') is not None: # Return None for key and section to indicate it's time to stop return None, self._delimiter, None # Anything else: ignore completely, just return it unchanged return None, match.group(), None interpolation_engines = { 'configparser': ConfigParserInterpolation, 'template': TemplateInterpolation, } def __newobj__(cls, *args): # Hack for pickle return cls.__new__(cls, *args) class Section(dict): """ A dictionary-like object that represents a section in a config file. It does string interpolation if the 'interpolation' attribute of the 'main' object is set to True. Interpolation is tried first from this object, then from the 'DEFAULT' section of this object, next from the parent and its 'DEFAULT' section, and so on until the main object is reached. A Section will behave like an ordered dictionary - following the order of the ``scalars`` and ``sections`` attributes. You can use this to change the order of members. Iteration follows the order: scalars, then sections. """ def __setstate__(self, state): dict.update(self, state[0]) self.__dict__.update(state[1]) def __reduce__(self): state = (dict(self), self.__dict__) return (__newobj__, (self.__class__,), state) def __init__(self, parent, depth, main, indict=None, name=None): """ * parent is the section above * depth is the depth level of this section * main is the main ConfigObj * indict is a dictionary to initialise the section with """ if indict is None: indict = {} dict.__init__(self) # used for nesting level *and* interpolation self.parent = parent # used for the interpolation attribute self.main = main # level of nesting depth of this Section self.depth = depth # purely for information self.name = name # self._initialise() # we do this explicitly so that __setitem__ is used properly # (rather than just passing to ``dict.__init__``) for entry, value in indict.iteritems(): self[entry] = value def _initialise(self): # the sequence of scalar values in this Section self.scalars = [] # the sequence of sections in this Section self.sections = [] # for comments :-) self.comments = {} self.inline_comments = {} # the configspec self.configspec = None # for defaults self.defaults = [] self.default_values = {} self.extra_values = [] self._created = False def _interpolate(self, key, value): try: # do we already have an interpolation engine? engine = self._interpolation_engine except AttributeError: # not yet: first time running _interpolate(), so pick the engine name = self.main.interpolation if name == True: # note that "if name:" would be incorrect here # backwards-compatibility: interpolation=True means use default name = DEFAULT_INTERPOLATION name = name.lower() # so that "Template", "template", etc. all work class_ = interpolation_engines.get(name, None) if class_ is None: # invalid value for self.main.interpolation self.main.interpolation = False return value else: # save reference to engine so we don't have to do this again engine = self._interpolation_engine = class_(self) # let the engine do the actual work return engine.interpolate(key, value) def __getitem__(self, key): """Fetch the item and do string interpolation.""" val = dict.__getitem__(self, key) if self.main.interpolation: if isinstance(val, basestring): return self._interpolate(key, val) if isinstance(val, list): def _check(entry): if isinstance(entry, basestring): return self._interpolate(key, entry) return entry new = [_check(entry) for entry in val] if new != val: return new return val def __setitem__(self, key, value, unrepr=False): """ Correctly set a value. Making dictionary values Section instances. (We have to special case 'Section' instances - which are also dicts) Keys must be strings. Values need only be strings (or lists of strings) if ``main.stringify`` is set. ``unrepr`` must be set when setting a value to a dictionary, without creating a new sub-section. """ if not isinstance(key, basestring): raise ValueError('The key "%s" is not a string.' % key) # add the comment if key not in self.comments: self.comments[key] = [] self.inline_comments[key] = '' # remove the entry from defaults if key in self.defaults: self.defaults.remove(key) # if isinstance(value, Section): if key not in self: self.sections.append(key) dict.__setitem__(self, key, value) elif isinstance(value, dict) and not unrepr: # First create the new depth level, # then create the section if key not in self: self.sections.append(key) new_depth = self.depth + 1 dict.__setitem__( self, key, Section( self, new_depth, self.main, indict=value, name=key)) else: if key not in self: self.scalars.append(key) if not self.main.stringify: if isinstance(value, basestring): pass elif isinstance(value, (list, tuple)): for entry in value: if not isinstance(entry, basestring): raise TypeError('Value is not a string "%s".' % entry) else: raise TypeError('Value is not a string "%s".' % value) dict.__setitem__(self, key, value) def __delitem__(self, key): """Remove items from the sequence when deleting.""" dict. __delitem__(self, key) if key in self.scalars: self.scalars.remove(key) else: self.sections.remove(key) del self.comments[key] del self.inline_comments[key] def get(self, key, default=None): """A version of ``get`` that doesn't bypass string interpolation.""" try: return self[key] except KeyError: return default def update(self, indict): """ A version of update that uses our ``__setitem__``. """ for entry in indict: self[entry] = indict[entry] def pop(self, key, default=MISSING): """ 'D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised' """ try: val = self[key] except KeyError: if default is MISSING: raise val = default else: del self[key] return val def popitem(self): """Pops the first (key,val)""" sequence = (self.scalars + self.sections) if not sequence: raise KeyError(": 'popitem(): dictionary is empty'") key = sequence[0] val = self[key] del self[key] return key, val def clear(self): """ A version of clear that also affects scalars/sections Also clears comments and configspec. Leaves other attributes alone : depth/main/parent are not affected """ dict.clear(self) self.scalars = [] self.sections = [] self.comments = {} self.inline_comments = {} self.configspec = None self.defaults = [] self.extra_values = [] def setdefault(self, key, default=None): """A version of setdefault that sets sequence if appropriate.""" try: return self[key] except KeyError: self[key] = default return self[key] def items(self): """D.items() -> list of D's (key, value) pairs, as 2-tuples""" return zip((self.scalars + self.sections), self.values()) def keys(self): """D.keys() -> list of D's keys""" return (self.scalars + self.sections) def values(self): """D.values() -> list of D's values""" return [self[key] for key in (self.scalars + self.sections)] def iteritems(self): """D.iteritems() -> an iterator over the (key, value) items of D""" return iter(self.items()) def iterkeys(self): """D.iterkeys() -> an iterator over the keys of D""" return iter((self.scalars + self.sections)) __iter__ = iterkeys def itervalues(self): """D.itervalues() -> an iterator over the values of D""" return iter(self.values()) def __repr__(self): """x.__repr__() <==> repr(x)""" def _getval(key): try: return self[key] except MissingInterpolationOption: return dict.__getitem__(self, key) return '{%s}' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) for key in (self.scalars + self.sections)]) __str__ = __repr__ __str__.__doc__ = "x.__str__() <==> str(x)" # Extra methods - not in a normal dictionary def dict(self): """ Return a deepcopy of self as a dictionary. All members that are ``Section`` instances are recursively turned to ordinary dictionaries - by calling their ``dict`` method. >>> n = a.dict() >>> n == a 1 >>> n is a 0 """ newdict = {} for entry in self: this_entry = self[entry] if isinstance(this_entry, Section): this_entry = this_entry.dict() elif isinstance(this_entry, list): # create a copy rather than a reference this_entry = list(this_entry) elif isinstance(this_entry, tuple): # create a copy rather than a reference this_entry = tuple(this_entry) newdict[entry] = this_entry return newdict def merge(self, indict): """ A recursive update - useful for merging config files. >>> a = '''[section1] ... option1 = True ... [[subsection]] ... more_options = False ... # end of file'''.splitlines() >>> b = '''# File is user.ini ... [section1] ... option1 = False ... # end of file'''.splitlines() >>> c1 = ConfigObj(b) >>> c2 = ConfigObj(a) >>> c2.merge(c1) >>> c2 ConfigObj({'section1': {'option1': 'False', 'subsection': {'more_options': 'False'}}}) """ for key, val in indict.items(): if (key in self and isinstance(self[key], dict) and isinstance(val, dict)): self[key].merge(val) else: self[key] = val def rename(self, oldkey, newkey): """ Change a keyname to another, without changing position in sequence. Implemented so that transformations can be made on keys, as well as on values. (used by encode and decode) Also renames comments. """ if oldkey in self.scalars: the_list = self.scalars elif oldkey in self.sections: the_list = self.sections else: raise KeyError('Key "%s" not found.' % oldkey) pos = the_list.index(oldkey) # val = self[oldkey] dict.__delitem__(self, oldkey) dict.__setitem__(self, newkey, val) the_list.remove(oldkey) the_list.insert(pos, newkey) comm = self.comments[oldkey] inline_comment = self.inline_comments[oldkey] del self.comments[oldkey] del self.inline_comments[oldkey] self.comments[newkey] = comm self.inline_comments[newkey] = inline_comment def walk(self, function, raise_errors=True, call_on_sections=False, **keywargs): """ Walk every member and call a function on the keyword and value. Return a dictionary of the return values If the function raises an exception, raise the errror unless ``raise_errors=False``, in which case set the return value to ``False``. Any unrecognised keyword arguments you pass to walk, will be pased on to the function you pass in. Note: if ``call_on_sections`` is ``True`` then - on encountering a subsection, *first* the function is called for the *whole* subsection, and then recurses into it's members. This means your function must be able to handle strings, dictionaries and lists. This allows you to change the key of subsections as well as for ordinary members. The return value when called on the whole subsection has to be discarded. See the encode and decode methods for examples, including functions. .. admonition:: caution You can use ``walk`` to transform the names of members of a section but you mustn't add or delete members. >>> config = '''[XXXXsection] ... XXXXkey = XXXXvalue'''.splitlines() >>> cfg = ConfigObj(config) >>> cfg ConfigObj({'XXXXsection': {'XXXXkey': 'XXXXvalue'}}) >>> def transform(section, key): ... val = section[key] ... newkey = key.replace('XXXX', 'CLIENT1') ... section.rename(key, newkey) ... if isinstance(val, (tuple, list, dict)): ... pass ... else: ... val = val.replace('XXXX', 'CLIENT1') ... section[newkey] = val >>> cfg.walk(transform, call_on_sections=True) {'CLIENT1section': {'CLIENT1key': None}} >>> cfg ConfigObj({'CLIENT1section': {'CLIENT1key': 'CLIENT1value'}}) """ out = {} # scalars first for i in range(len(self.scalars)): entry = self.scalars[i] try: val = function(self, entry, **keywargs) # bound again in case name has changed entry = self.scalars[i] out[entry] = val except Exception: if raise_errors: raise else: entry = self.scalars[i] out[entry] = False # then sections for i in range(len(self.sections)): entry = self.sections[i] if call_on_sections: try: function(self, entry, **keywargs) except Exception: if raise_errors: raise else: entry = self.sections[i] out[entry] = False # bound again in case name has changed entry = self.sections[i] # previous result is discarded out[entry] = self[entry].walk( function, raise_errors=raise_errors, call_on_sections=call_on_sections, **keywargs) return out def as_bool(self, key): """ Accepts a key as input. The corresponding value must be a string or the objects (``True`` or 1) or (``False`` or 0). We allow 0 and 1 to retain compatibility with Python 2.2. If the string is one of ``True``, ``On``, ``Yes``, or ``1`` it returns ``True``. If the string is one of ``False``, ``Off``, ``No``, or ``0`` it returns ``False``. ``as_bool`` is not case sensitive. Any other input will raise a ``ValueError``. >>> a = ConfigObj() >>> a['a'] = 'fish' >>> a.as_bool('a') Traceback (most recent call last): ValueError: Value "fish" is neither True nor False >>> a['b'] = 'True' >>> a.as_bool('b') 1 >>> a['b'] = 'off' >>> a.as_bool('b') 0 """ val = self[key] if val == True: return True elif val == False: return False else: try: if not isinstance(val, basestring): # TODO: Why do we raise a KeyError here? raise KeyError() else: return self.main._bools[val.lower()] except KeyError: raise ValueError('Value "%s" is neither True nor False' % val) def as_int(self, key): """ A convenience method which coerces the specified value to an integer. If the value is an invalid literal for ``int``, a ``ValueError`` will be raised. >>> a = ConfigObj() >>> a['a'] = 'fish' >>> a.as_int('a') Traceback (most recent call last): ValueError: invalid literal for int() with base 10: 'fish' >>> a['b'] = '1' >>> a.as_int('b') 1 >>> a['b'] = '3.2' >>> a.as_int('b') Traceback (most recent call last): ValueError: invalid literal for int() with base 10: '3.2' """ return int(self[key]) def as_float(self, key): """ A convenience method which coerces the specified value to a float. If the value is an invalid literal for ``float``, a ``ValueError`` will be raised. >>> a = ConfigObj() >>> a['a'] = 'fish' >>> a.as_float('a') Traceback (most recent call last): ValueError: invalid literal for float(): fish >>> a['b'] = '1' >>> a.as_float('b') 1.0 >>> a['b'] = '3.2' >>> a.as_float('b') 3.2000000000000002 """ return float(self[key]) def as_list(self, key): """ A convenience method which fetches the specified value, guaranteeing that it is a list. >>> a = ConfigObj() >>> a['a'] = 1 >>> a.as_list('a') [1] >>> a['a'] = (1,) >>> a.as_list('a') [1] >>> a['a'] = [1] >>> a.as_list('a') [1] """ result = self[key] if isinstance(result, (tuple, list)): return list(result) return [result] def restore_default(self, key): """ Restore (and return) default value for the specified key. This method will only work for a ConfigObj that was created with a configspec and has been validated. If there is no default value for this key, ``KeyError`` is raised. """ default = self.default_values[key] dict.__setitem__(self, key, default) if key not in self.defaults: self.defaults.append(key) return default def restore_defaults(self): """ Recursively restore default values to all members that have them. This method will only work for a ConfigObj that was created with a configspec and has been validated. It doesn't delete or modify entries without default values. """ for key in self.default_values: self.restore_default(key) for section in self.sections: self[section].restore_defaults() class ConfigObj(Section): """An object to read, create, and write config files.""" _keyword = re.compile(r'''^ # line start (\s*) # indentation ( # keyword (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'"=].*?) # no quotes ) \s*=\s* # divider (.*) # value (including list values and comments) $ # line end ''', re.VERBOSE) _sectionmarker = re.compile(r'''^ (\s*) # 1: indentation ((?:\[\s*)+) # 2: section marker open ( # 3: section name open (?:"\s*\S.*?\s*")| # at least one non-space with double quotes (?:'\s*\S.*?\s*')| # at least one non-space with single quotes (?:[^'"\s].*?) # at least one non-space unquoted ) # section name close ((?:\s*\])+) # 4: section marker close \s*(\#.*)? # 5: optional comment $''', re.VERBOSE) # this regexp pulls list values out as a single string # or single values and comments # FIXME: this regex adds a '' to the end of comma terminated lists # workaround in ``_handle_value`` _valueexp = re.compile(r'''^ (?: (?: ( (?: (?: (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\#][^,\#]*?) # unquoted ) \s*,\s* # comma )* # match all list items ending in a comma (if any) ) ( (?:".*?")| # double quotes (?:'.*?')| # single quotes (?:[^'",\#\s][^,]*?)| # unquoted (?:(? 1: msg = "Parsing failed with several errors.\nFirst error %s" % info error = ConfigObjError(msg) else: error = self._errors[0] # set the errors attribute; it's a list of tuples: # (error_type, message, line_number) error.errors = self._errors # set the config attribute error.config = self raise error # delete private attributes del self._errors if configspec is None: self.configspec = None else: self._handle_configspec(configspec) def _initialise(self, options=None): if options is None: options = OPTION_DEFAULTS # initialise a few variables self.filename = None self._errors = [] self.raise_errors = options['raise_errors'] self.interpolation = options['interpolation'] self.list_values = options['list_values'] self.create_empty = options['create_empty'] self.file_error = options['file_error'] self.stringify = options['stringify'] self.indent_type = options['indent_type'] self.encoding = options['encoding'] self.default_encoding = options['default_encoding'] self.BOM = False self.newlines = None self.write_empty_values = options['write_empty_values'] self.unrepr = options['unrepr'] self.initial_comment = [] self.final_comment = [] self.configspec = None if self._inspec: self.list_values = False # Clear section attributes as well Section._initialise(self) def __repr__(self): def _getval(key): try: return self[key] except MissingInterpolationOption: return dict.__getitem__(self, key) return ('ConfigObj({%s})' % ', '.join([('%s: %s' % (repr(key), repr(_getval(key)))) for key in (self.scalars + self.sections)])) def _handle_bom(self, infile): """ Handle any BOM, and decode if necessary. If an encoding is specified, that *must* be used - but the BOM should still be removed (and the BOM attribute set). (If the encoding is wrongly specified, then a BOM for an alternative encoding won't be discovered or removed.) If an encoding is not specified, UTF8 or UTF16 BOM will be detected and removed. The BOM attribute will be set. UTF16 will be decoded to unicode. NOTE: This method must not be called with an empty ``infile``. Specifying the *wrong* encoding is likely to cause a ``UnicodeDecodeError``. ``infile`` must always be returned as a list of lines, but may be passed in as a single string. """ if ((self.encoding is not None) and (self.encoding.lower() not in BOM_LIST)): # No need to check for a BOM # the encoding specified doesn't have one # just decode return self._decode(infile, self.encoding) if isinstance(infile, (list, tuple)): line = infile[0] else: line = infile if self.encoding is not None: # encoding explicitly supplied # And it could have an associated BOM # TODO: if encoding is just UTF16 - we ought to check for both # TODO: big endian and little endian versions. enc = BOM_LIST[self.encoding.lower()] if enc == 'utf_16': # For UTF16 we try big endian and little endian for BOM, (encoding, final_encoding) in BOMS.items(): if not final_encoding: # skip UTF8 continue if infile.startswith(BOM): ### BOM discovered ##self.BOM = True # Don't need to remove BOM return self._decode(infile, encoding) # If we get this far, will *probably* raise a DecodeError # As it doesn't appear to start with a BOM return self._decode(infile, self.encoding) # Must be UTF8 BOM = BOM_SET[enc] if not line.startswith(BOM): return self._decode(infile, self.encoding) newline = line[len(BOM):] # BOM removed if isinstance(infile, (list, tuple)): infile[0] = newline else: infile = newline self.BOM = True return self._decode(infile, self.encoding) # No encoding specified - so we need to check for UTF8/UTF16 for BOM, (encoding, final_encoding) in BOMS.items(): if not line.startswith(BOM): continue else: # BOM discovered self.encoding = final_encoding if not final_encoding: self.BOM = True # UTF8 # remove BOM newline = line[len(BOM):] if isinstance(infile, (list, tuple)): infile[0] = newline else: infile = newline # UTF8 - don't decode if isinstance(infile, basestring): return infile.splitlines(True) else: return infile # UTF16 - have to decode return self._decode(infile, encoding) # No BOM discovered and no encoding specified, just return if isinstance(infile, basestring): # infile read from a file will be a single string return infile.splitlines(True) return infile def _a_to_u(self, aString): """Decode ASCII strings to unicode if a self.encoding is specified.""" if self.encoding: return aString.decode('ascii') else: return aString def _decode(self, infile, encoding): """ Decode infile to unicode. Using the specified encoding. if is a string, it also needs converting to a list. """ if isinstance(infile, basestring): # can't be unicode # NOTE: Could raise a ``UnicodeDecodeError`` return infile.decode(encoding).splitlines(True) for i, line in enumerate(infile): if not isinstance(line, unicode): # NOTE: The isinstance test here handles mixed lists of unicode/string # NOTE: But the decode will break on any non-string values # NOTE: Or could raise a ``UnicodeDecodeError`` infile[i] = line.decode(encoding) return infile def _decode_element(self, line): """Decode element to unicode if necessary.""" if not self.encoding: return line if isinstance(line, str) and self.default_encoding: return line.decode(self.default_encoding) return line def _str(self, value): """ Used by ``stringify`` within validate, to turn non-string values into strings. """ if not isinstance(value, basestring): return str(value) else: return value def _parse(self, infile): """Actually parse the config file.""" temp_list_values = self.list_values if self.unrepr: self.list_values = False comment_list = [] done_start = False this_section = self maxline = len(infile) - 1 cur_index = -1 reset_comment = False while cur_index < maxline: if reset_comment: comment_list = [] cur_index += 1 line = infile[cur_index] sline = line.strip() # do we have anything on the line ? if not sline or sline.startswith('#'): reset_comment = False comment_list.append(line) continue if not done_start: # preserve initial comment self.initial_comment = comment_list comment_list = [] done_start = True reset_comment = True # first we check if it's a section marker mat = self._sectionmarker.match(line) if mat is not None: # is a section line (indent, sect_open, sect_name, sect_close, comment) = mat.groups() if indent and (self.indent_type is None): self.indent_type = indent cur_depth = sect_open.count('[') if cur_depth != sect_close.count(']'): self._handle_error("Cannot compute the section depth at line %s.", NestingError, infile, cur_index) continue if cur_depth < this_section.depth: # the new section is dropping back to a previous level try: parent = self._match_depth(this_section, cur_depth).parent except SyntaxError: self._handle_error("Cannot compute nesting level at line %s.", NestingError, infile, cur_index) continue elif cur_depth == this_section.depth: # the new section is a sibling of the current section parent = this_section.parent elif cur_depth == this_section.depth + 1: # the new section is a child the current section parent = this_section else: self._handle_error("Section too nested at line %s.", NestingError, infile, cur_index) sect_name = self._unquote(sect_name) if sect_name in parent: self._handle_error('Duplicate section name at line %s.', DuplicateError, infile, cur_index) continue # create the new section this_section = Section( parent, cur_depth, self, name=sect_name) parent[sect_name] = this_section parent.inline_comments[sect_name] = comment parent.comments[sect_name] = comment_list continue # # it's not a section marker, # so it should be a valid ``key = value`` line mat = self._keyword.match(line) if mat is None: # it neither matched as a keyword # or a section marker self._handle_error( 'Invalid line at line "%s".', ParseError, infile, cur_index) else: # is a keyword value # value will include any inline comment (indent, key, value) = mat.groups() if indent and (self.indent_type is None): self.indent_type = indent # check for a multiline value if value[:3] in ['"""', "'''"]: try: value, comment, cur_index = self._multiline( value, infile, cur_index, maxline) except SyntaxError: self._handle_error( 'Parse error in value at line %s.', ParseError, infile, cur_index) continue else: if self.unrepr: comment = '' try: value = unrepr(value) except Exception, e: if type(e) == UnknownType: msg = 'Unknown name or type in value at line %s.' else: msg = 'Parse error in value at line %s.' self._handle_error(msg, UnreprError, infile, cur_index) continue else: if self.unrepr: comment = '' try: value = unrepr(value) except Exception, e: if isinstance(e, UnknownType): msg = 'Unknown name or type in value at line %s.' else: msg = 'Parse error in value at line %s.' self._handle_error(msg, UnreprError, infile, cur_index) continue else: # extract comment and lists try: (value, comment) = self._handle_value(value) except SyntaxError: self._handle_error( 'Parse error in value at line %s.', ParseError, infile, cur_index) continue # key = self._unquote(key) if key in this_section: self._handle_error( 'Duplicate keyword name at line %s.', DuplicateError, infile, cur_index) continue # add the key. # we set unrepr because if we have got this far we will never # be creating a new section this_section.__setitem__(key, value, unrepr=True) this_section.inline_comments[key] = comment this_section.comments[key] = comment_list continue # if self.indent_type is None: # no indentation used, set the type accordingly self.indent_type = '' # preserve the final comment if not self and not self.initial_comment: self.initial_comment = comment_list elif not reset_comment: self.final_comment = comment_list self.list_values = temp_list_values def _match_depth(self, sect, depth): """ Given a section and a depth level, walk back through the sections parents to see if the depth level matches a previous section. Return a reference to the right section, or raise a SyntaxError. """ while depth < sect.depth: if sect is sect.parent: # we've reached the top level already raise SyntaxError() sect = sect.parent if sect.depth == depth: return sect # shouldn't get here raise SyntaxError() def _handle_error(self, text, ErrorClass, infile, cur_index): """ Handle an error according to the error settings. Either raise the error or store it. The error will have occured at ``cur_index`` """ line = infile[cur_index] cur_index += 1 message = text % cur_index error = ErrorClass(message, cur_index, line) if self.raise_errors: # raise the error - parsing stops here raise error # store the error # reraise when parsing has finished self._errors.append(error) def _unquote(self, value): """Return an unquoted version of a value""" if not value: # should only happen during parsing of lists raise SyntaxError if (value[0] == value[-1]) and (value[0] in ('"', "'")): value = value[1:-1] return value def _quote(self, value, multiline=True): """ Return a safely quoted version of a value. Raise a ConfigObjError if the value cannot be safely quoted. If multiline is ``True`` (default) then use triple quotes if necessary. * Don't quote values that don't need it. * Recursively quote members of a list and return a comma joined list. * Multiline is ``False`` for lists. * Obey list syntax for empty and single member lists. If ``list_values=False`` then the value is only quoted if it contains a ``\\n`` (is multiline) or '#'. If ``write_empty_values`` is set, and the value is an empty string, it won't be quoted. """ if multiline and self.write_empty_values and value == '': # Only if multiline is set, so that it is used for values not # keys, and not values that are part of a list return '' if multiline and isinstance(value, (list, tuple)): if not value: return ',' elif len(value) == 1: return self._quote(value[0], multiline=False) + ',' return ', '.join([self._quote(val, multiline=False) for val in value]) if not isinstance(value, basestring): if self.stringify: value = str(value) else: raise TypeError('Value "%s" is not a string.' % value) if not value: return '""' no_lists_no_quotes = not self.list_values and '\n' not in value and '#' not in value need_triple = multiline and ((("'" in value) and ('"' in value)) or ('\n' in value )) hash_triple_quote = multiline and not need_triple and ("'" in value) and ('"' in value) and ('#' in value) check_for_single = (no_lists_no_quotes or not need_triple) and not hash_triple_quote if check_for_single: if not self.list_values: # we don't quote if ``list_values=False`` quot = noquot # for normal values either single or double quotes will do elif '\n' in value: # will only happen if multiline is off - e.g. '\n' in key raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) elif ((value[0] not in wspace_plus) and (value[-1] not in wspace_plus) and (',' not in value)): quot = noquot else: quot = self._get_single_quote(value) else: # if value has '\n' or "'" *and* '"', it will need triple quotes quot = self._get_triple_quote(value) if quot == noquot and '#' in value and self.list_values: quot = self._get_single_quote(value) return quot % value def _get_single_quote(self, value): if ("'" in value) and ('"' in value): raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) elif '"' in value: quot = squot else: quot = dquot return quot def _get_triple_quote(self, value): if (value.find('"""') != -1) and (value.find("'''") != -1): raise ConfigObjError('Value "%s" cannot be safely quoted.' % value) if value.find('"""') == -1: quot = tdquot else: quot = tsquot return quot def _handle_value(self, value): """ Given a value string, unquote, remove comment, handle lists. (including empty and single member lists) """ if self._inspec: # Parsing a configspec so don't handle comments return (value, '') # do we look for lists in values ? if not self.list_values: mat = self._nolistvalue.match(value) if mat is None: raise SyntaxError() # NOTE: we don't unquote here return mat.groups() # mat = self._valueexp.match(value) if mat is None: # the value is badly constructed, probably badly quoted, # or an invalid list raise SyntaxError() (list_values, single, empty_list, comment) = mat.groups() if (list_values == '') and (single is None): # change this if you want to accept empty values raise SyntaxError() # NOTE: note there is no error handling from here if the regex # is wrong: then incorrect values will slip through if empty_list is not None: # the single comma - meaning an empty list return ([], comment) if single is not None: # handle empty values if list_values and not single: # FIXME: the '' is a workaround because our regex now matches # '' at the end of a list if it has a trailing comma single = None else: single = single or '""' single = self._unquote(single) if list_values == '': # not a list value return (single, comment) the_list = self._listvalueexp.findall(list_values) the_list = [self._unquote(val) for val in the_list] if single is not None: the_list += [single] return (the_list, comment) def _multiline(self, value, infile, cur_index, maxline): """Extract the value, where we are in a multiline situation.""" quot = value[:3] newvalue = value[3:] single_line = self._triple_quote[quot][0] multi_line = self._triple_quote[quot][1] mat = single_line.match(value) if mat is not None: retval = list(mat.groups()) retval.append(cur_index) return retval elif newvalue.find(quot) != -1: # somehow the triple quote is missing raise SyntaxError() # while cur_index < maxline: cur_index += 1 newvalue += '\n' line = infile[cur_index] if line.find(quot) == -1: newvalue += line else: # end of multiline, process it break else: # we've got to the end of the config, oops... raise SyntaxError() mat = multi_line.match(line) if mat is None: # a badly formed line raise SyntaxError() (value, comment) = mat.groups() return (newvalue + value, comment, cur_index) def _handle_configspec(self, configspec): """Parse the configspec.""" # FIXME: Should we check that the configspec was created with the # correct settings ? (i.e. ``list_values=False``) if not isinstance(configspec, ConfigObj): try: configspec = ConfigObj(configspec, raise_errors=True, file_error=True, _inspec=True) except ConfigObjError, e: # FIXME: Should these errors have a reference # to the already parsed ConfigObj ? raise ConfigspecError('Parsing configspec failed: %s' % e) except IOError, e: raise IOError('Reading configspec failed: %s' % e) self.configspec = configspec def _set_configspec(self, section, copy): """ Called by validate. Handles setting the configspec on subsections including sections to be validated by __many__ """ configspec = section.configspec many = configspec.get('__many__') if isinstance(many, dict): for entry in section.sections: if entry not in configspec: section[entry].configspec = many for entry in configspec.sections: if entry == '__many__': continue if entry not in section: section[entry] = {} section[entry]._created = True if copy: # copy comments section.comments[entry] = configspec.comments.get(entry, []) section.inline_comments[entry] = configspec.inline_comments.get(entry, '') # Could be a scalar when we expect a section if isinstance(section[entry], Section): section[entry].configspec = configspec[entry] def _write_line(self, indent_string, entry, this_entry, comment): """Write an individual line, for the write method""" # NOTE: the calls to self._quote here handles non-StringType values. if not self.unrepr: val = self._decode_element(self._quote(this_entry)) else: val = repr(this_entry) return '%s%s%s%s%s' % (indent_string, self._decode_element(self._quote(entry, multiline=False)), self._a_to_u(' = '), val, self._decode_element(comment)) def _write_marker(self, indent_string, depth, entry, comment): """Write a section marker line""" return '%s%s%s%s%s' % (indent_string, self._a_to_u('[' * depth), self._quote(self._decode_element(entry), multiline=False), self._a_to_u(']' * depth), self._decode_element(comment)) def _handle_comment(self, comment): """Deal with a comment.""" if not comment: return '' start = self.indent_type if not comment.startswith('#'): start += self._a_to_u(' # ') return (start + comment) # Public methods def write(self, outfile=None, section=None): """ Write the current ConfigObj as a file tekNico: FIXME: use StringIO instead of real files >>> filename = a.filename >>> a.filename = 'test.ini' >>> a.write() >>> a.filename = filename >>> a == ConfigObj('test.ini', raise_errors=True) 1 >>> import os >>> os.remove('test.ini') """ if self.indent_type is None: # this can be true if initialised from a dictionary self.indent_type = DEFAULT_INDENT_TYPE out = [] cs = self._a_to_u('#') csp = self._a_to_u('# ') if section is None: int_val = self.interpolation self.interpolation = False section = self for line in self.initial_comment: line = self._decode_element(line) stripped_line = line.strip() if stripped_line and not stripped_line.startswith(cs): line = csp + line out.append(line) indent_string = self.indent_type * section.depth for entry in (section.scalars + section.sections): if entry in section.defaults: # don't write out default values continue for comment_line in section.comments[entry]: comment_line = self._decode_element(comment_line.lstrip()) if comment_line and not comment_line.startswith(cs): comment_line = csp + comment_line out.append(indent_string + comment_line) this_entry = section[entry] comment = self._handle_comment(section.inline_comments[entry]) if isinstance(this_entry, dict): # a section out.append(self._write_marker( indent_string, this_entry.depth, entry, comment)) out.extend(self.write(section=this_entry)) else: out.append(self._write_line( indent_string, entry, this_entry, comment)) if section is self: for line in self.final_comment: line = self._decode_element(line) stripped_line = line.strip() if stripped_line and not stripped_line.startswith(cs): line = csp + line out.append(line) self.interpolation = int_val if section is not self: return out if (self.filename is None) and (outfile is None): # output a list of lines # might need to encode # NOTE: This will *screw* UTF16, each line will start with the BOM if self.encoding: out = [l.encode(self.encoding) for l in out] if (self.BOM and ((self.encoding is None) or (BOM_LIST.get(self.encoding.lower()) == 'utf_8'))): # Add the UTF8 BOM if not out: out.append('') out[0] = BOM_UTF8 + out[0] return out # Turn the list to a string, joined with correct newlines newline = self.newlines or os.linesep if (getattr(outfile, 'mode', None) is not None and outfile.mode == 'w' and sys.platform == 'win32' and newline == '\r\n'): # Windows specific hack to avoid writing '\r\r\n' newline = '\n' output = self._a_to_u(newline).join(out) if self.encoding: output = output.encode(self.encoding) if self.BOM and ((self.encoding is None) or match_utf8(self.encoding)): # Add the UTF8 BOM output = BOM_UTF8 + output if not output.endswith(newline): output += newline if outfile is not None: outfile.write(output) else: h = open(self.filename, 'wb') h.write(output) h.close() def validate(self, validator, preserve_errors=False, copy=False, section=None): """ Test the ConfigObj against a configspec. It uses the ``validator`` object from *validate.py*. To run ``validate`` on the current ConfigObj, call: :: test = config.validate(validator) (Normally having previously passed in the configspec when the ConfigObj was created - you can dynamically assign a dictionary of checks to the ``configspec`` attribute of a section though). It returns ``True`` if everything passes, or a dictionary of pass/fails (True/False). If every member of a subsection passes, it will just have the value ``True``. (It also returns ``False`` if all members fail). In addition, it converts the values from strings to their native types if their checks pass (and ``stringify`` is set). If ``preserve_errors`` is ``True`` (``False`` is default) then instead of a marking a fail with a ``False``, it will preserve the actual exception object. This can contain info about the reason for failure. For example the ``VdtValueTooSmallError`` indicates that the value supplied was too small. If a value (or section) is missing it will still be marked as ``False``. You must have the validate module to use ``preserve_errors=True``. You can then use the ``flatten_errors`` function to turn your nested results dictionary into a flattened list of failures - useful for displaying meaningful error messages. """ if section is None: if self.configspec is None: raise ValueError('No configspec supplied.') if preserve_errors: # We do this once to remove a top level dependency on the validate module # Which makes importing configobj faster from validate import VdtMissingValue self._vdtMissingValue = VdtMissingValue section = self if copy: section.initial_comment = section.configspec.initial_comment section.final_comment = section.configspec.final_comment section.encoding = section.configspec.encoding section.BOM = section.configspec.BOM section.newlines = section.configspec.newlines section.indent_type = section.configspec.indent_type # # section.default_values.clear() #?? configspec = section.configspec self._set_configspec(section, copy) def validate_entry(entry, spec, val, missing, ret_true, ret_false): section.default_values.pop(entry, None) try: section.default_values[entry] = validator.get_default_value(configspec[entry]) except (KeyError, AttributeError, validator.baseErrorClass): # No default, bad default or validator has no 'get_default_value' # (e.g. SimpleVal) pass try: check = validator.check(spec, val, missing=missing ) except validator.baseErrorClass, e: if not preserve_errors or isinstance(e, self._vdtMissingValue): out[entry] = False else: # preserve the error out[entry] = e ret_false = False ret_true = False else: ret_false = False out[entry] = True if self.stringify or missing: # if we are doing type conversion # or the value is a supplied default if not self.stringify: if isinstance(check, (list, tuple)): # preserve lists check = [self._str(item) for item in check] elif missing and check is None: # convert the None from a default to a '' check = '' else: check = self._str(check) if (check != val) or missing: section[entry] = check if not copy and missing and entry not in section.defaults: section.defaults.append(entry) return ret_true, ret_false # out = {} ret_true = True ret_false = True unvalidated = [k for k in section.scalars if k not in configspec] incorrect_sections = [k for k in configspec.sections if k in section.scalars] incorrect_scalars = [k for k in configspec.scalars if k in section.sections] for entry in configspec.scalars: if entry in ('__many__', '___many___'): # reserved names continue if (not entry in section.scalars) or (entry in section.defaults): # missing entries # or entries from defaults missing = True val = None if copy and entry not in section.scalars: # copy comments section.comments[entry] = ( configspec.comments.get(entry, [])) section.inline_comments[entry] = ( configspec.inline_comments.get(entry, '')) # else: missing = False val = section[entry] ret_true, ret_false = validate_entry(entry, configspec[entry], val, missing, ret_true, ret_false) many = None if '__many__' in configspec.scalars: many = configspec['__many__'] elif '___many___' in configspec.scalars: many = configspec['___many___'] if many is not None: for entry in unvalidated: val = section[entry] ret_true, ret_false = validate_entry(entry, many, val, False, ret_true, ret_false) unvalidated = [] for entry in incorrect_scalars: ret_true = False if not preserve_errors: out[entry] = False else: ret_false = False msg = 'Value %r was provided as a section' % entry out[entry] = validator.baseErrorClass(msg) for entry in incorrect_sections: ret_true = False if not preserve_errors: out[entry] = False else: ret_false = False msg = 'Section %r was provided as a single value' % entry out[entry] = validator.baseErrorClass(msg) # Missing sections will have been created as empty ones when the # configspec was read. for entry in section.sections: # FIXME: this means DEFAULT is not copied in copy mode if section is self and entry == 'DEFAULT': continue if section[entry].configspec is None: unvalidated.append(entry) continue if copy: section.comments[entry] = configspec.comments.get(entry, []) section.inline_comments[entry] = configspec.inline_comments.get(entry, '') check = self.validate(validator, preserve_errors=preserve_errors, copy=copy, section=section[entry]) out[entry] = check if check == False: ret_true = False elif check == True: ret_false = False else: ret_true = False section.extra_values = unvalidated if preserve_errors and not section._created: # If the section wasn't created (i.e. it wasn't missing) # then we can't return False, we need to preserve errors ret_false = False # if ret_false and preserve_errors and out: # If we are preserving errors, but all # the failures are from missing sections / values # then we can return False. Otherwise there is a # real failure that we need to preserve. ret_false = not any(out.values()) if ret_true: return True elif ret_false: return False return out def reset(self): """Clear ConfigObj instance and restore to 'freshly created' state.""" self.clear() self._initialise() # FIXME: Should be done by '_initialise', but ConfigObj constructor (and reload) # requires an empty dictionary self.configspec = None # Just to be sure ;-) self._original_configspec = None def reload(self): """ Reload a ConfigObj from file. This method raises a ``ReloadError`` if the ConfigObj doesn't have a filename attribute pointing to a file. """ if not isinstance(self.filename, basestring): raise ReloadError() filename = self.filename current_options = {} for entry in OPTION_DEFAULTS: if entry == 'configspec': continue current_options[entry] = getattr(self, entry) configspec = self._original_configspec current_options['configspec'] = configspec self.clear() self._initialise(current_options) self._load(filename, configspec) class SimpleVal(object): """ A simple validator. Can be used to check that all members expected are present. To use it, provide a configspec with all your members in (the value given will be ignored). Pass an instance of ``SimpleVal`` to the ``validate`` method of your ``ConfigObj``. ``validate`` will return ``True`` if all members are present, or a dictionary with True/False meaning present/missing. (Whole missing sections will be replaced with ``False``) """ def __init__(self): self.baseErrorClass = ConfigObjError def check(self, check, member, missing=False): """A dummy check method, always returns the value unchanged.""" if missing: raise self.baseErrorClass() return member def flatten_errors(cfg, res, levels=None, results=None): """ An example function that will turn a nested dictionary of results (as returned by ``ConfigObj.validate``) into a flat list. ``cfg`` is the ConfigObj instance being checked, ``res`` is the results dictionary returned by ``validate``. (This is a recursive function, so you shouldn't use the ``levels`` or ``results`` arguments - they are used by the function.) Returns a list of keys that failed. Each member of the list is a tuple:: ([list of sections...], key, result) If ``validate`` was called with ``preserve_errors=False`` (the default) then ``result`` will always be ``False``. *list of sections* is a flattened list of sections that the key was found in. If the section was missing (or a section was expected and a scalar provided - or vice-versa) then key will be ``None``. If the value (or section) was missing then ``result`` will be ``False``. If ``validate`` was called with ``preserve_errors=True`` and a value was present, but failed the check, then ``result`` will be the exception object returned. You can use this as a string that describes the failure. For example *The value "3" is of the wrong type*. """ if levels is None: # first time called levels = [] results = [] if res == True: return results if res == False or isinstance(res, Exception): results.append((levels[:], None, res)) if levels: levels.pop() return results for (key, val) in res.items(): if val == True: continue if isinstance(cfg.get(key), dict): # Go down one level levels.append(key) flatten_errors(cfg[key], val, levels, results) continue results.append((levels[:], key, val)) # # Go up one level if levels: levels.pop() # return results def get_extra_values(conf, _prepend=()): """ Find all the values and sections not in the configspec from a validated ConfigObj. ``get_extra_values`` returns a list of tuples where each tuple represents either an extra section, or an extra value. The tuples contain two values, a tuple representing the section the value is in and the name of the extra values. For extra values in the top level section the first member will be an empty tuple. For values in the 'foo' section the first member will be ``('foo',)``. For members in the 'bar' subsection of the 'foo' section the first member will be ``('foo', 'bar')``. NOTE: If you call ``get_extra_values`` on a ConfigObj instance that hasn't been validated it will return an empty list. """ out = [] out.extend([(_prepend, name) for name in conf.extra_values]) for name in conf.sections: if name not in conf.extra_values: out.extend(get_extra_values(conf[name], _prepend + (name,))) return out """*A programming language is a medium of expression.* - Paul Graham""" SABnzbd-0.7.20/sabnzbd/utils/feedparser.py0000644000000000000000000050526712433712602020521 0ustar00usergroup00000000000000"""Universal feed parser Handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds Visit https://code.google.com/p/feedparser/ for the latest version Visit http://packages.python.org/feedparser/ for the latest documentation Required: Python 2.4 or later Recommended: iconv_codec """ __version__ = "5.1.3" __license__ = """ Copyright (c) 2010-2012 Kurt McKee Copyright (c) 2002-2008 Mark Pilgrim All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.""" __author__ = "Mark Pilgrim " __contributors__ = ["Jason Diamond ", "John Beimler ", "Fazal Majid ", "Aaron Swartz ", "Kevin Marks ", "Sam Ruby ", "Ade Oshineye ", "Martin Pool ", "Kurt McKee ", "Bernd Schlapsi ",] # HTTP "User-Agent" header to send to servers when downloading feeds. # If you are embedding feedparser in a larger application, you should # change this to your application name and URL. USER_AGENT = "UniversalFeedParser/%s +https://code.google.com/p/feedparser/" % __version__ # HTTP "Accept" header to send to servers when downloading feeds. If you don't # want to send an Accept header, set this to None. ACCEPT_HEADER = "application/atom+xml,application/rdf+xml,application/rss+xml,application/x-netcdf,application/xml;q=0.9,text/xml;q=0.2,*/*;q=0.1" # List of preferred XML parsers, by SAX driver name. These will be tried first, # but if they're not installed, Python will keep searching through its own list # of pre-installed parsers until it finds one that supports everything we need. PREFERRED_XML_PARSERS = ["drv_libxml2"] # If you want feedparser to automatically run HTML markup through HTML Tidy, set # this to 1. Requires mxTidy # or utidylib . TIDY_MARKUP = 0 # List of Python interfaces for HTML Tidy, in order of preference. Only useful # if TIDY_MARKUP = 1 PREFERRED_TIDY_INTERFACES = ["uTidy", "mxTidy"] # If you want feedparser to automatically resolve all relative URIs, set this # to 1. RESOLVE_RELATIVE_URIS = 1 # If you want feedparser to automatically sanitize all potentially unsafe # HTML content, set this to 1. SANITIZE_HTML = 1 # If you want feedparser to automatically parse microformat content embedded # in entry contents, set this to 1 PARSE_MICROFORMATS = 1 # ---------- Python 3 modules (make it work if possible) ---------- try: import rfc822 except ImportError: from email import _parseaddr as rfc822 try: # Python 3.1 introduces bytes.maketrans and simultaneously # deprecates string.maketrans; use bytes.maketrans if possible _maketrans = bytes.maketrans except (NameError, AttributeError): import string _maketrans = string.maketrans # base64 support for Atom feeds that contain embedded binary data try: import base64, binascii except ImportError: base64 = binascii = None else: # Python 3.1 deprecates decodestring in favor of decodebytes _base64decode = getattr(base64, 'decodebytes', base64.decodestring) # _s2bytes: convert a UTF-8 str to bytes if the interpreter is Python 3 # _l2bytes: convert a list of ints to bytes if the interpreter is Python 3 try: if bytes is str: # In Python 2.5 and below, bytes doesn't exist (NameError) # In Python 2.6 and above, bytes and str are the same type raise NameError except NameError: # Python 2 def _s2bytes(s): return s def _l2bytes(l): return ''.join(map(chr, l)) else: # Python 3 def _s2bytes(s): return bytes(s, 'utf8') def _l2bytes(l): return bytes(l) # If you want feedparser to allow all URL schemes, set this to () # List culled from Python's urlparse documentation at: # http://docs.python.org/library/urlparse.html # as well as from "URI scheme" at Wikipedia: # https://secure.wikimedia.org/wikipedia/en/wiki/URI_scheme # Many more will likely need to be added! ACCEPTABLE_URI_SCHEMES = ( 'file', 'ftp', 'gopher', 'h323', 'hdl', 'http', 'https', 'imap', 'magnet', 'mailto', 'mms', 'news', 'nntp', 'prospero', 'rsync', 'rtsp', 'rtspu', 'sftp', 'shttp', 'sip', 'sips', 'snews', 'svn', 'svn+ssh', 'telnet', 'wais', # Additional common-but-unofficial schemes 'aim', 'callto', 'cvs', 'facetime', 'feed', 'git', 'gtalk', 'irc', 'ircs', 'irc6', 'itms', 'mms', 'msnim', 'skype', 'ssh', 'smb', 'svn', 'ymsg', ) #ACCEPTABLE_URI_SCHEMES = () # ---------- required modules (should come with any Python distribution) ---------- import cgi import codecs import copy import datetime import re import struct import time import types import urllib import urllib2 import urlparse import warnings from htmlentitydefs import name2codepoint, codepoint2name, entitydefs try: from io import BytesIO as _StringIO except ImportError: try: from cStringIO import StringIO as _StringIO except ImportError: from StringIO import StringIO as _StringIO # ---------- optional modules (feedparser will work without these, but with reduced functionality) ---------- # gzip is included with most Python distributions, but may not be available if you compiled your own try: import gzip except ImportError: gzip = None try: import zlib except ImportError: zlib = None # If a real XML parser is available, feedparser will attempt to use it. feedparser has # been tested with the built-in SAX parser and libxml2. On platforms where the # Python distribution does not come with an XML parser (such as Mac OS X 10.2 and some # versions of FreeBSD), feedparser will quietly fall back on regex-based parsing. try: import xml.sax from xml.sax.saxutils import escape as _xmlescape except ImportError: _XML_AVAILABLE = 0 def _xmlescape(data,entities={}): data = data.replace('&', '&') data = data.replace('>', '>') data = data.replace('<', '<') for char, entity in entities: data = data.replace(char, entity) return data else: try: xml.sax.make_parser(PREFERRED_XML_PARSERS) # test for valid parsers except xml.sax.SAXReaderNotAvailable: _XML_AVAILABLE = 0 else: _XML_AVAILABLE = 1 # sgmllib is not available by default in Python 3; if the end user doesn't have # it available then we'll lose illformed XML parsing, content santizing, and # microformat support (at least while feedparser depends on BeautifulSoup). try: import sgmllib except ImportError: # This is probably Python 3, which doesn't include sgmllib anymore _SGML_AVAILABLE = 0 # Mock sgmllib enough to allow subclassing later on class sgmllib(object): class SGMLParser(object): def goahead(self, i): pass def parse_starttag(self, i): pass else: _SGML_AVAILABLE = 1 # sgmllib defines a number of module-level regular expressions that are # insufficient for the XML parsing feedparser needs. Rather than modify # the variables directly in sgmllib, they're defined here using the same # names, and the compiled code objects of several sgmllib.SGMLParser # methods are copied into _BaseHTMLProcessor so that they execute in # feedparser's scope instead of sgmllib's scope. charref = re.compile('&#(\d+|[xX][0-9a-fA-F]+);') tagfind = re.compile('[a-zA-Z][-_.:a-zA-Z0-9]*') attrfind = re.compile( r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)[$]?(\s*=\s*' r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?' ) # Unfortunately, these must be copied over to prevent NameError exceptions entityref = sgmllib.entityref incomplete = sgmllib.incomplete interesting = sgmllib.interesting shorttag = sgmllib.shorttag shorttagopen = sgmllib.shorttagopen starttagopen = sgmllib.starttagopen class _EndBracketRegEx: def __init__(self): # Overriding the built-in sgmllib.endbracket regex allows the # parser to find angle brackets embedded in element attributes. self.endbracket = re.compile('''([^'"<>]|"[^"]*"(?=>|/|\s|\w+=)|'[^']*'(?=>|/|\s|\w+=))*(?=[<>])|.*?(?=[<>])''') def search(self, target, index=0): match = self.endbracket.match(target, index) if match is not None: # Returning a new object in the calling thread's context # resolves a thread-safety. return EndBracketMatch(match) return None class EndBracketMatch: def __init__(self, match): self.match = match def start(self, n): return self.match.end(n) endbracket = _EndBracketRegEx() # iconv_codec provides support for more character encodings. # It's available from http://cjkpython.i18n.org/ try: import iconv_codec except ImportError: pass # chardet library auto-detects character encodings # Download from http://chardet.feedparser.org/ try: import chardet except ImportError: chardet = None # BeautifulSoup is used to extract microformat content from HTML # feedparser is tested using BeautifulSoup 3.2.0 # http://www.crummy.com/software/BeautifulSoup/ try: import BeautifulSoup except ImportError: BeautifulSoup = None PARSE_MICROFORMATS = False # ---------- don't touch these ---------- class ThingsNobodyCaresAboutButMe(Exception): pass class CharacterEncodingOverride(ThingsNobodyCaresAboutButMe): pass class CharacterEncodingUnknown(ThingsNobodyCaresAboutButMe): pass class NonXMLContentType(ThingsNobodyCaresAboutButMe): pass class UndeclaredNamespace(Exception): pass SUPPORTED_VERSIONS = {'': u'unknown', 'rss090': u'RSS 0.90', 'rss091n': u'RSS 0.91 (Netscape)', 'rss091u': u'RSS 0.91 (Userland)', 'rss092': u'RSS 0.92', 'rss093': u'RSS 0.93', 'rss094': u'RSS 0.94', 'rss20': u'RSS 2.0', 'rss10': u'RSS 1.0', 'rss': u'RSS (unknown version)', 'atom01': u'Atom 0.1', 'atom02': u'Atom 0.2', 'atom03': u'Atom 0.3', 'atom10': u'Atom 1.0', 'atom': u'Atom (unknown version)', 'cdf': u'CDF', } class FeedParserDict(dict): keymap = {'channel': 'feed', 'items': 'entries', 'guid': 'id', 'date': 'updated', 'date_parsed': 'updated_parsed', 'description': ['summary', 'subtitle'], 'description_detail': ['summary_detail', 'subtitle_detail'], 'url': ['href'], 'modified': 'updated', 'modified_parsed': 'updated_parsed', 'issued': 'published', 'issued_parsed': 'published_parsed', 'copyright': 'rights', 'copyright_detail': 'rights_detail', 'tagline': 'subtitle', 'tagline_detail': 'subtitle_detail'} def __getitem__(self, key): if key == 'category': try: return dict.__getitem__(self, 'tags')[0]['term'] except IndexError: raise KeyError, "object doesn't have key 'category'" elif key == 'enclosures': norel = lambda link: FeedParserDict([(name,value) for (name,value) in link.items() if name!='rel']) return [norel(link) for link in dict.__getitem__(self, 'links') if link['rel']==u'enclosure'] elif key == 'license': for link in dict.__getitem__(self, 'links'): if link['rel']==u'license' and 'href' in link: return link['href'] elif key == 'updated': # Temporarily help developers out by keeping the old # broken behavior that was reported in issue 310. # This fix was proposed in issue 328. if not dict.__contains__(self, 'updated') and \ dict.__contains__(self, 'published'): warnings.warn("To avoid breaking existing software while " "fixing issue 310, a temporary mapping has been created " "from `updated` to `published` if `updated` doesn't " "exist. This fallback will be removed in a future version " "of feedparser.", DeprecationWarning) return dict.__getitem__(self, 'published') return dict.__getitem__(self, 'updated') elif key == 'updated_parsed': if not dict.__contains__(self, 'updated_parsed') and \ dict.__contains__(self, 'published_parsed'): warnings.warn("To avoid breaking existing software while " "fixing issue 310, a temporary mapping has been created " "from `updated_parsed` to `published_parsed` if " "`updated_parsed` doesn't exist. This fallback will be " "removed in a future version of feedparser.", DeprecationWarning) return dict.__getitem__(self, 'published_parsed') return dict.__getitem__(self, 'updated_parsed') else: realkey = self.keymap.get(key, key) if isinstance(realkey, list): for k in realkey: if dict.__contains__(self, k): return dict.__getitem__(self, k) elif dict.__contains__(self, realkey): return dict.__getitem__(self, realkey) return dict.__getitem__(self, key) def __contains__(self, key): if key in ('updated', 'updated_parsed'): # Temporarily help developers out by keeping the old # broken behavior that was reported in issue 310. # This fix was proposed in issue 328. return dict.__contains__(self, key) try: self.__getitem__(key) except KeyError: return False else: return True has_key = __contains__ def get(self, key, default=None): try: return self.__getitem__(key) except KeyError: return default def __setitem__(self, key, value): key = self.keymap.get(key, key) if isinstance(key, list): key = key[0] return dict.__setitem__(self, key, value) def setdefault(self, key, value): if key not in self: self[key] = value return value return self[key] def __getattr__(self, key): # __getattribute__() is called first; this will be called # only if an attribute was not already found try: return self.__getitem__(key) except KeyError: raise AttributeError, "object has no attribute '%s'" % key def __hash__(self): return id(self) _cp1252 = { 128: unichr(8364), # euro sign 130: unichr(8218), # single low-9 quotation mark 131: unichr( 402), # latin small letter f with hook 132: unichr(8222), # double low-9 quotation mark 133: unichr(8230), # horizontal ellipsis 134: unichr(8224), # dagger 135: unichr(8225), # double dagger 136: unichr( 710), # modifier letter circumflex accent 137: unichr(8240), # per mille sign 138: unichr( 352), # latin capital letter s with caron 139: unichr(8249), # single left-pointing angle quotation mark 140: unichr( 338), # latin capital ligature oe 142: unichr( 381), # latin capital letter z with caron 145: unichr(8216), # left single quotation mark 146: unichr(8217), # right single quotation mark 147: unichr(8220), # left double quotation mark 148: unichr(8221), # right double quotation mark 149: unichr(8226), # bullet 150: unichr(8211), # en dash 151: unichr(8212), # em dash 152: unichr( 732), # small tilde 153: unichr(8482), # trade mark sign 154: unichr( 353), # latin small letter s with caron 155: unichr(8250), # single right-pointing angle quotation mark 156: unichr( 339), # latin small ligature oe 158: unichr( 382), # latin small letter z with caron 159: unichr( 376), # latin capital letter y with diaeresis } _urifixer = re.compile('^([A-Za-z][A-Za-z0-9+-.]*://)(/*)(.*?)') def _urljoin(base, uri): uri = _urifixer.sub(r'\1\3', uri) #try: if not isinstance(uri, unicode): uri = uri.decode('utf-8', 'ignore') uri = urlparse.urljoin(base, uri) if not isinstance(uri, unicode): return uri.decode('utf-8', 'ignore') return uri #except: # uri = urlparse.urlunparse([urllib.quote(part) for part in urlparse.urlparse(uri)]) # return urlparse.urljoin(base, uri) class _FeedParserMixin: namespaces = { '': '', 'http://backend.userland.com/rss': '', 'http://blogs.law.harvard.edu/tech/rss': '', 'http://purl.org/rss/1.0/': '', 'http://my.netscape.com/rdf/simple/0.9/': '', 'http://example.com/newformat#': '', 'http://example.com/necho': '', 'http://purl.org/echo/': '', 'uri/of/echo/namespace#': '', 'http://purl.org/pie/': '', 'http://purl.org/atom/ns#': '', 'http://www.w3.org/2005/Atom': '', 'http://purl.org/rss/1.0/modules/rss091#': '', 'http://webns.net/mvcb/': 'admin', 'http://purl.org/rss/1.0/modules/aggregation/': 'ag', 'http://purl.org/rss/1.0/modules/annotate/': 'annotate', 'http://media.tangent.org/rss/1.0/': 'audio', 'http://backend.userland.com/blogChannelModule': 'blogChannel', 'http://web.resource.org/cc/': 'cc', 'http://backend.userland.com/creativeCommonsRssModule': 'creativeCommons', 'http://purl.org/rss/1.0/modules/company': 'co', 'http://purl.org/rss/1.0/modules/content/': 'content', 'http://my.theinfo.org/changed/1.0/rss/': 'cp', 'http://purl.org/dc/elements/1.1/': 'dc', 'http://purl.org/dc/terms/': 'dcterms', 'http://purl.org/rss/1.0/modules/email/': 'email', 'http://purl.org/rss/1.0/modules/event/': 'ev', 'http://rssnamespace.org/feedburner/ext/1.0': 'feedburner', 'http://freshmeat.net/rss/fm/': 'fm', 'http://xmlns.com/foaf/0.1/': 'foaf', 'http://www.w3.org/2003/01/geo/wgs84_pos#': 'geo', 'http://postneo.com/icbm/': 'icbm', 'http://purl.org/rss/1.0/modules/image/': 'image', 'http://www.itunes.com/DTDs/PodCast-1.0.dtd': 'itunes', 'http://example.com/DTDs/PodCast-1.0.dtd': 'itunes', 'http://purl.org/rss/1.0/modules/link/': 'l', 'http://search.yahoo.com/mrss': 'media', # Version 1.1.2 of the Media RSS spec added the trailing slash on the namespace 'http://search.yahoo.com/mrss/': 'media', 'http://madskills.com/public/xml/rss/module/pingback/': 'pingback', 'http://prismstandard.org/namespaces/1.2/basic/': 'prism', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#': 'rdf', 'http://www.w3.org/2000/01/rdf-schema#': 'rdfs', 'http://purl.org/rss/1.0/modules/reference/': 'ref', 'http://purl.org/rss/1.0/modules/richequiv/': 'reqv', 'http://purl.org/rss/1.0/modules/search/': 'search', 'http://purl.org/rss/1.0/modules/slash/': 'slash', 'http://schemas.xmlsoap.org/soap/envelope/': 'soap', 'http://purl.org/rss/1.0/modules/servicestatus/': 'ss', 'http://hacks.benhammersley.com/rss/streaming/': 'str', 'http://purl.org/rss/1.0/modules/subscription/': 'sub', 'http://purl.org/rss/1.0/modules/syndication/': 'sy', 'http://schemas.pocketsoap.com/rss/myDescModule/': 'szf', 'http://purl.org/rss/1.0/modules/taxonomy/': 'taxo', 'http://purl.org/rss/1.0/modules/threading/': 'thr', 'http://purl.org/rss/1.0/modules/textinput/': 'ti', 'http://madskills.com/public/xml/rss/module/trackback/': 'trackback', 'http://wellformedweb.org/commentAPI/': 'wfw', 'http://purl.org/rss/1.0/modules/wiki/': 'wiki', 'http://www.w3.org/1999/xhtml': 'xhtml', 'http://www.w3.org/1999/xlink': 'xlink', 'http://www.w3.org/XML/1998/namespace': 'xml', } _matchnamespaces = {} can_be_relative_uri = set(['link', 'id', 'wfw_comment', 'wfw_commentrss', 'docs', 'url', 'href', 'comments', 'icon', 'logo']) can_contain_relative_uris = set(['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description']) can_contain_dangerous_markup = set(['content', 'title', 'summary', 'info', 'tagline', 'subtitle', 'copyright', 'rights', 'description']) html_types = [u'text/html', u'application/xhtml+xml'] def __init__(self, baseuri=None, baselang=None, encoding=u'utf-8'): if not self._matchnamespaces: for k, v in self.namespaces.items(): self._matchnamespaces[k.lower()] = v self.feeddata = FeedParserDict() # feed-level data self.encoding = encoding # character encoding self.entries = [] # list of entry-level data self.version = u'' # feed type/version, see SUPPORTED_VERSIONS self.namespacesInUse = {} # dictionary of namespaces defined by the feed # the following are used internally to track state; # this is really out of control and should be refactored self.infeed = 0 self.inentry = 0 self.incontent = 0 self.intextinput = 0 self.inimage = 0 self.inauthor = 0 self.incontributor = 0 self.inpublisher = 0 self.insource = 0 self.sourcedata = FeedParserDict() self.contentparams = FeedParserDict() self._summaryKey = None self.namespacemap = {} self.elementstack = [] self.basestack = [] self.langstack = [] self.baseuri = baseuri or u'' self.lang = baselang or None self.svgOK = 0 self.title_depth = -1 self.depth = 0 if baselang: self.feeddata['language'] = baselang.replace('_','-') # A map of the following form: # { # object_that_value_is_set_on: { # property_name: depth_of_node_property_was_extracted_from, # other_property: depth_of_node_property_was_extracted_from, # }, # } self.property_depth_map = {} def _normalize_attributes(self, kv): k = kv[0].lower() v = k in ('rel', 'type') and kv[1].lower() or kv[1] # the sgml parser doesn't handle entities in attributes, nor # does it pass the attribute values through as unicode, while # strict xml parsers do -- account for this difference if isinstance(self, _LooseFeedParser): v = v.replace('&', '&') if not isinstance(v, unicode): v = v.decode('utf-8') return (k, v) def unknown_starttag(self, tag, attrs): # increment depth counter self.depth += 1 # normalize attrs attrs = map(self._normalize_attributes, attrs) # track xml:base and xml:lang attrsD = dict(attrs) baseuri = attrsD.get('xml:base', attrsD.get('base')) or self.baseuri if not isinstance(baseuri, unicode): baseuri = baseuri.decode(self.encoding, 'ignore') # ensure that self.baseuri is always an absolute URI that # uses a whitelisted URI scheme (e.g. not `javscript:`) if self.baseuri: self.baseuri = _makeSafeAbsoluteURI(self.baseuri, baseuri) or self.baseuri else: self.baseuri = _urljoin(self.baseuri, baseuri) lang = attrsD.get('xml:lang', attrsD.get('lang')) if lang == '': # xml:lang could be explicitly set to '', we need to capture that lang = None elif lang is None: # if no xml:lang is specified, use parent lang lang = self.lang if lang: if tag in ('feed', 'rss', 'rdf:RDF'): self.feeddata['language'] = lang.replace('_','-') self.lang = lang self.basestack.append(self.baseuri) self.langstack.append(lang) # track namespaces for prefix, uri in attrs: if prefix.startswith('xmlns:'): self.trackNamespace(prefix[6:], uri) elif prefix == 'xmlns': self.trackNamespace(None, uri) # track inline content if self.incontent and not self.contentparams.get('type', u'xml').endswith(u'xml'): if tag in ('xhtml:div', 'div'): return # typepad does this 10/2007 # element declared itself as escaped markup, but it isn't really self.contentparams['type'] = u'application/xhtml+xml' if self.incontent and self.contentparams.get('type') == u'application/xhtml+xml': if tag.find(':') <> -1: prefix, tag = tag.split(':', 1) namespace = self.namespacesInUse.get(prefix, '') if tag=='math' and namespace=='http://www.w3.org/1998/Math/MathML': attrs.append(('xmlns',namespace)) if tag=='svg' and namespace=='http://www.w3.org/2000/svg': attrs.append(('xmlns',namespace)) if tag == 'svg': self.svgOK += 1 return self.handle_data('<%s%s>' % (tag, self.strattrs(attrs)), escape=0) # match namespaces if tag.find(':') <> -1: prefix, suffix = tag.split(':', 1) else: prefix, suffix = '', tag prefix = self.namespacemap.get(prefix, prefix) if prefix: prefix = prefix + '_' # special hack for better tracking of empty textinput/image elements in illformed feeds if (not prefix) and tag not in ('title', 'link', 'description', 'name'): self.intextinput = 0 if (not prefix) and tag not in ('title', 'link', 'description', 'url', 'href', 'width', 'height'): self.inimage = 0 # call special handler (if defined) or default handler methodname = '_start_' + prefix + suffix try: method = getattr(self, methodname) return method(attrsD) except AttributeError: # Since there's no handler or something has gone wrong we explicitly add the element and its attributes unknown_tag = prefix + suffix if len(attrsD) == 0: # No attributes so merge it into the encosing dictionary return self.push(unknown_tag, 1) else: # Has attributes so create it in its own dictionary context = self._getContext() context[unknown_tag] = attrsD def unknown_endtag(self, tag): # match namespaces if tag.find(':') <> -1: prefix, suffix = tag.split(':', 1) else: prefix, suffix = '', tag prefix = self.namespacemap.get(prefix, prefix) if prefix: prefix = prefix + '_' if suffix == 'svg' and self.svgOK: self.svgOK -= 1 # call special handler (if defined) or default handler methodname = '_end_' + prefix + suffix try: if self.svgOK: raise AttributeError() method = getattr(self, methodname) method() except AttributeError: self.pop(prefix + suffix) # track inline content if self.incontent and not self.contentparams.get('type', u'xml').endswith(u'xml'): # element declared itself as escaped markup, but it isn't really if tag in ('xhtml:div', 'div'): return # typepad does this 10/2007 self.contentparams['type'] = u'application/xhtml+xml' if self.incontent and self.contentparams.get('type') == u'application/xhtml+xml': tag = tag.split(':')[-1] self.handle_data('' % tag, escape=0) # track xml:base and xml:lang going out of scope if self.basestack: self.basestack.pop() if self.basestack and self.basestack[-1]: self.baseuri = self.basestack[-1] if self.langstack: self.langstack.pop() if self.langstack: # and (self.langstack[-1] is not None): self.lang = self.langstack[-1] self.depth -= 1 def handle_charref(self, ref): # called for each character reference, e.g. for ' ', ref will be '160' if not self.elementstack: return ref = ref.lower() if ref in ('34', '38', '39', '60', '62', 'x22', 'x26', 'x27', 'x3c', 'x3e'): text = '&#%s;' % ref else: if ref[0] == 'x': c = int(ref[1:], 16) else: c = int(ref) text = unichr(c).encode('utf-8') self.elementstack[-1][2].append(text) def handle_entityref(self, ref): # called for each entity reference, e.g. for '©', ref will be 'copy' if not self.elementstack: return if ref in ('lt', 'gt', 'quot', 'amp', 'apos'): text = '&%s;' % ref elif ref in self.entities: text = self.entities[ref] if text.startswith('&#') and text.endswith(';'): return self.handle_entityref(text) else: try: name2codepoint[ref] except KeyError: text = '&%s;' % ref else: text = unichr(name2codepoint[ref]).encode('utf-8') self.elementstack[-1][2].append(text) def handle_data(self, text, escape=1): # called for each block of plain text, i.e. outside of any tag and # not containing any character or entity references if not self.elementstack: return if escape and self.contentparams.get('type') == u'application/xhtml+xml': text = _xmlescape(text) self.elementstack[-1][2].append(text) def handle_comment(self, text): # called for each comment, e.g. pass def handle_pi(self, text): # called for each processing instruction, e.g. pass def handle_decl(self, text): pass def parse_declaration(self, i): # override internal declaration handler to handle CDATA blocks if self.rawdata[i:i+9] == '', i) if k == -1: # CDATA block began but didn't finish k = len(self.rawdata) return k self.handle_data(_xmlescape(self.rawdata[i+9:k]), 0) return k+3 else: k = self.rawdata.find('>', i) if k >= 0: return k+1 else: # We have an incomplete CDATA block. return k def mapContentType(self, contentType): contentType = contentType.lower() if contentType == 'text' or contentType == 'plain': contentType = u'text/plain' elif contentType == 'html': contentType = u'text/html' elif contentType == 'xhtml': contentType = u'application/xhtml+xml' return contentType def trackNamespace(self, prefix, uri): loweruri = uri.lower() if not self.version: if (prefix, loweruri) == (None, 'http://my.netscape.com/rdf/simple/0.9/'): self.version = u'rss090' elif loweruri == 'http://purl.org/rss/1.0/': self.version = u'rss10' elif loweruri == 'http://www.w3.org/2005/atom': self.version = u'atom10' if loweruri.find(u'backend.userland.com/rss') <> -1: # match any backend.userland.com namespace uri = u'http://backend.userland.com/rss' loweruri = uri if loweruri in self._matchnamespaces: self.namespacemap[prefix] = self._matchnamespaces[loweruri] self.namespacesInUse[self._matchnamespaces[loweruri]] = uri else: self.namespacesInUse[prefix or ''] = uri def resolveURI(self, uri): return _urljoin(self.baseuri or u'', uri) def decodeEntities(self, element, data): return data def strattrs(self, attrs): return ''.join([' %s="%s"' % (t[0],_xmlescape(t[1],{'"':'"'})) for t in attrs]) def push(self, element, expectingText): self.elementstack.append([element, expectingText, []]) def pop(self, element, stripWhitespace=1): if not self.elementstack: return if self.elementstack[-1][0] != element: return element, expectingText, pieces = self.elementstack.pop() if self.version == u'atom10' and self.contentparams.get('type', u'text') == u'application/xhtml+xml': # remove enclosing child element, but only if it is a
    and # only if all the remaining content is nested underneath it. # This means that the divs would be retained in the following: #
    foo
    bar
    while pieces and len(pieces)>1 and not pieces[-1].strip(): del pieces[-1] while pieces and len(pieces)>1 and not pieces[0].strip(): del pieces[0] if pieces and (pieces[0] == '
    ' or pieces[0].startswith('
    ': depth = 0 for piece in pieces[:-1]: if piece.startswith(''): depth += 1 else: pieces = pieces[1:-1] # Ensure each piece is a str for Python 3 for (i, v) in enumerate(pieces): if not isinstance(v, unicode): pieces[i] = v.decode('utf-8') output = u''.join(pieces) if stripWhitespace: output = output.strip() if not expectingText: return output # decode base64 content if base64 and self.contentparams.get('base64', 0): try: output = _base64decode(output) except binascii.Error: pass except binascii.Incomplete: pass except TypeError: # In Python 3, base64 takes and outputs bytes, not str # This may not be the most correct way to accomplish this output = _base64decode(output.encode('utf-8')).decode('utf-8') # resolve relative URIs if (element in self.can_be_relative_uri) and output: output = self.resolveURI(output) # decode entities within embedded markup if not self.contentparams.get('base64', 0): output = self.decodeEntities(element, output) # some feed formats require consumers to guess # whether the content is html or plain text if not self.version.startswith(u'atom') and self.contentparams.get('type') == u'text/plain': if self.lookslikehtml(output): self.contentparams['type'] = u'text/html' # remove temporary cruft from contentparams try: del self.contentparams['mode'] except KeyError: pass try: del self.contentparams['base64'] except KeyError: pass is_htmlish = self.mapContentType(self.contentparams.get('type', u'text/html')) in self.html_types # resolve relative URIs within embedded markup if is_htmlish and RESOLVE_RELATIVE_URIS: if element in self.can_contain_relative_uris: output = _resolveRelativeURIs(output, self.baseuri, self.encoding, self.contentparams.get('type', u'text/html')) # parse microformats # (must do this before sanitizing because some microformats # rely on elements that we sanitize) if PARSE_MICROFORMATS and is_htmlish and element in ['content', 'description', 'summary']: mfresults = _parseMicroformats(output, self.baseuri, self.encoding) if mfresults: for tag in mfresults.get('tags', []): self._addTag(tag['term'], tag['scheme'], tag['label']) for enclosure in mfresults.get('enclosures', []): self._start_enclosure(enclosure) for xfn in mfresults.get('xfn', []): self._addXFN(xfn['relationships'], xfn['href'], xfn['name']) vcard = mfresults.get('vcard') if vcard: self._getContext()['vcard'] = vcard # sanitize embedded markup if is_htmlish and SANITIZE_HTML: if element in self.can_contain_dangerous_markup: output = _sanitizeHTML(output, self.encoding, self.contentparams.get('type', u'text/html')) if self.encoding and not isinstance(output, unicode): output = output.decode(self.encoding, 'ignore') # address common error where people take data that is already # utf-8, presume that it is iso-8859-1, and re-encode it. if self.encoding in (u'utf-8', u'utf-8_INVALID_PYTHON_3') and isinstance(output, unicode): try: output = output.encode('iso-8859-1').decode('utf-8') except (UnicodeEncodeError, UnicodeDecodeError): pass # map win-1252 extensions to the proper code points if isinstance(output, unicode): output = output.translate(_cp1252) # categories/tags/keywords/whatever are handled in _end_category if element == 'category': return output if element == 'title' and -1 < self.title_depth <= self.depth: return output # store output in appropriate place(s) if self.inentry and not self.insource: if element == 'content': self.entries[-1].setdefault(element, []) contentparams = copy.deepcopy(self.contentparams) contentparams['value'] = output self.entries[-1][element].append(contentparams) elif element == 'link': if not self.inimage: # query variables in urls in link elements are improperly # converted from `?a=1&b=2` to `?a=1&b;=2` as if they're # unhandled character references. fix this special case. output = re.sub("&([A-Za-z0-9_]+);", "&\g<1>", output) self.entries[-1][element] = output if output: self.entries[-1]['links'][-1]['href'] = output else: if element == 'description': element = 'summary' old_value_depth = self.property_depth_map.setdefault(self.entries[-1], {}).get(element) if old_value_depth is None or self.depth <= old_value_depth: self.property_depth_map[self.entries[-1]][element] = self.depth self.entries[-1][element] = output if self.incontent: contentparams = copy.deepcopy(self.contentparams) contentparams['value'] = output self.entries[-1][element + '_detail'] = contentparams elif (self.infeed or self.insource):# and (not self.intextinput) and (not self.inimage): context = self._getContext() if element == 'description': element = 'subtitle' context[element] = output if element == 'link': # fix query variables; see above for the explanation output = re.sub("&([A-Za-z0-9_]+);", "&\g<1>", output) context[element] = output context['links'][-1]['href'] = output elif self.incontent: contentparams = copy.deepcopy(self.contentparams) contentparams['value'] = output context[element + '_detail'] = contentparams return output def pushContent(self, tag, attrsD, defaultContentType, expectingText): self.incontent += 1 if self.lang: self.lang=self.lang.replace('_','-') self.contentparams = FeedParserDict({ 'type': self.mapContentType(attrsD.get('type', defaultContentType)), 'language': self.lang, 'base': self.baseuri}) self.contentparams['base64'] = self._isBase64(attrsD, self.contentparams) self.push(tag, expectingText) def popContent(self, tag): value = self.pop(tag) self.incontent -= 1 self.contentparams.clear() return value # a number of elements in a number of RSS variants are nominally plain # text, but this is routinely ignored. This is an attempt to detect # the most common cases. As false positives often result in silent # data loss, this function errs on the conservative side. @staticmethod def lookslikehtml(s): # must have a close tag or an entity reference to qualify if not (re.search(r'',s) or re.search("&#?\w+;",s)): return # all tags must be in a restricted subset of valid HTML tags if filter(lambda t: t.lower() not in _HTMLSanitizer.acceptable_elements, re.findall(r' -1: prefix = name[:colonpos] suffix = name[colonpos+1:] prefix = self.namespacemap.get(prefix, prefix) name = prefix + ':' + suffix return name def _getAttribute(self, attrsD, name): return attrsD.get(self._mapToStandardPrefix(name)) def _isBase64(self, attrsD, contentparams): if attrsD.get('mode', '') == 'base64': return 1 if self.contentparams['type'].startswith(u'text/'): return 0 if self.contentparams['type'].endswith(u'+xml'): return 0 if self.contentparams['type'].endswith(u'/xml'): return 0 return 1 def _itsAnHrefDamnIt(self, attrsD): href = attrsD.get('url', attrsD.get('uri', attrsD.get('href', None))) if href: try: del attrsD['url'] except KeyError: pass try: del attrsD['uri'] except KeyError: pass attrsD['href'] = href return attrsD def _save(self, key, value, overwrite=False): context = self._getContext() if overwrite: context[key] = value else: context.setdefault(key, value) def _start_rss(self, attrsD): versionmap = {'0.91': u'rss091u', '0.92': u'rss092', '0.93': u'rss093', '0.94': u'rss094'} #If we're here then this is an RSS feed. #If we don't have a version or have a version that starts with something #other than RSS then there's been a mistake. Correct it. if not self.version or not self.version.startswith(u'rss'): attr_version = attrsD.get('version', '') version = versionmap.get(attr_version) if version: self.version = version elif attr_version.startswith('2.'): self.version = u'rss20' else: self.version = u'rss' def _start_channel(self, attrsD): self.infeed = 1 self._cdf_common(attrsD) def _cdf_common(self, attrsD): if 'lastmod' in attrsD: self._start_modified({}) self.elementstack[-1][-1] = attrsD['lastmod'] self._end_modified() if 'href' in attrsD: self._start_link({}) self.elementstack[-1][-1] = attrsD['href'] self._end_link() def _start_feed(self, attrsD): self.infeed = 1 versionmap = {'0.1': u'atom01', '0.2': u'atom02', '0.3': u'atom03'} if not self.version: attr_version = attrsD.get('version') version = versionmap.get(attr_version) if version: self.version = version else: self.version = u'atom' def _end_channel(self): self.infeed = 0 _end_feed = _end_channel def _start_image(self, attrsD): context = self._getContext() if not self.inentry: context.setdefault('image', FeedParserDict()) self.inimage = 1 self.title_depth = -1 self.push('image', 0) def _end_image(self): self.pop('image') self.inimage = 0 def _start_textinput(self, attrsD): context = self._getContext() context.setdefault('textinput', FeedParserDict()) self.intextinput = 1 self.title_depth = -1 self.push('textinput', 0) _start_textInput = _start_textinput def _end_textinput(self): self.pop('textinput') self.intextinput = 0 _end_textInput = _end_textinput def _start_author(self, attrsD): self.inauthor = 1 self.push('author', 1) # Append a new FeedParserDict when expecting an author context = self._getContext() context.setdefault('authors', []) context['authors'].append(FeedParserDict()) _start_managingeditor = _start_author _start_dc_author = _start_author _start_dc_creator = _start_author _start_itunes_author = _start_author def _end_author(self): self.pop('author') self.inauthor = 0 self._sync_author_detail() _end_managingeditor = _end_author _end_dc_author = _end_author _end_dc_creator = _end_author _end_itunes_author = _end_author def _start_itunes_owner(self, attrsD): self.inpublisher = 1 self.push('publisher', 0) def _end_itunes_owner(self): self.pop('publisher') self.inpublisher = 0 self._sync_author_detail('publisher') def _start_contributor(self, attrsD): self.incontributor = 1 context = self._getContext() context.setdefault('contributors', []) context['contributors'].append(FeedParserDict()) self.push('contributor', 0) def _end_contributor(self): self.pop('contributor') self.incontributor = 0 def _start_dc_contributor(self, attrsD): self.incontributor = 1 context = self._getContext() context.setdefault('contributors', []) context['contributors'].append(FeedParserDict()) self.push('name', 0) def _end_dc_contributor(self): self._end_name() self.incontributor = 0 def _start_name(self, attrsD): self.push('name', 0) _start_itunes_name = _start_name def _end_name(self): value = self.pop('name') if self.inpublisher: self._save_author('name', value, 'publisher') elif self.inauthor: self._save_author('name', value) elif self.incontributor: self._save_contributor('name', value) elif self.intextinput: context = self._getContext() context['name'] = value _end_itunes_name = _end_name def _start_width(self, attrsD): self.push('width', 0) def _end_width(self): value = self.pop('width') try: value = int(value) except ValueError: value = 0 if self.inimage: context = self._getContext() context['width'] = value def _start_height(self, attrsD): self.push('height', 0) def _end_height(self): value = self.pop('height') try: value = int(value) except ValueError: value = 0 if self.inimage: context = self._getContext() context['height'] = value def _start_url(self, attrsD): self.push('href', 1) _start_homepage = _start_url _start_uri = _start_url def _end_url(self): value = self.pop('href') if self.inauthor: self._save_author('href', value) elif self.incontributor: self._save_contributor('href', value) _end_homepage = _end_url _end_uri = _end_url def _start_email(self, attrsD): self.push('email', 0) _start_itunes_email = _start_email def _end_email(self): value = self.pop('email') if self.inpublisher: self._save_author('email', value, 'publisher') elif self.inauthor: self._save_author('email', value) elif self.incontributor: self._save_contributor('email', value) _end_itunes_email = _end_email def _getContext(self): if self.insource: context = self.sourcedata elif self.inimage and 'image' in self.feeddata: context = self.feeddata['image'] elif self.intextinput: context = self.feeddata['textinput'] elif self.inentry: context = self.entries[-1] else: context = self.feeddata return context def _save_author(self, key, value, prefix='author'): context = self._getContext() context.setdefault(prefix + '_detail', FeedParserDict()) context[prefix + '_detail'][key] = value self._sync_author_detail() context.setdefault('authors', [FeedParserDict()]) context['authors'][-1][key] = value def _save_contributor(self, key, value): context = self._getContext() context.setdefault('contributors', [FeedParserDict()]) context['contributors'][-1][key] = value def _sync_author_detail(self, key='author'): context = self._getContext() detail = context.get('%s_detail' % key) if detail: name = detail.get('name') email = detail.get('email') if name and email: context[key] = u'%s (%s)' % (name, email) elif name: context[key] = name elif email: context[key] = email else: author, email = context.get(key), None if not author: return emailmatch = re.search(ur'''(([a-zA-Z0-9\_\-\.\+]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?))(\?subject=\S+)?''', author) if emailmatch: email = emailmatch.group(0) # probably a better way to do the following, but it passes all the tests author = author.replace(email, u'') author = author.replace(u'()', u'') author = author.replace(u'<>', u'') author = author.replace(u'<>', u'') author = author.strip() if author and (author[0] == u'('): author = author[1:] if author and (author[-1] == u')'): author = author[:-1] author = author.strip() if author or email: context.setdefault('%s_detail' % key, FeedParserDict()) if author: context['%s_detail' % key]['name'] = author if email: context['%s_detail' % key]['email'] = email def _start_subtitle(self, attrsD): self.pushContent('subtitle', attrsD, u'text/plain', 1) _start_tagline = _start_subtitle _start_itunes_subtitle = _start_subtitle def _end_subtitle(self): self.popContent('subtitle') _end_tagline = _end_subtitle _end_itunes_subtitle = _end_subtitle def _start_rights(self, attrsD): self.pushContent('rights', attrsD, u'text/plain', 1) _start_dc_rights = _start_rights _start_copyright = _start_rights def _end_rights(self): self.popContent('rights') _end_dc_rights = _end_rights _end_copyright = _end_rights def _start_item(self, attrsD): self.entries.append(FeedParserDict()) self.push('item', 0) self.inentry = 1 self.guidislink = 0 self.title_depth = -1 id = self._getAttribute(attrsD, 'rdf:about') if id: context = self._getContext() context['id'] = id self._cdf_common(attrsD) _start_entry = _start_item def _end_item(self): self.pop('item') self.inentry = 0 _end_entry = _end_item def _start_dc_language(self, attrsD): self.push('language', 1) _start_language = _start_dc_language def _end_dc_language(self): self.lang = self.pop('language') _end_language = _end_dc_language def _start_dc_publisher(self, attrsD): self.push('publisher', 1) _start_webmaster = _start_dc_publisher def _end_dc_publisher(self): self.pop('publisher') self._sync_author_detail('publisher') _end_webmaster = _end_dc_publisher def _start_published(self, attrsD): self.push('published', 1) _start_dcterms_issued = _start_published _start_issued = _start_published _start_pubdate = _start_published def _end_published(self): value = self.pop('published') self._save('published_parsed', _parse_date(value), overwrite=True) _end_dcterms_issued = _end_published _end_issued = _end_published _end_pubdate = _end_published def _start_updated(self, attrsD): self.push('updated', 1) _start_modified = _start_updated _start_dcterms_modified = _start_updated _start_dc_date = _start_updated _start_lastbuilddate = _start_updated def _end_updated(self): value = self.pop('updated') parsed_value = _parse_date(value) self._save('updated_parsed', parsed_value, overwrite=True) _end_modified = _end_updated _end_dcterms_modified = _end_updated _end_dc_date = _end_updated _end_lastbuilddate = _end_updated def _start_created(self, attrsD): self.push('created', 1) _start_dcterms_created = _start_created def _end_created(self): value = self.pop('created') self._save('created_parsed', _parse_date(value), overwrite=True) _end_dcterms_created = _end_created def _start_expirationdate(self, attrsD): self.push('expired', 1) def _end_expirationdate(self): self._save('expired_parsed', _parse_date(self.pop('expired')), overwrite=True) def _start_cc_license(self, attrsD): context = self._getContext() value = self._getAttribute(attrsD, 'rdf:resource') attrsD = FeedParserDict() attrsD['rel'] = u'license' if value: attrsD['href']=value context.setdefault('links', []).append(attrsD) def _start_creativecommons_license(self, attrsD): self.push('license', 1) _start_creativeCommons_license = _start_creativecommons_license def _end_creativecommons_license(self): value = self.pop('license') context = self._getContext() attrsD = FeedParserDict() attrsD['rel'] = u'license' if value: attrsD['href'] = value context.setdefault('links', []).append(attrsD) del context['license'] _end_creativeCommons_license = _end_creativecommons_license def _addXFN(self, relationships, href, name): context = self._getContext() xfn = context.setdefault('xfn', []) value = FeedParserDict({'relationships': relationships, 'href': href, 'name': name}) if value not in xfn: xfn.append(value) def _addTag(self, term, scheme, label): context = self._getContext() tags = context.setdefault('tags', []) if (not term) and (not scheme) and (not label): return value = FeedParserDict({'term': term, 'scheme': scheme, 'label': label}) if value not in tags: tags.append(value) def _start_category(self, attrsD): term = attrsD.get('term') scheme = attrsD.get('scheme', attrsD.get('domain')) label = attrsD.get('label') self._addTag(term, scheme, label) self.push('category', 1) _start_dc_subject = _start_category _start_keywords = _start_category def _start_media_category(self, attrsD): attrsD.setdefault('scheme', u'http://search.yahoo.com/mrss/category_schema') self._start_category(attrsD) def _end_itunes_keywords(self): for term in self.pop('itunes_keywords').split(','): if term.strip(): self._addTag(term.strip(), u'http://www.itunes.com/', None) def _start_itunes_category(self, attrsD): self._addTag(attrsD.get('text'), u'http://www.itunes.com/', None) self.push('category', 1) def _end_category(self): value = self.pop('category') if not value: return context = self._getContext() tags = context['tags'] if value and len(tags) and not tags[-1]['term']: tags[-1]['term'] = value else: self._addTag(value, None, None) _end_dc_subject = _end_category _end_keywords = _end_category _end_itunes_category = _end_category _end_media_category = _end_category def _start_cloud(self, attrsD): self._getContext()['cloud'] = FeedParserDict(attrsD) def _start_link(self, attrsD): attrsD.setdefault('rel', u'alternate') if attrsD['rel'] == u'self': attrsD.setdefault('type', u'application/atom+xml') else: attrsD.setdefault('type', u'text/html') context = self._getContext() attrsD = self._itsAnHrefDamnIt(attrsD) if 'href' in attrsD: attrsD['href'] = self.resolveURI(attrsD['href']) expectingText = self.infeed or self.inentry or self.insource context.setdefault('links', []) if not (self.inentry and self.inimage): context['links'].append(FeedParserDict(attrsD)) if 'href' in attrsD: expectingText = 0 if (attrsD.get('rel') == u'alternate') and (self.mapContentType(attrsD.get('type')) in self.html_types): context['link'] = attrsD['href'] else: self.push('link', expectingText) def _end_link(self): value = self.pop('link') def _start_guid(self, attrsD): self.guidislink = (attrsD.get('ispermalink', 'true') == 'true') self.push('id', 1) _start_id = _start_guid def _end_guid(self): value = self.pop('id') self._save('guidislink', self.guidislink and 'link' not in self._getContext()) if self.guidislink: # guid acts as link, but only if 'ispermalink' is not present or is 'true', # and only if the item doesn't already have a link element self._save('link', value) _end_id = _end_guid def _start_title(self, attrsD): if self.svgOK: return self.unknown_starttag('title', attrsD.items()) self.pushContent('title', attrsD, u'text/plain', self.infeed or self.inentry or self.insource) _start_dc_title = _start_title _start_media_title = _start_title def _end_title(self): if self.svgOK: return value = self.popContent('title') if not value: return self.title_depth = self.depth _end_dc_title = _end_title def _end_media_title(self): title_depth = self.title_depth self._end_title() self.title_depth = title_depth def _start_description(self, attrsD): context = self._getContext() if 'summary' in context: self._summaryKey = 'content' self._start_content(attrsD) else: self.pushContent('description', attrsD, u'text/html', self.infeed or self.inentry or self.insource) _start_dc_description = _start_description def _start_abstract(self, attrsD): self.pushContent('description', attrsD, u'text/plain', self.infeed or self.inentry or self.insource) def _end_description(self): if self._summaryKey == 'content': self._end_content() else: value = self.popContent('description') self._summaryKey = None _end_abstract = _end_description _end_dc_description = _end_description def _start_info(self, attrsD): self.pushContent('info', attrsD, u'text/plain', 1) _start_feedburner_browserfriendly = _start_info def _end_info(self): self.popContent('info') _end_feedburner_browserfriendly = _end_info def _start_generator(self, attrsD): if attrsD: attrsD = self._itsAnHrefDamnIt(attrsD) if 'href' in attrsD: attrsD['href'] = self.resolveURI(attrsD['href']) self._getContext()['generator_detail'] = FeedParserDict(attrsD) self.push('generator', 1) def _end_generator(self): value = self.pop('generator') context = self._getContext() if 'generator_detail' in context: context['generator_detail']['name'] = value def _start_admin_generatoragent(self, attrsD): self.push('generator', 1) value = self._getAttribute(attrsD, 'rdf:resource') if value: self.elementstack[-1][2].append(value) self.pop('generator') self._getContext()['generator_detail'] = FeedParserDict({'href': value}) def _start_admin_errorreportsto(self, attrsD): self.push('errorreportsto', 1) value = self._getAttribute(attrsD, 'rdf:resource') if value: self.elementstack[-1][2].append(value) self.pop('errorreportsto') def _start_summary(self, attrsD): context = self._getContext() if 'summary' in context: self._summaryKey = 'content' self._start_content(attrsD) else: self._summaryKey = 'summary' self.pushContent(self._summaryKey, attrsD, u'text/plain', 1) _start_itunes_summary = _start_summary def _end_summary(self): if self._summaryKey == 'content': self._end_content() else: self.popContent(self._summaryKey or 'summary') self._summaryKey = None _end_itunes_summary = _end_summary def _start_enclosure(self, attrsD): attrsD = self._itsAnHrefDamnIt(attrsD) context = self._getContext() attrsD['rel'] = u'enclosure' context.setdefault('links', []).append(FeedParserDict(attrsD)) def _start_source(self, attrsD): if 'url' in attrsD: # This means that we're processing a source element from an RSS 2.0 feed self.sourcedata['href'] = attrsD[u'url'] self.push('source', 1) self.insource = 1 self.title_depth = -1 def _end_source(self): self.insource = 0 value = self.pop('source') if value: self.sourcedata['title'] = value self._getContext()['source'] = copy.deepcopy(self.sourcedata) self.sourcedata.clear() def _start_content(self, attrsD): self.pushContent('content', attrsD, u'text/plain', 1) src = attrsD.get('src') if src: self.contentparams['src'] = src self.push('content', 1) def _start_body(self, attrsD): self.pushContent('content', attrsD, u'application/xhtml+xml', 1) _start_xhtml_body = _start_body def _start_content_encoded(self, attrsD): self.pushContent('content', attrsD, u'text/html', 1) _start_fullitem = _start_content_encoded def _end_content(self): copyToSummary = self.mapContentType(self.contentparams.get('type')) in ([u'text/plain'] + self.html_types) value = self.popContent('content') if copyToSummary: self._save('summary', value) _end_body = _end_content _end_xhtml_body = _end_content _end_content_encoded = _end_content _end_fullitem = _end_content def _start_itunes_image(self, attrsD): self.push('itunes_image', 0) if attrsD.get('href'): self._getContext()['image'] = FeedParserDict({'href': attrsD.get('href')}) elif attrsD.get('url'): self._getContext()['image'] = FeedParserDict({'href': attrsD.get('url')}) _start_itunes_link = _start_itunes_image def _end_itunes_block(self): value = self.pop('itunes_block', 0) self._getContext()['itunes_block'] = (value == 'yes') and 1 or 0 def _end_itunes_explicit(self): value = self.pop('itunes_explicit', 0) # Convert 'yes' -> True, 'clean' to False, and any other value to None # False and None both evaluate as False, so the difference can be ignored # by applications that only need to know if the content is explicit. self._getContext()['itunes_explicit'] = (None, False, True)[(value == 'yes' and 2) or value == 'clean' or 0] def _start_media_content(self, attrsD): context = self._getContext() context.setdefault('media_content', []) context['media_content'].append(attrsD) def _start_media_thumbnail(self, attrsD): context = self._getContext() context.setdefault('media_thumbnail', []) self.push('url', 1) # new context['media_thumbnail'].append(attrsD) def _end_media_thumbnail(self): url = self.pop('url') context = self._getContext() if url != None and len(url.strip()) != 0: if 'url' not in context['media_thumbnail'][-1]: context['media_thumbnail'][-1]['url'] = url def _start_media_player(self, attrsD): self.push('media_player', 0) self._getContext()['media_player'] = FeedParserDict(attrsD) def _end_media_player(self): value = self.pop('media_player') context = self._getContext() context['media_player']['content'] = value def _start_newlocation(self, attrsD): self.push('newlocation', 1) def _end_newlocation(self): url = self.pop('newlocation') context = self._getContext() # don't set newlocation if the context isn't right if context is not self.feeddata: return context['newlocation'] = _makeSafeAbsoluteURI(self.baseuri, url.strip()) if _XML_AVAILABLE: class _StrictFeedParser(_FeedParserMixin, xml.sax.handler.ContentHandler): def __init__(self, baseuri, baselang, encoding): xml.sax.handler.ContentHandler.__init__(self) _FeedParserMixin.__init__(self, baseuri, baselang, encoding) self.bozo = 0 self.exc = None self.decls = {} def startPrefixMapping(self, prefix, uri): if not uri: return # Jython uses '' instead of None; standardize on None prefix = prefix or None self.trackNamespace(prefix, uri) if prefix and uri == 'http://www.w3.org/1999/xlink': self.decls['xmlns:' + prefix] = uri def startElementNS(self, name, qname, attrs): namespace, localname = name lowernamespace = str(namespace or '').lower() if lowernamespace.find(u'backend.userland.com/rss') <> -1: # match any backend.userland.com namespace namespace = u'http://backend.userland.com/rss' lowernamespace = namespace if qname and qname.find(':') > 0: givenprefix = qname.split(':')[0] else: givenprefix = None prefix = self._matchnamespaces.get(lowernamespace, givenprefix) if givenprefix and (prefix == None or (prefix == '' and lowernamespace == '')) and givenprefix not in self.namespacesInUse: raise UndeclaredNamespace, "'%s' is not associated with a namespace" % givenprefix localname = str(localname).lower() # qname implementation is horribly broken in Python 2.1 (it # doesn't report any), and slightly broken in Python 2.2 (it # doesn't report the xml: namespace). So we match up namespaces # with a known list first, and then possibly override them with # the qnames the SAX parser gives us (if indeed it gives us any # at all). Thanks to MatejC for helping me test this and # tirelessly telling me that it didn't work yet. attrsD, self.decls = self.decls, {} if localname=='math' and namespace=='http://www.w3.org/1998/Math/MathML': attrsD['xmlns']=namespace if localname=='svg' and namespace=='http://www.w3.org/2000/svg': attrsD['xmlns']=namespace if prefix: localname = prefix.lower() + ':' + localname elif namespace and not qname: #Expat for name,value in self.namespacesInUse.items(): if name and value == namespace: localname = name + ':' + localname break for (namespace, attrlocalname), attrvalue in attrs.items(): lowernamespace = (namespace or '').lower() prefix = self._matchnamespaces.get(lowernamespace, '') if prefix: attrlocalname = prefix + ':' + attrlocalname attrsD[str(attrlocalname).lower()] = attrvalue for qname in attrs.getQNames(): attrsD[str(qname).lower()] = attrs.getValueByQName(qname) self.unknown_starttag(localname, attrsD.items()) def characters(self, text): self.handle_data(text) def endElementNS(self, name, qname): namespace, localname = name lowernamespace = str(namespace or '').lower() if qname and qname.find(':') > 0: givenprefix = qname.split(':')[0] else: givenprefix = '' prefix = self._matchnamespaces.get(lowernamespace, givenprefix) if prefix: localname = prefix + ':' + localname elif namespace and not qname: #Expat for name,value in self.namespacesInUse.items(): if name and value == namespace: localname = name + ':' + localname break localname = str(localname).lower() self.unknown_endtag(localname) def error(self, exc): self.bozo = 1 self.exc = exc # drv_libxml2 calls warning() in some cases warning = error def fatalError(self, exc): self.error(exc) raise exc class _BaseHTMLProcessor(sgmllib.SGMLParser): special = re.compile('''[<>'"]''') bare_ampersand = re.compile("&(?!#\d+;|#x[0-9a-fA-F]+;|\w+;)") elements_no_end_tag = set([ 'area', 'base', 'basefont', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr' ]) def __init__(self, encoding, _type): self.encoding = encoding self._type = _type sgmllib.SGMLParser.__init__(self) def reset(self): self.pieces = [] sgmllib.SGMLParser.reset(self) def _shorttag_replace(self, match): tag = match.group(1) if tag in self.elements_no_end_tag: return '<' + tag + ' />' else: return '<' + tag + '>' # By declaring these methods and overriding their compiled code # with the code from sgmllib, the original code will execute in # feedparser's scope instead of sgmllib's. This means that the # `tagfind` and `charref` regular expressions will be found as # they're declared above, not as they're declared in sgmllib. def goahead(self, i): pass goahead.func_code = sgmllib.SGMLParser.goahead.func_code def __parse_starttag(self, i): pass __parse_starttag.func_code = sgmllib.SGMLParser.parse_starttag.func_code def parse_starttag(self,i): j = self.__parse_starttag(i) if self._type == 'application/xhtml+xml': if j>2 and self.rawdata[j-2:j]=='/>': self.unknown_endtag(self.lasttag) return j def feed(self, data): data = re.compile(r'\s]+?)\s*/>', self._shorttag_replace, data) data = data.replace(''', "'") data = data.replace('"', '"') try: bytes if bytes is str: raise NameError self.encoding = self.encoding + u'_INVALID_PYTHON_3' except NameError: if self.encoding and isinstance(data, unicode): data = data.encode(self.encoding) sgmllib.SGMLParser.feed(self, data) sgmllib.SGMLParser.close(self) def normalize_attrs(self, attrs): if not attrs: return attrs # utility method to be called by descendants attrs = dict([(k.lower(), v) for k, v in attrs]).items() attrs = [(k, k in ('rel', 'type') and v.lower() or v) for k, v in attrs] attrs.sort() return attrs def unknown_starttag(self, tag, attrs): # called for each start tag # attrs is a list of (attr, value) tuples # e.g. for
    , tag='pre', attrs=[('class', 'screen')]
            uattrs = []
            strattrs=''
            if attrs:
                for key, value in attrs:
                    value=value.replace('>','>').replace('<','<').replace('"','"')
                    value = self.bare_ampersand.sub("&", value)
                    # thanks to Kevin Marks for this breathtaking hack to deal with (valid) high-bit attribute values in UTF-8 feeds
                    if not isinstance(value, unicode):
                        value = value.decode(self.encoding, 'ignore')
                    try:
                        # Currently, in Python 3 the key is already a str, and cannot be decoded again
                        uattrs.append((unicode(key, self.encoding), value))
                    except TypeError:
                        uattrs.append((key, value))
                strattrs = u''.join([u' %s="%s"' % (key, value) for key, value in uattrs])
                if self.encoding:
                    try:
                        strattrs = strattrs.encode(self.encoding)
                    except (UnicodeEncodeError, LookupError):
                        pass
            if tag in self.elements_no_end_tag:
                self.pieces.append('<%s%s />' % (tag, strattrs))
            else:
                self.pieces.append('<%s%s>' % (tag, strattrs))
    
        def unknown_endtag(self, tag):
            # called for each end tag, e.g. for 
    , tag will be 'pre' # Reconstruct the original end tag. if tag not in self.elements_no_end_tag: self.pieces.append("" % tag) def handle_charref(self, ref): # called for each character reference, e.g. for ' ', ref will be '160' # Reconstruct the original character reference. ref = ref.lower() if ref.startswith('x'): value = int(ref[1:], 16) else: value = int(ref) if value in _cp1252: self.pieces.append('&#%s;' % hex(ord(_cp1252[value]))[1:]) else: self.pieces.append('&#%s;' % ref) def handle_entityref(self, ref): # called for each entity reference, e.g. for '©', ref will be 'copy' # Reconstruct the original entity reference. if ref in name2codepoint or ref == 'apos': self.pieces.append('&%s;' % ref) else: self.pieces.append('&%s' % ref) def handle_data(self, text): # called for each block of plain text, i.e. outside of any tag and # not containing any character or entity references # Store the original text verbatim. self.pieces.append(text) def handle_comment(self, text): # called for each HTML comment, e.g. # Reconstruct the original comment. self.pieces.append('' % text) def handle_pi(self, text): # called for each processing instruction, e.g. # Reconstruct original processing instruction. self.pieces.append('' % text) def handle_decl(self, text): # called for the DOCTYPE, if present, e.g. # # Reconstruct original DOCTYPE self.pieces.append('' % text) _new_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9:]*\s*').match def _scan_name(self, i, declstartpos): rawdata = self.rawdata n = len(rawdata) if i == n: return None, -1 m = self._new_declname_match(rawdata, i) if m: s = m.group() name = s.strip() if (i + len(s)) == n: return None, -1 # end of buffer return name.lower(), m.end() else: self.handle_data(rawdata) # self.updatepos(declstartpos, i) return None, -1 def convert_charref(self, name): return '&#%s;' % name def convert_entityref(self, name): return '&%s;' % name def output(self): '''Return processed HTML as a single string''' return ''.join([str(p) for p in self.pieces]) def parse_declaration(self, i): try: return sgmllib.SGMLParser.parse_declaration(self, i) except sgmllib.SGMLParseError: # escape the doctype declaration and continue parsing self.handle_data('<') return i+1 class _LooseFeedParser(_FeedParserMixin, _BaseHTMLProcessor): def __init__(self, baseuri, baselang, encoding, entities): sgmllib.SGMLParser.__init__(self) _FeedParserMixin.__init__(self, baseuri, baselang, encoding) _BaseHTMLProcessor.__init__(self, encoding, 'application/xhtml+xml') self.entities=entities def decodeEntities(self, element, data): data = data.replace('<', '<') data = data.replace('<', '<') data = data.replace('<', '<') data = data.replace('>', '>') data = data.replace('>', '>') data = data.replace('>', '>') data = data.replace('&', '&') data = data.replace('&', '&') data = data.replace('"', '"') data = data.replace('"', '"') data = data.replace(''', ''') data = data.replace(''', ''') if not self.contentparams.get('type', u'xml').endswith(u'xml'): data = data.replace('<', '<') data = data.replace('>', '>') data = data.replace('&', '&') data = data.replace('"', '"') data = data.replace(''', "'") return data def strattrs(self, attrs): return ''.join([' %s="%s"' % (n,v.replace('"','"')) for n,v in attrs]) class _MicroformatsParser: STRING = 1 DATE = 2 URI = 3 NODE = 4 EMAIL = 5 known_xfn_relationships = set(['contact', 'acquaintance', 'friend', 'met', 'co-worker', 'coworker', 'colleague', 'co-resident', 'coresident', 'neighbor', 'child', 'parent', 'sibling', 'brother', 'sister', 'spouse', 'wife', 'husband', 'kin', 'relative', 'muse', 'crush', 'date', 'sweetheart', 'me']) known_binary_extensions = set(['zip','rar','exe','gz','tar','tgz','tbz2','bz2','z','7z','dmg','img','sit','sitx','hqx','deb','rpm','bz2','jar','rar','iso','bin','msi','mp2','mp3','ogg','ogm','mp4','m4v','m4a','avi','wma','wmv']) def __init__(self, data, baseuri, encoding): self.document = BeautifulSoup.BeautifulSoup(data) self.baseuri = baseuri self.encoding = encoding if isinstance(data, unicode): data = data.encode(encoding) self.tags = [] self.enclosures = [] self.xfn = [] self.vcard = None def vcardEscape(self, s): if isinstance(s, basestring): s = s.replace(',', '\\,').replace(';', '\\;').replace('\n', '\\n') return s def vcardFold(self, s): s = re.sub(';+$', '', s) sFolded = '' iMax = 75 sPrefix = '' while len(s) > iMax: sFolded += sPrefix + s[:iMax] + '\n' s = s[iMax:] sPrefix = ' ' iMax = 74 sFolded += sPrefix + s return sFolded def normalize(self, s): return re.sub(r'\s+', ' ', s).strip() def unique(self, aList): results = [] for element in aList: if element not in results: results.append(element) return results def toISO8601(self, dt): return time.strftime('%Y-%m-%dT%H:%M:%SZ', dt) def getPropertyValue(self, elmRoot, sProperty, iPropertyType=4, bAllowMultiple=0, bAutoEscape=0): all = lambda x: 1 sProperty = sProperty.lower() bFound = 0 bNormalize = 1 propertyMatch = {'class': re.compile(r'\b%s\b' % sProperty)} if bAllowMultiple and (iPropertyType != self.NODE): snapResults = [] containers = elmRoot(['ul', 'ol'], propertyMatch) for container in containers: snapResults.extend(container('li')) bFound = (len(snapResults) != 0) if not bFound: snapResults = elmRoot(all, propertyMatch) bFound = (len(snapResults) != 0) if (not bFound) and (sProperty == 'value'): snapResults = elmRoot('pre') bFound = (len(snapResults) != 0) bNormalize = not bFound if not bFound: snapResults = [elmRoot] bFound = (len(snapResults) != 0) arFilter = [] if sProperty == 'vcard': snapFilter = elmRoot(all, propertyMatch) for node in snapFilter: if node.findParent(all, propertyMatch): arFilter.append(node) arResults = [] for node in snapResults: if node not in arFilter: arResults.append(node) bFound = (len(arResults) != 0) if not bFound: if bAllowMultiple: return [] elif iPropertyType == self.STRING: return '' elif iPropertyType == self.DATE: return None elif iPropertyType == self.URI: return '' elif iPropertyType == self.NODE: return None else: return None arValues = [] for elmResult in arResults: sValue = None if iPropertyType == self.NODE: if bAllowMultiple: arValues.append(elmResult) continue else: return elmResult sNodeName = elmResult.name.lower() if (iPropertyType == self.EMAIL) and (sNodeName == 'a'): sValue = (elmResult.get('href') or '').split('mailto:').pop().split('?')[0] if sValue: sValue = bNormalize and self.normalize(sValue) or sValue.strip() if (not sValue) and (sNodeName == 'abbr'): sValue = elmResult.get('title') if sValue: sValue = bNormalize and self.normalize(sValue) or sValue.strip() if (not sValue) and (iPropertyType == self.URI): if sNodeName == 'a': sValue = elmResult.get('href') elif sNodeName == 'img': sValue = elmResult.get('src') elif sNodeName == 'object': sValue = elmResult.get('data') if sValue: sValue = bNormalize and self.normalize(sValue) or sValue.strip() if (not sValue) and (sNodeName == 'img'): sValue = elmResult.get('alt') if sValue: sValue = bNormalize and self.normalize(sValue) or sValue.strip() if not sValue: sValue = elmResult.renderContents() sValue = re.sub(r'<\S[^>]*>', '', sValue) sValue = sValue.replace('\r\n', '\n') sValue = sValue.replace('\r', '\n') if sValue: sValue = bNormalize and self.normalize(sValue) or sValue.strip() if not sValue: continue if iPropertyType == self.DATE: sValue = _parse_date_iso8601(sValue) if bAllowMultiple: arValues.append(bAutoEscape and self.vcardEscape(sValue) or sValue) else: return bAutoEscape and self.vcardEscape(sValue) or sValue return arValues def findVCards(self, elmRoot, bAgentParsing=0): sVCards = '' if not bAgentParsing: arCards = self.getPropertyValue(elmRoot, 'vcard', bAllowMultiple=1) else: arCards = [elmRoot] for elmCard in arCards: arLines = [] def processSingleString(sProperty): sValue = self.getPropertyValue(elmCard, sProperty, self.STRING, bAutoEscape=1).decode(self.encoding) if sValue: arLines.append(self.vcardFold(sProperty.upper() + ':' + sValue)) return sValue or u'' def processSingleURI(sProperty): sValue = self.getPropertyValue(elmCard, sProperty, self.URI) if sValue: sContentType = '' sEncoding = '' sValueKey = '' if sValue.startswith('data:'): sEncoding = ';ENCODING=b' sContentType = sValue.split(';')[0].split('/').pop() sValue = sValue.split(',', 1).pop() else: elmValue = self.getPropertyValue(elmCard, sProperty) if elmValue: if sProperty != 'url': sValueKey = ';VALUE=uri' sContentType = elmValue.get('type', '').strip().split('/').pop().strip() sContentType = sContentType.upper() if sContentType == 'OCTET-STREAM': sContentType = '' if sContentType: sContentType = ';TYPE=' + sContentType.upper() arLines.append(self.vcardFold(sProperty.upper() + sEncoding + sContentType + sValueKey + ':' + sValue)) def processTypeValue(sProperty, arDefaultType, arForceType=None): arResults = self.getPropertyValue(elmCard, sProperty, bAllowMultiple=1) for elmResult in arResults: arType = self.getPropertyValue(elmResult, 'type', self.STRING, 1, 1) if arForceType: arType = self.unique(arForceType + arType) if not arType: arType = arDefaultType sValue = self.getPropertyValue(elmResult, 'value', self.EMAIL, 0) if sValue: arLines.append(self.vcardFold(sProperty.upper() + ';TYPE=' + ','.join(arType) + ':' + sValue)) # AGENT # must do this before all other properties because it is destructive # (removes nested class="vcard" nodes so they don't interfere with # this vcard's other properties) arAgent = self.getPropertyValue(elmCard, 'agent', bAllowMultiple=1) for elmAgent in arAgent: if re.compile(r'\bvcard\b').search(elmAgent.get('class')): sAgentValue = self.findVCards(elmAgent, 1) + '\n' sAgentValue = sAgentValue.replace('\n', '\\n') sAgentValue = sAgentValue.replace(';', '\\;') if sAgentValue: arLines.append(self.vcardFold('AGENT:' + sAgentValue)) # Completely remove the agent element from the parse tree elmAgent.extract() else: sAgentValue = self.getPropertyValue(elmAgent, 'value', self.URI, bAutoEscape=1); if sAgentValue: arLines.append(self.vcardFold('AGENT;VALUE=uri:' + sAgentValue)) # FN (full name) sFN = processSingleString('fn') # N (name) elmName = self.getPropertyValue(elmCard, 'n') if elmName: sFamilyName = self.getPropertyValue(elmName, 'family-name', self.STRING, bAutoEscape=1) sGivenName = self.getPropertyValue(elmName, 'given-name', self.STRING, bAutoEscape=1) arAdditionalNames = self.getPropertyValue(elmName, 'additional-name', self.STRING, 1, 1) + self.getPropertyValue(elmName, 'additional-names', self.STRING, 1, 1) arHonorificPrefixes = self.getPropertyValue(elmName, 'honorific-prefix', self.STRING, 1, 1) + self.getPropertyValue(elmName, 'honorific-prefixes', self.STRING, 1, 1) arHonorificSuffixes = self.getPropertyValue(elmName, 'honorific-suffix', self.STRING, 1, 1) + self.getPropertyValue(elmName, 'honorific-suffixes', self.STRING, 1, 1) arLines.append(self.vcardFold('N:' + sFamilyName + ';' + sGivenName + ';' + ','.join(arAdditionalNames) + ';' + ','.join(arHonorificPrefixes) + ';' + ','.join(arHonorificSuffixes))) elif sFN: # implied "N" optimization # http://microformats.org/wiki/hcard#Implied_.22N.22_Optimization arNames = self.normalize(sFN).split() if len(arNames) == 2: bFamilyNameFirst = (arNames[0].endswith(',') or len(arNames[1]) == 1 or ((len(arNames[1]) == 2) and (arNames[1].endswith('.')))) if bFamilyNameFirst: arLines.append(self.vcardFold('N:' + arNames[0] + ';' + arNames[1])) else: arLines.append(self.vcardFold('N:' + arNames[1] + ';' + arNames[0])) # SORT-STRING sSortString = self.getPropertyValue(elmCard, 'sort-string', self.STRING, bAutoEscape=1) if sSortString: arLines.append(self.vcardFold('SORT-STRING:' + sSortString)) # NICKNAME arNickname = self.getPropertyValue(elmCard, 'nickname', self.STRING, 1, 1) if arNickname: arLines.append(self.vcardFold('NICKNAME:' + ','.join(arNickname))) # PHOTO processSingleURI('photo') # BDAY dtBday = self.getPropertyValue(elmCard, 'bday', self.DATE) if dtBday: arLines.append(self.vcardFold('BDAY:' + self.toISO8601(dtBday))) # ADR (address) arAdr = self.getPropertyValue(elmCard, 'adr', bAllowMultiple=1) for elmAdr in arAdr: arType = self.getPropertyValue(elmAdr, 'type', self.STRING, 1, 1) if not arType: arType = ['intl','postal','parcel','work'] # default adr types, see RFC 2426 section 3.2.1 sPostOfficeBox = self.getPropertyValue(elmAdr, 'post-office-box', self.STRING, 0, 1) sExtendedAddress = self.getPropertyValue(elmAdr, 'extended-address', self.STRING, 0, 1) sStreetAddress = self.getPropertyValue(elmAdr, 'street-address', self.STRING, 0, 1) sLocality = self.getPropertyValue(elmAdr, 'locality', self.STRING, 0, 1) sRegion = self.getPropertyValue(elmAdr, 'region', self.STRING, 0, 1) sPostalCode = self.getPropertyValue(elmAdr, 'postal-code', self.STRING, 0, 1) sCountryName = self.getPropertyValue(elmAdr, 'country-name', self.STRING, 0, 1) arLines.append(self.vcardFold('ADR;TYPE=' + ','.join(arType) + ':' + sPostOfficeBox + ';' + sExtendedAddress + ';' + sStreetAddress + ';' + sLocality + ';' + sRegion + ';' + sPostalCode + ';' + sCountryName)) # LABEL processTypeValue('label', ['intl','postal','parcel','work']) # TEL (phone number) processTypeValue('tel', ['voice']) # EMAIL processTypeValue('email', ['internet'], ['internet']) # MAILER processSingleString('mailer') # TZ (timezone) processSingleString('tz') # GEO (geographical information) elmGeo = self.getPropertyValue(elmCard, 'geo') if elmGeo: sLatitude = self.getPropertyValue(elmGeo, 'latitude', self.STRING, 0, 1) sLongitude = self.getPropertyValue(elmGeo, 'longitude', self.STRING, 0, 1) arLines.append(self.vcardFold('GEO:' + sLatitude + ';' + sLongitude)) # TITLE processSingleString('title') # ROLE processSingleString('role') # LOGO processSingleURI('logo') # ORG (organization) elmOrg = self.getPropertyValue(elmCard, 'org') if elmOrg: sOrganizationName = self.getPropertyValue(elmOrg, 'organization-name', self.STRING, 0, 1) if not sOrganizationName: # implied "organization-name" optimization # http://microformats.org/wiki/hcard#Implied_.22organization-name.22_Optimization sOrganizationName = self.getPropertyValue(elmCard, 'org', self.STRING, 0, 1) if sOrganizationName: arLines.append(self.vcardFold('ORG:' + sOrganizationName)) else: arOrganizationUnit = self.getPropertyValue(elmOrg, 'organization-unit', self.STRING, 1, 1) arLines.append(self.vcardFold('ORG:' + sOrganizationName + ';' + ';'.join(arOrganizationUnit))) # CATEGORY arCategory = self.getPropertyValue(elmCard, 'category', self.STRING, 1, 1) + self.getPropertyValue(elmCard, 'categories', self.STRING, 1, 1) if arCategory: arLines.append(self.vcardFold('CATEGORIES:' + ','.join(arCategory))) # NOTE processSingleString('note') # REV processSingleString('rev') # SOUND processSingleURI('sound') # UID processSingleString('uid') # URL processSingleURI('url') # CLASS processSingleString('class') # KEY processSingleURI('key') if arLines: arLines = [u'BEGIN:vCard',u'VERSION:3.0'] + arLines + [u'END:vCard'] # XXX - this is super ugly; properly fix this with issue 148 for i, s in enumerate(arLines): if not isinstance(s, unicode): arLines[i] = s.decode('utf-8', 'ignore') sVCards += u'\n'.join(arLines) + u'\n' return sVCards.strip() def isProbablyDownloadable(self, elm): attrsD = elm.attrMap if 'href' not in attrsD: return 0 linktype = attrsD.get('type', '').strip() if linktype.startswith('audio/') or \ linktype.startswith('video/') or \ (linktype.startswith('application/') and not linktype.endswith('xml')): return 1 try: path = urlparse.urlparse(attrsD['href'])[2] except ValueError: return 0 if path.find('.') == -1: return 0 fileext = path.split('.').pop().lower() return fileext in self.known_binary_extensions def findTags(self): all = lambda x: 1 for elm in self.document(all, {'rel': re.compile(r'\btag\b')}): href = elm.get('href') if not href: continue urlscheme, domain, path, params, query, fragment = \ urlparse.urlparse(_urljoin(self.baseuri, href)) segments = path.split('/') tag = segments.pop() if not tag: if segments: tag = segments.pop() else: # there are no tags continue tagscheme = urlparse.urlunparse((urlscheme, domain, '/'.join(segments), '', '', '')) if not tagscheme.endswith('/'): tagscheme += '/' self.tags.append(FeedParserDict({"term": tag, "scheme": tagscheme, "label": elm.string or ''})) def findEnclosures(self): all = lambda x: 1 enclosure_match = re.compile(r'\benclosure\b') for elm in self.document(all, {'href': re.compile(r'.+')}): if not enclosure_match.search(elm.get('rel', u'')) and not self.isProbablyDownloadable(elm): continue if elm.attrMap not in self.enclosures: self.enclosures.append(elm.attrMap) if elm.string and not elm.get('title'): self.enclosures[-1]['title'] = elm.string def findXFN(self): all = lambda x: 1 for elm in self.document(all, {'rel': re.compile('.+'), 'href': re.compile('.+')}): rels = elm.get('rel', u'').split() xfn_rels = [r for r in rels if r in self.known_xfn_relationships] if xfn_rels: self.xfn.append({"relationships": xfn_rels, "href": elm.get('href', ''), "name": elm.string}) def _parseMicroformats(htmlSource, baseURI, encoding): if not BeautifulSoup: return try: p = _MicroformatsParser(htmlSource, baseURI, encoding) except UnicodeEncodeError: # sgmllib throws this exception when performing lookups of tags # with non-ASCII characters in them. return p.vcard = p.findVCards(p.document) p.findTags() p.findEnclosures() p.findXFN() return {"tags": p.tags, "enclosures": p.enclosures, "xfn": p.xfn, "vcard": p.vcard} class _RelativeURIResolver(_BaseHTMLProcessor): relative_uris = set([('a', 'href'), ('applet', 'codebase'), ('area', 'href'), ('blockquote', 'cite'), ('body', 'background'), ('del', 'cite'), ('form', 'action'), ('frame', 'longdesc'), ('frame', 'src'), ('iframe', 'longdesc'), ('iframe', 'src'), ('head', 'profile'), ('img', 'longdesc'), ('img', 'src'), ('img', 'usemap'), ('input', 'src'), ('input', 'usemap'), ('ins', 'cite'), ('link', 'href'), ('object', 'classid'), ('object', 'codebase'), ('object', 'data'), ('object', 'usemap'), ('q', 'cite'), ('script', 'src'), ('video', 'poster')]) def __init__(self, baseuri, encoding, _type): _BaseHTMLProcessor.__init__(self, encoding, _type) self.baseuri = baseuri def resolveURI(self, uri): return _makeSafeAbsoluteURI(self.baseuri, uri.strip()) def unknown_starttag(self, tag, attrs): attrs = self.normalize_attrs(attrs) attrs = [(key, ((tag, key) in self.relative_uris) and self.resolveURI(value) or value) for key, value in attrs] _BaseHTMLProcessor.unknown_starttag(self, tag, attrs) def _resolveRelativeURIs(htmlSource, baseURI, encoding, _type): if not _SGML_AVAILABLE: return htmlSource p = _RelativeURIResolver(baseURI, encoding, _type) p.feed(htmlSource) return p.output() def _makeSafeAbsoluteURI(base, rel=None): # bail if ACCEPTABLE_URI_SCHEMES is empty if not ACCEPTABLE_URI_SCHEMES: try: return _urljoin(base, rel or u'') except ValueError: return u'' if not base: return rel or u'' if not rel: try: scheme = urlparse.urlparse(base)[0] except ValueError: return u'' if not scheme or scheme in ACCEPTABLE_URI_SCHEMES: return base return u'' try: uri = _urljoin(base, rel) except ValueError: return u'' if uri.strip().split(':', 1)[0] not in ACCEPTABLE_URI_SCHEMES: return u'' return uri class _HTMLSanitizer(_BaseHTMLProcessor): acceptable_elements = set(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'big', 'blockquote', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'command', 'datagrid', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'em', 'event-source', 'fieldset', 'figcaption', 'figure', 'footer', 'font', 'form', 'header', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'input', 'ins', 'keygen', 'kbd', 'label', 'legend', 'li', 'm', 'map', 'menu', 'meter', 'multicol', 'nav', 'nextid', 'ol', 'output', 'optgroup', 'option', 'p', 'pre', 'progress', 'q', 's', 'samp', 'section', 'select', 'small', 'sound', 'source', 'spacer', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'time', 'tfoot', 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'video', 'noscript']) acceptable_attributes = set(['abbr', 'accept', 'accept-charset', 'accesskey', 'action', 'align', 'alt', 'autocomplete', 'autofocus', 'axis', 'background', 'balance', 'bgcolor', 'bgproperties', 'border', 'bordercolor', 'bordercolordark', 'bordercolorlight', 'bottompadding', 'cellpadding', 'cellspacing', 'ch', 'challenge', 'char', 'charoff', 'choff', 'charset', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'compact', 'contenteditable', 'controls', 'coords', 'data', 'datafld', 'datapagesize', 'datasrc', 'datetime', 'default', 'delay', 'dir', 'disabled', 'draggable', 'dynsrc', 'enctype', 'end', 'face', 'for', 'form', 'frame', 'galleryimg', 'gutter', 'headers', 'height', 'hidefocus', 'hidden', 'high', 'href', 'hreflang', 'hspace', 'icon', 'id', 'inputmode', 'ismap', 'keytype', 'label', 'leftspacing', 'lang', 'list', 'longdesc', 'loop', 'loopcount', 'loopend', 'loopstart', 'low', 'lowsrc', 'max', 'maxlength', 'media', 'method', 'min', 'multiple', 'name', 'nohref', 'noshade', 'nowrap', 'open', 'optimum', 'pattern', 'ping', 'point-size', 'poster', 'pqg', 'preload', 'prompt', 'radiogroup', 'readonly', 'rel', 'repeat-max', 'repeat-min', 'replace', 'required', 'rev', 'rightspacing', 'rows', 'rowspan', 'rules', 'scope', 'selected', 'shape', 'size', 'span', 'src', 'start', 'step', 'summary', 'suppress', 'tabindex', 'target', 'template', 'title', 'toppadding', 'type', 'unselectable', 'usemap', 'urn', 'valign', 'value', 'variable', 'volume', 'vspace', 'vrml', 'width', 'wrap', 'xml:lang']) unacceptable_elements_with_end_tag = set(['script', 'applet', 'style']) acceptable_css_properties = set(['azimuth', 'background-color', 'border-bottom-color', 'border-collapse', 'border-color', 'border-left-color', 'border-right-color', 'border-top-color', 'clear', 'color', 'cursor', 'direction', 'display', 'elevation', 'float', 'font', 'font-family', 'font-size', 'font-style', 'font-variant', 'font-weight', 'height', 'letter-spacing', 'line-height', 'overflow', 'pause', 'pause-after', 'pause-before', 'pitch', 'pitch-range', 'richness', 'speak', 'speak-header', 'speak-numeral', 'speak-punctuation', 'speech-rate', 'stress', 'text-align', 'text-decoration', 'text-indent', 'unicode-bidi', 'vertical-align', 'voice-family', 'volume', 'white-space', 'width']) # survey of common keywords found in feeds acceptable_css_keywords = set(['auto', 'aqua', 'black', 'block', 'blue', 'bold', 'both', 'bottom', 'brown', 'center', 'collapse', 'dashed', 'dotted', 'fuchsia', 'gray', 'green', '!important', 'italic', 'left', 'lime', 'maroon', 'medium', 'none', 'navy', 'normal', 'nowrap', 'olive', 'pointer', 'purple', 'red', 'right', 'solid', 'silver', 'teal', 'top', 'transparent', 'underline', 'white', 'yellow']) valid_css_values = re.compile('^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|' + '\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$') mathml_elements = set(['annotation', 'annotation-xml', 'maction', 'math', 'merror', 'mfenced', 'mfrac', 'mi', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle', 'msub', 'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'none', 'semantics']) mathml_attributes = set(['actiontype', 'align', 'columnalign', 'columnalign', 'columnalign', 'close', 'columnlines', 'columnspacing', 'columnspan', 'depth', 'display', 'displaystyle', 'encoding', 'equalcolumns', 'equalrows', 'fence', 'fontstyle', 'fontweight', 'frame', 'height', 'linethickness', 'lspace', 'mathbackground', 'mathcolor', 'mathvariant', 'mathvariant', 'maxsize', 'minsize', 'open', 'other', 'rowalign', 'rowalign', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'scriptlevel', 'selection', 'separator', 'separators', 'stretchy', 'width', 'width', 'xlink:href', 'xlink:show', 'xlink:type', 'xmlns', 'xmlns:xlink']) # svgtiny - foreignObject + linearGradient + radialGradient + stop svg_elements = set(['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'circle', 'defs', 'desc', 'ellipse', 'foreignObject', 'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern', 'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph', 'mpath', 'path', 'polygon', 'polyline', 'radialGradient', 'rect', 'set', 'stop', 'svg', 'switch', 'text', 'title', 'tspan', 'use']) # svgtiny + class + opacity + offset + xmlns + xmlns:xlink svg_attributes = set(['accent-height', 'accumulate', 'additive', 'alphabetic', 'arabic-form', 'ascent', 'attributeName', 'attributeType', 'baseProfile', 'bbox', 'begin', 'by', 'calcMode', 'cap-height', 'class', 'color', 'color-rendering', 'content', 'cx', 'cy', 'd', 'dx', 'dy', 'descent', 'display', 'dur', 'end', 'fill', 'fill-opacity', 'fill-rule', 'font-family', 'font-size', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'from', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'gradientUnits', 'hanging', 'height', 'horiz-adv-x', 'horiz-origin-x', 'id', 'ideographic', 'k', 'keyPoints', 'keySplines', 'keyTimes', 'lang', 'mathematical', 'marker-end', 'marker-mid', 'marker-start', 'markerHeight', 'markerUnits', 'markerWidth', 'max', 'min', 'name', 'offset', 'opacity', 'orient', 'origin', 'overline-position', 'overline-thickness', 'panose-1', 'path', 'pathLength', 'points', 'preserveAspectRatio', 'r', 'refX', 'refY', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'restart', 'rotate', 'rx', 'ry', 'slope', 'stemh', 'stemv', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'systemLanguage', 'target', 'text-anchor', 'to', 'transform', 'type', 'u1', 'u2', 'underline-position', 'underline-thickness', 'unicode', 'unicode-range', 'units-per-em', 'values', 'version', 'viewBox', 'visibility', 'width', 'widths', 'x', 'x-height', 'x1', 'x2', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'xmlns', 'xmlns:xlink', 'y', 'y1', 'y2', 'zoomAndPan']) svg_attr_map = None svg_elem_map = None acceptable_svg_properties = set([ 'fill', 'fill-opacity', 'fill-rule', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'stroke-opacity']) def reset(self): _BaseHTMLProcessor.reset(self) self.unacceptablestack = 0 self.mathmlOK = 0 self.svgOK = 0 def unknown_starttag(self, tag, attrs): acceptable_attributes = self.acceptable_attributes keymap = {} if not tag in self.acceptable_elements or self.svgOK: if tag in self.unacceptable_elements_with_end_tag: self.unacceptablestack += 1 # add implicit namespaces to html5 inline svg/mathml if self._type.endswith('html'): if not dict(attrs).get('xmlns'): if tag=='svg': attrs.append( ('xmlns','http://www.w3.org/2000/svg') ) if tag=='math': attrs.append( ('xmlns','http://www.w3.org/1998/Math/MathML') ) # not otherwise acceptable, perhaps it is MathML or SVG? if tag=='math' and ('xmlns','http://www.w3.org/1998/Math/MathML') in attrs: self.mathmlOK += 1 if tag=='svg' and ('xmlns','http://www.w3.org/2000/svg') in attrs: self.svgOK += 1 # chose acceptable attributes based on tag class, else bail if self.mathmlOK and tag in self.mathml_elements: acceptable_attributes = self.mathml_attributes elif self.svgOK and tag in self.svg_elements: # for most vocabularies, lowercasing is a good idea. Many # svg elements, however, are camel case if not self.svg_attr_map: lower=[attr.lower() for attr in self.svg_attributes] mix=[a for a in self.svg_attributes if a not in lower] self.svg_attributes = lower self.svg_attr_map = dict([(a.lower(),a) for a in mix]) lower=[attr.lower() for attr in self.svg_elements] mix=[a for a in self.svg_elements if a not in lower] self.svg_elements = lower self.svg_elem_map = dict([(a.lower(),a) for a in mix]) acceptable_attributes = self.svg_attributes tag = self.svg_elem_map.get(tag,tag) keymap = self.svg_attr_map elif not tag in self.acceptable_elements: return # declare xlink namespace, if needed if self.mathmlOK or self.svgOK: if filter(lambda (n,v): n.startswith('xlink:'),attrs): if not ('xmlns:xlink','http://www.w3.org/1999/xlink') in attrs: attrs.append(('xmlns:xlink','http://www.w3.org/1999/xlink')) clean_attrs = [] for key, value in self.normalize_attrs(attrs): if key in acceptable_attributes: key=keymap.get(key,key) # make sure the uri uses an acceptable uri scheme if key == u'href': value = _makeSafeAbsoluteURI(value) clean_attrs.append((key,value)) elif key=='style': clean_value = self.sanitize_style(value) if clean_value: clean_attrs.append((key,clean_value)) _BaseHTMLProcessor.unknown_starttag(self, tag, clean_attrs) def unknown_endtag(self, tag): if not tag in self.acceptable_elements: if tag in self.unacceptable_elements_with_end_tag: self.unacceptablestack -= 1 if self.mathmlOK and tag in self.mathml_elements: if tag == 'math' and self.mathmlOK: self.mathmlOK -= 1 elif self.svgOK and tag in self.svg_elements: tag = self.svg_elem_map.get(tag,tag) if tag == 'svg' and self.svgOK: self.svgOK -= 1 else: return _BaseHTMLProcessor.unknown_endtag(self, tag) def handle_pi(self, text): pass def handle_decl(self, text): pass def handle_data(self, text): if not self.unacceptablestack: _BaseHTMLProcessor.handle_data(self, text) def sanitize_style(self, style): # disallow urls style=re.compile('url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ',style) # gauntlet if not re.match("""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): return '' # This replaced a regexp that used re.match and was prone to pathological back-tracking. if re.sub("\s*[-\w]+\s*:\s*[^:;]*;?", '', style).strip(): return '' clean = [] for prop,value in re.findall("([-\w]+)\s*:\s*([^:;]*)",style): if not value: continue if prop.lower() in self.acceptable_css_properties: clean.append(prop + ': ' + value + ';') elif prop.split('-')[0].lower() in ['background','border','margin','padding']: for keyword in value.split(): if not keyword in self.acceptable_css_keywords and \ not self.valid_css_values.match(keyword): break else: clean.append(prop + ': ' + value + ';') elif self.svgOK and prop.lower() in self.acceptable_svg_properties: clean.append(prop + ': ' + value + ';') return ' '.join(clean) def parse_comment(self, i, report=1): ret = _BaseHTMLProcessor.parse_comment(self, i, report) if ret >= 0: return ret # if ret == -1, this may be a malicious attempt to circumvent # sanitization, or a page-destroying unclosed comment match = re.compile(r'--[^>]*>').search(self.rawdata, i+4) if match: return match.end() # unclosed comment; deliberately fail to handle_data() return len(self.rawdata) def _sanitizeHTML(htmlSource, encoding, _type): if not _SGML_AVAILABLE: return htmlSource p = _HTMLSanitizer(encoding, _type) htmlSource = htmlSource.replace(''): data = data.split('>', 1)[1] if data.count(' stream This function lets you define parsers that take any input source (URL, pathname to local or network file, or actual data as a string) and deal with it in a uniform manner. Returned object is guaranteed to have all the basic stdio read methods (read, readline, readlines). Just .close() the object when you're done with it. If the etag argument is supplied, it will be used as the value of an If-None-Match request header. If the modified argument is supplied, it can be a tuple of 9 integers (as returned by gmtime() in the standard Python time module) or a date string in any format supported by feedparser. Regardless, it MUST be in GMT (Greenwich Mean Time). It will be reformatted into an RFC 1123-compliant date and used as the value of an If-Modified-Since request header. If the agent argument is supplied, it will be used as the value of a User-Agent request header. If the referrer argument is supplied, it will be used as the value of a Referer[sic] request header. If handlers is supplied, it is a list of handlers used to build a urllib2 opener. if request_headers is supplied it is a dictionary of HTTP request headers that will override the values generated by FeedParser. """ if hasattr(url_file_stream_or_string, 'read'): return url_file_stream_or_string if isinstance(url_file_stream_or_string, basestring) \ and urlparse.urlparse(url_file_stream_or_string)[0] in ('http', 'https', 'ftp', 'file', 'feed'): # Deal with the feed URI scheme if url_file_stream_or_string.startswith('feed:http'): url_file_stream_or_string = url_file_stream_or_string[5:] elif url_file_stream_or_string.startswith('feed:'): url_file_stream_or_string = 'http:' + url_file_stream_or_string[5:] if not agent: agent = USER_AGENT # Test for inline user:password credentials for HTTP basic auth auth = None if base64 and not url_file_stream_or_string.startswith('ftp:'): urltype, rest = urllib.splittype(url_file_stream_or_string) realhost, rest = urllib.splithost(rest) if realhost: user_passwd, realhost = urllib.splituser(realhost) if user_passwd: url_file_stream_or_string = '%s://%s%s' % (urltype, realhost, rest) auth = base64.standard_b64encode(user_passwd).strip() # iri support if isinstance(url_file_stream_or_string, unicode): url_file_stream_or_string = _convert_to_idn(url_file_stream_or_string) # try to open with urllib2 (to use optional headers) request = _build_urllib2_request(url_file_stream_or_string, agent, etag, modified, referrer, auth, request_headers) opener = urllib2.build_opener(*tuple(handlers + [_FeedURLHandler()])) opener.addheaders = [] # RMK - must clear so we only send our custom User-Agent try: return opener.open(request) finally: opener.close() # JohnD # try to open with native open function (if url_file_stream_or_string is a filename) try: return open(url_file_stream_or_string, 'rb') except (IOError, UnicodeEncodeError, TypeError): # if url_file_stream_or_string is a unicode object that # cannot be converted to the encoding returned by # sys.getfilesystemencoding(), a UnicodeEncodeError # will be thrown # If url_file_stream_or_string is a string that contains NULL # (such as an XML document encoded in UTF-32), TypeError will # be thrown. pass # treat url_file_stream_or_string as string if isinstance(url_file_stream_or_string, unicode): return _StringIO(url_file_stream_or_string.encode('utf-8')) return _StringIO(url_file_stream_or_string) def _convert_to_idn(url): """Convert a URL to IDN notation""" # this function should only be called with a unicode string # strategy: if the host cannot be encoded in ascii, then # it'll be necessary to encode it in idn form parts = list(urlparse.urlsplit(url)) try: parts[1].encode('ascii') except UnicodeEncodeError: # the url needs to be converted to idn notation host = parts[1].rsplit(':', 1) newhost = [] port = u'' if len(host) == 2: port = host.pop() for h in host[0].split('.'): newhost.append(h.encode('idna').decode('utf-8')) parts[1] = '.'.join(newhost) if port: parts[1] += ':' + port return urlparse.urlunsplit(parts) else: return url def _build_urllib2_request(url, agent, etag, modified, referrer, auth, request_headers): request = urllib2.Request(url) request.add_header('User-Agent', agent) if etag: request.add_header('If-None-Match', etag) if isinstance(modified, basestring): modified = _parse_date(modified) elif isinstance(modified, datetime.datetime): modified = modified.utctimetuple() if modified: # format into an RFC 1123-compliant timestamp. We can't use # time.strftime() since the %a and %b directives can be affected # by the current locale, but RFC 2616 states that dates must be # in English. short_weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] request.add_header('If-Modified-Since', '%s, %02d %s %04d %02d:%02d:%02d GMT' % (short_weekdays[modified[6]], modified[2], months[modified[1] - 1], modified[0], modified[3], modified[4], modified[5])) if referrer: request.add_header('Referer', referrer) if gzip and zlib: request.add_header('Accept-encoding', 'gzip, deflate') elif gzip: request.add_header('Accept-encoding', 'gzip') elif zlib: request.add_header('Accept-encoding', 'deflate') else: request.add_header('Accept-encoding', '') if auth: request.add_header('Authorization', 'Basic %s' % auth) if ACCEPT_HEADER: request.add_header('Accept', ACCEPT_HEADER) # use this for whatever -- cookies, special headers, etc # [('Cookie','Something'),('x-special-header','Another Value')] for header_name, header_value in request_headers.items(): request.add_header(header_name, header_value) request.add_header('A-IM', 'feed') # RFC 3229 support return request _date_handlers = [] def registerDateHandler(func): '''Register a date handler function (takes string, returns 9-tuple date in GMT)''' _date_handlers.insert(0, func) # ISO-8601 date parsing routines written by Fazal Majid. # The ISO 8601 standard is very convoluted and irregular - a full ISO 8601 # parser is beyond the scope of feedparser and would be a worthwhile addition # to the Python library. # A single regular expression cannot parse ISO 8601 date formats into groups # as the standard is highly irregular (for instance is 030104 2003-01-04 or # 0301-04-01), so we use templates instead. # Please note the order in templates is significant because we need a # greedy match. _iso8601_tmpl = ['YYYY-?MM-?DD', 'YYYY-0MM?-?DD', 'YYYY-MM', 'YYYY-?OOO', 'YY-?MM-?DD', 'YY-?OOO', 'YYYY', '-YY-?MM', '-OOO', '-YY', '--MM-?DD', '--MM', '---DD', 'CC', ''] _iso8601_re = [ tmpl.replace( 'YYYY', r'(?P\d{4})').replace( 'YY', r'(?P\d\d)').replace( 'MM', r'(?P[01]\d)').replace( 'DD', r'(?P[0123]\d)').replace( 'OOO', r'(?P[0123]\d\d)').replace( 'CC', r'(?P\d\d$)') + r'(T?(?P\d{2}):(?P\d{2})' + r'(:(?P\d{2}))?' + r'(\.(?P\d+))?' + r'(?P[+-](?P\d{2})(:(?P\d{2}))?|Z)?)?' for tmpl in _iso8601_tmpl] try: del tmpl except NameError: pass _iso8601_matches = [re.compile(regex).match for regex in _iso8601_re] try: del regex except NameError: pass def _parse_date_iso8601(dateString): '''Parse a variety of ISO-8601-compatible formats like 20040105''' m = None for _iso8601_match in _iso8601_matches: m = _iso8601_match(dateString) if m: break if not m: return if m.span() == (0, 0): return params = m.groupdict() ordinal = params.get('ordinal', 0) if ordinal: ordinal = int(ordinal) else: ordinal = 0 year = params.get('year', '--') if not year or year == '--': year = time.gmtime()[0] elif len(year) == 2: # ISO 8601 assumes current century, i.e. 93 -> 2093, NOT 1993 year = 100 * int(time.gmtime()[0] / 100) + int(year) else: year = int(year) month = params.get('month', '-') if not month or month == '-': # ordinals are NOT normalized by mktime, we simulate them # by setting month=1, day=ordinal if ordinal: month = 1 else: month = time.gmtime()[1] month = int(month) day = params.get('day', 0) if not day: # see above if ordinal: day = ordinal elif params.get('century', 0) or \ params.get('year', 0) or params.get('month', 0): day = 1 else: day = time.gmtime()[2] else: day = int(day) # special case of the century - is the first year of the 21st century # 2000 or 2001 ? The debate goes on... if 'century' in params: year = (int(params['century']) - 1) * 100 + 1 # in ISO 8601 most fields are optional for field in ['hour', 'minute', 'second', 'tzhour', 'tzmin']: if not params.get(field, None): params[field] = 0 hour = int(params.get('hour', 0)) minute = int(params.get('minute', 0)) second = int(float(params.get('second', 0))) # weekday is normalized by mktime(), we can ignore it weekday = 0 daylight_savings_flag = -1 tm = [year, month, day, hour, minute, second, weekday, ordinal, daylight_savings_flag] # ISO 8601 time zone adjustments tz = params.get('tz') if tz and tz != 'Z': if tz[0] == '-': tm[3] += int(params.get('tzhour', 0)) tm[4] += int(params.get('tzmin', 0)) elif tz[0] == '+': tm[3] -= int(params.get('tzhour', 0)) tm[4] -= int(params.get('tzmin', 0)) else: return None # Python's time.mktime() is a wrapper around the ANSI C mktime(3c) # which is guaranteed to normalize d/m/y/h/m/s. # Many implementations have bugs, but we'll pretend they don't. return time.localtime(time.mktime(tuple(tm))) registerDateHandler(_parse_date_iso8601) # 8-bit date handling routines written by ytrewq1. _korean_year = u'\ub144' # b3e2 in euc-kr _korean_month = u'\uc6d4' # bff9 in euc-kr _korean_day = u'\uc77c' # c0cf in euc-kr _korean_am = u'\uc624\uc804' # bfc0 c0fc in euc-kr _korean_pm = u'\uc624\ud6c4' # bfc0 c8c4 in euc-kr _korean_onblog_date_re = \ re.compile('(\d{4})%s\s+(\d{2})%s\s+(\d{2})%s\s+(\d{2}):(\d{2}):(\d{2})' % \ (_korean_year, _korean_month, _korean_day)) _korean_nate_date_re = \ re.compile(u'(\d{4})-(\d{2})-(\d{2})\s+(%s|%s)\s+(\d{,2}):(\d{,2}):(\d{,2})' % \ (_korean_am, _korean_pm)) def _parse_date_onblog(dateString): '''Parse a string according to the OnBlog 8-bit date format''' m = _korean_onblog_date_re.match(dateString) if not m: return w3dtfdate = '%(year)s-%(month)s-%(day)sT%(hour)s:%(minute)s:%(second)s%(zonediff)s' % \ {'year': m.group(1), 'month': m.group(2), 'day': m.group(3),\ 'hour': m.group(4), 'minute': m.group(5), 'second': m.group(6),\ 'zonediff': '+09:00'} return _parse_date_w3dtf(w3dtfdate) registerDateHandler(_parse_date_onblog) def _parse_date_nate(dateString): '''Parse a string according to the Nate 8-bit date format''' m = _korean_nate_date_re.match(dateString) if not m: return hour = int(m.group(5)) ampm = m.group(4) if (ampm == _korean_pm): hour += 12 hour = str(hour) if len(hour) == 1: hour = '0' + hour w3dtfdate = '%(year)s-%(month)s-%(day)sT%(hour)s:%(minute)s:%(second)s%(zonediff)s' % \ {'year': m.group(1), 'month': m.group(2), 'day': m.group(3),\ 'hour': hour, 'minute': m.group(6), 'second': m.group(7),\ 'zonediff': '+09:00'} return _parse_date_w3dtf(w3dtfdate) registerDateHandler(_parse_date_nate) # Unicode strings for Greek date strings _greek_months = \ { \ u'\u0399\u03b1\u03bd': u'Jan', # c9e1ed in iso-8859-7 u'\u03a6\u03b5\u03b2': u'Feb', # d6e5e2 in iso-8859-7 u'\u039c\u03ac\u03ce': u'Mar', # ccdcfe in iso-8859-7 u'\u039c\u03b1\u03ce': u'Mar', # cce1fe in iso-8859-7 u'\u0391\u03c0\u03c1': u'Apr', # c1f0f1 in iso-8859-7 u'\u039c\u03ac\u03b9': u'May', # ccdce9 in iso-8859-7 u'\u039c\u03b1\u03ca': u'May', # cce1fa in iso-8859-7 u'\u039c\u03b1\u03b9': u'May', # cce1e9 in iso-8859-7 u'\u0399\u03bf\u03cd\u03bd': u'Jun', # c9effded in iso-8859-7 u'\u0399\u03bf\u03bd': u'Jun', # c9efed in iso-8859-7 u'\u0399\u03bf\u03cd\u03bb': u'Jul', # c9effdeb in iso-8859-7 u'\u0399\u03bf\u03bb': u'Jul', # c9f9eb in iso-8859-7 u'\u0391\u03cd\u03b3': u'Aug', # c1fde3 in iso-8859-7 u'\u0391\u03c5\u03b3': u'Aug', # c1f5e3 in iso-8859-7 u'\u03a3\u03b5\u03c0': u'Sep', # d3e5f0 in iso-8859-7 u'\u039f\u03ba\u03c4': u'Oct', # cfeaf4 in iso-8859-7 u'\u039d\u03bf\u03ad': u'Nov', # cdefdd in iso-8859-7 u'\u039d\u03bf\u03b5': u'Nov', # cdefe5 in iso-8859-7 u'\u0394\u03b5\u03ba': u'Dec', # c4e5ea in iso-8859-7 } _greek_wdays = \ { \ u'\u039a\u03c5\u03c1': u'Sun', # caf5f1 in iso-8859-7 u'\u0394\u03b5\u03c5': u'Mon', # c4e5f5 in iso-8859-7 u'\u03a4\u03c1\u03b9': u'Tue', # d4f1e9 in iso-8859-7 u'\u03a4\u03b5\u03c4': u'Wed', # d4e5f4 in iso-8859-7 u'\u03a0\u03b5\u03bc': u'Thu', # d0e5ec in iso-8859-7 u'\u03a0\u03b1\u03c1': u'Fri', # d0e1f1 in iso-8859-7 u'\u03a3\u03b1\u03b2': u'Sat', # d3e1e2 in iso-8859-7 } _greek_date_format_re = \ re.compile(u'([^,]+),\s+(\d{2})\s+([^\s]+)\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})\s+([^\s]+)') def _parse_date_greek(dateString): '''Parse a string according to a Greek 8-bit date format.''' m = _greek_date_format_re.match(dateString) if not m: return wday = _greek_wdays[m.group(1)] month = _greek_months[m.group(3)] rfc822date = '%(wday)s, %(day)s %(month)s %(year)s %(hour)s:%(minute)s:%(second)s %(zonediff)s' % \ {'wday': wday, 'day': m.group(2), 'month': month, 'year': m.group(4),\ 'hour': m.group(5), 'minute': m.group(6), 'second': m.group(7),\ 'zonediff': m.group(8)} return _parse_date_rfc822(rfc822date) registerDateHandler(_parse_date_greek) # Unicode strings for Hungarian date strings _hungarian_months = \ { \ u'janu\u00e1r': u'01', # e1 in iso-8859-2 u'febru\u00e1ri': u'02', # e1 in iso-8859-2 u'm\u00e1rcius': u'03', # e1 in iso-8859-2 u'\u00e1prilis': u'04', # e1 in iso-8859-2 u'm\u00e1ujus': u'05', # e1 in iso-8859-2 u'j\u00fanius': u'06', # fa in iso-8859-2 u'j\u00falius': u'07', # fa in iso-8859-2 u'augusztus': u'08', u'szeptember': u'09', u'okt\u00f3ber': u'10', # f3 in iso-8859-2 u'november': u'11', u'december': u'12', } _hungarian_date_format_re = \ re.compile(u'(\d{4})-([^-]+)-(\d{,2})T(\d{,2}):(\d{2})((\+|-)(\d{,2}:\d{2}))') def _parse_date_hungarian(dateString): '''Parse a string according to a Hungarian 8-bit date format.''' m = _hungarian_date_format_re.match(dateString) if not m or m.group(2) not in _hungarian_months: return None month = _hungarian_months[m.group(2)] day = m.group(3) if len(day) == 1: day = '0' + day hour = m.group(4) if len(hour) == 1: hour = '0' + hour w3dtfdate = '%(year)s-%(month)s-%(day)sT%(hour)s:%(minute)s%(zonediff)s' % \ {'year': m.group(1), 'month': month, 'day': day,\ 'hour': hour, 'minute': m.group(5),\ 'zonediff': m.group(6)} return _parse_date_w3dtf(w3dtfdate) registerDateHandler(_parse_date_hungarian) # W3DTF-style date parsing adapted from PyXML xml.utils.iso8601, written by # Drake and licensed under the Python license. Removed all range checking # for month, day, hour, minute, and second, since mktime will normalize # these later # Modified to also support MSSQL-style datetimes as defined at: # http://msdn.microsoft.com/en-us/library/ms186724.aspx # (which basically means allowing a space as a date/time/timezone separator) def _parse_date_w3dtf(dateString): def __extract_date(m): year = int(m.group('year')) if year < 100: year = 100 * int(time.gmtime()[0] / 100) + int(year) if year < 1000: return 0, 0, 0 julian = m.group('julian') if julian: julian = int(julian) month = julian / 30 + 1 day = julian % 30 + 1 jday = None while jday != julian: t = time.mktime((year, month, day, 0, 0, 0, 0, 0, 0)) jday = time.gmtime(t)[-2] diff = abs(jday - julian) if jday > julian: if diff < day: day = day - diff else: month = month - 1 day = 31 elif jday < julian: if day + diff < 28: day = day + diff else: month = month + 1 return year, month, day month = m.group('month') day = 1 if month is None: month = 1 else: month = int(month) day = m.group('day') if day: day = int(day) else: day = 1 return year, month, day def __extract_time(m): if not m: return 0, 0, 0 hours = m.group('hours') if not hours: return 0, 0, 0 hours = int(hours) minutes = int(m.group('minutes')) seconds = m.group('seconds') if seconds: seconds = int(seconds) else: seconds = 0 return hours, minutes, seconds def __extract_tzd(m): '''Return the Time Zone Designator as an offset in seconds from UTC.''' if not m: return 0 tzd = m.group('tzd') if not tzd: return 0 if tzd == 'Z': return 0 hours = int(m.group('tzdhours')) minutes = m.group('tzdminutes') if minutes: minutes = int(minutes) else: minutes = 0 offset = (hours*60 + minutes) * 60 if tzd[0] == '+': return -offset return offset __date_re = ('(?P\d\d\d\d)' '(?:(?P-|)' '(?:(?P\d\d)(?:(?P=dsep)(?P\d\d))?' '|(?P\d\d\d)))?') __tzd_re = ' ?(?P[-+](?P\d\d)(?::?(?P\d\d))|Z)?' __time_re = ('(?P\d\d)(?P:|)(?P\d\d)' '(?:(?P=tsep)(?P\d\d)(?:[.,]\d+)?)?' + __tzd_re) __datetime_re = '%s(?:[T ]%s)?' % (__date_re, __time_re) __datetime_rx = re.compile(__datetime_re) m = __datetime_rx.match(dateString) if (m is None) or (m.group() != dateString): return gmt = __extract_date(m) + __extract_time(m) + (0, 0, 0) if gmt[0] == 0: return return time.gmtime(time.mktime(gmt) + __extract_tzd(m) - time.timezone) registerDateHandler(_parse_date_w3dtf) # Define the strings used by the RFC822 datetime parser _rfc822_months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'] _rfc822_daynames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] # Only the first three letters of the month name matter _rfc822_month = "(?P%s)(?:[a-z]*,?)" % ('|'.join(_rfc822_months)) # The year may be 2 or 4 digits; capture the century if it exists _rfc822_year = "(?P(?:\d{2})?\d{2})" _rfc822_day = "(?P *\d{1,2})" _rfc822_date = "%s %s %s" % (_rfc822_day, _rfc822_month, _rfc822_year) _rfc822_hour = "(?P\d{2}):(?P\d{2})(?::(?P\d{2}))?" _rfc822_tz = "(?Put|gmt(?:[+-]\d{2}:\d{2})?|[aecmp][sd]?t|[zamny]|[+-]\d{4})" _rfc822_tznames = { 'ut': 0, 'gmt': 0, 'z': 0, 'adt': -3, 'ast': -4, 'at': -4, 'edt': -4, 'est': -5, 'et': -5, 'cdt': -5, 'cst': -6, 'ct': -6, 'mdt': -6, 'mst': -7, 'mt': -7, 'pdt': -7, 'pst': -8, 'pt': -8, 'a': -1, 'n': 1, 'm': -12, 'y': 12, } # The timezone may be prefixed by 'Etc/' _rfc822_time = "%s (?:etc/)?%s" % (_rfc822_hour, _rfc822_tz) _rfc822_dayname = "(?P%s)" % ('|'.join(_rfc822_daynames)) _rfc822_match = re.compile( "(?:%s, )?%s(?: %s)?" % (_rfc822_dayname, _rfc822_date, _rfc822_time) ).match def _parse_date_group_rfc822(m): # Calculate a date and timestamp for k in ('year', 'day', 'hour', 'minute', 'second'): m[k] = int(m[k]) m['month'] = _rfc822_months.index(m['month']) + 1 # If the year is 2 digits, assume everything in the 90's is the 1990's if m['year'] < 100: m['year'] += (1900, 2000)[m['year'] < 90] stamp = datetime.datetime(*[m[i] for i in ('year', 'month', 'day', 'hour', 'minute', 'second')]) # Use the timezone information to calculate the difference between # the given date and timestamp and Universal Coordinated Time tzhour = 0 tzmin = 0 if m['tz'] and m['tz'].startswith('gmt'): # Handle GMT and GMT+hh:mm timezone syntax (the trailing # timezone info will be handled by the next `if` block) m['tz'] = ''.join(m['tz'][3:].split(':')) or 'gmt' if not m['tz']: pass elif m['tz'].startswith('+'): tzhour = int(m['tz'][1:3]) tzmin = int(m['tz'][3:]) elif m['tz'].startswith('-'): tzhour = int(m['tz'][1:3]) * -1 tzmin = int(m['tz'][3:]) * -1 else: tzhour = _rfc822_tznames[m['tz']] delta = datetime.timedelta(0, 0, 0, 0, tzmin, tzhour) # Return the date and timestamp in UTC return (stamp - delta).utctimetuple() def _parse_date_rfc822(dt): """Parse RFC 822 dates and times, with one minor difference: years may be 4DIGIT or 2DIGIT. http://tools.ietf.org/html/rfc822#section-5""" try: m = _rfc822_match(dt.lower()).groupdict(0) except AttributeError: return None return _parse_date_group_rfc822(m) registerDateHandler(_parse_date_rfc822) def _parse_date_rfc822_grubby(dt): """Parse date format similar to RFC 822, but the comma after the dayname is optional and month/day are inverted""" _rfc822_date_grubby = "%s %s %s" % (_rfc822_month, _rfc822_day, _rfc822_year) _rfc822_match_grubby = re.compile( "(?:%s[,]? )?%s(?: %s)?" % (_rfc822_dayname, _rfc822_date_grubby, _rfc822_time) ).match try: m = _rfc822_match_grubby(dt.lower()).groupdict(0) except AttributeError: return None return _parse_date_group_rfc822(m) registerDateHandler(_parse_date_rfc822_grubby) def _parse_date_asctime(dt): """Parse asctime-style dates""" dayname, month, day, remainder = dt.split(None, 3) # Convert month and day into zero-padded integers month = '%02i ' % (_rfc822_months.index(month.lower()) + 1) day = '%02i ' % (int(day),) dt = month + day + remainder return time.strptime(dt, '%m %d %H:%M:%S %Y')[:-1] + (0, ) registerDateHandler(_parse_date_asctime) def _parse_date_perforce(aDateString): """parse a date in yyyy/mm/dd hh:mm:ss TTT format""" # Fri, 2006/09/15 08:19:53 EDT _my_date_pattern = re.compile( \ r'(\w{,3}), (\d{,4})/(\d{,2})/(\d{2}) (\d{,2}):(\d{2}):(\d{2}) (\w{,3})') m = _my_date_pattern.search(aDateString) if m is None: return None dow, year, month, day, hour, minute, second, tz = m.groups() months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] dateString = "%s, %s %s %s %s:%s:%s %s" % (dow, day, months[int(month) - 1], year, hour, minute, second, tz) tm = rfc822.parsedate_tz(dateString) if tm: return time.gmtime(rfc822.mktime_tz(tm)) registerDateHandler(_parse_date_perforce) def _parse_date(dateString): '''Parses a variety of date formats into a 9-tuple in GMT''' if not dateString: return None for handler in _date_handlers: try: date9tuple = handler(dateString) except (KeyError, OverflowError, ValueError): continue if not date9tuple: continue if len(date9tuple) != 9: continue return date9tuple return None # Each marker represents some of the characters of the opening XML # processing instruction (' RE_XML_DECLARATION = re.compile('^<\?xml[^>]*?>') # Capture the value of the XML processing instruction's encoding attribute. # Example: RE_XML_PI_ENCODING = re.compile(_s2bytes('^<\?.*encoding=[\'"](.*?)[\'"].*\?>')) def convert_to_utf8(http_headers, data): '''Detect and convert the character encoding to UTF-8. http_headers is a dictionary data is a raw string (not Unicode)''' # This is so much trickier than it sounds, it's not even funny. # According to RFC 3023 ('XML Media Types'), if the HTTP Content-Type # is application/xml, application/*+xml, # application/xml-external-parsed-entity, or application/xml-dtd, # the encoding given in the charset parameter of the HTTP Content-Type # takes precedence over the encoding given in the XML prefix within the # document, and defaults to 'utf-8' if neither are specified. But, if # the HTTP Content-Type is text/xml, text/*+xml, or # text/xml-external-parsed-entity, the encoding given in the XML prefix # within the document is ALWAYS IGNORED and only the encoding given in # the charset parameter of the HTTP Content-Type header should be # respected, and it defaults to 'us-ascii' if not specified. # Furthermore, discussion on the atom-syntax mailing list with the # author of RFC 3023 leads me to the conclusion that any document # served with a Content-Type of text/* and no charset parameter # must be treated as us-ascii. (We now do this.) And also that it # must always be flagged as non-well-formed. (We now do this too.) # If Content-Type is unspecified (input was local file or non-HTTP source) # or unrecognized (server just got it totally wrong), then go by the # encoding given in the XML prefix of the document and default to # 'iso-8859-1' as per the HTTP specification (RFC 2616). # Then, assuming we didn't find a character encoding in the HTTP headers # (and the HTTP Content-type allowed us to look in the body), we need # to sniff the first few bytes of the XML data and try to determine # whether the encoding is ASCII-compatible. Section F of the XML # specification shows the way here: # http://www.w3.org/TR/REC-xml/#sec-guessing-no-ext-info # If the sniffed encoding is not ASCII-compatible, we need to make it # ASCII compatible so that we can sniff further into the XML declaration # to find the encoding attribute, which will tell us the true encoding. # Of course, none of this guarantees that we will be able to parse the # feed in the declared character encoding (assuming it was declared # correctly, which many are not). iconv_codec can help a lot; # you should definitely install it if you can. # http://cjkpython.i18n.org/ bom_encoding = u'' xml_encoding = u'' rfc3023_encoding = u'' # Look at the first few bytes of the document to guess what # its encoding may be. We only need to decode enough of the # document that we can use an ASCII-compatible regular # expression to search for an XML encoding declaration. # The heuristic follows the XML specification, section F: # http://www.w3.org/TR/REC-xml/#sec-guessing-no-ext-info # Check for BOMs first. if data[:4] == codecs.BOM_UTF32_BE: bom_encoding = u'utf-32be' data = data[4:] elif data[:4] == codecs.BOM_UTF32_LE: bom_encoding = u'utf-32le' data = data[4:] elif data[:2] == codecs.BOM_UTF16_BE and data[2:4] != ZERO_BYTES: bom_encoding = u'utf-16be' data = data[2:] elif data[:2] == codecs.BOM_UTF16_LE and data[2:4] != ZERO_BYTES: bom_encoding = u'utf-16le' data = data[2:] elif data[:3] == codecs.BOM_UTF8: bom_encoding = u'utf-8' data = data[3:] # Check for the characters '''' if RE_XML_DECLARATION.search(data): data = RE_XML_DECLARATION.sub(new_declaration, data) else: data = new_declaration + u'\n' + data data = data.encode('utf-8') break # if still no luck, give up if not known_encoding: error = CharacterEncodingUnknown( 'document encoding unknown, I tried ' + '%s, %s, utf-8, windows-1252, and iso-8859-2 but nothing worked' % (rfc3023_encoding, xml_encoding)) rfc3023_encoding = u'' elif proposed_encoding != rfc3023_encoding: error = CharacterEncodingOverride( 'document declared as %s, but parsed as %s' % (rfc3023_encoding, proposed_encoding)) rfc3023_encoding = proposed_encoding return data, rfc3023_encoding, error # Match XML entity declarations. # Example: RE_ENTITY_PATTERN = re.compile(_s2bytes(r'^\s*]*?)>'), re.MULTILINE) # Match XML DOCTYPE declarations. # Example: RE_DOCTYPE_PATTERN = re.compile(_s2bytes(r'^\s*]*?)>'), re.MULTILINE) # Match safe entity declarations. # This will allow hexadecimal character references through, # as well as text, but not arbitrary nested entities. # Example: cubed "³" # Example: copyright "(C)" # Forbidden: explode1 "&explode2;&explode2;" RE_SAFE_ENTITY_PATTERN = re.compile(_s2bytes('\s+(\w+)\s+"(&#\w+;|[^&"]*)"')) def replace_doctype(data): '''Strips and replaces the DOCTYPE, returns (rss_version, stripped_data) rss_version may be 'rss091n' or None stripped_data is the same XML document with a replaced DOCTYPE ''' # Divide the document into two groups by finding the location # of the first element that doesn't begin with '\n\n]>') data = RE_DOCTYPE_PATTERN.sub(replacement, head) + data # Precompute the safe entities for the loose parser. safe_entities = dict((k.decode('utf-8'), v.decode('utf-8')) for k, v in RE_SAFE_ENTITY_PATTERN.findall(replacement)) return version, data, safe_entities def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, referrer=None, handlers=None, request_headers=None, response_headers=None): '''Parse a feed from a URL, file, stream, or string. request_headers, if given, is a dict from http header name to value to add to the request; this overrides internally generated values. ''' if handlers is None: handlers = [] if request_headers is None: request_headers = {} if response_headers is None: response_headers = {} result = FeedParserDict() result['feed'] = FeedParserDict() result['entries'] = [] result['bozo'] = 0 if not isinstance(handlers, list): handlers = [handlers] try: f = _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, handlers, request_headers) data = f.read() except Exception, e: result['bozo'] = 1 result['bozo_exception'] = e data = None f = None if hasattr(f, 'headers'): result['headers'] = dict(f.headers) # overwrite existing headers using response_headers if 'headers' in result: result['headers'].update(response_headers) elif response_headers: result['headers'] = copy.deepcopy(response_headers) # lowercase all of the HTTP headers for comparisons per RFC 2616 if 'headers' in result: http_headers = dict((k.lower(), v) for k, v in result['headers'].items()) else: http_headers = {} # if feed is gzip-compressed, decompress it if f and data and http_headers: if gzip and 'gzip' in http_headers.get('content-encoding', ''): try: data = gzip.GzipFile(fileobj=_StringIO(data)).read() except (IOError, struct.error), e: # IOError can occur if the gzip header is bad. # struct.error can occur if the data is damaged. result['bozo'] = 1 result['bozo_exception'] = e if isinstance(e, struct.error): # A gzip header was found but the data is corrupt. # Ideally, we should re-request the feed without the # 'Accept-encoding: gzip' header, but we don't. data = None elif zlib and 'deflate' in http_headers.get('content-encoding', ''): try: data = zlib.decompress(data) except zlib.error, e: try: # The data may have no headers and no checksum. data = zlib.decompress(data, -15) except zlib.error, e: result['bozo'] = 1 result['bozo_exception'] = e # save HTTP headers if http_headers: if 'etag' in http_headers: etag = http_headers.get('etag', u'') if not isinstance(etag, unicode): etag = etag.decode('utf-8', 'ignore') if etag: result['etag'] = etag if 'last-modified' in http_headers: modified = http_headers.get('last-modified', u'') if modified: result['modified'] = modified result['modified_parsed'] = _parse_date(modified) if hasattr(f, 'url'): if not isinstance(f.url, unicode): result['href'] = f.url.decode('utf-8', 'ignore') else: result['href'] = f.url result['status'] = 200 if hasattr(f, 'status'): result['status'] = f.status if hasattr(f, 'close'): f.close() if data is None: return result # Stop processing if the server sent HTTP 304 Not Modified. if getattr(f, 'code', 0) == 304: result['version'] = u'' result['debug_message'] = 'The feed has not changed since you last checked, ' + \ 'so the server sent no data. This is a feature, not a bug!' return result data, result['encoding'], error = convert_to_utf8(http_headers, data) use_strict_parser = result['encoding'] and True or False if error is not None: result['bozo'] = 1 result['bozo_exception'] = error result['version'], data, entities = replace_doctype(data) # Ensure that baseuri is an absolute URI using an acceptable URI scheme. contentloc = http_headers.get('content-location', u'') href = result.get('href', u'') baseuri = _makeSafeAbsoluteURI(href, contentloc) or _makeSafeAbsoluteURI(contentloc) or href baselang = http_headers.get('content-language', None) if not isinstance(baselang, unicode) and baselang is not None: baselang = baselang.decode('utf-8', 'ignore') if not _XML_AVAILABLE: use_strict_parser = 0 if use_strict_parser: # initialize the SAX parser feedparser = _StrictFeedParser(baseuri, baselang, 'utf-8') saxparser = xml.sax.make_parser(PREFERRED_XML_PARSERS) saxparser.setFeature(xml.sax.handler.feature_namespaces, 1) try: # disable downloading external doctype references, if possible saxparser.setFeature(xml.sax.handler.feature_external_ges, 0) except xml.sax.SAXNotSupportedException: pass saxparser.setContentHandler(feedparser) saxparser.setErrorHandler(feedparser) source = xml.sax.xmlreader.InputSource() source.setByteStream(_StringIO(data)) try: saxparser.parse(source) except xml.sax.SAXException, e: result['bozo'] = 1 result['bozo_exception'] = feedparser.exc or e use_strict_parser = 0 if not use_strict_parser and _SGML_AVAILABLE: feedparser = _LooseFeedParser(baseuri, baselang, 'utf-8', entities) feedparser.feed(data.decode('utf-8', 'replace')) result['feed'] = feedparser.feeddata result['entries'] = feedparser.entries result['version'] = result['version'] or feedparser.version result['namespaces'] = feedparser.namespacesInUse return result SABnzbd-0.7.20/sabnzbd/utils/json.py0000644000000000000000000000657112433712602017344 0ustar00usergroup00000000000000import string import types ## json.py implements a JSON (http://json.org) reader and writer. ## Copyright (C) 2005 Patrick D. Logan ## Contact mailto:patrickdlogan@stardecisions.com ## ## This library is free software; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public ## License as published by the Free Software Foundation; either ## version 2.1 of the License, or (at your option) any later version. ## ## This library 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 ## Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public ## License along with this library; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Remark by ShyPike: removed the decoding of JSON, ## because it's not used by SABnzbd ## The full source package can be obtained from: ## http://sourceforge.net/projects/json-py class WriteException(Exception): pass class JsonWriter(object): def _append(self, s): self._results.append(s) def write(self, obj, escaped_forward_slash=False): self._escaped_forward_slash = escaped_forward_slash self._results = [] self._write(obj) return "".join(self._results) def _write(self, obj): ty = type(obj) if ty is types.DictType: n = len(obj) self._append("{") for k, v in obj.items(): self._write(k) self._append(":") self._write(v) n = n - 1 if n > 0: self._append(",") self._append("}") elif ty is types.ListType or ty is types.TupleType: n = len(obj) self._append("[") for item in obj: self._write(item) n = n - 1 if n > 0: self._append(",") self._append("]") elif ty is types.StringType or ty is types.UnicodeType: self._append('"') if ty is types.UnicodeType: obj = obj.encode('utf-8', 'replace') else: try: obj.decode('utf-8') except: obj = obj.decode('latin-1').encode('utf-8', 'replace') obj = obj.replace('\\', r'\\') if self._escaped_forward_slash: obj = obj.replace('/', r'\/') obj = obj.replace('"', r'\"') obj = obj.replace('\b', r'\b') obj = obj.replace('\f', r'\f') obj = obj.replace('\n', r'\n') obj = obj.replace('\r', r'\r') obj = obj.replace('\t', r'\t') self._append(obj) self._append('"') elif ty is types.IntType or ty is types.LongType: self._append(str(obj)) elif ty is types.FloatType: self._append("%f" % obj) elif obj is True: self._append("true") elif obj is False: self._append("false") elif obj is None: self._append("null") else: raise WriteException, "Cannot write in JSON: %s" % repr(obj) SABnzbd-0.7.20/sabnzbd/utils/kronos.py0000644000000000000000000004621612433712602017706 0ustar00usergroup00000000000000#!/usr/bin/python """Module that provides a cron-like task scheduler. This task scheduler is designed to be used from inside your own program. You can schedule Python functions to be called at specific intervals or days. It uses the standard 'sched' module for the actual task scheduling, but provides much more: * repeated tasks (at intervals, or on specific days) * error handling (exceptions in tasks don't kill the scheduler) * optional to run scheduler in its own thread or separate process * optional to run a task in its own thread or separate process If the threading module is available, you can use the various Threaded variants of the scheduler and associated tasks. If threading is not available, you could still use the forked variants. If fork is also not available, all processing is done in a single process, sequentially. There are three Scheduler classes: Scheduler ThreadedScheduler ForkedScheduler You usually add new tasks to a scheduler using the add_interval_task or add_daytime_task methods, with the appropriate processmethod argument to select sequential, threaded or forked processing. NOTE: it is impossible to add new tasks to a ForkedScheduler, after the scheduler has been started! For more control you can use one of the following Task classes and use schedule_task or schedule_task_abs: IntervalTask ThreadedIntervalTask ForkedIntervalTask SingleTask ThreadedSingleTask ForkedSingleTask WeekdayTask ThreadedWeekdayTask ForkedWeekdayTask MonthdayTask ThreadedMonthdayTask ForkedMonthdayTask Kronos is the Greek God of Time. Kronos scheduler (c) Irmen de Jong. This version has been extracted from the Turbogears source repository and slightly changed to be completely stand-alone again. Also some fixes have been made to make it work on Python 2.6 (sched module changes). The version in Turbogears is based on the original stand-alone Kronos. This is open-source software, released under the MIT Software License: http://www.opensource.org/licenses/mit-license.php """ __version__="2.0" __all__ = [ "DayTaskRescheduler", "ForkedIntervalTask", "ForkedMonthdayTask", "ForkedScheduler", "ForkedSingleTask", "ForkedTaskMixin", "ForkedWeekdayTask", "IntervalTask", "MonthdayTask", "Scheduler", "SingleTask", "Task", "ThreadedIntervalTask", "ThreadedMonthdayTask", "ThreadedScheduler", "ThreadedSingleTask", "ThreadedTaskMixin", "ThreadedWeekdayTask", "WeekdayTask", "add_interval_task", "add_monthday_task", "add_single_task", "add_weekday_task", "cancel", "method", ] import os import sys import sched import time import traceback import weakref import logging class method: sequential="sequential" forked="forked" threaded="threaded" class Scheduler: """The Scheduler itself.""" def __init__(self): self.running=True self.sched = sched.scheduler(time.time, self.__delayfunc) def __delayfunc(self, delay): # This delay function is basically a time.sleep() that is # divided up, so that we can check the self.running flag while delaying. # there is an additional check in here to ensure that the top item of # the queue hasn't changed if delay<10: time.sleep(delay) else: toptime = self._getqueuetoptime() endtime = time.time() + delay period = 5 stoptime = endtime - period while self.running and stoptime > time.time() and \ self._getqueuetoptime() == toptime: time.sleep(period) if not self.running or self._getqueuetoptime() != toptime: return now = time.time() if endtime > now: time.sleep(endtime - now) def _acquire_lock(self): pass def _release_lock(self): pass def add_interval_task(self, action, taskname, initialdelay, interval, processmethod, args, kw): """Add a new Interval Task to the schedule. A very short initialdelay or one of zero cannot be honored, you will see a slight delay before the task is first executed. This is because the scheduler needs to pick it up in its loop. """ if initialdelay < 0 or interval < 1: raise ValueError("Delay or interval must be >0") # Select the correct IntervalTask class. Not all types may be available! if processmethod == method.sequential: TaskClass = IntervalTask elif processmethod == method.threaded: TaskClass = ThreadedIntervalTask elif processmethod == method.forked: TaskClass = ForkedIntervalTask else: raise ValueError("Invalid processmethod") if not args: args = [] if not kw: kw = {} task = TaskClass(taskname, interval, action, args, kw) self.schedule_task(task, initialdelay) return task def add_single_task(self, action, taskname, initialdelay, processmethod, args, kw): """Add a new task to the scheduler that will only be executed once.""" if initialdelay < 0: raise ValueError("Delay must be >0") # Select the correct SingleTask class. Not all types may be available! if processmethod == method.sequential: TaskClass = SingleTask elif processmethod == method.threaded: TaskClass = ThreadedSingleTask elif processmethod == method.forked: TaskClass = ForkedSingleTask else: raise ValueError("Invalid processmethod") if not args: args = [] if not kw: kw = {} task = TaskClass(taskname, action, args, kw) self.schedule_task(task, initialdelay) return task def add_daytime_task(self, action, taskname, weekdays, monthdays, timeonday, processmethod, args, kw): """Add a new Day Task (Weekday or Monthday) to the schedule.""" if weekdays and monthdays: raise ValueError("You can only specify weekdays or monthdays, " "not both") if not args: args = [] if not kw: kw = {} if weekdays: # Select the correct WeekdayTask class. # Not all types may be available! if processmethod == method.sequential: TaskClass = WeekdayTask elif processmethod == method.threaded: TaskClass = ThreadedWeekdayTask elif processmethod == method.forked: TaskClass = ForkedWeekdayTask else: raise ValueError("Invalid processmethod") task=TaskClass(taskname, weekdays, timeonday, action, args, kw) if monthdays: # Select the correct MonthdayTask class. # Not all types may be available! if processmethod == method.sequential: TaskClass = MonthdayTask elif processmethod == method.threaded: TaskClass = ThreadedMonthdayTask elif processmethod == method.forked: TaskClass = ForkedMonthdayTask else: raise ValueError("Invalid processmethod") task=TaskClass(taskname, monthdays, timeonday, action, args, kw) firsttime=task.get_schedule_time(True) self.schedule_task_abs(task, firsttime) return task def schedule_task(self, task, delay): """Add a new task to the scheduler with the given delay (seconds). Low-level method for internal use. """ if self.running: # lock the sched queue, if needed self._acquire_lock() try: task.event = self.sched.enter(delay, 0, task, (weakref.ref(self),) ) finally: self._release_lock() else: task.event = self.sched.enter(delay, 0, task, (weakref.ref(self),) ) def schedule_task_abs(self, task, abstime): """Add a new task to the scheduler for the given absolute time value. Low-level method for internal use. """ if self.running: # lock the sched queue, if needed self._acquire_lock() try: task.event = self.sched.enterabs(abstime, 0, task, (weakref.ref(self),) ) finally: self._release_lock() else: task.event = self.sched.enterabs(abstime, 0, task, (weakref.ref(self),) ) def start(self): """Start the scheduler.""" self._run() def stop(self): """Remove all pending tasks and stop the Scheduler.""" self.running = False self._clearschedqueue() def cancel(self, task): """Cancel given scheduled task.""" self.sched.cancel(task.event) if sys.version_info>=(2,6): # code for sched module of python 2.6+ def _getqueuetoptime(self): try: return self.sched._queue[0].time except IndexError: return 0.0 def _clearschedqueue(self): self.sched._queue[:] = [] else: # code for sched module of python 2.5 and older def _getqueuetoptime(self): try: return self.sched.queue[0][0] except IndexError: return 0.0 def _clearschedqueue(self): self.sched.queue[:] = [] def _run(self): # Low-level run method to do the actual scheduling loop. while self.running: try: self.sched.run() except Exception,x: logging.error("ERROR DURING SCHEDULER EXECUTION %s" % str(x), exc_info=True) # queue is empty; sleep a short while before checking again if self.running: time.sleep(5) class Task: """Abstract base class of all scheduler tasks""" def __init__(self, name, action, args, kw): """This is an abstract class!""" self.name=name self.action=action self.args=args self.kw=kw def __call__(self, schedulerref): """Execute the task action in the scheduler's thread.""" try: self.execute() except Exception,x: self.handle_exception(x) self.reschedule(schedulerref()) def reschedule(self, scheduler): """This method should be defined in one of the sub classes!""" raise NotImplementedError("You're using the abstract base class 'Task'," " use a concrete class instead") def execute(self): """Execute the actual task.""" self.action(*self.args, **self.kw) def handle_exception(self, exc): """Handle any exception that occured during task execution.""" logging.error("ERROR DURING SCHEDULER EXECUTION %s" % str(exc), exc_info=True) class SingleTask(Task): """A task that only runs once.""" def reschedule(self, scheduler): pass class IntervalTask(Task): """A repeated task that occurs at certain intervals (in seconds).""" def __init__(self, name, interval, action, args=None, kw=None): Task.__init__(self, name, action, args, kw) self.interval = interval def reschedule(self, scheduler): """Reschedule this task according to its interval (in seconds).""" scheduler.schedule_task(self, self.interval) class DayTaskRescheduler: """A mixin class that contains the reschedule logic for the DayTasks.""" def __init__(self, timeonday): self.timeonday = timeonday def get_schedule_time(self, today): """Calculate the time value at which this task is to be scheduled.""" now = list(time.localtime()) if today: # schedule for today. let's see if that is still possible if (now[3], now[4]) >= self.timeonday: # too bad, it will be tomorrow now[2] += 1 else: # tomorrow now[2] += 1 # set new time on day (hour,minute) now[3], now[4] = self.timeonday # seconds now[5] = 0 return time.mktime(now) def reschedule(self, scheduler): """Reschedule this task according to the daytime for the task. The task is scheduled for tomorrow, for the given daytime. """ # (The execute method in the concrete Task classes will check # if the current day is a day on which the task must run). abstime = self.get_schedule_time(False) scheduler.schedule_task_abs(self, abstime) class WeekdayTask(DayTaskRescheduler, Task): """A task that is called at specific days in a week (1-7), at a fixed time on the day. """ def __init__(self, name, weekdays, timeonday, action, args=None, kw=None): if type(timeonday) not in (list, tuple) or len(timeonday) != 2: raise TypeError("timeonday must be a 2-tuple (hour,minute)") if type(weekdays) not in (list, tuple): raise TypeError("weekdays must be a sequence of weekday numbers " "1-7 (1 is Monday)") DayTaskRescheduler.__init__(self, timeonday) Task.__init__(self, name, action, args, kw) self.days = weekdays def execute(self): # This is called every day, at the correct time. We only need to # check if we should run this task today (this day of the week). weekday = time.localtime().tm_wday + 1 if weekday in self.days: self.action(*self.args, **self.kw) class MonthdayTask(DayTaskRescheduler, Task): """A task that is called at specific days in a month (1-31), at a fixed time on the day. """ def __init__(self, name, monthdays, timeonday, action, args=None, kw=None): if type(timeonday) not in (list, tuple) or len(timeonday) != 2: raise TypeError("timeonday must be a 2-tuple (hour,minute)") if type(monthdays) not in (list, tuple): raise TypeError("monthdays must be a sequence of monthdays numbers " "1-31") DayTaskRescheduler.__init__(self, timeonday) Task.__init__(self, name, action, args, kw) self.days = monthdays def execute(self): # This is called every day, at the correct time. We only need to # check if we should run this task today (this day of the month). if time.localtime().tm_mday in self.days: self.action(*self.args, **self.kw) try: import threading class ThreadedScheduler(Scheduler): """A Scheduler that runs in its own thread.""" def __init__(self): Scheduler.__init__(self) # we require a lock around the task queue self._lock = threading.Lock() def start(self): """Splice off a thread in which the scheduler will run.""" self.thread = threading.Thread(target=self._run) self.thread.setDaemon(True) self.thread.start() def stop(self): """Stop the scheduler and wait for the thread to finish.""" Scheduler.stop(self) try: self.thread.join() except AttributeError: pass def _acquire_lock(self): """Lock the thread's task queue.""" self._lock.acquire() def _release_lock(self): """Release the lock on th ethread's task queue.""" self._lock.release() class ThreadedTaskMixin: """A mixin class to make a Task execute in a separate thread.""" def __call__(self, schedulerref): """Execute the task action in its own thread.""" threading.Thread(target=self.threadedcall).start() self.reschedule(schedulerref()) def threadedcall(self): # This method is run within its own thread, so we have to # do the execute() call and exception handling here. try: self.execute() except Exception,x: self.handle_exception(x) class ThreadedIntervalTask(ThreadedTaskMixin, IntervalTask): """Interval Task that executes in its own thread.""" pass class ThreadedSingleTask(ThreadedTaskMixin, SingleTask): """Single Task that executes in its own thread.""" pass class ThreadedWeekdayTask(ThreadedTaskMixin, WeekdayTask): """Weekday Task that executes in its own thread.""" pass class ThreadedMonthdayTask(ThreadedTaskMixin, MonthdayTask): """Monthday Task that executes in its own thread.""" pass except ImportError: # threading is not available pass if hasattr(os, "fork"): import signal class ForkedScheduler(Scheduler): """A Scheduler that runs in its own forked process.""" def __del__(self): if hasattr(self, "childpid"): os.kill(self.childpid, signal.SIGKILL) def start(self): """Fork off a new process in which the scheduler will run.""" pid = os.fork() if pid == 0: # we are the child signal.signal(signal.SIGUSR1, self.signalhandler) self._run() os._exit(0) else: # we are the parent self.childpid = pid # can no longer insert in the scheduler queue del self.sched def stop(self): """Stop the scheduler and wait for the process to finish.""" os.kill(self.childpid, signal.SIGUSR1) os.waitpid(self.childpid, 0) def signalhandler(self, sig, stack): Scheduler.stop(self) class ForkedTaskMixin: """A mixin class to make a Task execute in a separate process.""" def __call__(self, schedulerref): """Execute the task action in its own process.""" pid = os.fork() if pid == 0: # we are the child try: self.execute() except Exception,x: self.handle_exception(x) os._exit(0) else: # we are the parent self.reschedule(schedulerref()) class ForkedIntervalTask(ForkedTaskMixin, IntervalTask): """Interval Task that executes in its own process.""" pass class ForkedSingleTask(ForkedTaskMixin, SingleTask): """Single Task that executes in its own process.""" pass class ForkedWeekdayTask(ForkedTaskMixin, WeekdayTask): """Weekday Task that executes in its own process.""" pass class ForkedMonthdayTask(ForkedTaskMixin, MonthdayTask): """Monthday Task that executes in its own process.""" pass if __name__=="__main__": def testaction(arg): print ">>>TASK",arg,"sleeping 3 seconds" time.sleep(3) print "<<>> elem_quote('hello') 'hello' >>> elem_quote('hello', nonquote=False) '"hello"' >>> elem_quote('"hello"') '\\'"hello"\\'' >>> elem_quote(3) Traceback (most recent call last): TypeError: Can only quote strings. "3" >>> elem_quote(3, stringify=True) '3' >>> elem_quote('hello', encoding='ascii') u'hello' >>> elem_quote('\\n') Traceback (most recent call last): QuoteError: Multiline values can't be quoted. " " """ if not isinstance(member, basestring): if stringify: member = str(member) else: # FIXME: is this the appropriate error message ? raise TypeError('Can only quote strings. "%s"' % str(member)) if encoding and isinstance(member, str): # from string to unicode member = unicode(member, encoding) if '\n' in member: raise QuoteError('Multiline values can\'t be quoted.\n"%s"' % str(member)) # if nonquote and badchars.match(member) is not None: return member # this ordering of tests determines which quote character will be used in # preference - here we have \" first... elif member.find('"') == -1: return '"%s"' % member # but we will use either... which may not suit some people elif member.find("'") == -1: return "'%s'" % member else: raise QuoteError('Value can\'t be quoted : "%s"' % member) def unquote(inline, fullquote=True, retain=False): """ Unquote a value. If the value isn't quoted it returns the value. If the value is badly quoted it raises ``UnQuoteError``. If retain is ``True`` (default is ``False``) then the quotes are left around the value (but leading or trailing whitespace will have been removed). If fullquote is ``False`` (default is ``True``) then unquote will only unquote the first part of the ``inline``. If there is anything after the quoted element, this will be returned as well (instead of raising an error). In this case the return value is ``(value, rest)``. >>> unquote('hello') 'hello' >>> unquote('"hello"') 'hello' >>> unquote('"hello') Traceback (most recent call last): UnQuoteError: Value is badly quoted: ""hello" >>> unquote('"hello" fish') Traceback (most recent call last): UnQuoteError: Value is badly quoted: ""hello" fish" >>> unquote("'hello'", retain=True) "'hello'" >>> unquote('"hello" fish', fullquote=False) ('hello', ' fish') """ mat = inquotes.match(inline) if mat is None: if inline.strip()[0] not in '\'\"': # not quoted return inline else: # badly quoted raise UnQuoteError('Value is badly quoted: "%s"' % inline) quoted, rest = mat.groups() if fullquote and rest.strip(): # badly quoted raise UnQuoteError('Value is badly quoted: "%s"' % inline) if not retain: quoted = quoted[1:-1] if not fullquote: return quoted, rest else: return quoted def quote_escape(value, lf='&mjf-lf;', quot='&mjf-quot;'): """ Escape a string so that it can safely be quoted. You should use this if the value to be quoted *may* contain line-feeds or both single quotes and double quotes. If the value contains ``\n`` then it will be escaped using ``lf``. By default this is ``&mjf-lf;``. If the value contains single quotes *and* double quotes, then all double quotes will be escaped using ``quot``. By default this is ``&mjf-quot;``. >>> quote_escape('hello') 'hello' >>> quote_escape('hello\\n') 'hello&mjf-lf;' >>> quote_escape('hello"') 'hello"' >>> quote_escape('hello"\\'') "hello&mjf-quot;'" >>> quote_escape('hello"\\'\\n', '&fish;', '&wobble;') "hello&wobble;'&fish;" """ if '\n' in value: value = value.replace('\n', lf) if '\'' in value and '\"' in value: value = value.replace('"', quot) return value def quote_unescape(value, lf='&mjf-lf;', quot='&mjf-quot;'): """ Unescape a string escaped by ``quote_escape``. If it was escaped using anything other than the defaults for ``lf`` and ``quot`` you must pass them to this function. >>> quote_unescape("hello&wobble;'&fish;", '&fish;', '&wobble;') 'hello"\\'\\n' >>> quote_unescape('hello') 'hello' >>> quote_unescape('hello&mjf-lf;') 'hello\\n' >>> quote_unescape("'hello'") "'hello'" >>> quote_unescape('hello"') 'hello"' >>> quote_unescape("hello&mjf-quot;'") 'hello"\\'' >>> quote_unescape("hello&wobble;'&fish;", '&fish;', '&wobble;') 'hello"\\'\\n' """ return value.replace(lf, '\n').replace(quot, '"') def simplelist(inline): """ Parse a string to a list. A simple regex that extracts quoted items from a list. It retains quotes around elements. (So unquote each element) >>> simplelist('''hello, goodbye, 'title', "name", "I can't"''') ['hello', 'goodbye', "'title'", '"name"', '"I can\\'t"'] FIXME: This doesn't work fully (allows some badly formed lists): e.g. >>> simplelist('hello, fish, "wobble" bottom hooray') ['hello', 'fish', '"wobble"', 'bottom hooray'] """ return paramfinder.findall(inline) ############################################## # LineParser - a multi purpose line parser # handles lines with comma seperated values on it, followed by a comment # correctly handles quoting # *and* can handle nested lists - marked between '[...]' or '(...)' # See the docstring for how this works # by default it returns a (list, comment) tuple ! # There are several keyword arguments that control how LineParser works. class LineParser(object): """An object to parse nested lists from strings.""" liststart = { '[' : ']', '(' : ')' } quotes = ['\'', '"'] def __init__(self, options=None, **keywargs): """Initialise the LineParser.""" self.reset(options, **keywargs) def reset(self, options=None, **keywargs): """Reset the parser with the specified options.""" if options is None: options = {} options.update(keywargs) # defaults = { 'recursive': True, 'comment': True, 'retain': False, 'force_list': False, 'csv': False } defaults.update(options) if defaults['csv']: defaults.update({ 'recursive': False, 'force_list': True, 'comment': False, }) # check all the options are valid for entry in defaults.keys(): if entry not in ['comment', 'retain', 'csv', 'recursive', 'force_list']: raise TypeError, ("'%s' is an invalid keyword argument for " "this function" % entry) # self.recursive = defaults['recursive'] self.comment = defaults['comment'] self.retain = defaults['retain'] self.force_list = defaults['force_list'] def feed(self, inline, endchar=None): """ Parse a single line (or fragment). Uses the options set in the parser object. Can parse lists - including nested lists. (If ``recursive`` is ``False`` then nested lists will cause a ``BadLineError``). Return value depends on options. If ``comment`` is ``False`` it returns ``outvalue`` If ``comment`` is ``True`` it returns ``(outvalue, comment)``. (Even if comment is just ``''``). If ``force_list`` is ``False`` then ``outvalue`` may be a list or a single item. If ``force_list`` is ``True`` then ``outvalue`` will always be a list - even if it has just one member. List syntax : * Comma separated lines ``a, b, c, d`` * Lists can optionally be between square or ordinary brackets - ``[a, b, c, d]`` - ``(a, b, c, d)`` * Nested lists *must* be between brackets - ``a, [a, b, c, d], c`` * A single element list can be shown by a trailing quote - ``a,`` * An empty list is shown by ``()`` or ``[]`` Elements can be quoted with single or double quotes (but can't contain both). The line can optionally end with a comment (preeded by a '#'). This depends on the ``comment`` attribute. If the line is badly built then this method will raise one of : :: CommentError, BadLineError, UnQuoteError Using the ``csv`` option is the same as setting : :: 'recursive': False 'force_list': True 'comment': False """ # preserve the original line # for error messages if endchar is None: self.origline = inline inline = inline.lstrip() # outlist = [] comma_needed = False found_comma = False while inline: # NOTE: this sort of operation would be quicker # with lists - but then can't use regexes thischar = inline[0] if thischar == '#': # reached a comment # end of the line... break # if thischar == endchar: return outlist, inline[1:] # if comma_needed: if thischar == ',': inline = inline[1:].lstrip() comma_needed = False found_comma = True continue raise BadLineError('Line is badly built :\n%s' % self.origline) # try: # the character that marks the end of the list listend = self.liststart[thischar] except KeyError: pass else: if not self.recursive and endchar is not None: raise BadLineError('Line is badly built :\n%s' % self.origline) newlist, inline = self.feed(inline[1:], endchar=listend) outlist.append(newlist) inline = inline.lstrip() comma_needed = True continue # if thischar in self.quotes: # this might raise an error # FIXME: trap the error and raise a more appropriate one ? element, inline = unquote(inline, fullquote=False, retain=self.retain) inline = inline.lstrip() outlist.append(element) comma_needed = True continue # # must be an unquoted element mat = unquoted.match(inline) if mat is not None: # FIXME: if the regex was better we wouldn't need an rstrip element = mat.group(1).rstrip() # group 2 will be ``None`` if we reach the end of the line inline = mat.group(2) or '' outlist.append(element) comma_needed = True continue # or it's a badly built line raise BadLineError('Line is badly built :\n%s' % self.origline) # # if we've been called recursively # we shouldn't have got this far if endchar is not None: raise BadLineError('Line is badly built :\n%s' % self.origline) # if not found_comma: # if we didn't find a comma # the value could be a nested list if outlist: outlist = outlist[0] else: outlist = '' if self.force_list and not isinstance(outlist, list): if outlist: outlist = [outlist] else: outlist = [] if not self.comment: if inline: raise CommentError('Comment not allowed :\n%s' % self.origline) return outlist return outlist, inline def lineparse(inline, options=None, **keywargs): """ A compatibility function that mimics the old lineparse. Also more convenient for single line use. Note: It still uses the new ``LineParser`` - and so takes the same keyword arguments as that. >>> lineparse('''"hello", 'goodbye', "I can't do that", 'You "can" !' # a comment''') (['hello', 'goodbye', "I can't do that", 'You "can" !'], '# a comment') >>> lineparse('''"hello", 'goodbye', "I can't do that", 'You "can" !' # a comment''', comment=False) Traceback (most recent call last): CommentError: Comment not allowed : "hello", 'goodbye', "I can't do that", 'You "can" !' # a comment >>> lineparse('''"hello", 'goodbye', "I can't do that", 'You "can" !' # a comment''', recursive=False) (['hello', 'goodbye', "I can't do that", 'You "can" !'], '# a comment') >>> lineparse('''"hello", 'goodbye', "I can't do that", 'You "can" !' # a comment''', csv=True) Traceback (most recent call last): CommentError: Comment not allowed : "hello", 'goodbye', "I can't do that", 'You "can" !' # a comment >>> lineparse('''"hello", 'goodbye', "I can't do that", 'You "can" !' ''', comment=False) ['hello', 'goodbye', "I can't do that", 'You "can" !'] >>> lineparse('') ('', '') >>> lineparse('', force_list=True) ([], '') >>> lineparse('[]') ([], '') >>> lineparse('()') ([], '') >>> lineparse('()', force_list=True) ([], '') >>> lineparse('1,') (['1'], '') >>> lineparse('"Yo"') ('Yo', '') >>> lineparse('"Yo"', force_list=True) (['Yo'], '') >>> lineparse('''h, i, j, (h, i, ['hello', "f"], [], ([]),), k''') (['h', 'i', 'j', ['h', 'i', ['hello', 'f'], [], [[]]], 'k'], '') >>> lineparse('''h, i, j, (h, i, ['hello', "f"], [], ([]),), k''', recursive=False) Traceback (most recent call last): BadLineError: Line is badly built : h, i, j, (h, i, ['hello', "f"], [], ([]),), k >>> lineparse('fish#dog') ('fish', '#dog') >>> lineparse('"fish"#dog') ('fish', '#dog') >>> lineparse('(((())))') ([[[[]]]], '') >>> lineparse('((((,))))') Traceback (most recent call last): BadLineError: Line is badly built : ((((,)))) >>> lineparse('hi, ()') (['hi', []], '') >>> lineparse('"hello", "",') (['hello', ''], '') >>> lineparse('"hello", ,') Traceback (most recent call last): BadLineError: Line is badly built : "hello", , >>> lineparse('"hello", ["hi", ""], ""') (['hello', ['hi', ''], ''], '') >>> lineparse('''"member 1", "member 2", ["nest 1", ("nest 2", 'nest 2b', ['nest 3', 'value'], nest 2c), nest1b]''') (['member 1', 'member 2', ['nest 1', ['nest 2', 'nest 2b', ['nest 3', 'value'], 'nest 2c'], 'nest1b']], '') >>> lineparse('''"member 1", "member 2", ["nest 1", ("nest 2", 'nest 2b', ['nest 3', 'value'], nest 2c), nest1b]]''') Traceback (most recent call last): BadLineError: Line is badly built : "member 1", "member 2", ["nest 1", ("nest 2", 'nest 2b', ['nest 3', 'value'], nest 2c), nest1b]] """ p = LineParser(options, **keywargs) return p.feed(inline) ############################################################################ # a couple of functions to help build lists def list_stringify(inlist): """ Recursively rebuilds a list - making sure all the members are strings. Can take any iterable or a sequence as the argument and always returns a list. Useful before writing out lists. Used by makelist if stringify is set. Uses the ``str`` function for stringification. Every element will be a string or a unicode object. Doesn't handle decoding strings into unicode objects (or vice-versa). >>> list_stringify([2, 2, 2, 2, (3, 3, 2.9)]) ['2', '2', '2', '2', ['3', '3', '2.9']] >>> list_stringify(None) Traceback (most recent call last): TypeError: 'NoneType' object is not iterable >>> list_stringify([]) [] FIXME: can receive any iterable - e.g. a sequence >>> list_stringify('') [] >>> list_stringify('Hello There') ['H', 'e', 'l', 'l', 'o', ' ', 'T', 'h', 'e', 'r', 'e'] """ outlist = [] for item in inlist: if not isinstance(item, (tuple, list)): if not isinstance(item, basestring): item = str(item) else: item = list_stringify(item) outlist.append(item) return outlist def makelist(inlist, listchar='', stringify=False, escape=False, encoding=None): """ Given a list - turn it into a string that represents that list. (Suitable for parsing by ``LineParser``). listchar should be ``'['``, ``'('`` or ``''``. This is the type of bracket used to enclose the list. (``''`` meaning no bracket of course). If you have nested lists and listchar is ``''``, makelist will automatically use ``'['`` for the nested lists. If stringify is ``True`` (default is ``False``) makelist will stringify the inlist first (using ``list_stringify``). If ``escape`` is ``True`` (default is ``False``) makelist will call ``quote_escape`` on each element before passing them to ``elem_quote`` to be quoted. If encoding keyword is not ``None``, all strings are decoded to unicode with the specified encoding. Each item will then be a unicode object instead of a string. >>> makelist([]) '[]' >>> makelist(['a', 'b', 'I can\\'t do it', 'Yes you "can" !']) 'a, b, "I can\\'t do it", \\'Yes you "can" !\\'' >>> makelist([3, 4, 5, [6, 7, 8]], stringify=True) '3, 4, 5, [6, 7, 8]' >>> makelist([3, 4, 5, [6, 7, 8]]) Traceback (most recent call last): TypeError: Can only quote strings. "3" >>> makelist(['a', 'b', 'c', ('d', 'e'), ('f', 'g')], listchar='(') '(a, b, c, (d, e), (f, g))' >>> makelist(['hi\\n', 'Quote "heck\\''], escape=True) 'hi&mjf-lf;, "Quote &mjf-quot;heck\\'"' >>> makelist(['a', 'b', 'c', ('d', 'e'), ('f', 'g')], encoding='UTF8') u'a, b, c, [d, e], [f, g]' """ if stringify: inlist = list_stringify(inlist) listdict = {'[' : '[%s]', '(' : '(%s)', '' : '%s'} outline = [] # this makes '[' the default for empty or single value lists if len(inlist) < 2: listchar = listchar or '[' for item in inlist: if not isinstance(item, (list, tuple)): if escape: item = quote_escape(item) outline.append(elem_quote(item, encoding=encoding)) else: # recursive for nested lists outline.append(makelist(item, listchar or '[', stringify, escape, encoding)) return listdict[listchar] % (', '.join(outline)) ############################################################################ # CSV functions # csvread, csvwrite def csvread(infile): """ Given an infile as an iterable, return the CSV as a list of lists. infile can be an open file object or a list of lines. If any of the lines are badly built then a ``CSVError`` will be raised. This has a ``csv`` attribute - which is a reference to the parsed CSV. Every line that couldn't be parsed will have ``[]`` for it's entry. The error *also* has an ``errors`` attribute. This is a list of all the errors raised. Error in this will have an ``index`` attribute, which is the line number, and a ``line`` attribute - which is the actual line that caused the error. Example of usage : .. raw:: html {+coloring} handle = open(filename) # remove the trailing '\n' from each line the_file = [line.rstrip('\n') for line in handle.readlines()] csv = csvread(the_file) {-coloring} >>> a = '''"object 1", 'object 2', object 3 ... test 1 , "test 2" ,'test 3' ... 'obj 1',obj 2,"obj 3"''' >>> csvread(a.splitlines()) [['object 1', 'object 2', 'object 3'], ['test 1', 'test 2', 'test 3'], ['obj 1', 'obj 2', 'obj 3']] >>> csvread(['object 1,']) [['object 1']] >>> try: ... csvread(['object 1, "hello', 'object 1, # a comment in a csv ?']) ... except CSVError, e: ... for entry in e.errors: ... print entry.index, entry 0 Value is badly quoted: ""hello" 1 Comment not allowed : object 1, # a comment in a csv ? """ out_csv = [] errors = [] index = -1 p = LineParser(csv=True) for line in infile: index += 1 try: values = p.feed(line) except ListQuoteError, e: values = [] e.line = line e.index = index errors.append(e) # out_csv.append(values) # if errors: e = CSVError("Parsing CSV failed. See 'errors' attribute.") e.csv = out_csv e.errors = errors raise e return out_csv def csvwrite(inlist, stringify=False): """ Given a list of lists it turns each entry into a line in a CSV. (Given a list of lists it returns a list of strings). The lines will *not* be ``\n`` terminated. Set stringify to ``True`` (default is ``False``) to convert entries to strings before creating the line. If stringify is ``False`` then any non string value will raise a ``TypeError``. Every member will be quoted using ``elem_quote``, but no escaping is done. Example of usage : .. raw:: html {+coloring} # escape each entry in each line (optional) for index in range(len(the_list)): the_list[index] = [quote_escape(val) for val in the_list[index]] # the_file = csvwrite(the_list) # add a '\n' to each line - ready to write to file the_file = [line + '\n' for line in the_file] {-coloring} >>> csvwrite([['object 1', 'object 2', 'object 3'], ['test 1', 'test 2', 'test 3'], ['obj 1', 'obj 2', 'obj 3']]) ['"object 1", "object 2", "object 3"', '"test 1", "test 2", "test 3"', '"obj 1", "obj 2", "obj 3"'] >>> csvwrite([[3, 3, 3]]) Traceback (most recent call last): TypeError: Can only quote strings. "3" >>> csvwrite([[3, 3, 3]], True) ['3, 3, 3'] """ out_list = [] for entry in inlist: if stringify: new_entry = [] for val in entry: if not isinstance(val, basestring): val = str(val) new_entry.append(val) entry = new_entry this_line = ', '.join([elem_quote(val) for val in entry]) out_list.append(this_line) return out_list ############################################################################ def _test(): import doctest doctest.testmod() if __name__ == "__main__": _test() """ ISSUES/TODO =========== Fix bug in simplelist Triple quote multiline values ? Doesn't allow Python style string escaping (but has '&mjf-quot;' and '&mjf-lf;'). Uses both \' and \" as quotes and sometimes doesn't quote at all - see elem_quote - may not *always* be compatible with other programs. Allow space seperated lists ? e.g. 10 5 100 20 Lineparser could create tuples. Allow ',' as an empty list ? CHANGELOG ========= 2005/08/28 - Version 1.4.0 -------------------------- * Greater use of regular expressions for added speed * Re-implemented ``lineparse`` as the ``LineParser`` object * Added doctests * Custom exceptions * Changed the behaviour of ``csvread`` and ``csvwrite`` * Removed the CSV ``compare`` function and the ``uncomment`` function * Only ``'#'`` allowed for comments * ``elem_quote`` raises exceptions * Changed behaviour of ``unquote`` * Added ``quote_escape`` and ``quote_unescape`` * Removed the ``uni_conv`` option in the CSV functions .. note:: These changes are quite extensive. If any of them cause you problems then let me know. I can provide a workaround in the next release. 2005/06/01 Version 1.3.0 Fixed bug in lineparse handling of empty list members. Thnks to bug report and fix by Par Pandit The 'unquote' function is now regex based. (bugfix it now doesn't return a tuple if fullquote is 0) Added the simplelist regex/function. elem_quote and uncomment use a regex for clarity and speed. Added a bunch of asserts to the tests. 2005/03/07 Version 1.2.1 makelist improved - better handling of empty or single member lists 2005/02/23 Version 1.2.0 Added uncomment for ConfigObj 3.3.0 Optimised unquote - not a character by character search any more. lineparse does full '&mjf..;' escape conversions - even when unquote isn't used makelist and elem_quote takes an 'encoding' keyword for string members to be used to decode strigns to unicode optimised makelist (including a minor bugfix) Change to lineparse - it wouldn't allow '[' or '(' inside elements unless they were quoted. 2004/12/04 Version 1.1.2 Changed the license (*again* - now OSI compatible). Empty values are now quoted by elem_quote. 30-08-04 Version 1.1.1 Removed the unicode hammer in csvread. Improved docs. 16-08-04 Version 1.1.0 Added handling for non-string elements in elem_quote (optional). Replaced some old += with lists and ''.join() for speed improvements... Using basestring and hasattr('__getitem__') tests instead of isinstance(list) and str in a couple of places. Changed license text. Made the tests useful. 19-06-04 Version 1.0.0 Seems to work ok. A worthy successor to listparse and csv_s - although not as elegant as it could be. """ SABnzbd-0.7.20/sabnzbd/utils/pathbrowser.py0000644000000000000000000001035112433712602020722 0ustar00usergroup00000000000000#------------------------------------------------------------------------------------------------ # This file is an excerpt from Sick Beard's browser.py # Modified and improved to fit SABnzbd. # # Author: Nic Wolfe # URL: http://code.google.com/p/sickbeard/ # # Sick Beard 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 3 of the License, or # (at your option) any later version. # # Sick Beard 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 Sick Beard. If not, see . import os if os.name == 'nt': import win32api, win32con, win32file MASK = win32con.FILE_ATTRIBUTE_DIRECTORY | win32con.FILE_ATTRIBUTE_HIDDEN TMASK = win32con.FILE_ATTRIBUTE_DIRECTORY DRIVES = (2, 3, 4) NT = True else: NT = False import sabnzbd _JUNKFOLDERS = ( 'boot', 'bootmgr', 'cache', 'msocache', 'recovery', '$recycle.bin', 'recycler', 'system volume information', 'temporary internet files', # windows specific '.fseventd', '.spotlight', '.trashes', '.vol', 'cachedmessages', 'caches', 'trash' # osx specific ) # this is for the drive letter code, it only works on windows if os.name == 'nt': from ctypes import windll # adapted from http://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python/827490 def get_win_drives(): """ Return list of detected drives """ assert NT drives = [] bitmask = windll.kernel32.GetLogicalDrives() for letter in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': if (bitmask & 1) and win32file.GetDriveType('%s:\\' % letter) in DRIVES: drives.append(letter) bitmask >>= 1 return drives def folders_at_path(path, include_parent = False): """ Returns a list of dictionaries with the folders contained at the given path Give the empty string as the path to list the contents of the root path under Unix this means "/", on Windows this will be a list of drive letters) """ from sabnzbd.encoding import unicoder if path == "": if NT: entries = [{'name': letter + ':\\', 'path': letter + ':\\'} for letter in get_win_drives()] entries.insert(0, {'current_path': 'Root'}) return entries else: path = '/' # walk up the tree until we find a valid path path = sabnzbd.misc.real_path(sabnzbd.DIR_HOME, path) while path and not os.path.isdir(path): if path == os.path.dirname(path): return folders_at_path('', include_parent) else: path = os.path.dirname(path) # fix up the path and find the parent path = os.path.abspath(os.path.normpath(path)) parent_path = os.path.dirname(path) # if we're at the root then the next step is the meta-node showing our drive letters if path == parent_path and os.name == 'nt': parent_path = "" file_list = [] try: for filename in os.listdir(path): fpath = os.path.join(path, filename) try: if NT: doit = (win32api.GetFileAttributes(fpath) & MASK) == TMASK and filename != 'PerfLogs' else: doit = not filename.startswith('.') except: doit = False if doit: file_list.append({ 'name': unicoder(filename), 'path': unicoder(fpath) }) file_list = filter(lambda entry: os.path.isdir(entry['path']), file_list) file_list = filter(lambda entry: entry['name'].lower() not in _JUNKFOLDERS, file_list) file_list = sorted(file_list, lambda x, y: cmp(os.path.basename(x['name']).lower(), os.path.basename(y['path']).lower())) except: # No access, ignore pass file_list.insert(0, {'current_path': path}) if include_parent and parent_path != path: file_list.insert(1,{ 'name': "..", 'path': parent_path }) return file_list SABnzbd-0.7.20/sabnzbd/utils/rarfile.py0000644000000000000000000004053212433712602020012 0ustar00usergroup00000000000000# rarfile.py # # Copyright (c) 2005 Marko Kreen # # Improved by ShyPike 2008-08-11: # - use tempfile.mkstemp() instead of the unsafe os.tempnam() # - Improve compatibility with Python's ZipFile support: # - Always use Unix separators '/' in pathnames (ascii & unicode) # - Foldernames must always end with a '/' (ascii & unicode) # - Use CP850 as default codepage # - Convert ASCII filenames to Python's default 'latin-1' encoding # # Optimized to fit in SABnzbd: # - No extract hack (not needed for just rarred NZB files). # - Use "SimpleRarExtract" function of newsunpack.py # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import os, re from struct import pack, unpack from binascii import crc32 from cStringIO import StringIO import tempfile import logging import sabnzbd # whether to speed up decompression by using tmp archive _use_extract_hack = 0 # # rar constants # RAR_ID = "Rar!\x1a\x07\x00" RAR5_ID = "Rar!\x1a\x07\x01\x00" # block types RAR_BLOCK_MARK = 0x72 # r RAR_BLOCK_MAIN = 0x73 # s RAR_BLOCK_FILE = 0x74 # t RAR_BLOCK_OLD_COMMENT = 0x75 # u RAR_BLOCK_OLD_EXTRA = 0x76 # v RAR_BLOCK_OLD_SUB = 0x77 # w RAR_BLOCK_OLD_RECOVERY = 0x78 # x RAR_BLOCK_OLD_AUTH = 0x79 # y RAR_BLOCK_SUB = 0x7a # z RAR_BLOCK_ENDARC = 0x7b # { # main header flags RAR_MAIN_VOLUME = 0x0001 RAR_MAIN_COMMENT = 0x0002 RAR_MAIN_LOCK = 0x0004 RAR_MAIN_SOLID = 0x0008 RAR_MAIN_NEWNUMBERING = 0x0010 RAR_MAIN_AUTH = 0x0020 RAR_MAIN_RECOVERY = 0x0040 RAR_MAIN_PASSWORD = 0x0080 RAR_MAIN_FIRSTVOLUME = 0x0100 # file header flags RAR_FILE_SPLIT_BEFORE = 0x0001 RAR_FILE_SPLIT_AFTER = 0x0002 RAR_FILE_PASSWORD = 0x0004 RAR_FILE_COMMENT = 0x0008 RAR_FILE_SOLID = 0x0010 RAR_FILE_DICTMASK = 0x00e0 RAR_FILE_DICT64 = 0x0000 RAR_FILE_DICT128 = 0x0020 RAR_FILE_DICT256 = 0x0040 RAR_FILE_DICT512 = 0x0060 RAR_FILE_DICT1024 = 0x0080 RAR_FILE_DICT2048 = 0x00a0 RAR_FILE_DICT4096 = 0x00c0 RAR_FILE_DIRECTORY = 0x00e0 RAR_FILE_LARGE = 0x0100 RAR_FILE_UNICODE = 0x0200 RAR_FILE_SALT = 0x0400 RAR_FILE_VERSION = 0x0800 RAR_FILE_EXTTIME = 0x1000 RAR_FILE_EXTFLAGS = 0x2000 RAR_ENDARC_NEXT_VOLUME = 0x0001 RAR_ENDARC_DATACRC = 0x0002 RAR_ENDARC_REVSPACE = 0x0004 # flags common to all blocks RAR_SKIP_IF_UNKNOWN = 0x4000 RAR_LONG_BLOCK = 0x8000 # Host OS types RAR_OS_MSDOS = 0 RAR_OS_OS2 = 1 RAR_OS_WIN32 = 2 RAR_OS_UNIX = 3 # # Public interface # def is_rarfile(fn): '''Check quickly whether file is rar archive.''' try: buf = open(fn, "rb").read(50) return buf.startswith(RAR_ID) or buf.startswith(RAR5_ID) except: return False class RarInfo: '''An entry in rar archive.''' def isdir(self): '''Returns True if the entry is a directory.''' if self.type == RAR_BLOCK_FILE: return (self.flags & RAR_FILE_DIRECTORY) == RAR_FILE_DIRECTORY return False class RarFile: '''Rar archive handling.''' def __init__(self, rarfile, mode="r", charset='cp850', info_callback=None, all_names=False): # 'all_names' = show names of 'split' files too self.rarfile = rarfile self.charset = charset self.all_names = all_names self.info_list = [] self.is_solid = 0 self.encrypted = 0 self.corrupt = 0 self.uses_newnumbering = 0 self.uses_volumes = 0 self.info_callback = info_callback self.got_mainhdr = 0 file, ext = os.path.splitext(rarfile) if 'r' in ext: self._gen_volname = self._gen_oldvol else: self._gen_volname = self._gen_newvol if mode != "r": raise Exception("Only mode=r supported") self._parse() def namelist(self): '''Return list of filenames in rar''' res = [] for f in self.info_list: res.append(f.filename) return res def unamelist(self): '''Return list of unicode filenames in rar''' res = [] for f in self.info_list: res.append(f.unicode_filename) return res def infolist(self): '''Return rar entries.''' return self.info_list def getinfo(self, fname): '''Return RarInfo for fname.''' if type(fname) == type(u''): target = fname.replace(u'\\', u'/') for f in self.info_list: if f.unicode_filename.endswith(u'/') and not target.endswith(u'/'): if (target+u'/') == f.unicode_filename: return f else: if target == f.unicode_filename: return f else: target = fname.replace('\\', '/') for f in self.info_list: if f.filename.endswith('/') and not target.endswith('/'): if (target+'/') == f.filename: return f else: if target == f.filename: return f def read(self, fname): '''Return decompressed data.''' inf = self.getinfo(fname) if not inf: raise Exception("No such file") if inf.isdir(): raise Exception("No data in directory") if inf.compress_type == 0x30: res = self._extract_clear(inf) elif _use_extract_hack and not self.is_solid and not self.uses_volumes: res = self._extract_hack(inf) else: res = self._extract_unrar(self.rarfile, inf) return res def close(self): pass def printdir(self): for f in self.info_list: print f.filename # store entry def _process_entry(self, item): # RAR_BLOCK_NEWSUB has files too: CMT, RR if item.type == RAR_BLOCK_FILE: # use only first part if self.all_names or (item.flags & RAR_FILE_SPLIT_BEFORE) == 0: # Always use Unix separators item.filename = item.filename.replace('\\', '/') item.unicode_filename = item.unicode_filename.replace(u'\\', u'/') # Folder items must end with '/' if (item.flags & RAR_FILE_DIRECTORY) == RAR_FILE_DIRECTORY: item.filename += '/' item.unicode_filename += u'/' self.info_list.append(item) if self.info_callback: self.info_callback(item) # read rar def _parse(self): fd = open(self.rarfile, "rb") id = fd.read(len(RAR_ID)) if id != RAR_ID: raise Exception("Not a Rar") volume = 0 # first vol (.rar) is 0 more_vols = 0 while 1: h = self._parse_header(fd) if not h: if more_vols: volume += 1 try: fd = open(self._gen_volname(volume), "rb") except: fd = None more_vols = 0 if fd: continue break h.volume = volume if h.type == RAR_BLOCK_MAIN and not self.got_mainhdr: if h.flags & RAR_MAIN_NEWNUMBERING: self.uses_newnumbering = 1 self._gen_volname = self._gen_newvol self.uses_volumes = h.flags & RAR_MAIN_VOLUME self.is_solid = h.flags & RAR_MAIN_SOLID self.got_mainhdr = 1 if h.flags & RAR_MAIN_PASSWORD: self.encrypted = 1 elif h.type == RAR_BLOCK_ENDARC: more_vols = h.flags & RAR_ENDARC_NEXT_VOLUME # store it self._process_entry(h) # skip data if h.add_size > 0: fd.seek(h.add_size, 1) def _parse_header(self, fd): h = self._parse_block_header(fd) if h and (h.type == RAR_BLOCK_FILE or h.type == RAR_BLOCK_SUB): self._parse_file_header(h) return h # common header def _parse_block_header(self, fd): HDRLEN = 7 h = RarInfo() h.header_offset = fd.tell() buf = fd.read(HDRLEN) if not buf or len(buf) < HDRLEN: return None t = unpack(" HDRLEN: h.data = fd.read(h.header_size - HDRLEN) else: h.data = "" h.file_offset = fd.tell() if h.flags & RAR_LONG_BLOCK: h.add_size = unpack("> 5 min = stamp & 0x3F; stamp = stamp >> 6 hr = stamp & 0x1F; stamp = stamp >> 5 day = stamp & 0x1F; stamp = stamp >> 5 mon = stamp & 0x0F; stamp = stamp >> 4 yr = (stamp & 0x7F) + 1980 return (yr, mon, day, hr, min, sec) # new-style volume name def _gen_newvol(self, volume): # allow % in filenames fn = self.rarfile.replace("%", "%%") m = re.search(r"([0-9][0-9]*)[^0-9]*$", fn) if not m: raise Exception("Cannot construct volume name") n1 = m.start(1) n2 = m.end(1) fmt = "%%0%dd" % (n2 - n1) volfmt = fn[:n1] + fmt + fn[n2:] return volfmt % (volume + 1) # old-style volume naming def _gen_oldvol(self, volume): if volume == 0: return self.rarfile i = self.rarfile.rfind(".") base = self.rarfile[:i] if volume <= 100: ext = ".r%02d" % (volume - 1) else: ext = ".s%02d" % (volume - 101) return base + ext # read uncompressed file def _extract_clear(self, inf): volume = inf.volume buf = "" cur = None while 1: f = open(self._gen_volname(volume), "rb") if not cur: f.seek(inf.header_offset) while 1: cur = self._parse_header(f) if cur.type in (RAR_BLOCK_MARK, RAR_BLOCK_MAIN): if cur.add_size: f.seek(cur.add_size, 1) continue if cur.filename == inf.filename: buf += f.read(cur.add_size) break raise Exception("file not found?") # no more parts? if (cur.flags & RAR_FILE_SPLIT_AFTER) == 0: break volume += 1 return buf # put file compressed data into temporary .rar archive, and run # unrar on that, thus avoiding unrar going over whole archive def _extract_hack(self, inf): BSIZE = 32*1024 size = inf.compress_size + inf.header_size rf = open(self.rarfile, "rb") rf.seek(inf.header_offset) tmpf, tmpname = tempfile.mkstemp(suffix='.rar', text=False) # create main header: crc, type, flags, size, res1, res2 mh = pack(" 0: if size > BSIZE: buf = rf.read(BSIZE) else: buf = rf.read(size) os.write(tmpf, buf) size -= len(buf) os.close(tmpf) buf = self._extract_unrar(tmpname, inf) os.unlink(tmpname) return buf # extract using unrar def _extract_unrar(self, rarfile, inf): fn = inf.filename if sabnzbd.WIN32: # Windows unrar wants '\', not '/' fn = fn.replace("/", "\\") else: # shell escapes for Unix/OSX fn = fn.replace("`", "\\`") fn = fn.replace('"', '\\"') fn = fn.replace("$", "\\$") err, buf = sabnzbd.SimpleRarExtract(rarfile, fn) if err > 0: raise Exception("Error reading file") return buf class _UnicodeFilename: def __init__(self, name, encdata): self.std_name = name self.encdata = encdata self.pos = self.encpos = 0 self.buf = StringIO() def enc_byte(self): c = self.encdata[self.encpos] self.encpos += 1 return ord(c) def std_byte(self): return ord(self.std_name[self.pos]) def put(self, lo, hi): self.buf.write(chr(lo) + chr(hi)) self.pos += 1 def decode(self): hi = self.enc_byte() flagbits = 0 while self.encpos < len(self.encdata): if flagbits == 0: flags = self.enc_byte() flagbits = 8 flagbits -= 2 t = (flags >> flagbits) & 3 if t == 0: self.put(self.enc_byte(), 0) elif t == 1: self.put(self.enc_byte(), hi) elif t == 2: self.put(self.enc_byte(), self.enc_byte()) else: n = self.enc_byte() if n & 0x80: c = self.enc_byte() for i in range((n & 0x7f) + 2): lo = (self.std_byte() + c) & 0xFF self.put(lo, hi) else: for i in range(n + 2): self.put(self.std_byte(), 0) return self.buf.getvalue().decode("utf-16le", "replace") SABnzbd-0.7.20/sabnzbd/utils/rsslib.py0000644000000000000000000002646512433712602017675 0ustar00usergroup00000000000000#"""RSS 2.0 Generator # #This library encapsulates the generation of an RSS (2.0) feed # # #You may freely use this code in any way you can think of. #""" import xml.sax.saxutils #------------------------------------------------------------------------------ def encode_for_xml(unicode_data, encoding='ascii'): """ Encode unicode_data for use as XML or HTML, with characters outside of the encoding converted to XML numeric character references. """ try: return unicode_data.encode(encoding, 'xmlcharrefreplace') except ValueError: # ValueError is raised if there are unencodable chars in the # data and the 'xmlcharrefreplace' error handler is not found. # Pre-2.3 Python doesn't support the 'xmlcharrefreplace' error # handler, so we'll emulate it. return _xmlcharref_encode(unicode_data, encoding) def _xmlcharref_encode(unicode_data, encoding): """Emulate Python 2.3's 'xmlcharrefreplace' encoding error handler.""" chars = [] # Step through the unicode_data string one character at a time in # order to catch unencodable characters: for char in unicode_data: try: chars.append(char.encode(encoding, 'strict')) except UnicodeError: chars.append('&#%i;' % ord(char)) return ''.join(chars) class RSS: # """ # RSS # # This class encapsulates the creation of an RSS 2.0 feed # # The RSS2.0 spec can be found here: # http://blogs.law.harvard.edu/tech/rss # # # RSS validator : http://rss.scripting.com # # # The generation of an RSS feed is simple, the following is a # sample: # from rsslib import RSS, Item, Namespace # rss = RSS() # rss.channel.link = "http://channel.com" # rss.channel.title = "my channel title" # rss.channel.description = "my channel description" # # ns = Namespace( "foobar", "http://foobar.baz" ) # rss.channel.namespaces.append( ns ) # # item = Item() # item.link = "http://link.com" # item.description = "my link description" # item.title ="my item title" # item.nsItems[ns.name + ":foo"] = "bar" # rss.channel.items.append( item ) # # item = Item() # item.link = "http://link2.com" # item.description = "my link2 description" # item.title ="my item2 title" # item.nsItems[ns.name +":foo"] = "foo bar baz" # rss.channel.items.append( item ) # # print rss.write() # # output: # # # # my channel title # http://channel.com # my channel description # # my item title # http://link.com # my link description # bar # # # my item2 title # http://link2.com # my link2 description # foo bar baz # # # # # # author: cmallory /a t/ berserk /dot/ o r g # """ def __init__(self): self.channel = Channel() self.version = "2.0" self.contents = None # if __name__ == "__main__" : # from rsslib import RSS, Item, Namespace # rss = RSS() # rss.channel.link = "http://channel.com" # rss.channel.title = "my channel title" # rss.channel.description = "my channel description" # # ns = Namespace( "foobar", "http://foobar.baz" ) # rss.addNamespace( ns ) # # item = Item() # item.link = "http://link.com" # item.description = "my link description" # item.title ="my item title" # # item.enclosure.url = "http://enclosure.url.com" # item.enclosure.length = 12345 # item.enclosure.type = "audio/mpeg" # # item.nsItems[ns.name + ":foo"] = "bar" # rss.addItem( item ) # # item = Item() # item.link = "http://link2.com" # item.description = "my link2 description" # item.title ="my item2 title" # item.nsItems[ns.name +":foo"] = "foo bar baz" # rss.addItem( item ) # # print rss.write() #Write out the rss document def write( self ): self.contents = "\n" #contents += "\n" self.contents += " element def generateChannel( self ): contents = "" if ( self.channel.initialized() ): contents += "\n" contents += self.optionalWrite("title", self.channel.title ); contents += self.optionalWrite("link", self.channel.link ); contents += self.optionalWrite("description", self.channel.description ); contents += self.optionalWrite("language", self.channel.language ); contents += self.optionalWrite("copyright", self.channel.copyright ); contents += self.optionalWrite("category", self.channel.category ); contents += self.optionalWrite("managingEditor", self.channel.managingEditor ); contents += self.optionalWrite("webMaster", self.channel.webMaster ); contents += self.optionalWrite("pubDate", self.channel.pubDate ); contents += self.optionalWrite("lastBuildDate", self.channel.lastBuildDate ); contents += self.optionalWrite("docs", self.channel.docs ); contents += self.optionalWrite("cloud", self.channel.cloud ); contents += self.optionalWrite("ttl", self.channel.ttl ); contents += self.optionalWrite("generator", self.channel.generator ); contents += self.optionalWrite("image", self.channel.image ); contents += self.optionalWrite("rating", self.channel.rating ); contents += self.optionalWrite("textInput", self.channel.textInput ); contents += self.optionalWrite("skipHours", self.channel.skipHours ); contents += self.optionalWrite("skipDays", self.channel.skipDays ); contents += "\n" + self.generateItems() + "\n" else : contents = "[Channel not properly initialized. " contents +="A required field is not set.(title/link/description]" return contents #Generates all items within a channel def generateItems( self ): c = "" for i in self.channel.items : c += "" c += self.optionalWrite("title", i.title); c += self.optionalWrite("link", i.link ); c += self.optionalWrite("description", i.description); c += self.optionalWrite("author", i.author ); c += self.optionalWrite("pubDate", str(i.pubDate) ) c += self.optionalWrite("category", i.category ) c += self.optionalWrite("comments", i.comments ) c += self.optionalWrite("guid", i.guid ) c += self.optionalWrite("source", i.source ) if ( i.enclosure.url != "" ): c+= "\n" for k in i.nsItems.keys(): c += self.optionalWrite( k , i.nsItems[ k ] ) c += "\n\n" return c def addNamespace( self, ns ): if ( self.channel.namespaces is not None ): self.channel.namespaces.append( ns ) def addItem( self, item ): if ( self.channel is not None): self.channel.items.append( item ) def optionalWrite( self, key, val ): if ( val is not None and val != "" ): return "<" + key + ">" + encode_for_xml(xml.sax.saxutils.escape(val)) + "\n" else: return "" #Namespace class Namespace: def __init__( self, name, url ): self.url = url self.name = name class Channel: # """ # Channel # # (http://blogs.law.harvard.edu/tech/rss) # # This object represents an RSS channel (as of ver2.0) # """ def __init__( self ): # # Required Fields # self.title= None self.link= None self.description= None # # Optional Fields # self.language = "" self.copyright = "" self.managingEditor = "" self.webMaster = "" self.pubDate = "" self.lastBuildDate = "" self.category = "" self.generator = "" self.docs = "" self.cloud = "" self.ttl = "" self.image = "" self.rating = "" self.textInput = "" self.skipHours = "" self.skipDays = "" self.items = [] self.namespaces = [] def initialized( self ): return self.title is not None and self.link is not None and self.description is not None class Item: # """ # Item # # http://blogs.law.harvard.edu/tech/rss#hrelementsOfLtitemgt # # A channel may contain any number of <item>s. An item may # represent a "story" -- much like a story in a newspaper or magazine; # if so its description is a synopsis of the story, and the link # points to the full story. An item may also be complete in itself, # if so, the description contains the text (entity-encoded HTML is # allowed; see examples), and the link and title may be omitted. # All elements of an item are optional, however at least one of # title or description must be present. # """ def __init__( self ): self.title = "" self.link = "" self.description = "" self.author = "" self.category = "" self.comments = "" self.enclosure = "" self.guid = "" self.pubDate = "" self.source = "" self.enclosure = Enclosure() self.nsItems = {} class Enclosure: # """ # Enclosure # # sub-element of # # is an optional sub-element of . # # It has three required attributes: # # url: says where the enclosure is located, # length: says how big it is in bytes, and # type: says what its type is, a standard MIME type. # # The url must be an http url. # # Example: # # """ def __init__(self): self.url = "" self.length = 0 self.type = "" SABnzbd-0.7.20/sabnzbd/utils/servertests.py0000644000000000000000000001134612433712602020760 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.utils.servertests - Debugging server connections. Currently only NNTP server tests are done. """ import socket import sys from sabnzbd.newswrapper import NewsWrapper from sabnzbd.downloader import Server, clues_login, clues_too_many from sabnzbd.config import get_servers from sabnzbd.encoding import xml_name from sabnzbd.misc import int_conv def test_nntp_server_dict(kwargs): # Grab the host/port/user/pass/connections/ssl host = kwargs.get('host', '').strip() if not host: return False, T('The hostname is not set.') username = kwargs.get('username', '').strip() password = kwargs.get('password', '').strip() server = kwargs.get('server', '').strip() connections = int_conv(kwargs.get('connections', 0)) if not connections: return False, T('There are no connections set. Please set at least one connection.') ssl = int_conv(kwargs.get('ssl', 0)) port = int_conv(kwargs.get('port', 0)) if not port: if ssl: port = 563 else: port = 119 return test_nntp_server(host, port, server, username=username, \ password=password, ssl=ssl) def test_nntp_server(host, port, server=None, username=None, password=None, ssl=None): ''' Will connect (blocking) to the nttp server and report back any errors ''' timeout = 4.0 if '*' in password and not password.strip('*'): # If the password is masked, try retrieving it from the config if not server: servers = get_servers() got_pass = False for server in servers: if host in server: srv = servers[server] password = srv.password() got_pass = True else: srv = get_servers().get(server) if srv: password = srv.password() got_pass = True if not got_pass: return False, T('Password masked in ******, please re-enter') try: s = Server(-1, host, port, timeout, 0, 0, ssl, username, password) except: return False, T('Invalid server details') try: nw = NewsWrapper(s, -1, block=True) nw.init_connect(None) while not nw.connected: nw.lines = [] nw.recv_chunk(block=True) nw.finish_connect(nw.lines[0][:3]) except socket.timeout, e: if port != 119 and not ssl: return False, T('Timed out: Try enabling SSL or connecting on a different port.') else: return False, T('Timed out') except socket.error, e: return False, xml_name(str(e)) except TypeError, e: return False, xml_name(T('Invalid server address.')) except IndexError: # No data was received in recv_chunk() call return False, xml_name(T('Server quit during login sequence.')) except: return False, xml_name(str(sys.exc_info()[1])) if not username or not password: nw.nntp.sock.sendall('ARTICLE \r\n') try: nw.lines = [] nw.recv_chunk(block=True) except: return False, xml_name(str(sys.exc_info()[1])) # Could do with making a function for return codes to be used by downloader try: code = nw.lines[0][:3] except IndexError: code = '' nw.lines.append('') if code == '480': return False, T('Server requires username and password.') elif code == '100' or code.startswith('2') or code.startswith('4'): return True, T('Connection Successful!') elif code == '502' or clues_login(nw.lines[0]): return False, T('Authentication failed, check username/password.') elif clues_too_many(nw.lines[0]): return False, T('Too many connections, please pause downloading or try again later') else: return False, T('Could not determine connection result (%s)') % xml_name(nw.lines[0]) # Close the connection nw.terminate(quit=True) SABnzbd-0.7.20/sabnzbd/utils/ssmtplib.py0000644000000000000000000001331112433712602020216 0ustar00usergroup00000000000000"""SMTP over SSL client. Public class: SMTP_SSL Public errors: SMTPSSLException """ # Author: Matt Butcher , Feb. 2007 # License: MIT License (or, at your option, the GPL, v.2 or later as posted at # http://gnu.org). ## ## Begin License # # Copyright (c) 2007 M Butcher # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. ## ##End License # # This is just a minor modification to the smtplib code by Dragon De Monsyn. import smtplib, socket __version__ = "1.00" __all__ = ['SMTPSSLException', 'SMTP_SSL'] SSMTP_PORT = 465 class SMTPSSLException(smtplib.SMTPException): """Base class for exceptions resulting from SSL negotiation.""" class SMTP_SSL (smtplib.SMTP): """This class provides SSL access to an SMTP server. SMTP over SSL typical listens on port 465. Unlike StartTLS, SMTP over SSL makes an SSL connection before doing a helo/ehlo. All transactions, then, are done over an encrypted channel. This class is a simple subclass of the smtplib.SMTP class that comes with Python. It overrides the connect() method to use an SSL socket, and it overrides the starttles() function to throw an error (you can't do starttls within an SSL session). """ certfile = None keyfile = None def __init__(self, host='', port=0, local_hostname=None, keyfile=None, certfile=None): """Initialize a new SSL SMTP object. If specified, `host' is the name of the remote host to which this object will connect. If specified, `port' specifies the port (on `host') to which this object will connect. `local_hostname' is the name of the localhost. By default, the value of socket.getfqdn() is used. An SMTPConnectError is raised if the SMTP host does not respond correctly. An SMTPSSLError is raised if SSL negotiation fails. Warning: This object uses socket.ssl(), which does not do client-side verification of the server's cert. """ self.certfile = certfile self.keyfile = keyfile smtplib.SMTP.__init__(self, host, port, local_hostname) def connect(self, host='localhost', port=0): """Connect to an SMTP server using SSL. `host' is localhost by default. Port will be set to 465 (the default SSL SMTP port) if no port is specified. If the host name ends with a colon (`:') followed by a number, that suffix will be stripped off and the number interpreted as the port number to use. This will override the `port' parameter. Note: This method is automatically invoked by __init__, if a host is specified during instantiation. """ # MB: Most of this (Except for the socket connection code) is from # the SMTP.connect() method. I changed only the bare minimum for the # sake of compatibility. if not port and (host.find(':') == host.rfind(':')): i = host.rfind(':') if i >= 0: host, port = host[:i], host[i+1:] try: port = int(port) except ValueError: raise socket.error, "nonnumeric port" if not port: port = SSMTP_PORT if self.debuglevel > 0: print>>stderr, 'connect:', (host, port) msg = "getaddrinfo returns an empty list" self.sock = None for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM): af, socktype, proto, canonname, sa = res try: self.sock = socket.socket(af, socktype, proto) if self.debuglevel > 0: print>>stderr, 'connect:', (host, port) self.sock.connect(sa) # MB: Make the SSL connection. sslobj = socket.ssl(self.sock, self.keyfile, self.certfile) except socket.error, msg: if self.debuglevel > 0: print>>stderr, 'connect fail:', (host, port) if self.sock: self.sock.close() self.sock = None continue break if not self.sock: raise socket.error, msg # MB: Now set up fake socket and fake file classes. # Thanks to the design of smtplib, this is all we need to do # to get SSL working with all other methods. self.sock = smtplib.SSLFakeSocket(self.sock, sslobj) self.file = smtplib.SSLFakeFile(sslobj); (code, msg) = self.getreply() if self.debuglevel > 0: print>>stderr, "connect:", msg return (code, msg) def setkeyfile(self, keyfile): """Set the absolute path to a file containing a private key. This method will only be effective if it is called before connect(). This key will be used to make the SSL connection.""" self.keyfile = keyfile def setcertfile(self, certfile): """Set the absolute path to a file containing a x.509 certificate. This method will only be effective if it is called before connect(). This certificate will be used to make the SSL connection.""" self.certfile = certfile def starttls(self, keyfile = None, certfile = None): """Raises an exception. You cannot do StartTLS inside of an ssl session. Calling starttls() will return an SMTPSSLException""" raise SMTPSSLException, "Cannot perform StartTLS within SSL session." SABnzbd-0.7.20/sabnzbd/utils/systrayiconthread.py0000644000000000000000000002333712433712602022151 0ustar00usergroup00000000000000#!/usr/bin/env python # based on SysTrayIcon.py by Simon Brunning - simon@brunningonline.net # http://www.brunningonline.net/simon/blog/archives/001835.html # http://www.brunningonline.net/simon/blog/archives/SysTrayIcon.py.html # modified on 2011-10-04 by Jan Schejbal to support threading and preload icons # override doUpdates to perform actions inside the icon thread import os import sys import pywintypes import win32api import win32con import win32gui_struct try: import winxpgui as win32gui except ImportError: import win32gui from threading import Thread from time import sleep class SysTrayIconThread(Thread): '''TODO''' QUIT = 'QUIT' SPECIAL_ACTIONS = [QUIT] FIRST_ID = 1023 terminate = False def __init__(self, icon, hover_text, menu_options, on_quit=None, default_menu_index=None, window_class_name=None,): Thread.__init__(self) self.icon = icon self.icons = {} self.hover_text = hover_text self.on_quit = on_quit # menu_options = menu_options + (('Quit', None, self.QUIT),) self._next_action_id = self.FIRST_ID self.menu_actions_by_id = set() self.menu_options = self._add_ids_to_menu_options(list(menu_options)) self.menu_actions_by_id = dict(self.menu_actions_by_id) del self._next_action_id self.default_menu_index = (default_menu_index or 0) self.window_class_name = window_class_name or "SysTrayIconPy" self.start() def initialize(self): message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart, win32con.WM_DESTROY: self.destroy, win32con.WM_COMMAND: self.command, win32con.WM_USER+20 : self.notify,} # Register the Window class. window_class = win32gui.WNDCLASS() hinst = window_class.hInstance = win32gui.GetModuleHandle(None) window_class.lpszClassName = self.window_class_name window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW; window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) window_class.hbrBackground = win32con.COLOR_WINDOW window_class.lpfnWndProc = message_map # could also specify a wndproc. classAtom = win32gui.RegisterClass(window_class) # Create the Window. style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU self.hwnd = win32gui.CreateWindow(classAtom, self.window_class_name, style, 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, 0, 0, hinst, None) win32gui.UpdateWindow(self.hwnd) self.notify_id = None self.refresh_icon() def run(self): self.initialize() while not self.terminate: win32gui.PumpWaitingMessages() self.doUpdates() sleep(0.100) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, (self.hwnd, 0)) # override this def doUpdates(self): pass def _add_ids_to_menu_options(self, menu_options): result = [] for menu_option in menu_options: option_text, option_icon, option_action = menu_option if callable(option_action) or option_action in self.SPECIAL_ACTIONS: self.menu_actions_by_id.add((self._next_action_id, option_action)) result.append(menu_option + (self._next_action_id,)) elif non_string_iterable(option_action): result.append((option_text, option_icon, self._add_ids_to_menu_options(option_action), self._next_action_id)) else: print 'Unknown item', option_text, option_icon, option_action self._next_action_id += 1 return result def get_icon(self, path): hicon = self.icons.get(path); if hicon != None: return hicon # Try and find a custom icon hinst = win32gui.GetModuleHandle(None) if os.path.isfile(path): icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE hicon = win32gui.LoadImage(hinst, path, win32con.IMAGE_ICON, 0, 0, icon_flags) else: print "Can't find icon file - using default." hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION) self.icons[path] = hicon return hicon def refresh_icon(self): hicon = self.get_icon(self.icon) if self.notify_id: message = win32gui.NIM_MODIFY else: message = win32gui.NIM_ADD self.notify_id = (self.hwnd, 0, win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, win32con.WM_USER+20, hicon, self.hover_text) try: win32gui.Shell_NotifyIcon(message, self.notify_id) except: # Timeouts can occur after system comes out of standby/hibernate pass def restart(self, hwnd, msg, wparam, lparam): self.refresh_icon() def destroy(self, hwnd, msg, wparam, lparam): if self.on_quit: self.on_quit(self) nid = (self.hwnd, 0) win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid) win32gui.PostQuitMessage(0) # Terminate the app. def notify(self, hwnd, msg, wparam, lparam): if lparam==win32con.WM_LBUTTONDBLCLK: self.execute_menu_option(self.default_menu_index + self.FIRST_ID) elif lparam==win32con.WM_RBUTTONUP: self.show_menu() elif lparam==win32con.WM_LBUTTONUP: pass return True def show_menu(self): menu = win32gui.CreatePopupMenu() self.create_menu(menu, self.menu_options) #win32gui.SetMenuDefaultItem(menu, 1000, 0) try: pos = win32gui.GetCursorPos() # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp win32gui.SetForegroundWindow(self.hwnd) win32gui.TrackPopupMenu(menu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None) win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0) except pywintypes.error: # Weird PyWin/win32gui bug, just ignore it for now logging.debug('win32gui problem, cannot show SysTray menu') def create_menu(self, menu, menu_options): for option_text, option_icon, option_action, option_id in menu_options[::-1]: if option_icon: option_icon = self.prep_menu_icon(option_icon) if option_id in self.menu_actions_by_id: item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text, hbmpItem=option_icon, wID=option_id) win32gui.InsertMenuItem(menu, 0, 1, item) else: submenu = win32gui.CreatePopupMenu() self.create_menu(submenu, option_action) item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text, hbmpItem=option_icon, hSubMenu=submenu) win32gui.InsertMenuItem(menu, 0, 1, item) def prep_menu_icon(self, icon): # First load the icon. ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON) ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON) hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE) hdcBitmap = win32gui.CreateCompatibleDC(0) hdcScreen = win32gui.GetDC(0) hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y) hbmOld = win32gui.SelectObject(hdcBitmap, hbm) # Fill the background. brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU) win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush) # unclear if brush needs to be feed. Best clue I can find is: # "GetSysColorBrush returns a cached brush instead of allocating a new # one." - implies no DeleteObject # draw the icon win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL) win32gui.SelectObject(hdcBitmap, hbmOld) win32gui.DeleteDC(hdcBitmap) return hbm def command(self, hwnd, msg, wparam, lparam): id = win32gui.LOWORD(wparam) self.execute_menu_option(id) def execute_menu_option(self, id): menu_action = self.menu_actions_by_id[id] if menu_action == self.QUIT: win32gui.DestroyWindow(self.hwnd) else: menu_action(self) def non_string_iterable(obj): try: iter(obj) except TypeError: return False else: return not isinstance(obj, basestring) SABnzbd-0.7.20/sabnzbd/utils/upload.py0000644000000000000000000000456312433712602017656 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2009-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.utils.upload - File assosiation functions for adding nzb files to sabnzbd """ import urllib2 import urllib import logging import os import sabnzbd.cfg as cfg from sabnzbd.misc import get_ext, get_filename import sabnzbd.newsunpack from sabnzbd.dirscanner import ProcessArchiveFile, ProcessSingleFile def upload_file(url, fp): """ Function for uploading nzbs to a running sabnzbd instance """ try: fp = urllib.quote_plus(fp) url = '%s&mode=addlocalfile&name=%s' % (url, fp) # Add local apikey if it wasn't already in the registered URL apikey = cfg.api_key() if apikey and 'apikey' not in url: url = '%s&apikey=%s' % (url, apikey) if 'apikey' not in url: # Use alternative login method username = cfg.username() password = cfg.password() if username and password: url = '%s&ma_username=%s&ma_password=%s' % (url, username, password) sabnzbd.newsunpack.get_from_url(url) except: logging.error("Failed to upload file: %s", fp) logging.info("Traceback: ", exc_info = True) def add_local(f): """ Function for easily adding nzb/zip/rar/nzb.gz to sabnzbd """ if os.path.exists(f): fn = get_filename(f) if fn: if get_ext(fn) in ('.zip', '.rar'): ProcessArchiveFile(fn, f, keep=True) elif get_ext(fn) in ('.nzb', '.gz'): ProcessSingleFile(fn, f, keep=True) else: logging.error("Filename not found: %s", f) else: logging.error("File not found: %s", f)SABnzbd-0.7.20/sabnzbd/utils/__init__.py0000644000000000000000000000001612433712602020116 0ustar00usergroup00000000000000# __init__.py SABnzbd-0.7.20/solaris/manifest.xml0000644000000000000000000000334412433712557017246 0ustar00usergroup00000000000000 SABnzbd-0.7.20/tools/make_mo.py0000755000000000000000000002705612433712602016364 0ustar00usergroup00000000000000#!/usr/bin/python -OO # -*- coding: utf-8 -*- # Copyright 2010-2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Compile PO files to MO files import glob import os import re import sys import gettext TOOL = 'msgfmt' PO_DIR = 'po/main' POE_DIR = 'po/email' PON_DIR = 'po/nsis' MO_DIR = 'locale' EMAIL_DIR = 'email' MO_LOCALE = '/LC_MESSAGES' DOMAIN = 'SABnzbd' DOMAIN_E = 'SABemail' DOMAIN_N = 'SABnsis' LANG_MARKER = 'language.txt' NSIS= 'NSIS_Installer.nsi' LanguageTable = { 'aa' : ('Afar', 'Afaraf'), 'af' : ('Afrikaans', 'Afrikaans'), 'ak' : ('Akan', 'Akan'), 'sq' : ('Albanian', 'Shqip'), 'an' : ('Aragonese', 'Aragonés'), 'ae' : ('Avestan', 'Avesta'), 'ay' : ('Aymara', 'Aymararu'), 'bm' : ('Bambara', 'Bamanankan'), 'eu' : ('Basque', 'Euskara'), 'bi' : ('Bislama', 'Bislama'), 'bs' : ('Bosnian', 'Bosanskijezik'), 'br' : ('Breton', 'Brezhoneg'), 'ca' : ('Catalan', 'Català'), 'ch' : ('Chamorro', 'Chamoru'), 'kw' : ('Cornish', 'Kernewek'), 'co' : ('Corsican', 'Corsu'), 'hr' : ('Croatian', 'Hrvatski'), 'cs' : ('Czech', 'Cesky, ceština'), 'da' : ('Danish', 'Dansk'), 'nl' : ('Dutch', 'Nederlands'), 'en' : ('English', 'English'), 'eo' : ('Esperanto', 'Esperanto'), 'et' : ('Estonian', 'Eesti'), 'fo' : ('Faroese', 'Føroyskt'), 'fj' : ('Fijian', 'Vosa Vakaviti'), 'fi' : ('Finnish', 'Suomi'), 'fr' : ('French', 'Français'), 'gl' : ('Galician', 'Galego'), 'de' : ('German', 'Deutsch'), 'hz' : ('Herero', 'Otjiherero'), 'ho' : ('Hiri Motu', 'Hiri Motu'), 'hu' : ('Hungarian', 'Magyar'), 'id' : ('Indonesian', 'Bahasa Indonesia'), 'ga' : ('Irish', 'Gaeilge'), 'io' : ('Ido', 'Ido'), 'is' : ('Icelandic', 'Íslenska'), 'it' : ('Italian', 'Italiano'), 'jv' : ('Javanese', 'BasaJawa'), 'rw' : ('Kinyarwanda', 'Ikinyarwanda'), 'kg' : ('Kongo', 'KiKongo'), 'kj' : ('Kwanyama', 'Kuanyama'), 'la' : ('Latin', 'Lingua latina'), 'lb' : ('Luxembourgish', 'Lëtzebuergesch'), 'lg' : ('Luganda', 'Luganda'), 'li' : ('Limburgish', 'Limburgs'), 'ln' : ('Lingala', 'Lingála'), 'lt' : ('Lithuanian', 'Lietuviukalba'), 'lv' : ('Latvian', 'Latviešuvaloda'), 'gv' : ('Manx', 'Gaelg'), 'mg' : ('Malagasy', 'Malagasy fiteny'), 'mt' : ('Maltese', 'Malti'), 'nb' : ('Norwegian', 'Norsk'), # Bokmål 'nn' : ('Norwegian', 'Norsk'), # Nynorsk 'no' : ('Norwegian', 'Norsk'), 'oc' : ('Occitan', 'Occitan'), 'om' : ('Oromo', 'Afaan Oromoo'), 'pl' : ('Polish', 'Polski'), 'pt' : ('Portuguese', 'Português'), 'pt_BR' : ('PortugueseBR', 'Português, Brasil'), # NSIS uses "PortugueseBR" 'rm' : ('Romansh', 'Rumantsch grischun'), 'rn' : ('Kirundi', 'kiRundi'), 'ro' : ('Romanian', 'Româna'), 'sc' : ('Sardinian', 'Sardu'), 'se' : ('Northern Sami', 'Davvisámegiella'), 'sm' : ('Samoan', 'Gagana fa\'a Samoa'), 'gd' : ('Gaelic', 'Gàidhlig'), 'sn' : ('Shona', 'Chi Shona'), 'sk' : ('Slovak', 'Slovencina'), 'sl' : ('Slovene', 'Slovenšcina'), 'st' : ('Southern Sotho', 'Sesotho'), 'es' : ('Spanish', 'Español, castellano'), # NSIS cannot handle "Spanish Castilian" 'su' : ('Sundanese', 'Basa Sunda'), 'sw' : ('Swahili', 'Kiswahili'), 'ss' : ('Swati', 'SiSwati'), 'sv' : ('Swedish', 'Svenska'), 'tn' : ('Tswana', 'Setswana'), 'to' : ('Tonga (Tonga Islands)', 'faka Tonga'), 'tr' : ('Turkish', 'Türkçe'), 'ts' : ('Tsonga', 'Xitsonga'), 'tw' : ('Twi', 'Twi'), 'ty' : ('Tahitian', 'Reo Tahiti'), 'wa' : ('Walloon', 'Walon'), 'cy' : ('Welsh', 'Cymraeg'), 'wo' : ('Wolof', 'Wollof'), 'fy' : ('Western Frisian', 'Frysk'), 'xh' : ('Xhosa', 'isi Xhosa'), 'yo' : ('Yoruba', 'Yorùbá'), 'zu' : ('Zulu', 'isi Zulu'), } # Filter for retrieving readable language from PO file RE_LANG = re.compile(r'"Language-Description:\s([^"]+)\\n') def process_po_folder(domain, folder, extra=''): """ Process each PO file in folder """ for fname in glob.glob(os.path.join(folder, '*.po')): podir, basename = os.path.split(fname) name, ext = os.path.splitext(basename) mo_path = os.path.normpath('%s/%s%s' % (MO_DIR, name, MO_LOCALE)) mo_name = '%s.mo' % domain if not os.path.exists(mo_path): os.makedirs(mo_path) # Create the MO file mo_file = os.path.join(mo_path, mo_name) print 'Compile %s' % mo_file ret = os.system('%s %s -o "%s" "%s"' % (TOOL, extra, mo_file, fname)) if ret != 0: print '\nMissing %s. Please install this package first.' % TOOL exit(1) def remove_mo_files(): """ Remove MO files in locale """ for root, dirs, files in os.walk(MO_DIR, topdown=False): for f in files: if not f.startswith(DOMAIN): os.remove(os.path.join(root, f)) def translate_tmpl(prefix, lng): """ Translate template 'prefix' into language 'lng' """ src = open(EMAIL_DIR + '/%s-en.tmpl' % prefix, 'r') data = src.read().decode('utf-8') src.close() data = _(data).encode('utf-8') fp = open('email/%s-%s.tmpl' % (prefix, lng), 'wb') if not (-1 < data.find('UTF-8') < 30): fp.write('#encoding UTF-8\n') fp.write(data) fp.close() def make_templates(): """ Create email templates """ if not os.path.exists('email'): os.makedirs('email') for path in glob.glob(os.path.join(MO_DIR, '*')): lng = os.path.split(path)[1] if lng != 'en': print 'Create email template for %s' % lng trans = gettext.translation(DOMAIN_E, MO_DIR, [lng], fallback=False, codeset='latin-1') # The unicode flag will make _() return Unicode trans.install(unicode=True, names=['lgettext']) translate_tmpl('email', lng) translate_tmpl('rss', lng) translate_tmpl('badfetch', lng) mo_path = os.path.normpath('%s/%s%s/%s.mo' % (MO_DIR, path, MO_LOCALE, DOMAIN_E)) if os.path.exists(mo_path): os.remove(mo_path) # Convert Romanian PX files to Latin1 PO files ro_table = { u"\u015f" : u"s", # ș u"\u015e" : u"S", # Ș u"\u0163" : u"t", # ț u"\u0162" : u"T", # Ț u"\u0103" : u"ã", # ă u"\u0102" : u"Ã", # Ă u'\u021b' : u"t", # ț u'\u0218' : u"S", # Ș u'\u0219' : u"s" # ș } # Convert Polish PX files to Latin1 PO files pl_table = { u"\u0104" : u"A", # Ą u"\u0106" : u"C", # Ć u"\u0118" : u"E", # Ę u"\u0141" : u"L", # Ł u"\u013B" : u"L", # Ł u"\u0143" : u"N", # Ń #u"\u00D3" : u"O", # Ó u"\u015A" : u"S", # Ś u"\u0179" : u"Z", # Ź u"\u017B" : u"Z", # Ż u"\u0105" : u"a", # ą u"\u0107" : u"c", # ć u"\u0119" : u"e", # ę u"\u0142" : u"l", # ł u"\u0144" : u"n", # ń #u"\u00F3" : u"o", # ó u"\u015B" : u"s", # ś u"\u017A" : u"z", # ź u"\u017C" : u"z" # ż } def fix_ro(): """ Convert ro.px files to ro.po files with only Latin1 """ for section in ('main', 'email', 'nsis'): f = open('po/%s/ro.px' % section, 'rb') data = f.read().decode('utf-8') f.close() for ch in ro_table: data = data.replace(ch, ro_table[ch]) f = open('po/%s/ro.po' % section, 'wb') f.write(data.encode('utf-8')) f.close() try: lnum = 0 for line in data.split('\n'): lnum += 1 line.encode('latin-1') except: print line.encode('utf-8') print 'WARNING: line %d in file po/%s/ro.po is not Latin-1' % (lnum, section) exit(1) def fix_pl(): """ Convert pl.px files to pl.po files with only Latin1 """ for section in ('main', 'email', 'nsis'): f = open('po/%s/pl.px' % section, 'rb') data = f.read().decode('utf-8') f.close() for ch in pl_table: data = data.replace(ch, pl_table[ch]) f = open('po/%s/pl.po' % section, 'wb') f.write(data.encode('utf-8')) f.close() try: lnum = 0 for line in data.split('\n'): lnum += 1 line.encode('latin-1') except: print line.encode('utf-8') print 'WARNING: line %d in file po/%s/pl.po is not Latin-1' % (lnum, section) exit(1) def patch_nsis(): """ Patch translation into the NSIS script """ RE_NSIS = re.compile(r'^(\s*LangString\s+\w+\s+\$\{LANG_)(\w+)\}\s+(".*)', re.I) languages = [os.path.split(path)[1] for path in glob.glob(os.path.join(MO_DIR, '*'))] src = open(NSIS, 'r') new = [] for line in src: m = RE_NSIS.search(line) if m: leader = m.group(1) langname = m.group(2).upper() text = m.group(3).strip('"\n') if langname == 'ENGLISH': # Write back old content new.append(line) # Replace silly $\ construction with just a \ text = text.replace('$\\"', '"').replace('$\\', '\\') for lcode in languages: lng = LanguageTable.get(lcode) if lng and lcode != 'en': lng = lng[0].decode('utf-8').encode('latin-1').upper() trans = gettext.translation(DOMAIN_N, MO_DIR, [lcode], fallback=False, codeset='latin-1') # The unicode flag will make _() return Unicode trans.install(unicode=True, names=['lgettext']) trans = lgettext(text) trans = trans.replace('\r', '').replace('\n', '\\r\\n') trans = trans.replace('\\', '$\\').replace('"', '$\\"') line = '%s%s} "%s"\n' % (leader, lng, trans) new.append(line) elif lng is None: print 'Warning: unsupported language %s (%s), add to table in this script' % (langname, lcode) else: new.append(line) src.close() dst = open(NSIS+'.tmp', 'w') for line in new: dst.write(line) dst.close() # Determine location of MsgFmt tool path, py = os.path.split(sys.argv[0]) tl = os.path.abspath(os.path.normpath(os.path.join(path, 'msgfmt.py'))) if os.path.exists(tl): if os.name == 'nt': TOOL = 'python "%s"' % tl else: TOOL = '"%s"' % tl # Fix up Romanian and Polish texts fix_ro() fix_pl() if len(sys.argv) > 1 and sys.argv[1] == 'all': print 'NSIS MO file' process_po_folder(DOMAIN_N, PON_DIR) print "Patch NSIS script" patch_nsis() print 'Email MO files' process_po_folder(DOMAIN_E, POE_DIR) print "Create email templates from MO files" make_templates() print 'Main program MO files' # -n option added to remove all newlines from the translations process_po_folder(DOMAIN, PO_DIR, '-n') print "Remove temporary templates" remove_mo_files() SABnzbd-0.7.20/tools/msgfmt.py0000755000000000000000000001373512433712602016250 0ustar00usergroup00000000000000#! /usr/bin/env python # -*- coding: iso-8859-1 -*- # Written by Martin v. L�wis """Generate binary message catalog from textual translation description. This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the GNU msgfmt program, however, it is a simpler implementation. Usage: msgfmt.py [OPTIONS] filename.po Options: -o file --output-file=file Specify the output file to write to. If omitted, output will go to a file named filename.mo (based off the input file name). -n Remove all newlines (\r\n) from translations -h --help Print this message and exit. -V --version Display version information and exit. """ import sys import os import getopt import struct import array import re __version__ = "1.1" MESSAGES = {} nonewlines = False # Detector for HTML elements RE_HTML = re.compile('<[^>]+>') def usage(code, msg=''): print >> sys.stderr, __doc__ if msg: print >> sys.stderr, msg sys.exit(code) def add(id, str, fuzzy): "Add a non-fuzzy translation to the dictionary." global MESSAGES, nonewlines, RE_HTML if not fuzzy and str: if id.count('%s') == str.count('%s'): if nonewlines and id and ('\r' in str or '\n' in str) and RE_HTML.search(str): MESSAGES[id] = str.replace('\n', '').replace('\r', '') else: MESSAGES[id] = str else: print 'WARNING: %s mismatch, skipping!' print ' %s' % id print ' %s' % str def generate(): "Return the generated output." global MESSAGES keys = MESSAGES.keys() # the keys are sorted in the .mo file keys.sort() offsets = [] ids = strs = '' for id in keys: # For each string, we need size and file offset. Each string is NUL # terminated; the NUL does not count into the size. offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id]))) ids += id + '\0' strs += MESSAGES[id] + '\0' output = '' # The header is 7 32-bit unsigned integers. We don't use hash tables, so # the keys start right after the index tables. # translated string. keystart = 7*4+16*len(keys) # and the values start after the keys valuestart = keystart + len(ids) koffsets = [] voffsets = [] # The string table first has the list of keys, then the list of values. # Each entry has first the size of the string, then the file offset. for o1, l1, o2, l2 in offsets: koffsets += [l1, o1+keystart] voffsets += [l2, o2+valuestart] offsets = koffsets + voffsets output = struct.pack("Iiiiiii", 0x950412deL, # Magic 0, # Version len(keys), # # of entries 7*4, # start of key index 7*4+len(keys)*8, # start of value index 0, 0) # size and offset of hash table output += array.array("i", offsets).tostring() output += ids output += strs return output def make(filename, outfile): ID = 1 STR = 2 # Compute .mo name from .po name and arguments if filename.endswith('.po'): infile = filename else: infile = filename + '.po' if outfile is None: outfile = os.path.splitext(infile)[0] + '.mo' try: lines = open(infile).readlines() except IOError, msg: print >> sys.stderr, msg sys.exit(1) section = None fuzzy = 0 # Parse the catalog lno = 0 for l in lines: lno += 1 # If we get a comment line after a msgstr, this is a new entry if l[0] == '#' and section == STR: add(msgid, msgstr, fuzzy) section = None fuzzy = 0 # Record a fuzzy mark if l[:2] == '#,' and 'fuzzy' in l: fuzzy = 1 # Skip comments if l[0] == '#': continue # Now we are in a msgid section, output previous section if l.startswith('msgid'): if section == STR: add(msgid, msgstr, fuzzy) section = ID l = l[5:] msgid = msgstr = '' # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR l = l[6:] # Skip empty lines l = l.strip() if not l: continue # XXX: Does this always follow Python escape semantics? l = eval(l) if section == ID: msgid += l elif section == STR: msgstr += l else: print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ 'before:' print >> sys.stderr, l sys.exit(1) # Add last entry if section == STR: add(msgid, msgstr, fuzzy) # Compute output output = generate() try: open(outfile,"wb").write(output) except IOError,msg: print >> sys.stderr, msg def main(): global nonewlines try: opts, args = getopt.getopt(sys.argv[1:], 'nhVo:', ['help', 'version', 'output-file=']) except getopt.error, msg: usage(1, msg) outfile = None # parse options for opt, arg in opts: if opt in ('-h', '--help'): usage(0) elif opt in ('-V', '--version'): print >> sys.stderr, "msgfmt.py", __version__ sys.exit(0) elif opt in ('-o', '--output-file'): outfile = arg elif opt in ('-n', ): nonewlines = True # do it if not args: print >> sys.stderr, 'No input file given' print >> sys.stderr, "Try `msgfmt --help' for more information." return for filename in args: make(filename, outfile) if __name__ == '__main__': main() SABnzbd-0.7.20/util/apireg.py0000644000000000000000000000636312433712602016033 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2012 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ util.apireg - Registration of API connection info """ import _winreg def reg_info(user): """ Return the reg key for API """ if user: # Normally use the USER part of the registry section = _winreg.HKEY_CURRENT_USER keypath = r"Software\SABnzbd" else: # A Windows Service will use the service key instead section = _winreg.HKEY_LOCAL_MACHINE keypath = r"SYSTEM\CurrentControlSet\Services\SABnzbd" return section, keypath def get_connection_info(user=True): """ Return URL of the API running SABnzbd instance 'user' == True will first try user's registry, otherwise system is used """ section, keypath = reg_info(user) url = None try: hive = _winreg.ConnectRegistry(None, section) key = _winreg.OpenKey(hive, keypath + r'\api') for i in range(0, _winreg.QueryInfoKey(key)[1]): name, value, val_type = _winreg.EnumValue(key, i) value = value.encode('latin-1', 'replace') if name == 'url': url = value _winreg.CloseKey(key) except WindowsError: pass finally: _winreg.CloseKey(hive) # Nothing in user's registry, try system registry if user and not url: url = get_connection_info(user=False) return url def set_connection_info(url, user=True): """ Set API info in register """ section, keypath = reg_info(user) try: hive = _winreg.ConnectRegistry(None, section) try: key = _winreg.CreateKey(hive, keypath) except: pass key = _winreg.OpenKey(hive, keypath) mykey = _winreg.CreateKey(key, 'api') _winreg.SetValueEx(mykey, 'url', None, _winreg.REG_SZ, url) _winreg.CloseKey(mykey) _winreg.CloseKey(key) except WindowsError: if user: set_connection_info(url, user=False) pass finally: _winreg.CloseKey(hive) def del_connection_info(user=True): """ Remove API info from register """ section, keypath = reg_info(user) try: hive = _winreg.ConnectRegistry(None, section) key = _winreg.OpenKey(hive, keypath) _winreg.DeleteKey(key, 'api') _winreg.CloseKey(key) except WindowsError: if user: del_connection_info(user=False) pass finally: _winreg.CloseKey(hive) #print get_connection_info() #del_connection_info() #set_connection_info('localhost', '8080', 'blabla', user=False) SABnzbd-0.7.20/util/mailslot.py0000644000000000000000000000773312433712602016412 0ustar00usergroup00000000000000#!/usr/bin/python -OO # Copyright 2008-2011 The SABnzbd-Team # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ sabnzbd.mailslot - Mailslot communication """ import os from win32file import GENERIC_WRITE, FILE_SHARE_READ, \ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL from ctypes import c_uint, c_buffer, byref, sizeof, windll # Win32API Shortcuts CreateFile = windll.kernel32.CreateFileA ReadFile = windll.kernel32.ReadFile WriteFile = windll.kernel32.WriteFile CloseHandle = windll.kernel32.CloseHandle CreateMailslot = windll.kernel32.CreateMailslotA class MailSlot(object): """ Simple Windows Mailslot communication """ slotname = r'mailslot\SABnzbd\ServiceSlot' def __init__(self): self.handle = -1 def create(self, timeout): """ Create the Mailslot, after this only receiving is possible timeout is the read timeout used for receive calls. """ slot = r'\\.\%s' % MailSlot.slotname self.handle = CreateMailslot(slot, 0, timeout, None) return self.handle != -1 def connect(self): """ Connect to existing Mailslot so that writing is possible """ slot = r'\\%s\%s' % (os.environ['COMPUTERNAME'], MailSlot.slotname) self.handle = CreateFile(slot, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) return self.handle != -1 def disconnect(self): """ Disconnect from Mailslot """ if self.handle != -1: CloseHandle(self.handle) self.handle = -1 return True def send(self, command): """ Send one message to Mailslot """ if self.handle == -1: return False w = c_uint() return bool(WriteFile(self.handle, command, len(command), byref(w), 0)) def receive(self): """ Receive one message from Mailslot """ r = c_uint() buf = c_buffer(1024) if ReadFile(self.handle, buf, sizeof(buf), byref(r), 0): return buf.value else: return None #------------------------------------------------------------------------------ # Simple test # # First start "mailslot.py server" in one process, # Then start "mailslot.py client" in another. # Five "restart" and one "stop" will be send from client to server. # The server will stop after receiving "stop" if __name__ == '__main__': import sys from time import sleep if not __debug__: print 'Run this test in non-optimized mode' exit(1) if len(sys.argv) > 1 and 'server' in sys.argv[1]: recv = MailSlot() ret = recv.create(2) assert ret, 'Failed to create' while True: data = recv.receive() if data is not None: print data if data.startswith('stop'): break sleep(2.0) recv.disconnect() elif len(sys.argv) > 1 and 'client' in sys.argv[1]: send = MailSlot() ret = send.connect() assert ret, 'Failed to connect' for n in xrange(5): ret = send.send('restart') assert ret, 'Failed to send' sleep(2.0) send.send('stop') assert ret, 'Failed to send' send.disconnect() else: print 'Usage: mailslot.py server|client' SABnzbd-0.7.20/util/pystone.py0000644000000000000000000001630712433712602016264 0ustar00usergroup00000000000000#! /usr/bin/env python """ "PYSTONE" Benchmark Program Version: Python/1.1 (corresponds to C/1.1 plus 2 Pystone fixes) Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013. Translated from ADA to C by Rick Richardson. Every method to preserve ADA-likeness has been used, at the expense of C-ness. Translated from C to Python by Guido van Rossum. Version History: Version 1.1 corrects two bugs in version 1.0: First, it leaked memory: in Proc1(), NextRecord ends up having a pointer to itself. I have corrected this by zapping NextRecord.PtrComp at the end of Proc1(). Second, Proc3() used the operator != to compare a record to None. This is rather inefficient and not true to the intention of the original benchmark (where a pointer comparison to None is intended; the != operator attempts to find a method __cmp__ to do value comparison of the record). Version 1.1 runs 5-10 percent faster than version 1.0, so benchmark figures of different versions can't be compared directly. """ LOOPS = 50000 from time import clock __version__ = "1.1" [Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6) class Record: def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0, IntComp = 0, StringComp = 0): self.PtrComp = PtrComp self.Discr = Discr self.EnumComp = EnumComp self.IntComp = IntComp self.StringComp = StringComp def copy(self): return Record(self.PtrComp, self.Discr, self.EnumComp, self.IntComp, self.StringComp) TRUE = 1 FALSE = 0 def main(loops=LOOPS): benchtime, stones = pystones(loops) print "Pystone(%s) time for %d passes = %g" % \ (__version__, loops, benchtime) print "This machine benchmarks at %g pystones/second" % stones def pystones(loops=LOOPS): return Proc0(loops) IntGlob = 0 BoolGlob = FALSE Char1Glob = '\0' Char2Glob = '\0' Array1Glob = [0]*51 Array2Glob = map(lambda x: x[:], [Array1Glob]*51) PtrGlb = None PtrGlbNext = None def Proc0(loops=LOOPS): global IntGlob global BoolGlob global Char1Glob global Char2Glob global Array1Glob global Array2Glob global PtrGlb global PtrGlbNext starttime = clock() for i in range(loops): pass nulltime = clock() - starttime PtrGlbNext = Record() PtrGlb = Record() PtrGlb.PtrComp = PtrGlbNext PtrGlb.Discr = Ident1 PtrGlb.EnumComp = Ident3 PtrGlb.IntComp = 40 PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING" String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING" Array2Glob[8][7] = 10 starttime = clock() for i in range(loops): Proc5() Proc4() IntLoc1 = 2 IntLoc2 = 3 String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING" EnumLoc = Ident2 BoolGlob = not Func2(String1Loc, String2Loc) while IntLoc1 < IntLoc2: IntLoc3 = 5 * IntLoc1 - IntLoc2 IntLoc3 = Proc7(IntLoc1, IntLoc2) IntLoc1 = IntLoc1 + 1 Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3) PtrGlb = Proc1(PtrGlb) CharIndex = 'A' while CharIndex <= Char2Glob: if EnumLoc == Func1(CharIndex, 'C'): EnumLoc = Proc6(Ident1) CharIndex = chr(ord(CharIndex)+1) IntLoc3 = IntLoc2 * IntLoc1 IntLoc2 = IntLoc3 / IntLoc1 IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1 IntLoc1 = Proc2(IntLoc1) benchtime = clock() - starttime - nulltime if benchtime == 0.0: loopsPerBenchtime = 0.0 else: loopsPerBenchtime = (loops / benchtime) return benchtime, loopsPerBenchtime def Proc1(PtrParIn): PtrParIn.PtrComp = NextRecord = PtrGlb.copy() PtrParIn.IntComp = 5 NextRecord.IntComp = PtrParIn.IntComp NextRecord.PtrComp = PtrParIn.PtrComp NextRecord.PtrComp = Proc3(NextRecord.PtrComp) if NextRecord.Discr == Ident1: NextRecord.IntComp = 6 NextRecord.EnumComp = Proc6(PtrParIn.EnumComp) NextRecord.PtrComp = PtrGlb.PtrComp NextRecord.IntComp = Proc7(NextRecord.IntComp, 10) else: PtrParIn = NextRecord.copy() NextRecord.PtrComp = None return PtrParIn def Proc2(IntParIO): IntLoc = IntParIO + 10 while 1: if Char1Glob == 'A': IntLoc = IntLoc - 1 IntParIO = IntLoc - IntGlob EnumLoc = Ident1 if EnumLoc == Ident1: break return IntParIO def Proc3(PtrParOut): global IntGlob if PtrGlb is not None: PtrParOut = PtrGlb.PtrComp else: IntGlob = 100 PtrGlb.IntComp = Proc7(10, IntGlob) return PtrParOut def Proc4(): global Char2Glob BoolLoc = Char1Glob == 'A' BoolLoc = BoolLoc or BoolGlob Char2Glob = 'B' def Proc5(): global Char1Glob global BoolGlob Char1Glob = 'A' BoolGlob = FALSE def Proc6(EnumParIn): EnumParOut = EnumParIn if not Func3(EnumParIn): EnumParOut = Ident4 if EnumParIn == Ident1: EnumParOut = Ident1 elif EnumParIn == Ident2: if IntGlob > 100: EnumParOut = Ident1 else: EnumParOut = Ident4 elif EnumParIn == Ident3: EnumParOut = Ident2 elif EnumParIn == Ident4: pass elif EnumParIn == Ident5: EnumParOut = Ident3 return EnumParOut def Proc7(IntParI1, IntParI2): IntLoc = IntParI1 + 2 IntParOut = IntParI2 + IntLoc return IntParOut def Proc8(Array1Par, Array2Par, IntParI1, IntParI2): global IntGlob IntLoc = IntParI1 + 5 Array1Par[IntLoc] = IntParI2 Array1Par[IntLoc+1] = Array1Par[IntLoc] Array1Par[IntLoc+30] = IntLoc for IntIndex in range(IntLoc, IntLoc+2): Array2Par[IntLoc][IntIndex] = IntLoc Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1 Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc] IntGlob = 5 def Func1(CharPar1, CharPar2): CharLoc1 = CharPar1 CharLoc2 = CharLoc1 if CharLoc2 != CharPar2: return Ident1 else: return Ident2 def Func2(StrParI1, StrParI2): IntLoc = 1 while IntLoc <= 1: if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1: CharLoc = 'A' IntLoc = IntLoc + 1 if CharLoc >= 'W' and CharLoc <= 'Z': IntLoc = 7 if CharLoc == 'X': return TRUE else: if StrParI1 > StrParI2: IntLoc = IntLoc + 7 return TRUE else: return FALSE def Func3(EnumParIn): EnumLoc = EnumParIn if EnumLoc == Ident3: return TRUE return FALSE if __name__ == '__main__': import sys def error(msg): print >>sys.stderr, msg, print >>sys.stderr, "usage: %s [number_of_loops]" % sys.argv[0] sys.exit(100) nargs = len(sys.argv) - 1 if nargs > 1: error("%d arguments are too many;" % nargs) elif nargs == 1: try: loops = int(sys.argv[1]) except ValueError: error("Invalid argument %r;" % sys.argv[1]) else: loops = LOOPS main(loops) SABnzbd-0.7.20/util/__init__.py0000644000000000000000000000000012433712602016301 0ustar00usergroup00000000000000SABnzbd-0.7.20/0000755000000000000000000000000012613775511013071 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/0000755000000000000000000000000012613775512015215 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Plush/0000755000000000000000000000000012613775511016307 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Plush/templates/0000755000000000000000000000000012613775511020305 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Plush/templates/static/0000755000000000000000000000000012613775511021574 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/0000755000000000000000000000000012613775511024125 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/0000755000000000000000000000000012613775512024715 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/webtoolkit.aim.js0000644000000000000000000000271612612410632030175 0ustar00rootroot00000000000000/** * * AJAX IFRAME METHOD (AIM) * http://www.webtoolkit.info/ * * Copyright (c) 2006-2008 www.webtoolkit.info * Licensed under Gnu Public Licence V3 or higher. * http://www.gnu.org/licenses/gpl.html **/ AIM = { frame : function(c) { var n = 'f' + Math.floor(Math.random() * 99999); var d = document.createElement('DIV'); d.innerHTML = ''; document.body.appendChild(d); var i = document.getElementById(n); if (c && typeof(c.onComplete) == 'function') { i.onComplete = c.onComplete; } return n; }, form : function(f, name) { f.setAttribute('target', name); }, submit : function(f, c) { AIM.form(f, AIM.frame(c)); if (c && typeof(c.onStart) == 'function') { return c.onStart(); } else { return true; } }, loaded : function(id) { var i = document.getElementById(id); if (i.contentDocument) { var d = i.contentDocument; } else if (i.contentWindow) { var d = i.contentWindow.document; } else { var d = window.frames[id].document; } if (d.location.href == "about:blank") { return; } if (typeof(i.onComplete) == 'function') { i.onComplete(d.body.innerHTML); } } }SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.ui.dialog.js0000644000000000000000000005242112612410632030434 0ustar00rootroot00000000000000/* * jQuery UI Dialog 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Dialog * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * jquery.ui.button.js * jquery.ui.draggable.js * jquery.ui.mouse.js * jquery.ui.position.js * jquery.ui.resizable.js */ (function( $, undefined ) { var uiDialogClasses = 'ui-dialog ' + 'ui-widget ' + 'ui-widget-content ' + 'ui-corner-all ', sizeRelatedOptions = { buttons: true, height: true, maxHeight: true, maxWidth: true, minHeight: true, minWidth: true, width: true }, resizableRelatedOptions = { maxHeight: true, maxWidth: true, minHeight: true, minWidth: true }, // support for jQuery 1.3.2 - handle common attrFn methods for dialog attrFn = $.attrFn || { val: true, css: true, html: true, text: true, data: true, width: true, height: true, offset: true, click: true }; $.widget("ui.dialog", { options: { autoOpen: true, buttons: {}, closeOnEscape: true, closeText: 'close', dialogClass: '', draggable: true, hide: null, height: 'auto', maxHeight: false, maxWidth: false, minHeight: 150, minWidth: 150, modal: false, position: { my: 'center', at: 'center', collision: 'fit', // ensure that the titlebar is never outside the document using: function(pos) { var topOffset = $(this).css(pos).offset().top; if (topOffset < 0) { $(this).css('top', pos.top - topOffset); } } }, resizable: true, show: null, stack: true, title: '', width: 300, zIndex: 1000 }, _create: function() { this.originalTitle = this.element.attr('title'); // #5742 - .attr() might return a DOMElement if ( typeof this.originalTitle !== "string" ) { this.originalTitle = ""; } this.options.title = this.options.title || this.originalTitle; var self = this, options = self.options, title = options.title || ' ', titleId = $.ui.dialog.getTitleId(self.element), uiDialog = (self.uiDialog = $('
    ')) .appendTo(document.body) .hide() .addClass(uiDialogClasses + options.dialogClass) .css({ zIndex: options.zIndex }) // setting tabIndex makes the div focusable // setting outline to 0 prevents a border on focus in Mozilla .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { if (options.closeOnEscape && event.keyCode && event.keyCode === $.ui.keyCode.ESCAPE) { self.close(event); event.preventDefault(); } }) .attr({ role: 'dialog', 'aria-labelledby': titleId }) .mousedown(function(event) { self.moveToTop(false, event); }), uiDialogContent = self.element .show() .removeAttr('title') .addClass( 'ui-dialog-content ' + 'ui-widget-content') .appendTo(uiDialog), uiDialogTitlebar = (self.uiDialogTitlebar = $('
    ')) .addClass( 'ui-dialog-titlebar ' + 'ui-widget-header ' + 'ui-corner-all ' + 'ui-helper-clearfix' ) .prependTo(uiDialog), uiDialogTitlebarClose = $('') .addClass( 'ui-dialog-titlebar-close ' + 'ui-corner-all' ) .attr('role', 'button') .hover( function() { uiDialogTitlebarClose.addClass('ui-state-hover'); }, function() { uiDialogTitlebarClose.removeClass('ui-state-hover'); } ) .focus(function() { uiDialogTitlebarClose.addClass('ui-state-focus'); }) .blur(function() { uiDialogTitlebarClose.removeClass('ui-state-focus'); }) .click(function(event) { self.close(event); return false; }) .appendTo(uiDialogTitlebar), uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('')) .addClass( 'ui-icon ' + 'ui-icon-closethick' ) .text(options.closeText) .appendTo(uiDialogTitlebarClose), uiDialogTitle = $('') .addClass('ui-dialog-title') .attr('id', titleId) .html(title) .prependTo(uiDialogTitlebar); //handling of deprecated beforeclose (vs beforeClose) option //Ticket #4669 http://dev.jqueryui.com/ticket/4669 //TODO: remove in 1.9pre if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) { options.beforeClose = options.beforeclose; } uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); if (options.draggable && $.fn.draggable) { self._makeDraggable(); } if (options.resizable && $.fn.resizable) { self._makeResizable(); } self._createButtons(options.buttons); self._isOpen = false; if ($.fn.bgiframe) { uiDialog.bgiframe(); } }, _init: function() { if ( this.options.autoOpen ) { this.open(); } }, destroy: function() { var self = this; if (self.overlay) { self.overlay.destroy(); } self.uiDialog.hide(); self.element .unbind('.dialog') .removeData('dialog') .removeClass('ui-dialog-content ui-widget-content') .hide().appendTo('body'); self.uiDialog.remove(); if (self.originalTitle) { self.element.attr('title', self.originalTitle); } return self; }, widget: function() { return this.uiDialog; }, close: function(event) { var self = this, maxZ, thisZ; if (false === self._trigger('beforeClose', event)) { return; } if (self.overlay) { self.overlay.destroy(); } self.uiDialog.unbind('keypress.ui-dialog'); self._isOpen = false; if (self.options.hide) { self.uiDialog.hide(self.options.hide, function() { self._trigger('close', event); }); } else { self.uiDialog.hide(); self._trigger('close', event); } $.ui.dialog.overlay.resize(); // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) if (self.options.modal) { maxZ = 0; $('.ui-dialog').each(function() { if (this !== self.uiDialog[0]) { thisZ = $(this).css('z-index'); if(!isNaN(thisZ)) { maxZ = Math.max(maxZ, thisZ); } } }); $.ui.dialog.maxZ = maxZ; } return self; }, isOpen: function() { return this._isOpen; }, // the force parameter allows us to move modal dialogs to their correct // position on open moveToTop: function(force, event) { var self = this, options = self.options, saveScroll; if ((options.modal && !force) || (!options.stack && !options.modal)) { return self._trigger('focus', event); } if (options.zIndex > $.ui.dialog.maxZ) { $.ui.dialog.maxZ = options.zIndex; } if (self.overlay) { $.ui.dialog.maxZ += 1; self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ); } //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. // http://ui.jquery.com/bugs/ticket/3193 saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() }; $.ui.dialog.maxZ += 1; self.uiDialog.css('z-index', $.ui.dialog.maxZ); self.element.attr(saveScroll); self._trigger('focus', event); return self; }, open: function() { if (this._isOpen) { return; } var self = this, options = self.options, uiDialog = self.uiDialog; self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null; self._size(); self._position(options.position); uiDialog.show(options.show); self.moveToTop(true); // prevent tabbing out of modal dialogs if (options.modal) { uiDialog.bind('keypress.ui-dialog', function(event) { if (event.keyCode !== $.ui.keyCode.TAB) { return; } var tabbables = $(':tabbable', this), first = tabbables.filter(':first'), last = tabbables.filter(':last'); if (event.target === last[0] && !event.shiftKey) { first.focus(1); return false; } else if (event.target === first[0] && event.shiftKey) { last.focus(1); return false; } }); } // set focus to the first tabbable element in the content area or the first button // if there are no tabbable elements, set focus on the dialog itself $(self.element.find(':tabbable').get().concat( uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat( uiDialog.get()))).eq(0).focus(); self._isOpen = true; self._trigger('open'); return self; }, _createButtons: function(buttons) { var self = this, hasButtons = false, uiDialogButtonPane = $('
    ') .addClass( 'ui-dialog-buttonpane ' + 'ui-widget-content ' + 'ui-helper-clearfix' ), uiButtonSet = $( "
    " ) .addClass( "ui-dialog-buttonset" ) .appendTo( uiDialogButtonPane ); // if we already have a button pane, remove it self.uiDialog.find('.ui-dialog-buttonpane').remove(); if (typeof buttons === 'object' && buttons !== null) { $.each(buttons, function() { return !(hasButtons = true); }); } if (hasButtons) { $.each(buttons, function(name, props) { props = $.isFunction( props ) ? { click: props, text: name } : props; var button = $('') .click(function() { props.click.apply(self.element[0], arguments); }) .appendTo(uiButtonSet); // can't use .attr( props, true ) with jQuery 1.3.2. $.each( props, function( key, value ) { if ( key === "click" ) { return; } if ( key in attrFn ) { button[ key ]( value ); } else { button.attr( key, value ); } }); if ($.fn.button) { button.button(); } }); uiDialogButtonPane.appendTo(self.uiDialog); } }, _makeDraggable: function() { var self = this, options = self.options, doc = $(document), heightBeforeDrag; function filteredUi(ui) { return { position: ui.position, offset: ui.offset }; } self.uiDialog.draggable({ cancel: '.ui-dialog-content, .ui-dialog-titlebar-close', handle: '.ui-dialog-titlebar', containment: 'document', start: function(event, ui) { heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height(); $(this).height($(this).height()).addClass("ui-dialog-dragging"); self._trigger('dragStart', event, filteredUi(ui)); }, drag: function(event, ui) { self._trigger('drag', event, filteredUi(ui)); }, stop: function(event, ui) { options.position = [ui.position.left - doc.scrollLeft(), ui.position.top - doc.scrollTop()]; $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); self._trigger('dragStop', event, filteredUi(ui)); $.ui.dialog.overlay.resize(); } }); }, _makeResizable: function(handles) { handles = (handles === undefined ? this.options.resizable : handles); var self = this, options = self.options, // .ui-resizable has position: relative defined in the stylesheet // but dialogs have to use absolute or fixed positioning position = self.uiDialog.css('position'), resizeHandles = (typeof handles === 'string' ? handles : 'n,e,s,w,se,sw,ne,nw' ); function filteredUi(ui) { return { originalPosition: ui.originalPosition, originalSize: ui.originalSize, position: ui.position, size: ui.size }; } self.uiDialog.resizable({ cancel: '.ui-dialog-content', containment: 'document', alsoResize: self.element, maxWidth: options.maxWidth, maxHeight: options.maxHeight, minWidth: options.minWidth, minHeight: self._minHeight(), handles: resizeHandles, start: function(event, ui) { $(this).addClass("ui-dialog-resizing"); self._trigger('resizeStart', event, filteredUi(ui)); }, resize: function(event, ui) { self._trigger('resize', event, filteredUi(ui)); }, stop: function(event, ui) { $(this).removeClass("ui-dialog-resizing"); options.height = $(this).height(); options.width = $(this).width(); self._trigger('resizeStop', event, filteredUi(ui)); $.ui.dialog.overlay.resize(); } }) .css('position', position) .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); }, _minHeight: function() { var options = this.options; if (options.height === 'auto') { return options.minHeight; } else { return Math.min(options.minHeight, options.height); } }, _position: function(position) { var myAt = [], offset = [0, 0], isVisible; if (position) { // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( // if (typeof position == 'string' || $.isArray(position)) { // myAt = $.isArray(position) ? position : position.split(' '); if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { myAt = position.split ? position.split(' ') : [position[0], position[1]]; if (myAt.length === 1) { myAt[1] = myAt[0]; } $.each(['left', 'top'], function(i, offsetPosition) { if (+myAt[i] === myAt[i]) { offset[i] = myAt[i]; myAt[i] = offsetPosition; } }); position = { my: myAt.join(" "), at: myAt.join(" "), offset: offset.join(" ") }; } position = $.extend({}, $.ui.dialog.prototype.options.position, position); } else { position = $.ui.dialog.prototype.options.position; } // need to show the dialog to get the actual offset in the position plugin isVisible = this.uiDialog.is(':visible'); if (!isVisible) { this.uiDialog.show(); } this.uiDialog // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 .css({ top: 0, left: 0 }) .position($.extend({ of: window }, position)); if (!isVisible) { this.uiDialog.hide(); } }, _setOptions: function( options ) { var self = this, resizableOptions = {}, resize = false; $.each( options, function( key, value ) { self._setOption( key, value ); if ( key in sizeRelatedOptions ) { resize = true; } if ( key in resizableRelatedOptions ) { resizableOptions[ key ] = value; } }); if ( resize ) { this._size(); } if ( this.uiDialog.is( ":data(resizable)" ) ) { this.uiDialog.resizable( "option", resizableOptions ); } }, _setOption: function(key, value){ var self = this, uiDialog = self.uiDialog; switch (key) { //handling of deprecated beforeclose (vs beforeClose) option //Ticket #4669 http://dev.jqueryui.com/ticket/4669 //TODO: remove in 1.9pre case "beforeclose": key = "beforeClose"; break; case "buttons": self._createButtons(value); break; case "closeText": // ensure that we always pass a string self.uiDialogTitlebarCloseText.text("" + value); break; case "dialogClass": uiDialog .removeClass(self.options.dialogClass) .addClass(uiDialogClasses + value); break; case "disabled": if (value) { uiDialog.addClass('ui-dialog-disabled'); } else { uiDialog.removeClass('ui-dialog-disabled'); } break; case "draggable": var isDraggable = uiDialog.is( ":data(draggable)" ); if ( isDraggable && !value ) { uiDialog.draggable( "destroy" ); } if ( !isDraggable && value ) { self._makeDraggable(); } break; case "position": self._position(value); break; case "resizable": // currently resizable, becoming non-resizable var isResizable = uiDialog.is( ":data(resizable)" ); if (isResizable && !value) { uiDialog.resizable('destroy'); } // currently resizable, changing handles if (isResizable && typeof value === 'string') { uiDialog.resizable('option', 'handles', value); } // currently non-resizable, becoming resizable if (!isResizable && value !== false) { self._makeResizable(value); } break; case "title": // convert whatever was passed in o a string, for html() to not throw up $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || ' ')); break; } $.Widget.prototype._setOption.apply(self, arguments); }, _size: function() { /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content * divs will both have width and height set, so we need to reset them */ var options = this.options, nonContentHeight, minContentHeight, isVisible = this.uiDialog.is( ":visible" ); // reset content sizing this.element.show().css({ width: 'auto', minHeight: 0, height: 0 }); if (options.minWidth > options.width) { options.width = options.minWidth; } // reset wrapper sizing // determine the height of all the non-content elements nonContentHeight = this.uiDialog.css({ height: 'auto', width: options.width }) .height(); minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); if ( options.height === "auto" ) { // only needed for IE6 support if ( $.support.minHeight ) { this.element.css({ minHeight: minContentHeight, height: "auto" }); } else { this.uiDialog.show(); var autoHeight = this.element.css( "height", "auto" ).height(); if ( !isVisible ) { this.uiDialog.hide(); } this.element.height( Math.max( autoHeight, minContentHeight ) ); } } else { this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); } if (this.uiDialog.is(':data(resizable)')) { this.uiDialog.resizable('option', 'minHeight', this._minHeight()); } } }); $.extend($.ui.dialog, { version: "1.8.15", uuid: 0, maxZ: 0, getTitleId: function($el) { var id = $el.attr('id'); if (!id) { this.uuid += 1; id = this.uuid; } return 'ui-dialog-title-' + id; }, overlay: function(dialog) { this.$el = $.ui.dialog.overlay.create(dialog); } }); $.extend($.ui.dialog.overlay, { instances: [], // reuse old instances due to IE memory leak with alpha transparency (see #5185) oldInstances: [], maxZ: 0, events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), function(event) { return event + '.dialog-overlay'; }).join(' '), create: function(dialog) { if (this.instances.length === 0) { // prevent use of anchors and inputs // we use a setTimeout in case the overlay is created from an // event that we're going to be cancelling (see #2804) setTimeout(function() { // handle $(el).dialog().dialog('close') (see #4065) if ($.ui.dialog.overlay.instances.length) { $(document).bind($.ui.dialog.overlay.events, function(event) { // stop events if the z-index of the target is < the z-index of the overlay // we cannot return true when we don't want to cancel the event (#3523) if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) { return false; } }); } }, 1); // allow closing by pressing the escape key $(document).bind('keydown.dialog-overlay', function(event) { if (dialog.options.closeOnEscape && event.keyCode && event.keyCode === $.ui.keyCode.ESCAPE) { dialog.close(event); event.preventDefault(); } }); // handle window resize $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); } var $el = (this.oldInstances.pop() || $('
    ').addClass('ui-widget-overlay')) .appendTo(document.body) .css({ width: this.width(), height: this.height() }); if ($.fn.bgiframe) { $el.bgiframe(); } this.instances.push($el); return $el; }, destroy: function($el) { var indexOf = $.inArray($el, this.instances); if (indexOf != -1){ this.oldInstances.push(this.instances.splice(indexOf, 1)[0]); } if (this.instances.length === 0) { $([document, window]).unbind('.dialog-overlay'); } $el.remove(); // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) var maxZ = 0; $.each(this.instances, function() { maxZ = Math.max(maxZ, this.css('z-index')); }); this.maxZ = maxZ; }, height: function() { var scrollHeight, offsetHeight; // handle IE 6 if ($.browser.msie && $.browser.version < 7) { scrollHeight = Math.max( document.documentElement.scrollHeight, document.body.scrollHeight ); offsetHeight = Math.max( document.documentElement.offsetHeight, document.body.offsetHeight ); if (scrollHeight < offsetHeight) { return $(window).height() + 'px'; } else { return scrollHeight + 'px'; } // handle "good" browsers } else { return $(document).height() + 'px'; } }, width: function() { var scrollWidth, offsetWidth; // handle IE if ( $.browser.msie ) { scrollWidth = Math.max( document.documentElement.scrollWidth, document.body.scrollWidth ); offsetWidth = Math.max( document.documentElement.offsetWidth, document.body.offsetWidth ); if (scrollWidth < offsetWidth) { return $(window).width() + 'px'; } else { return scrollWidth + 'px'; } // handle "good" browsers } else { return $(document).width() + 'px'; } }, resize: function() { /* If the dialog is draggable and the user drags it past the * right edge of the window, the document becomes wider so we * need to stretch the overlay. If the user then drags the * dialog back to the left, the document will become narrower, * so we need to shrink the overlay to the appropriate size. * This is handled by shrinking the overlay before setting it * to the full document size. */ var $overlays = $([]); $.each($.ui.dialog.overlay.instances, function() { $overlays = $overlays.add(this); }); $overlays.css({ width: 0, height: 0 }).css({ width: $.ui.dialog.overlay.width(), height: $.ui.dialog.overlay.height() }); } }); $.extend($.ui.dialog.overlay.prototype, { destroy: function() { $.ui.dialog.overlay.destroy(this.$el); } }); }(jQuery)); SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.tablednd.0.5.js0000644000000000000000000004041112612410632030633 0ustar00rootroot00000000000000/** * TableDnD plug-in for JQuery, allows you to drag and drop table rows * You can set up various options to control how the system will work * Copyright (c) Denis Howlett * Licensed like jQuery, see http://docs.jquery.com/License. * * Configuration options: * * onDragStyle * This is the style that is assigned to the row during drag. There are limitations to the styles that can be * associated with a row (such as you can't assign a border--well you can, but it won't be * displayed). (So instead consider using onDragClass.) The CSS style to apply is specified as * a map (as used in the jQuery css(...) function). * onDropStyle * This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations * to what you can do. Also this replaces the original style, so again consider using onDragClass which * is simply added and then removed on drop. * onDragClass * This class is added for the duration of the drag and then removed when the row is dropped. It is more * flexible than using onDragStyle since it can be inherited by the row cells and other content. The default * is class is tDnD_whileDrag. So to use the default, simply customise this CSS class in your * stylesheet. * onDrop * Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table * and the row that was dropped. You can work out the new order of the rows by using * table.rows. * onDragStart * Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the * table and the row which the user has started to drag. * onAllowDrop * Pass a function that will be called as a row is over another row. If the function returns true, allow * dropping on that row, otherwise not. The function takes 2 parameters: the dragged row and the row under * the cursor. It returns a boolean: true allows the drop, false doesn't allow it. * scrollAmount * This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the * window. The page should automatically scroll up or down as appropriate (tested in IE6, IE7, Safari, FF2, * FF3 beta * dragHandle * This is the name of a class that you assign to one or more cells in each row that is draggable. If you * specify this class, then you are responsible for setting cursor: move in the CSS and only these cells * will have the drag behaviour. If you do not specify a dragHandle, then you get the old behaviour where * the whole row is draggable. * * Other ways to control behaviour: * * Add class="nodrop" to any rows for which you don't want to allow dropping, and class="nodrag" to any rows * that you don't want to be draggable. * * Inside the onDrop method you can also call $.tableDnD.serialize() this returns a string of the form * []=&[]= so that you can send this back to the server. The table must have * an ID as must all the rows. * * Other methods: * * $("...").tableDnDUpdate() * Will update all the matching tables, that is it will reapply the mousedown method to the rows (or handle cells). * This is useful if you have updated the table rows using Ajax and you want to make the table draggable again. * The table maintains the original configuration (so you don't have to specify it again). * * $("...").tableDnDSerialize() * Will serialize and return the serialized string as above, but for each of the matching tables--so it can be * called from anywhere and isn't dependent on the currentTable being set up correctly before calling * * Known problems: * - Auto-scoll has some problems with IE7 (it scrolls even when it shouldn't), work-around: set scrollAmount to 0 * * Version 0.2: 2008-02-20 First public version * Version 0.3: 2008-02-07 Added onDragStart option * Made the scroll amount configurable (default is 5 as before) * Version 0.4: 2008-03-15 Changed the noDrag/noDrop attributes to nodrag/nodrop classes * Added onAllowDrop to control dropping * Fixed a bug which meant that you couldn't set the scroll amount in both directions * Added serialize method * Version 0.5: 2008-05-16 Changed so that if you specify a dragHandle class it doesn't make the whole row * draggable * Improved the serialize method to use a default (and settable) regular expression. * Added tableDnDupate() and tableDnDSerialize() to be called when you are outside the table */ jQuery.tableDnD = { /** Keep hold of the current table being dragged */ currentTable : null, /** Keep hold of the current drag object if any */ dragObject: null, /** The current mouse offset */ mouseOffset: null, /** Remember the old value of Y so that we don't do too much processing */ oldY: 0, /** Actually build the structure */ build: function(options) { // Set up the defaults if any this.each(function() { // This is bound to each matching table, set up the defaults and override with user options this.tableDnDConfig = $.extend({ onDragStyle: null, onDropStyle: null, // Add in the default class for whileDragging onDragClass: "tDnD_whileDrag", onDrop: null, onDragStart: null, scrollAmount: 5, serializeRegexp: /[^\-]*$/, // The regular expression to use to trim row IDs serializeParamName: null, // If you want to specify another parameter name instead of the table ID dragHandle: null // If you give the name of a class here, then only Cells with this class will be draggable }, options || {}); // Now make the rows draggable jQuery.tableDnD.makeDraggable(this); }); // Now we need to capture the mouse up and mouse move event // We can use bind so that we don't interfere with other event handlers jQuery(document) .bind('mousemove', jQuery.tableDnD.mousemove) .bind('mouseup', jQuery.tableDnD.mouseup); // Don't break the chain return this; }, /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */ makeDraggable: function(table) { var config = table.tableDnDConfig; if (table.tableDnDConfig.dragHandle) { // We only need to add the event to the specified cells var cells = $("td."+table.tableDnDConfig.dragHandle, table); cells.each(function() { // The cell is bound to "this" jQuery(this).mousedown(function(ev) { jQuery.tableDnD.dragObject = this.parentNode; jQuery.tableDnD.currentTable = table; jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev); if (config.onDragStart) { // Call the onDrop method if there is one config.onDragStart(table, this); } return false; }); }) } else { // For backwards compatibility, we add the event to the whole row var rows = jQuery("tr", table); // get all the rows as a wrapped set rows.each(function() { // Iterate through each row, the row is bound to "this" var row = $(this); if (! row.hasClass("nodrag")) { row.mousedown(function(ev) { if (ev.target.tagName == "TD") { jQuery.tableDnD.dragObject = this; jQuery.tableDnD.currentTable = table; jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(this, ev); if (config.onDragStart) { // Call the onDrop method if there is one config.onDragStart(table, this); } return false; } }).css("cursor", "move"); // Store the tableDnD object } }); } }, updateTables: function() { this.each(function() { // this is now bound to each matching table if (this.tableDnDConfig) { jQuery.tableDnD.makeDraggable(this); } }) }, /** Get the mouse coordinates from the event (allowing for browser differences) */ mouseCoords: function(ev){ if(ev.pageX || ev.pageY){ return {x:ev.pageX, y:ev.pageY}; } return { x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, y:ev.clientY + document.body.scrollTop - document.body.clientTop }; }, /** Given a target element and a mouse event, get the mouse offset from that element. To do this we need the element's position and the mouse position */ getMouseOffset: function(target, ev) { ev = ev || window.event; var docPos = this.getPosition(target); var mousePos = this.mouseCoords(ev); return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; }, /** Get the position of an element by going up the DOM tree and adding up all the offsets */ getPosition: function(e){ var left = 0; var top = 0; /** Safari fix -- thanks to Luis Chato for this! */ if (e.offsetHeight == 0) { /** Safari 2 doesn't correctly grab the offsetTop of a table row this is detailed here: http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/ the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild. note that firefox will return a text node as a first child, so designing a more thorough solution may need to take that into account, for now this seems to work in firefox, safari, ie */ e = e.firstChild; // a table cell } while (e.offsetParent){ left += e.offsetLeft; top += e.offsetTop; e = e.offsetParent; } left += e.offsetLeft; top += e.offsetTop; return {x:left, y:top}; }, mousemove: function(ev) { if (jQuery.tableDnD.dragObject == null) { return; } var dragObj = jQuery(jQuery.tableDnD.dragObject); var config = jQuery.tableDnD.currentTable.tableDnDConfig; var mousePos = jQuery.tableDnD.mouseCoords(ev); var y = mousePos.y - jQuery.tableDnD.mouseOffset.y; //auto scroll the window var yOffset = window.pageYOffset; if (document.all) { // Windows version //yOffset=document.body.scrollTop; if (typeof document.compatMode != 'undefined' && document.compatMode != 'BackCompat') { yOffset = document.documentElement.scrollTop; } else if (typeof document.body != 'undefined') { yOffset=document.body.scrollTop; } } if (mousePos.y-yOffset < config.scrollAmount) { window.scrollBy(0, -config.scrollAmount); } else { var windowHeight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight; if (windowHeight-(mousePos.y-yOffset) < config.scrollAmount) { window.scrollBy(0, config.scrollAmount); } } if (y != jQuery.tableDnD.oldY) { // work out if we're going up or down... var movingDown = y > jQuery.tableDnD.oldY; // update the old value jQuery.tableDnD.oldY = y; // update the style to show we're dragging if (config.onDragClass) { dragObj.addClass(config.onDragClass); } else { dragObj.css(config.onDragStyle); } // If we're over a row then move the dragged row to there so that the user sees the // effect dynamically var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y); if (currentRow) { // TODO worry about what happens when there are multiple TBODIES if (movingDown && jQuery.tableDnD.dragObject != currentRow) { jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling); } else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) { jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow); } } } return false; }, /** We're only worried about the y position really, because we can only move rows up and down */ findDropTargetRow: function(draggedRow, y) { var rows = jQuery.tableDnD.currentTable.rows; for (var i=0; i rowY - rowHeight) && (y < (rowY + rowHeight))) { // that's the row we're over // If it's the same as the current row, ignore it if (row == draggedRow) {return null;} var config = jQuery.tableDnD.currentTable.tableDnDConfig; if (config.onAllowDrop) { if (config.onAllowDrop(draggedRow, row)) { return row; } else { return null; } } else { // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic) var nodrop = $(row).hasClass("nodrop"); if (! nodrop) { return row; } else { return null; } } return row; } } return null; }, mouseup: function(e) { if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) { var droppedRow = jQuery.tableDnD.dragObject; var config = jQuery.tableDnD.currentTable.tableDnDConfig; // If we have a dragObject, then we need to release it, // The row will already have been moved to the right place so we just reset stuff if (config.onDragClass) { jQuery(droppedRow).removeClass(config.onDragClass); } else { jQuery(droppedRow).css(config.onDropStyle); } jQuery.tableDnD.dragObject = null; if (config.onDrop) { // Call the onDrop method if there is one config.onDrop(jQuery.tableDnD.currentTable, droppedRow); } jQuery.tableDnD.currentTable = null; // let go of the table too } }, serialize: function() { if (jQuery.tableDnD.currentTable) { return jQuery.tableDnD.serializeTable(jQuery.tableDnD.currentTable); } else { return "Error: No Table id set, you need to set an id on your table and every row"; } }, serializeTable: function(table) { var result = ""; var tableId = table.id; var rows = table.rows; for (var i=0; i 0) result += "&"; var rowId = rows[i].id; if (rowId && rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) { rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0]; } result += tableId + '[]=' + rows[i].id; } return result; }, serializeTables: function() { var result = ""; this.each(function() { // this is now bound to each matching table result += jQuery.tableDnD.serializeTable(this); }); return result; } } jQuery.fn.extend( { tableDnD : jQuery.tableDnD.build, tableDnDUpdate : jQuery.tableDnD.updateTables, tableDnDSerialize: jQuery.tableDnD.serializeTables } );SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.ui.selectable.js0000644000000000000000000001527412612410632031305 0ustar00rootroot00000000000000/* * jQuery UI Selectable 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Selectables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function( $, undefined ) { $.widget("ui.selectable", $.ui.mouse, { options: { appendTo: 'body', autoRefresh: true, distance: 0, filter: '*', tolerance: 'touch' }, _create: function() { var self = this; this.element.addClass("ui-selectable"); this.dragged = false; // cache selectee children based on filter var selectees; this.refresh = function() { selectees = $(self.options.filter, self.element[0]); selectees.each(function() { var $this = $(this); var pos = $this.offset(); $.data(this, "selectable-item", { element: this, $element: $this, left: pos.left, top: pos.top, right: pos.left + $this.outerWidth(), bottom: pos.top + $this.outerHeight(), startselected: false, selected: $this.hasClass('ui-selected'), selecting: $this.hasClass('ui-selecting'), unselecting: $this.hasClass('ui-unselecting') }); }); }; this.refresh(); this.selectees = selectees.addClass("ui-selectee"); this._mouseInit(); this.helper = $("
    "); }, destroy: function() { this.selectees .removeClass("ui-selectee") .removeData("selectable-item"); this.element .removeClass("ui-selectable ui-selectable-disabled") .removeData("selectable") .unbind(".selectable"); this._mouseDestroy(); return this; }, _mouseStart: function(event) { var self = this; this.opos = [event.pageX, event.pageY]; if (this.options.disabled) return; var options = this.options; this.selectees = $(options.filter, this.element[0]); this._trigger("start", event); $(options.appendTo).append(this.helper); // position helper (lasso) this.helper.css({ "left": event.clientX, "top": event.clientY, "width": 0, "height": 0 }); if (options.autoRefresh) { this.refresh(); } this.selectees.filter('.ui-selected').each(function() { var selectee = $.data(this, "selectable-item"); selectee.startselected = true; if (!event.metaKey) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } }); $(event.target).parents().andSelf().each(function() { var selectee = $.data(this, "selectable-item"); if (selectee) { var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected'); selectee.$element .removeClass(doSelect ? "ui-unselecting" : "ui-selected") .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); selectee.unselecting = !doSelect; selectee.selecting = doSelect; selectee.selected = doSelect; // selectable (UN)SELECTING callback if (doSelect) { self._trigger("selecting", event, { selecting: selectee.element }); } else { self._trigger("unselecting", event, { unselecting: selectee.element }); } return false; } }); }, _mouseDrag: function(event) { var self = this; this.dragged = true; if (this.options.disabled) return; var options = this.options; var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); this.selectees.each(function() { var selectee = $.data(this, "selectable-item"); //prevent helper from being selected if appendTo: selectable if (!selectee || selectee.element == self.element[0]) return; var hit = false; if (options.tolerance == 'touch') { hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); } else if (options.tolerance == 'fit') { hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); } if (hit) { // SELECT if (selectee.selected) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; } if (selectee.unselecting) { selectee.$element.removeClass('ui-unselecting'); selectee.unselecting = false; } if (!selectee.selecting) { selectee.$element.addClass('ui-selecting'); selectee.selecting = true; // selectable SELECTING callback self._trigger("selecting", event, { selecting: selectee.element }); } } else { // UNSELECT if (selectee.selecting) { if (event.metaKey && selectee.startselected) { selectee.$element.removeClass('ui-selecting'); selectee.selecting = false; selectee.$element.addClass('ui-selected'); selectee.selected = true; } else { selectee.$element.removeClass('ui-selecting'); selectee.selecting = false; if (selectee.startselected) { selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; } // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } } if (selectee.selected) { if (!event.metaKey && !selectee.startselected) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } } } }); return false; }, _mouseStop: function(event) { var self = this; this.dragged = false; var options = this.options; $('.ui-unselecting', this.element[0]).each(function() { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass('ui-unselecting'); selectee.unselecting = false; selectee.startselected = false; self._trigger("unselected", event, { unselected: selectee.element }); }); $('.ui-selecting', this.element[0]).each(function() { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); selectee.selecting = false; selectee.selected = true; selectee.startselected = true; self._trigger("selected", event, { selected: selectee.element }); }); this._trigger("stop", event); this.helper.remove(); return false; } }); $.extend($.ui.selectable, { version: "1.8.15" }); })(jQuery); SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.ui.position.js0000644000000000000000000001626312612410632031045 0ustar00rootroot00000000000000/* * jQuery UI Position 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Position */ (function( $, undefined ) { $.ui = $.ui || {}; var horizontalPositions = /left|center|right/, verticalPositions = /top|center|bottom/, center = "center", _position = $.fn.position, _offset = $.fn.offset; $.fn.position = function( options ) { if ( !options || !options.of ) { return _position.apply( this, arguments ); } // make a copy, we don't want to modify arguments options = $.extend( {}, options ); var target = $( options.of ), targetElem = target[0], collision = ( options.collision || "flip" ).split( " " ), offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], targetWidth, targetHeight, basePosition; if ( targetElem.nodeType === 9 ) { targetWidth = target.width(); targetHeight = target.height(); basePosition = { top: 0, left: 0 }; // TODO: use $.isWindow() in 1.9 } else if ( targetElem.setTimeout ) { targetWidth = target.width(); targetHeight = target.height(); basePosition = { top: target.scrollTop(), left: target.scrollLeft() }; } else if ( targetElem.preventDefault ) { // force left top to allow flipping options.at = "left top"; targetWidth = targetHeight = 0; basePosition = { top: options.of.pageY, left: options.of.pageX }; } else { targetWidth = target.outerWidth(); targetHeight = target.outerHeight(); basePosition = target.offset(); } // force my and at to have valid horizontal and veritcal positions // if a value is missing or invalid, it will be converted to center $.each( [ "my", "at" ], function() { var pos = ( options[this] || "" ).split( " " ); if ( pos.length === 1) { pos = horizontalPositions.test( pos[0] ) ? pos.concat( [center] ) : verticalPositions.test( pos[0] ) ? [ center ].concat( pos ) : [ center, center ]; } pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center; pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center; options[ this ] = pos; }); // normalize collision option if ( collision.length === 1 ) { collision[ 1 ] = collision[ 0 ]; } // normalize offset option offset[ 0 ] = parseInt( offset[0], 10 ) || 0; if ( offset.length === 1 ) { offset[ 1 ] = offset[ 0 ]; } offset[ 1 ] = parseInt( offset[1], 10 ) || 0; if ( options.at[0] === "right" ) { basePosition.left += targetWidth; } else if ( options.at[0] === center ) { basePosition.left += targetWidth / 2; } if ( options.at[1] === "bottom" ) { basePosition.top += targetHeight; } else if ( options.at[1] === center ) { basePosition.top += targetHeight / 2; } basePosition.left += offset[ 0 ]; basePosition.top += offset[ 1 ]; return this.each(function() { var elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0, marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0, collisionWidth = elemWidth + marginLeft + ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ), collisionHeight = elemHeight + marginTop + ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ), position = $.extend( {}, basePosition ), collisionPosition; if ( options.my[0] === "right" ) { position.left -= elemWidth; } else if ( options.my[0] === center ) { position.left -= elemWidth / 2; } if ( options.my[1] === "bottom" ) { position.top -= elemHeight; } else if ( options.my[1] === center ) { position.top -= elemHeight / 2; } // prevent fractions (see #5280) position.left = Math.round( position.left ); position.top = Math.round( position.top ); collisionPosition = { left: position.left - marginLeft, top: position.top - marginTop }; $.each( [ "left", "top" ], function( i, dir ) { if ( $.ui.position[ collision[i] ] ) { $.ui.position[ collision[i] ][ dir ]( position, { targetWidth: targetWidth, targetHeight: targetHeight, elemWidth: elemWidth, elemHeight: elemHeight, collisionPosition: collisionPosition, collisionWidth: collisionWidth, collisionHeight: collisionHeight, offset: offset, my: options.my, at: options.at }); } }); if ( $.fn.bgiframe ) { elem.bgiframe(); } elem.offset( $.extend( position, { using: options.using } ) ); }); }; $.ui.position = { fit: { left: function( position, data ) { var win = $( window ), over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(); position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left ); }, top: function( position, data ) { var win = $( window ), over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(); position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top ); } }, flip: { left: function( position, data ) { if ( data.at[0] === center ) { return; } var win = $( window ), over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(), myOffset = data.my[ 0 ] === "left" ? -data.elemWidth : data.my[ 0 ] === "right" ? data.elemWidth : 0, atOffset = data.at[ 0 ] === "left" ? data.targetWidth : -data.targetWidth, offset = -2 * data.offset[ 0 ]; position.left += data.collisionPosition.left < 0 ? myOffset + atOffset + offset : over > 0 ? myOffset + atOffset + offset : 0; }, top: function( position, data ) { if ( data.at[1] === center ) { return; } var win = $( window ), over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(), myOffset = data.my[ 1 ] === "top" ? -data.elemHeight : data.my[ 1 ] === "bottom" ? data.elemHeight : 0, atOffset = data.at[ 1 ] === "top" ? data.targetHeight : -data.targetHeight, offset = -2 * data.offset[ 1 ]; position.top += data.collisionPosition.top < 0 ? myOffset + atOffset + offset : over > 0 ? myOffset + atOffset + offset : 0; } } }; // offset setter from jQuery 1.4 if ( !$.offset.setOffset ) { $.offset.setOffset = function( elem, options ) { // set position first, in-case top/left are set even on static elem if ( /static/.test( $.curCSS( elem, "position" ) ) ) { elem.style.position = "relative"; } var curElem = $( elem ), curOffset = curElem.offset(), curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0, curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0, props = { top: (options.top - curOffset.top) + curTop, left: (options.left - curOffset.left) + curLeft }; if ( 'using' in options ) { options.using.call( elem, props ); } else { curElem.css( props ); } }; $.fn.offset = function( options ) { var elem = this[ 0 ]; if ( !elem || !elem.ownerDocument ) { return null; } if ( options ) { return this.each(function() { $.offset.setOffset( this, options ); }); } return _offset.call( this ); }; } }( jQuery )); SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.ui.draggable.js0000644000000000000000000007433612612410632031116 0ustar00rootroot00000000000000/* * jQuery UI Draggable 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Draggables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function( $, undefined ) { $.widget("ui.draggable", $.ui.mouse, { widgetEventPrefix: "drag", options: { addClasses: true, appendTo: "parent", axis: false, connectToSortable: false, containment: false, cursor: "auto", cursorAt: false, grid: false, handle: false, helper: "original", iframeFix: false, opacity: false, refreshPositions: false, revert: false, revertDuration: 500, scope: "default", scroll: true, scrollSensitivity: 20, scrollSpeed: 20, snap: false, snapMode: "both", snapTolerance: 20, stack: false, zIndex: false }, _create: function() { if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) this.element[0].style.position = 'relative'; (this.options.addClasses && this.element.addClass("ui-draggable")); (this.options.disabled && this.element.addClass("ui-draggable-disabled")); this._mouseInit(); }, destroy: function() { if(!this.element.data('draggable')) return; this.element .removeData("draggable") .unbind(".draggable") .removeClass("ui-draggable" + " ui-draggable-dragging" + " ui-draggable-disabled"); this._mouseDestroy(); return this; }, _mouseCapture: function(event) { var o = this.options; // among others, prevent a drag on a resizable-handle if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) return false; //Quit if we're not on a valid handle this.handle = this._getHandle(event); if (!this.handle) return false; $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { $('
    ') .css({ width: this.offsetWidth+"px", height: this.offsetHeight+"px", position: "absolute", opacity: "0.001", zIndex: 1000 }) .css($(this).offset()) .appendTo("body"); }); return true; }, _mouseStart: function(event) { var o = this.options; //Create and append the visible helper this.helper = this._createHelper(event); //Cache the helper size this._cacheHelperProportions(); //If ddmanager is used for droppables, set the global draggable if($.ui.ddmanager) $.ui.ddmanager.current = this; /* * - Position generation - * This block generates everything position related - it's the core of draggables. */ //Cache the margins of the original element this._cacheMargins(); //Store the helper's css position this.cssPosition = this.helper.css("position"); this.scrollParent = this.helper.scrollParent(); //The element's absolute position on the page minus margins this.offset = this.positionAbs = this.element.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left }; $.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); //Generate the original position this.originalPosition = this.position = this._generatePosition(event); this.originalPageX = event.pageX; this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); //Set a containment if given in the options if(o.containment) this._setContainment(); //Trigger event + callbacks if(this._trigger("start", event) === false) { this._clear(); return false; } //Recache the helper size this._cacheHelperProportions(); //Prepare the droppable offsets if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, event); this.helper.addClass("ui-draggable-dragging"); this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); return true; }, _mouseDrag: function(event, noPropagation) { //Compute the helpers position this.position = this._generatePosition(event); this.positionAbs = this._convertPositionTo("absolute"); //Call plugins and callbacks and use the resulting position if something is returned if (!noPropagation) { var ui = this._uiHash(); if(this._trigger('drag', event, ui) === false) { this._mouseUp({}); return false; } this.position = ui.position; } if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); return false; }, _mouseStop: function(event) { //If we are using droppables, inform the manager about the drop var dropped = false; if ($.ui.ddmanager && !this.options.dropBehaviour) dropped = $.ui.ddmanager.drop(this, event); //if a drop comes from outside (a sortable) if(this.dropped) { dropped = this.dropped; this.dropped = false; } //if the original element is removed, don't bother to continue if helper is set to "original" if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original") return false; if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { var self = this; $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { if(self._trigger("stop", event) !== false) { self._clear(); } }); } else { if(this._trigger("stop", event) !== false) { this._clear(); } } return false; }, _mouseUp: function(event) { if (this.options.iframeFix === true) { $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers } //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); return $.ui.mouse.prototype._mouseUp.call(this, event); }, cancel: function() { if(this.helper.is(".ui-draggable-dragging")) { this._mouseUp({}); } else { this._clear(); } return this; }, _getHandle: function(event) { var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; $(this.options.handle, this.element) .find("*") .andSelf() .each(function() { if(this == event.target) handle = true; }); return handle; }, _createHelper: function(event) { var o = this.options; var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); if(!helper.parents('body').length) helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) helper.css("position", "absolute"); return helper; }, _adjustOffsetFromHelper: function(obj) { if (typeof obj == 'string') { obj = obj.split(' '); } if ($.isArray(obj)) { obj = {left: +obj[0], top: +obj[1] || 0}; } if ('left' in obj) { this.offset.click.left = obj.left + this.margins.left; } if ('right' in obj) { this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; } if ('top' in obj) { this.offset.click.top = obj.top + this.margins.top; } if ('bottom' in obj) { this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } }, _getParentOffset: function() { //Get the offsetParent and cache its position this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); // This is a special case where we need to modify a offset calculated on start, since the following happened: // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix po = { top: 0, left: 0 }; return { top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) }; }, _getRelativeOffset: function() { if(this.cssPosition == "relative") { var p = this.element.position(); return { top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; } }, _cacheMargins: function() { this.margins = { left: (parseInt(this.element.css("marginLeft"),10) || 0), top: (parseInt(this.element.css("marginTop"),10) || 0), right: (parseInt(this.element.css("marginRight"),10) || 0), bottom: (parseInt(this.element.css("marginBottom"),10) || 0) }; }, _cacheHelperProportions: function() { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, _setContainment: function() { var o = this.options; if(o.containment == 'parent') o.containment = this.helper[0].parentNode; if(o.containment == 'document' || o.containment == 'window') this.containment = [ o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top ]; if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { var c = $(o.containment); var ce = c[0]; if(!ce) return; var co = c.offset(); var over = ($(ce).css("overflow") != 'hidden'); this.containment = [ (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom ]; this.relative_container = c; } else if(o.containment.constructor == Array) { this.containment = o.containment; } }, _convertPositionTo: function(d, pos) { if(!pos) pos = this.position; var mod = d == "absolute" ? 1 : -1; var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); return { top: ( pos.top // The absolute mouse position + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) ), left: ( pos.left // The absolute mouse position + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) ) }; }, _generatePosition: function(event) { var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); var pageX = event.pageX; var pageY = event.pageY; /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ if(this.originalPosition) { //If we are not dragging yet, we won't check for options var containment; if(this.containment) { if (this.relative_container){ var co = this.relative_container.offset(); containment = [ this.containment[0] + co.left, this.containment[1] + co.top, this.containment[2] + co.left, this.containment[3] + co.top ]; } else { containment = this.containment; } if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; } if(o.grid) { //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; } } return { top: ( pageY // The absolute mouse position - this.offset.click.top // Click offset (relative to the element) - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) ), left: ( pageX // The absolute mouse position - this.offset.click.left // Click offset (relative to the element) - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) ) }; }, _clear: function() { this.helper.removeClass("ui-draggable-dragging"); if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); //if($.ui.ddmanager) $.ui.ddmanager.current = null; this.helper = null; this.cancelHelperRemoval = false; }, // From now on bulk stuff - mainly helpers _trigger: function(type, event, ui) { ui = ui || this._uiHash(); $.ui.plugin.call(this, type, [event, ui]); if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins return $.Widget.prototype._trigger.call(this, type, event, ui); }, plugins: {}, _uiHash: function(event) { return { helper: this.helper, position: this.position, originalPosition: this.originalPosition, offset: this.positionAbs }; } }); $.extend($.ui.draggable, { version: "1.8.15" }); $.ui.plugin.add("draggable", "connectToSortable", { start: function(event, ui) { var inst = $(this).data("draggable"), o = inst.options, uiSortable = $.extend({}, ui, { item: inst.element }); inst.sortables = []; $(o.connectToSortable).each(function() { var sortable = $.data(this, 'sortable'); if (sortable && !sortable.options.disabled) { inst.sortables.push({ instance: sortable, shouldRevert: sortable.options.revert }); sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). sortable._trigger("activate", event, uiSortable); } }); }, stop: function(event, ui) { //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper var inst = $(this).data("draggable"), uiSortable = $.extend({}, ui, { item: inst.element }); $.each(inst.sortables, function() { if(this.instance.isOver) { this.instance.isOver = 0; inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' if(this.shouldRevert) this.instance.options.revert = true; //Trigger the stop of the sortable this.instance._mouseStop(event); this.instance.options.helper = this.instance.options._helper; //If the helper has been the original item, restore properties in the sortable if(inst.options.helper == 'original') this.instance.currentItem.css({ top: 'auto', left: 'auto' }); } else { this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance this.instance._trigger("deactivate", event, uiSortable); } }); }, drag: function(event, ui) { var inst = $(this).data("draggable"), self = this; var checkPos = function(o) { var dyClick = this.offset.click.top, dxClick = this.offset.click.left; var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; var itemHeight = o.height, itemWidth = o.width; var itemTop = o.top, itemLeft = o.left; return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); }; $.each(inst.sortables, function(i) { //Copy over some variables to allow calling the sortable's native _intersectsWith this.instance.positionAbs = inst.positionAbs; this.instance.helperProportions = inst.helperProportions; this.instance.offset.click = inst.offset.click; if(this.instance._intersectsWith(this.instance.containerCache)) { //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once if(!this.instance.isOver) { this.instance.isOver = 1; //Now we fake the start of dragging for the sortable instance, //by cloning the list group item, appending it to the sortable and using it as inst.currentItem //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it this.instance.options.helper = function() { return ui.helper[0]; }; event.target = this.instance.currentItem[0]; this.instance._mouseCapture(event, true); this.instance._mouseStart(event, true, true); //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes this.instance.offset.click.top = inst.offset.click.top; this.instance.offset.click.left = inst.offset.click.left; this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; inst._trigger("toSortable", event); inst.dropped = this.instance.element; //draggable revert needs that //hack so receive/update callbacks work (mostly) inst.currentItem = inst.element; this.instance.fromOutside = inst; } //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable if(this.instance.currentItem) this.instance._mouseDrag(event); } else { //If it doesn't intersect with the sortable, and it intersected before, //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval if(this.instance.isOver) { this.instance.isOver = 0; this.instance.cancelHelperRemoval = true; //Prevent reverting on this forced stop this.instance.options.revert = false; // The out event needs to be triggered independently this.instance._trigger('out', event, this.instance._uiHash(this.instance)); this.instance._mouseStop(event, true); this.instance.options.helper = this.instance.options._helper; //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size this.instance.currentItem.remove(); if(this.instance.placeholder) this.instance.placeholder.remove(); inst._trigger("fromSortable", event); inst.dropped = false; //draggable revert needs that } }; }); } }); $.ui.plugin.add("draggable", "cursor", { start: function(event, ui) { var t = $('body'), o = $(this).data('draggable').options; if (t.css("cursor")) o._cursor = t.css("cursor"); t.css("cursor", o.cursor); }, stop: function(event, ui) { var o = $(this).data('draggable').options; if (o._cursor) $('body').css("cursor", o._cursor); } }); $.ui.plugin.add("draggable", "opacity", { start: function(event, ui) { var t = $(ui.helper), o = $(this).data('draggable').options; if(t.css("opacity")) o._opacity = t.css("opacity"); t.css('opacity', o.opacity); }, stop: function(event, ui) { var o = $(this).data('draggable').options; if(o._opacity) $(ui.helper).css('opacity', o._opacity); } }); $.ui.plugin.add("draggable", "scroll", { start: function(event, ui) { var i = $(this).data("draggable"); if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); }, drag: function(event, ui) { var i = $(this).data("draggable"), o = i.options, scrolled = false; if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { if(!o.axis || o.axis != 'x') { if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; } if(!o.axis || o.axis != 'y') { if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; } } else { if(!o.axis || o.axis != 'x') { if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); } if(!o.axis || o.axis != 'y') { if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } } if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(i, event); } }); $.ui.plugin.add("draggable", "snap", { start: function(event, ui) { var i = $(this).data("draggable"), o = i.options; i.snapElements = []; $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { var $t = $(this); var $o = $t.offset(); if(this != i.element[0]) i.snapElements.push({ item: this, width: $t.outerWidth(), height: $t.outerHeight(), top: $o.top, left: $o.left }); }); }, drag: function(event, ui) { var inst = $(this).data("draggable"), o = inst.options; var d = o.snapTolerance; var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; for (var i = inst.snapElements.length - 1; i >= 0; i--){ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; //Yes, I know, this is insane ;) if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); inst.snapElements[i].snapping = false; continue; } if(o.snapMode != 'inner') { var ts = Math.abs(t - y2) <= d; var bs = Math.abs(b - y1) <= d; var ls = Math.abs(l - x2) <= d; var rs = Math.abs(r - x1) <= d; if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; } var first = (ts || bs || ls || rs); if(o.snapMode != 'outer') { var ts = Math.abs(t - y1) <= d; var bs = Math.abs(b - y2) <= d; var ls = Math.abs(l - x1) <= d; var rs = Math.abs(r - x2) <= d; if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; } if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); inst.snapElements[i].snapping = (ts || bs || ls || rs || first); }; } }); $.ui.plugin.add("draggable", "stack", { start: function(event, ui) { var o = $(this).data("draggable").options; var group = $.makeArray($(o.stack)).sort(function(a,b) { return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); }); if (!group.length) { return; } var min = parseInt(group[0].style.zIndex) || 0; $(group).each(function(i) { this.style.zIndex = min + i; }); this[0].style.zIndex = min + group.length; } }); $.ui.plugin.add("draggable", "zIndex", { start: function(event, ui) { var t = $(ui.helper), o = $(this).data("draggable").options; if(t.css("zIndex")) o._zIndex = t.css("zIndex"); t.css('zIndex', o.zIndex); }, stop: function(event, ui) { var o = $(this).data("draggable").options; if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); } }); })(jQuery); SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.cookie_1.0.js0000644000000000000000000000720112612410632030404 0ustar00rootroot00000000000000/*jslint browser: true */ /*global jQuery: true */ /** * jQuery Cookie plugin * * Copyright (c) 2010 Klaus Hartl (stilbuero.de) * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * */ // TODO JsDoc /** * Create a cookie with the given key and value and other optional parameters. * * @example $.cookie('the_cookie', 'the_value'); * @desc Set the value of a cookie. * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); * @desc Create a cookie with all available options. * @example $.cookie('the_cookie', 'the_value'); * @desc Create a session cookie. * @example $.cookie('the_cookie', null); * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain * used when the cookie was set. * * @param String key The key of the cookie. * @param String value The value of the cookie. * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. * If set to null or omitted, the cookie will be a session cookie and will not be retained * when the the browser exits. * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will * require a secure protocol (like HTTPS). * @type undefined * * @name $.cookie * @cat Plugins/Cookie * @author Klaus Hartl/klaus.hartl@stilbuero.de */ /** * Get the value of a cookie with the given key. * * @example $.cookie('the_cookie'); * @desc Get the value of a cookie. * * @param String key The key of the cookie. * @return The value of the cookie. * @type String * * @name $.cookie * @cat Plugins/Cookie * @author Klaus Hartl/klaus.hartl@stilbuero.de */ jQuery.cookie = function (key, value, options) { // key and at least value given, set cookie... if (arguments.length > 1 && String(value) !== "[object Object]") { options = jQuery.extend({}, options); if (value === null || value === undefined) { options.expires = -1; } if (typeof options.expires === 'number') { var days = options.expires, t = options.expires = new Date(); t.setDate(t.getDate() + days); } value = String(value); return (document.cookie = [ encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value), options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE options.path ? '; path=' + options.path : '', options.domain ? '; domain=' + options.domain : '', options.secure ? '; secure' : '' ].join('')); } // key and possibly options given, get cookie... options = value || {}; var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent; return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null; }; SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.ui.button.js0000644000000000000000000002605312612410632030512 0ustar00rootroot00000000000000/* * jQuery UI Button 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Button * * Depends: * jquery.ui.core.js * jquery.ui.widget.js */ (function( $, undefined ) { var lastActive, startXPos, startYPos, clickDragged, baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", stateClasses = "ui-state-hover ui-state-active ", typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", formResetHandler = function() { var buttons = $( this ).find( ":ui-button" ); setTimeout(function() { buttons.button( "refresh" ); }, 1 ); }, radioGroup = function( radio ) { var name = radio.name, form = radio.form, radios = $( [] ); if ( name ) { if ( form ) { radios = $( form ).find( "[name='" + name + "']" ); } else { radios = $( "[name='" + name + "']", radio.ownerDocument ) .filter(function() { return !this.form; }); } } return radios; }; $.widget( "ui.button", { options: { disabled: null, text: true, label: null, icons: { primary: null, secondary: null } }, _create: function() { this.element.closest( "form" ) .unbind( "reset.button" ) .bind( "reset.button", formResetHandler ); if ( typeof this.options.disabled !== "boolean" ) { this.options.disabled = this.element.propAttr( "disabled" ); } this._determineButtonType(); this.hasTitle = !!this.buttonElement.attr( "title" ); var self = this, options = this.options, toggleButton = this.type === "checkbox" || this.type === "radio", hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ), focusClass = "ui-state-focus"; if ( options.label === null ) { options.label = this.buttonElement.html(); } if ( this.element.is( ":disabled" ) ) { options.disabled = true; } this.buttonElement .addClass( baseClasses ) .attr( "role", "button" ) .bind( "mouseenter.button", function() { if ( options.disabled ) { return; } $( this ).addClass( "ui-state-hover" ); if ( this === lastActive ) { $( this ).addClass( "ui-state-active" ); } }) .bind( "mouseleave.button", function() { if ( options.disabled ) { return; } $( this ).removeClass( hoverClass ); }) .bind( "click.button", function( event ) { if ( options.disabled ) { event.preventDefault(); event.stopImmediatePropagation(); } }); this.element .bind( "focus.button", function() { // no need to check disabled, focus won't be triggered anyway self.buttonElement.addClass( focusClass ); }) .bind( "blur.button", function() { self.buttonElement.removeClass( focusClass ); }); if ( toggleButton ) { this.element.bind( "change.button", function() { if ( clickDragged ) { return; } self.refresh(); }); // if mouse moves between mousedown and mouseup (drag) set clickDragged flag // prevents issue where button state changes but checkbox/radio checked state // does not in Firefox (see ticket #6970) this.buttonElement .bind( "mousedown.button", function( event ) { if ( options.disabled ) { return; } clickDragged = false; startXPos = event.pageX; startYPos = event.pageY; }) .bind( "mouseup.button", function( event ) { if ( options.disabled ) { return; } if ( startXPos !== event.pageX || startYPos !== event.pageY ) { clickDragged = true; } }); } if ( this.type === "checkbox" ) { this.buttonElement.bind( "click.button", function() { if ( options.disabled || clickDragged ) { return false; } $( this ).toggleClass( "ui-state-active" ); self.buttonElement.attr( "aria-pressed", self.element[0].checked ); }); } else if ( this.type === "radio" ) { this.buttonElement.bind( "click.button", function() { if ( options.disabled || clickDragged ) { return false; } $( this ).addClass( "ui-state-active" ); self.buttonElement.attr( "aria-pressed", "true" ); var radio = self.element[ 0 ]; radioGroup( radio ) .not( radio ) .map(function() { return $( this ).button( "widget" )[ 0 ]; }) .removeClass( "ui-state-active" ) .attr( "aria-pressed", "false" ); }); } else { this.buttonElement .bind( "mousedown.button", function() { if ( options.disabled ) { return false; } $( this ).addClass( "ui-state-active" ); lastActive = this; $( document ).one( "mouseup", function() { lastActive = null; }); }) .bind( "mouseup.button", function() { if ( options.disabled ) { return false; } $( this ).removeClass( "ui-state-active" ); }) .bind( "keydown.button", function(event) { if ( options.disabled ) { return false; } if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) { $( this ).addClass( "ui-state-active" ); } }) .bind( "keyup.button", function() { $( this ).removeClass( "ui-state-active" ); }); if ( this.buttonElement.is("a") ) { this.buttonElement.keyup(function(event) { if ( event.keyCode === $.ui.keyCode.SPACE ) { // TODO pass through original event correctly (just as 2nd argument doesn't work) $( this ).click(); } }); } } // TODO: pull out $.Widget's handling for the disabled option into // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can // be overridden by individual plugins this._setOption( "disabled", options.disabled ); this._resetButton(); }, _determineButtonType: function() { if ( this.element.is(":checkbox") ) { this.type = "checkbox"; } else if ( this.element.is(":radio") ) { this.type = "radio"; } else if ( this.element.is("input") ) { this.type = "input"; } else { this.type = "button"; } if ( this.type === "checkbox" || this.type === "radio" ) { // we don't search against the document in case the element // is disconnected from the DOM var ancestor = this.element.parents().filter(":last"), labelSelector = "label[for=" + this.element.attr("id") + "]"; this.buttonElement = ancestor.find( labelSelector ); if ( !this.buttonElement.length ) { ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); this.buttonElement = ancestor.filter( labelSelector ); if ( !this.buttonElement.length ) { this.buttonElement = ancestor.find( labelSelector ); } } this.element.addClass( "ui-helper-hidden-accessible" ); var checked = this.element.is( ":checked" ); if ( checked ) { this.buttonElement.addClass( "ui-state-active" ); } this.buttonElement.attr( "aria-pressed", checked ); } else { this.buttonElement = this.element; } }, widget: function() { return this.buttonElement; }, destroy: function() { this.element .removeClass( "ui-helper-hidden-accessible" ); this.buttonElement .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) .removeAttr( "role" ) .removeAttr( "aria-pressed" ) .html( this.buttonElement.find(".ui-button-text").html() ); if ( !this.hasTitle ) { this.buttonElement.removeAttr( "title" ); } $.Widget.prototype.destroy.call( this ); }, _setOption: function( key, value ) { $.Widget.prototype._setOption.apply( this, arguments ); if ( key === "disabled" ) { if ( value ) { this.element.propAttr( "disabled", true ); } else { this.element.propAttr( "disabled", false ); } return; } this._resetButton(); }, refresh: function() { var isDisabled = this.element.is( ":disabled" ); if ( isDisabled !== this.options.disabled ) { this._setOption( "disabled", isDisabled ); } if ( this.type === "radio" ) { radioGroup( this.element[0] ).each(function() { if ( $( this ).is( ":checked" ) ) { $( this ).button( "widget" ) .addClass( "ui-state-active" ) .attr( "aria-pressed", "true" ); } else { $( this ).button( "widget" ) .removeClass( "ui-state-active" ) .attr( "aria-pressed", "false" ); } }); } else if ( this.type === "checkbox" ) { if ( this.element.is( ":checked" ) ) { this.buttonElement .addClass( "ui-state-active" ) .attr( "aria-pressed", "true" ); } else { this.buttonElement .removeClass( "ui-state-active" ) .attr( "aria-pressed", "false" ); } } }, _resetButton: function() { if ( this.type === "input" ) { if ( this.options.label ) { this.element.val( this.options.label ); } return; } var buttonElement = this.buttonElement.removeClass( typeClasses ), buttonText = $( "" ) .addClass( "ui-button-text" ) .html( this.options.label ) .appendTo( buttonElement.empty() ) .text(), icons = this.options.icons, multipleIcons = icons.primary && icons.secondary, buttonClasses = []; if ( icons.primary || icons.secondary ) { if ( this.options.text ) { buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); } if ( icons.primary ) { buttonElement.prepend( "" ); } if ( icons.secondary ) { buttonElement.append( "" ); } if ( !this.options.text ) { buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); if ( !this.hasTitle ) { buttonElement.attr( "title", buttonText ); } } } else { buttonClasses.push( "ui-button-text-only" ); } buttonElement.addClass( buttonClasses.join( " " ) ); } }); $.widget( "ui.buttonset", { options: { items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" }, _create: function() { this.element.addClass( "ui-buttonset" ); }, _init: function() { this.refresh(); }, _setOption: function( key, value ) { if ( key === "disabled" ) { this.buttons.button( "option", key, value ); } $.Widget.prototype._setOption.apply( this, arguments ); }, refresh: function() { var ltr = this.element.css( "direction" ) === "ltr"; this.buttons = this.element.find( this.options.items ) .filter( ":ui-button" ) .button( "refresh" ) .end() .not( ":ui-button" ) .button() .end() .map(function() { return $( this ).button( "widget" )[ 0 ]; }) .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) .filter( ":first" ) .addClass( ltr ? "ui-corner-left" : "ui-corner-right" ) .end() .filter( ":last" ) .addClass( ltr ? "ui-corner-right" : "ui-corner-left" ) .end() .end(); }, destroy: function() { this.element.removeClass( "ui-buttonset" ); this.buttons .map(function() { return $( this ).button( "widget" )[ 0 ]; }) .removeClass( "ui-corner-left ui-corner-right" ) .end() .button( "destroy" ); $.Widget.prototype.destroy.call( this ); } }); }( jQuery ) ); SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/lib.js0000644000000000000000000000055412612413171026012 0ustar00rootroot00000000000000This directory holds sources for minified javascript files, for Debian policy compliance reasons. # interfaces/Plush/templates/static/javascripts/lib.js jQuery v1.6.2 incl. Sizzle.js jQuery UI 1.8.15 ColorBox v1.3.17.2 jQuery Cookie plugin 1.0 jQuery hoverIntent r5 jquery livequery 1.1.1 Superfish v1.4.8 TableDnD 0.5 Ajax webtoolkit RateIt jQuery plugin 1.0.13 SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.rateit.js0000644000000000000000000003476312612410632030062 0ustar00rootroot00000000000000/* RateIt version 1.0.13 08/17/2013 http://rateit.codeplex.com Twitter: @gjunge */ (function ($) { $.rateit = { aria : { resetLabel: 'reset rating', ratingLabel: 'rating' } } $.fn.rateit = function (p1, p2) { //quick way out. var index = 1; var options = {}; var mode = 'init'; var capitaliseFirstLetter = function (string) { return string.charAt(0).toUpperCase() + string.substr(1); }; if (this.length == 0) return this; var tp1 = $.type(p1); if (tp1 == 'object' || p1 === undefined || p1 == null) { options = $.extend({}, $.fn.rateit.defaults, p1); //wants to init new rateit plugin(s). } else if (tp1 == 'string' && p2 === undefined) { return this.data('rateit' + capitaliseFirstLetter(p1)); //wants to get a value. } else if (tp1 == 'string') { mode = 'setvalue' } return this.each(function () { var item = $(this); //shorten all the item.data('rateit-XXX'), will save space in closure compiler, will be like item.data('XXX') will become x('XXX') var itemdata = function (key, value) { if (value != null) { //update aria values var ariakey = 'aria-value' + ((key == 'value') ? 'now' : key); var range = item.find('.rateit-range'); if (range.attr(ariakey) != undefined) { range.attr(ariakey, value); } } arguments[0] = 'rateit' + capitaliseFirstLetter(key); return item.data.apply(item, arguments); ////Fix for WI: 523 }; //add the rate it class. if (!item.hasClass('rateit')) item.addClass('rateit'); var ltr = item.css('direction') != 'rtl'; // set value mode if (mode == 'setvalue') { if (!itemdata('init')) throw 'Can\'t set value before init'; //if readonly now and it wasn't readonly, remove the eventhandlers. if (p1 == 'readonly' && p2 == true && !itemdata('readonly')) { item.find('.rateit-range').unbind(); itemdata('wired', false); } //when we receive a null value, reset the score to its min value. if (p1 == 'value') p2 = (p2 == null) ? itemdata('min') : Math.max(itemdata('min'), Math.min(itemdata('max'), p2)); if (itemdata('backingfld')) { //if we have a backing field, check which fields we should update. //In case of input[type=range], although we did read its attributes even in browsers that don't support it (using fld.attr()) //we only update it in browser that support it (&& fld[0].min only works in supporting browsers), not only does it save us from checking if it is range input type, it also is unnecessary. var fld = $(itemdata('backingfld')); if (p1 == 'value') fld.val(p2); if (p1 == 'min' && fld[0].min) fld[0].min = p2; if (p1 == 'max' && fld[0].max) fld[0].max = p2; if (p1 == 'step' && fld[0].step) fld[0].step = p2; } itemdata(p1, p2); } //init rateit plugin if (!itemdata('init')) { //get our values, either from the data-* html5 attribute or from the options. itemdata('min', itemdata('min') || options.min); itemdata('max', itemdata('max') || options.max); itemdata('step', itemdata('step') || options.step); itemdata('readonly', itemdata('readonly') !== undefined ? itemdata('readonly') : options.readonly); itemdata('resetable', itemdata('resetable') !== undefined ? itemdata('resetable') : options.resetable); itemdata('backingfld', itemdata('backingfld') || options.backingfld); itemdata('starwidth', itemdata('starwidth') || options.starwidth); itemdata('starheight', itemdata('starheight') || options.starheight); itemdata('value', Math.max(itemdata('min'), Math.min(itemdata('max'), (itemdata('value') || options.value || options.min) ))); itemdata('ispreset', itemdata('ispreset') !== undefined ? itemdata('ispreset') : options.ispreset); //are we LTR or RTL? if (itemdata('backingfld')) { //if we have a backing field, hide it, and get its value, and override defaults if range. var fld = $(itemdata('backingfld')); itemdata('value', fld.hide().val()); if (fld.attr('disabled') || fld.attr('readonly')) itemdata('readonly', true); //http://rateit.codeplex.com/discussions/362055 , if a backing field is disabled or readonly at instantiation, make rateit readonly. if (fld[0].nodeName == 'INPUT') { if (fld[0].type == 'range' || fld[0].type == 'text') { //in browsers not support the range type, it defaults to text itemdata('min', parseInt(fld.attr('min')) || itemdata('min')); //if we would have done fld[0].min it wouldn't have worked in browsers not supporting the range type. itemdata('max', parseInt(fld.attr('max')) || itemdata('max')); itemdata('step', parseInt(fld.attr('step')) || itemdata('step')); } } if (fld[0].nodeName == 'SELECT' && fld[0].options.length > 1) { itemdata('min', Number(fld[0].options[0].value)); itemdata('max', Number(fld[0].options[fld[0].length - 1].value)); itemdata('step', Number(fld[0].options[1].value) - Number(fld[0].options[0].value)); } } //Create the necessary tags. For ARIA purposes we need to give the items an ID. So we use an internal index to create unique ids var element = item[0].nodeName == 'DIV' ? 'div' : 'span'; index++; var html = '<{{element}} id="rateit-range-{{index}}" class="rateit-range" tabindex="0" role="slider" aria-label="' + $.rateit.aria.ratingLabel + '" aria-owns="rateit-reset-{{index}}" aria-valuemin="' + itemdata('min') + '" aria-valuemax="' + itemdata('max') + '" aria-valuenow="' + itemdata('value') + '"><{{element}} class="rateit-selected" style="height:' + itemdata('starheight') + 'px"><{{element}} class="rateit-hover" style="height:' + itemdata('starheight') + 'px">'; item.append(html.replace(/{{index}}/gi, index).replace(/{{element}}/gi, element)); //if we are in RTL mode, we have to change the float of the "reset button" if (!ltr) { item.find('.rateit-reset').css('float', 'right'); item.find('.rateit-selected').addClass('rateit-selected-rtl'); item.find('.rateit-hover').addClass('rateit-hover-rtl'); } itemdata('init', true); } //set the range element to fit all the stars. var range = item.find('.rateit-range'); range.width(itemdata('starwidth') * (itemdata('max') - itemdata('min'))).height(itemdata('starheight')); //add/remove the preset class var presetclass = 'rateit-preset' + ((ltr) ? '' : '-rtl'); if (itemdata('ispreset')) item.find('.rateit-selected').addClass(presetclass); else item.find('.rateit-selected').removeClass(presetclass); //set the value if we have it. if (itemdata('value') != null) { var score = (itemdata('value') - itemdata('min')) * itemdata('starwidth'); item.find('.rateit-selected').width(score); } //setup the reset button var resetbtn = item.find('.rateit-reset'); if (resetbtn.data('wired') !== true) { resetbtn.bind('click', function (e) { e.preventDefault(); resetbtn.blur(); itemdata('value', itemdata('min')); range.find('.rateit-hover').hide().width(0); range.find('.rateit-selected').width(0).show(); if (itemdata('backingfld')) $(itemdata('backingfld')).val(itemdata('min')); item.trigger('reset'); }).data('wired', true); } //this function calculates the score based on the current position of the mouse. var calcRawScore = function (element, event) { var pageX = (event.changedTouches) ? event.changedTouches[0].pageX : event.pageX; var offsetx = pageX - $(element).offset().left; if (!ltr) offsetx = range.width() - offsetx; if (offsetx > range.width()) offsetx = range.width(); if (offsetx < 0) offsetx = 0; return score = Math.ceil(offsetx / itemdata('starwidth') * (1 / itemdata('step'))); }; //sets the hover element based on the score. var setHover = function (score) { var w = score * itemdata('starwidth') * itemdata('step'); var h = range.find('.rateit-hover'); if (h.data('width') != w) { range.find('.rateit-selected').hide(); h.width(w).show().data('width', w); var data = [(score * itemdata('step')) + itemdata('min')]; item.trigger('hover', data).trigger('over', data); } }; var setSelection = function (value) { itemdata('value', value); if (itemdata('backingfld')) { $(itemdata('backingfld')).val(value); } if (itemdata('ispreset')) { //if it was a preset value, unset that. range.find('.rateit-selected').removeClass(presetclass); itemdata('ispreset', false); } range.find('.rateit-hover').hide(); range.find('.rateit-selected').width(value * itemdata('starwidth') - (itemdata('min') * itemdata('starwidth'))).show(); item.trigger('hover', [null]).trigger('over', [null]).trigger('rated', [value]); }; if (!itemdata('readonly')) { //if we are not read only, add all the events //if we have a reset button, set the event handler. if (!itemdata('resetable')) resetbtn.hide(); //when the mouse goes over the range element, we set the "hover" stars. if (!itemdata('wired')) { range.bind('touchmove touchend', touchHandler); //bind touch events range.mousemove(function (e) { var score = calcRawScore(this, e); setHover(score); }); //when the mouse leaves the range, we have to hide the hover stars, and show the current value. range.mouseleave(function (e) { range.find('.rateit-hover').hide().width(0).data('width', ''); item.trigger('hover', [null]).trigger('over', [null]); range.find('.rateit-selected').show(); }); //when we click on the range, we have to set the value, hide the hover. range.mouseup(function (e) { var score = calcRawScore(this, e); var value = (score * itemdata('step')) + itemdata('min'); setSelection(value); }); //support key nav range.keyup( function (e) { if (e.which == 38 || e.which == (ltr ? 39 : 37)) { setSelection(Math.min(itemdata('value') + itemdata('step'), itemdata('max'))); } if (e.which == 40 || e.which == (ltr ? 37 : 39)) { setSelection(Math.max(itemdata('value') - itemdata('step'), itemdata('min'))); } }); itemdata('wired', true); } if (itemdata('resetable')) { resetbtn.show(); } } else { resetbtn.hide(); } range.attr('aria-readonly', itemdata('readonly')); }); }; //touch converter http://ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript/ function touchHandler(event) { var touches = event.originalEvent.changedTouches, first = touches[0], type = ""; switch (event.type) { case "touchmove": type = "mousemove"; break; case "touchend": type = "mouseup"; break; default: return; } var simulatedEvent = document.createEvent("MouseEvent"); simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0/*left*/, null); first.target.dispatchEvent(simulatedEvent); event.preventDefault(); }; //some default values. $.fn.rateit.defaults = { min: 0, max: 5, step: 0.5, starwidth: 16, starheight: 16, readonly: false, resetable: true, ispreset: false}; //invoke it on all .rateit elements. This could be removed if not wanted. $(function () { $('div.rateit, span.rateit').rateit(); }); })(jQuery);SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.hoverIntent.r5.js0000644000000000000000000001066212612410632031414 0ustar00rootroot00000000000000/** * hoverIntent is similar to jQuery's built-in "hover" function except that * instead of firing the onMouseOver event immediately, hoverIntent checks * to see if the user's mouse has slowed down (beneath the sensitivity * threshold) before firing the onMouseOver event. * * hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+ * * * hoverIntent is currently available for use in all personal or commercial * projects under both MIT and GPL licenses. This means that you can choose * the license that best suits your project, and use it accordingly. * * // basic usage (just like .hover) receives onMouseOver and onMouseOut functions * $("ul li").hoverIntent( showNav , hideNav ); * * // advanced usage receives configuration object only * $("ul li").hoverIntent({ * sensitivity: 7, // number = sensitivity threshold (must be 1 or higher) * interval: 100, // number = milliseconds of polling interval * over: showNav, // function = onMouseOver callback (required) * timeout: 0, // number = milliseconds delay before onMouseOut function call * out: hideNav // function = onMouseOut callback (required) * }); * * @param f onMouseOver function || An object with configuration options * @param g onMouseOut function || Nothing (use configuration options object) * @author Brian Cherne */ (function($) { $.fn.hoverIntent = function(f,g) { // default configuration options var cfg = { sensitivity: 7, interval: 100, timeout: 0 }; // override configuration options with user supplied object cfg = $.extend(cfg, g ? { over: f, out: g } : f ); // instantiate variables // cX, cY = current X and Y position of mouse, updated by mousemove event // pX, pY = previous X and Y position of mouse, set by mouseover and polling interval var cX, cY, pX, pY; // A private function for getting mouse position var track = function(ev) { cX = ev.pageX; cY = ev.pageY; }; // A private function for comparing current and previous mouse position var compare = function(ev,ob) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); // compare mouse positions to see if they've crossed the threshold if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { $(ob).unbind("mousemove",track); // set hoverIntent state to true (so mouseOut can be called) ob.hoverIntent_s = 1; return cfg.over.apply(ob,[ev]); } else { // set previous coordinates for next time pX = cX; pY = cY; // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval ); } }; // A private function for delaying the mouseOut function var delay = function(ev,ob) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); ob.hoverIntent_s = 0; return cfg.out.apply(ob,[ev]); }; // A private function for handling mouse 'hovering' var handleHover = function(e) { // next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget; while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } } if ( p == this ) { return false; } // copy objects to be passed into t (required for event object to be passed in IE) var ev = jQuery.extend({},e); var ob = this; // cancel hoverIntent timer if it exists if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); } // else e.type == "onmouseover" if (e.type == "mouseover") { // set "previous" X and Y position based on initial entry point pX = ev.pageX; pY = ev.pageY; // update "current" X and Y position based on mousemove $(ob).bind("mousemove",track); // start polling interval (self-calling timeout) to compare mouse coordinates over time if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );} // else e.type == "onmouseout" } else { // unbind expensive mousemove event $(ob).unbind("mousemove",track); // if hoverIntent state is true, then call the mouseOut function after the specified delay if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );} } }; // bind the function to the two event listeners return this.mouseover(handleHover).mouseout(handleHover); }; })(jQuery); SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.ui.resizable.js0000644000000000000000000006621312612410632031161 0ustar00rootroot00000000000000/* * jQuery UI Resizable 1.8.15 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Resizables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function( $, undefined ) { $.widget("ui.resizable", $.ui.mouse, { widgetEventPrefix: "resize", options: { alsoResize: false, animate: false, animateDuration: "slow", animateEasing: "swing", aspectRatio: false, autoHide: false, containment: false, ghost: false, grid: false, handles: "e,s,se", helper: false, maxHeight: null, maxWidth: null, minHeight: 10, minWidth: 10, zIndex: 1000 }, _create: function() { var self = this, o = this.options; this.element.addClass("ui-resizable"); $.extend(this, { _aspectRatio: !!(o.aspectRatio), aspectRatio: o.aspectRatio, originalElement: this.element, _proportionallyResizeElements: [], _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null }); //Wrap the element if it cannot hold child nodes if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { //Opera fix for relative positioning if (/relative/.test(this.element.css('position')) && $.browser.opera) this.element.css({ position: 'relative', top: 'auto', left: 'auto' }); //Create a wrapper element and set the wrapper to the new current internal element this.element.wrap( $('
    ').css({ position: this.element.css('position'), width: this.element.outerWidth(), height: this.element.outerHeight(), top: this.element.css('top'), left: this.element.css('left') }) ); //Overwrite the original this.element this.element = this.element.parent().data( "resizable", this.element.data('resizable') ); this.elementIsWrapper = true; //Move margins to the wrapper this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); //Prevent Safari textarea resize this.originalResizeStyle = this.originalElement.css('resize'); this.originalElement.css('resize', 'none'); //Push the actual element to our proportionallyResize internal array this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); // avoid IE jump (hard set the margin) this.originalElement.css({ margin: this.originalElement.css('margin') }); // fix handlers offset this._proportionallyResize(); } this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' }); if(this.handles.constructor == String) { if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; var n = this.handles.split(","); this.handles = {}; for(var i = 0; i < n.length; i++) { var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; var axis = $('
    '); // increase zIndex of sw, se, ne, nw axis //TODO : this modifies original option if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex }); //TODO : What's going on here? if ('se' == handle) { axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); }; //Insert into internal handles object and append to element this.handles[handle] = '.ui-resizable-'+handle; this.element.append(axis); } } this._renderAxis = function(target) { target = target || this.element; for(var i in this.handles) { if(this.handles[i].constructor == String) this.handles[i] = $(this.handles[i], this.element).show(); //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { var axis = $(this.handles[i], this.element), padWrapper = 0; //Checking the correct pad and border padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); //The padding type i have to apply... var padPos = [ 'padding', /ne|nw|n/.test(i) ? 'Top' : /se|sw|s/.test(i) ? 'Bottom' : /^e$/.test(i) ? 'Right' : 'Left' ].join(""); target.css(padPos, padWrapper); this._proportionallyResize(); } //TODO: What's that good for? There's not anything to be executed left if(!$(this.handles[i]).length) continue; } }; //TODO: make renderAxis a prototype function this._renderAxis(this.element); this._handles = $('.ui-resizable-handle', this.element) .disableSelection(); //Matching axis name this._handles.mouseover(function() { if (!self.resizing) { if (this.className) var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); //Axis, default = se self.axis = axis && axis[1] ? axis[1] : 'se'; } }); //If we want to auto hide the elements if (o.autoHide) { this._handles.hide(); $(this.element) .addClass("ui-resizable-autohide") .hover(function() { if (o.disabled) return; $(this).removeClass("ui-resizable-autohide"); self._handles.show(); }, function(){ if (o.disabled) return; if (!self.resizing) { $(this).addClass("ui-resizable-autohide"); self._handles.hide(); } }); } //Initialize the mouse interaction this._mouseInit(); }, destroy: function() { this._mouseDestroy(); var _destroy = function(exp) { $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); }; //TODO: Unwrap at same DOM position if (this.elementIsWrapper) { _destroy(this.element); var wrapper = this.element; wrapper.after( this.originalElement.css({ position: wrapper.css('position'), width: wrapper.outerWidth(), height: wrapper.outerHeight(), top: wrapper.css('top'), left: wrapper.css('left') }) ).remove(); } this.originalElement.css('resize', this.originalResizeStyle); _destroy(this.originalElement); return this; }, _mouseCapture: function(event) { var handle = false; for (var i in this.handles) { if ($(this.handles[i])[0] == event.target) { handle = true; } } return !this.options.disabled && handle; }, _mouseStart: function(event) { var o = this.options, iniPos = this.element.position(), el = this.element; this.resizing = true; this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; // bugfix for http://dev.jquery.com/ticket/1749 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); } //Opera fixing relative position if ($.browser.opera && (/relative/).test(el.css('position'))) el.css({ position: 'relative', top: 'auto', left: 'auto' }); this._renderProxy(); var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); if (o.containment) { curleft += $(o.containment).scrollLeft() || 0; curtop += $(o.containment).scrollTop() || 0; } //Store needed variables this.offset = this.helper.offset(); this.position = { left: curleft, top: curtop }; this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; this.originalPosition = { left: curleft, top: curtop }; this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; this.originalMousePosition = { left: event.pageX, top: event.pageY }; //Aspect Ratio this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); var cursor = $('.ui-resizable-' + this.axis).css('cursor'); $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); el.addClass("ui-resizable-resizing"); this._propagate("start", event); return true; }, _mouseDrag: function(event) { //Increase performance, avoid regex var el = this.helper, o = this.options, props = {}, self = this, smp = this.originalMousePosition, a = this.axis; var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; var trigger = this._change[a]; if (!trigger) return false; // Calculate the attrs that will be change var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; // Put this in the mouseDrag handler since the user can start pressing shift while resizing this._updateVirtualBoundaries(event.shiftKey); if (this._aspectRatio || event.shiftKey) data = this._updateRatio(data, event); data = this._respectSize(data, event); // plugins callbacks need to be called first this._propagate("resize", event); el.css({ top: this.position.top + "px", left: this.position.left + "px", width: this.size.width + "px", height: this.size.height + "px" }); if (!this._helper && this._proportionallyResizeElements.length) this._proportionallyResize(); this._updateCache(data); // calling the user callback at the end this._trigger('resize', event, this.ui()); return false; }, _mouseStop: function(event) { this.resizing = false; var o = this.options, self = this; if(this._helper) { var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, soffsetw = ista ? 0 : self.sizeDiff.width; var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) }, left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; if (!o.animate) this.element.css($.extend(s, { top: top, left: left })); self.helper.height(self.size.height); self.helper.width(self.size.width); if (this._helper && !o.animate) this._proportionallyResize(); } $('body').css('cursor', 'auto'); this.element.removeClass("ui-resizable-resizing"); this._propagate("stop", event); if (this._helper) this.helper.remove(); return false; }, _updateVirtualBoundaries: function(forceAspectRatio) { var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; b = { minWidth: isNumber(o.minWidth) ? o.minWidth : 0, maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, minHeight: isNumber(o.minHeight) ? o.minHeight : 0, maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity }; if(this._aspectRatio || forceAspectRatio) { // We want to create an enclosing box whose aspect ration is the requested one // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension pMinWidth = b.minHeight * this.aspectRatio; pMinHeight = b.minWidth / this.aspectRatio; pMaxWidth = b.maxHeight * this.aspectRatio; pMaxHeight = b.maxWidth / this.aspectRatio; if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; } this._vBoundaries = b; }, _updateCache: function(data) { var o = this.options; this.offset = this.helper.offset(); if (isNumber(data.left)) this.position.left = data.left; if (isNumber(data.top)) this.position.top = data.top; if (isNumber(data.height)) this.size.height = data.height; if (isNumber(data.width)) this.size.width = data.width; }, _updateRatio: function(data, event) { var o = this.options, cpos = this.position, csize = this.size, a = this.axis; if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); if (a == 'sw') { data.left = cpos.left + (csize.width - data.width); data.top = null; } if (a == 'nw') { data.top = cpos.top + (csize.height - data.height); data.left = cpos.left + (csize.width - data.width); } return data; }, _respectSize: function(data, event) { var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); if (isminw) data.width = o.minWidth; if (isminh) data.height = o.minHeight; if (ismaxw) data.width = o.maxWidth; if (ismaxh) data.height = o.maxHeight; var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); if (isminw && cw) data.left = dw - o.minWidth; if (ismaxw && cw) data.left = dw - o.maxWidth; if (isminh && ch) data.top = dh - o.minHeight; if (ismaxh && ch) data.top = dh - o.maxHeight; // fixing jump error on top/left - bug #2330 var isNotwh = !data.width && !data.height; if (isNotwh && !data.left && data.top) data.top = null; else if (isNotwh && !data.top && data.left) data.left = null; return data; }, _proportionallyResize: function() { var o = this.options; if (!this._proportionallyResizeElements.length) return; var element = this.helper || this.element; for (var i=0; i < this._proportionallyResizeElements.length; i++) { var prel = this._proportionallyResizeElements[i]; if (!this.borderDif) { var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; this.borderDif = $.map(b, function(v, i) { var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; return border + padding; }); } if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length))) continue; prel.css({ height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 }); }; }, _renderProxy: function() { var el = this.element, o = this.options; this.elementOffset = el.offset(); if(this._helper) { this.helper = this.helper || $('
    '); // fix ie6 offset TODO: This seems broken var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0), pxyoffset = ( ie6 ? 2 : -1 ); this.helper.addClass(this._helper).css({ width: this.element.outerWidth() + pxyoffset, height: this.element.outerHeight() + pxyoffset, position: 'absolute', left: this.elementOffset.left - ie6offset +'px', top: this.elementOffset.top - ie6offset +'px', zIndex: ++o.zIndex //TODO: Don't modify option }); this.helper .appendTo("body") .disableSelection(); } else { this.helper = this.element; } }, _change: { e: function(event, dx, dy) { return { width: this.originalSize.width + dx }; }, w: function(event, dx, dy) { var o = this.options, cs = this.originalSize, sp = this.originalPosition; return { left: sp.left + dx, width: cs.width - dx }; }, n: function(event, dx, dy) { var o = this.options, cs = this.originalSize, sp = this.originalPosition; return { top: sp.top + dy, height: cs.height - dy }; }, s: function(event, dx, dy) { return { height: this.originalSize.height + dy }; }, se: function(event, dx, dy) { return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); }, sw: function(event, dx, dy) { return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); }, ne: function(event, dx, dy) { return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); }, nw: function(event, dx, dy) { return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); } }, _propagate: function(n, event) { $.ui.plugin.call(this, n, [event, this.ui()]); (n != "resize" && this._trigger(n, event, this.ui())); }, plugins: {}, ui: function() { return { originalElement: this.originalElement, element: this.element, helper: this.helper, position: this.position, size: this.size, originalSize: this.originalSize, originalPosition: this.originalPosition }; } }); $.extend($.ui.resizable, { version: "1.8.15" }); /* * Resizable Extensions */ $.ui.plugin.add("resizable", "alsoResize", { start: function (event, ui) { var self = $(this).data("resizable"), o = self.options; var _store = function (exp) { $(exp).each(function() { var el = $(this); el.data("resizable-alsoresize", { width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10), position: el.css('position') // to reset Opera on stop() }); }); }; if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } else { $.each(o.alsoResize, function (exp) { _store(exp); }); } }else{ _store(o.alsoResize); } }, resize: function (event, ui) { var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition; var delta = { height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 }, _alsoResize = function (exp, c) { $(exp).each(function() { var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; $.each(css, function (i, prop) { var sum = (start[prop]||0) + (delta[prop]||0); if (sum && sum >= 0) style[prop] = sum || null; }); // Opera fixing relative position if ($.browser.opera && /relative/.test(el.css('position'))) { self._revertToRelativePosition = true; el.css({ position: 'absolute', top: 'auto', left: 'auto' }); } el.css(style); }); }; if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); }else{ _alsoResize(o.alsoResize); } }, stop: function (event, ui) { var self = $(this).data("resizable"), o = self.options; var _reset = function (exp) { $(exp).each(function() { var el = $(this); // reset position for Opera - no need to verify it was changed el.css({ position: el.data("resizable-alsoresize").position }); }); }; if (self._revertToRelativePosition) { self._revertToRelativePosition = false; if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { $.each(o.alsoResize, function (exp) { _reset(exp); }); }else{ _reset(o.alsoResize); } } $(this).removeData("resizable-alsoresize"); } }); $.ui.plugin.add("resizable", "animate", { stop: function(event, ui) { var self = $(this).data("resizable"), o = self.options; var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, soffsetw = ista ? 0 : self.sizeDiff.width; var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; self.element.animate( $.extend(style, top && left ? { top: top, left: left } : {}), { duration: o.animateDuration, easing: o.animateEasing, step: function() { var data = { width: parseInt(self.element.css('width'), 10), height: parseInt(self.element.css('height'), 10), top: parseInt(self.element.css('top'), 10), left: parseInt(self.element.css('left'), 10) }; if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); // propagating resize, and updating values for each animation step self._updateCache(data); self._propagate("resize", event); } } ); } }); $.ui.plugin.add("resizable", "containment", { start: function(event, ui) { var self = $(this).data("resizable"), o = self.options, el = self.element; var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; if (!ce) return; self.containerElement = $(ce); if (/document/.test(oc) || oc == document) { self.containerOffset = { left: 0, top: 0 }; self.containerPosition = { left: 0, top: 0 }; self.parentData = { element: $(document), left: 0, top: 0, width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight }; } // i'm a node, so compute top, left, right, bottom else { var element = $(ce), p = []; $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); self.containerOffset = element.offset(); self.containerPosition = element.position(); self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width, width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); self.parentData = { element: ce, left: co.left, top: co.top, width: width, height: height }; } }, resize: function(event, ui) { var self = $(this).data("resizable"), o = self.options, ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position, pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement; if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; if (cp.left < (self._helper ? co.left : 0)) { self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left)); if (pRatio) self.size.height = self.size.width / o.aspectRatio; self.position.left = o.helper ? co.left : 0; } if (cp.top < (self._helper ? co.top : 0)) { self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top); if (pRatio) self.size.width = self.size.height * o.aspectRatio; self.position.top = self._helper ? co.top : 0; } self.offset.left = self.parentData.left+self.position.left; self.offset.top = self.parentData.top+self.position.top; var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ), hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height ); var isParent = self.containerElement.get(0) == self.element.parent().get(0), isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position')); if(isParent && isOffsetRelative) woset -= self.parentData.left; if (woset + self.size.width >= self.parentData.width) { self.size.width = self.parentData.width - woset; if (pRatio) self.size.height = self.size.width / self.aspectRatio; } if (hoset + self.size.height >= self.parentData.height) { self.size.height = self.parentData.height - hoset; if (pRatio) self.size.width = self.size.height * self.aspectRatio; } }, stop: function(event, ui){ var self = $(this).data("resizable"), o = self.options, cp = self.position, co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement; var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height; if (self._helper && !o.animate && (/relative/).test(ce.css('position'))) $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); if (self._helper && !o.animate && (/static/).test(ce.css('position'))) $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); } }); $.ui.plugin.add("resizable", "ghost", { start: function(event, ui) { var self = $(this).data("resizable"), o = self.options, cs = self.size; self.ghost = self.originalElement.clone(); self.ghost .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) .addClass('ui-resizable-ghost') .addClass(typeof o.ghost == 'string' ? o.ghost : ''); self.ghost.appendTo(self.helper); }, resize: function(event, ui){ var self = $(this).data("resizable"), o = self.options; if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width }); }, stop: function(event, ui){ var self = $(this).data("resizable"), o = self.options; if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0)); } }); $.ui.plugin.add("resizable", "grid", { resize: function(event, ui) { var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); if (/^(se|s|e)$/.test(a)) { self.size.width = os.width + ox; self.size.height = os.height + oy; } else if (/^(ne)$/.test(a)) { self.size.width = os.width + ox; self.size.height = os.height + oy; self.position.top = op.top - oy; } else if (/^(sw)$/.test(a)) { self.size.width = os.width + ox; self.size.height = os.height + oy; self.position.left = op.left - ox; } else { self.size.width = os.width + ox; self.size.height = os.height + oy; self.position.top = op.top - oy; self.position.left = op.left - ox; } } }); var num = function(v) { return parseInt(v, 10) || 0; }; var isNumber = function(value) { return !isNaN(parseInt(value, 10)); }; })(jQuery); SABnzbd-0.7.20/interfaces/Plush/templates/static/javascripts/src/jquery.colorbox_1.3.17.2.js0000644000000000000000000006532312612410632031364 0ustar00rootroot00000000000000// ColorBox v1.3.17.2 - a full featured, light-weight, customizable lightbox based on jQuery 1.3+ // Copyright (c) 2011 Jack Moore - jack@colorpowered.com // Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php (function ($, document, window) { var // ColorBox Default Settings. // See http://colorpowered.com/colorbox for details. defaults = { transition: "elastic", speed: 300, width: false, initialWidth: "600", innerWidth: false, maxWidth: false, height: false, initialHeight: "450", innerHeight: false, maxHeight: false, scalePhotos: true, scrolling: true, inline: false, html: false, iframe: false, fastIframe: true, photo: false, href: false, title: false, rel: false, opacity: 0.9, preloading: true, current: "image {current} of {total}", previous: "previous", next: "next", close: "close", open: false, returnFocus: true, loop: true, slideshow: false, slideshowAuto: true, slideshowSpeed: 2500, slideshowStart: "start slideshow", slideshowStop: "stop slideshow", onOpen: false, onLoad: false, onComplete: false, onCleanup: false, onClosed: false, overlayClose: true, escKey: true, arrowKey: true, top: false, bottom: false, left: false, right: false, fixed: false, data: false }, // Abstracting the HTML and event identifiers for easy rebranding colorbox = 'colorbox', prefix = 'cbox', boxElement = prefix + 'Element', // Events event_open = prefix + '_open', event_load = prefix + '_load', event_complete = prefix + '_complete', event_cleanup = prefix + '_cleanup', event_closed = prefix + '_closed', event_purge = prefix + '_purge', // Special Handling for IE isIE = $.browser.msie && !$.support.opacity, // Detects IE6,7,8. IE9 supports opacity. Feature detection alone gave a false positive on at least one phone browser and on some development versions of Chrome, hence the user-agent test. isIE6 = isIE && $.browser.version < 7, event_ie6 = prefix + '_IE6', // Cached jQuery Object Variables $overlay, $box, $wrap, $content, $topBorder, $leftBorder, $rightBorder, $bottomBorder, $related, $window, $loaded, $loadingBay, $loadingOverlay, $title, $current, $slideshow, $next, $prev, $close, $groupControls, // Variables for cached values or use across multiple functions settings, interfaceHeight, interfaceWidth, loadedHeight, loadedWidth, element, index, photo, open, active, closing, handler, loadingTimer, publicMethod; // **************** // HELPER FUNCTIONS // **************** // jQuery object generator to reduce code size function $div(id, cssText, div) { div = document.createElement('div'); if (id) { div.id = prefix + id; } div.style.cssText = cssText || ''; return $(div); } // Convert '%' and 'px' values to integers function setSize(size, dimension) { return Math.round((/%/.test(size) ? ((dimension === 'x' ? $window.width() : $window.height()) / 100) : 1) * parseInt(size, 10)); } // Checks an href to see if it is a photo. // There is a force photo option (photo: true) for hrefs that cannot be matched by this regex. function isImage(url) { return settings.photo || /\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*))?(?:#(\.*))?$/i.test(url); } // Assigns function results to their respective settings. This allows functions to be used as values. function makeSettings(i) { settings = $.extend({}, $.data(element, colorbox)); for (i in settings) { if ($.isFunction(settings[i]) && i.substring(0, 2) !== 'on') { // checks to make sure the function isn't one of the callbacks, they will be handled at the appropriate time. settings[i] = settings[i].call(element); } } settings.rel = settings.rel || element.rel || 'nofollow'; settings.href = settings.href || $(element).attr('href'); settings.title = settings.title || element.title; if (typeof settings.href === "string") { settings.href = $.trim(settings.href); } } function trigger(event, callback) { if (callback) { callback.call(element); } $.event.trigger(event); } // Slideshow functionality function slideshow() { var timeOut, className = prefix + "Slideshow_", click = "click." + prefix, start, stop, clear; if (settings.slideshow && $related[1]) { start = function () { $slideshow .text(settings.slideshowStop) .unbind(click) .bind(event_complete, function () { if (index < $related.length - 1 || settings.loop) { timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed); } }) .bind(event_load, function () { clearTimeout(timeOut); }) .one(click + ' ' + event_cleanup, stop); $box.removeClass(className + "off").addClass(className + "on"); timeOut = setTimeout(publicMethod.next, settings.slideshowSpeed); }; stop = function () { clearTimeout(timeOut); $slideshow .text(settings.slideshowStart) .unbind([event_complete, event_load, event_cleanup, click].join(' ')) .one(click, start); $box.removeClass(className + "on").addClass(className + "off"); }; if (settings.slideshowAuto) { start(); } else { stop(); } } else { $box.removeClass(className + "off " + className + "on"); } } function launch(target) { if (!closing) { element = target; makeSettings(); $related = $(element); index = 0; if (settings.rel !== 'nofollow') { $related = $('.' + boxElement).filter(function () { var relRelated = $.data(this, colorbox).rel || this.rel; return (relRelated === settings.rel); }); index = $related.index(element); // Check direct calls to ColorBox. if (index === -1) { $related = $related.add(element); index = $related.length - 1; } } if (!open) { open = active = true; // Prevents the page-change action from queuing up if the visitor holds down the left or right keys. $box.show(); if (settings.returnFocus) { try { element.blur(); $(element).one(event_closed, function () { try { this.focus(); } catch (e) { // do nothing } }); } catch (e) { // do nothing } } // +settings.opacity avoids a problem in IE when using non-zero-prefixed-string-values, like '.5' $overlay.css({"opacity": +settings.opacity, "cursor": settings.overlayClose ? "pointer" : "auto"}).show(); // Opens inital empty ColorBox prior to content being loaded. settings.w = setSize(settings.initialWidth, 'x'); settings.h = setSize(settings.initialHeight, 'y'); publicMethod.position(); if (isIE6) { $window.bind('resize.' + event_ie6 + ' scroll.' + event_ie6, function () { $overlay.css({width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft()}); }).trigger('resize.' + event_ie6); } trigger(event_open, settings.onOpen); $groupControls.add($title).hide(); $close.html(settings.close).show(); } publicMethod.load(true); } } // **************** // PUBLIC FUNCTIONS // Usage format: $.fn.colorbox.close(); // Usage from within an iframe: parent.$.fn.colorbox.close(); // **************** publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) { var $this = this; options = options || {}; if (!$this[0]) { if ($this.selector) { // if a selector was given and it didn't match any elements, go ahead and exit. return $this; } // if no selector was given (ie. $.colorbox()), create a temporary element to work with $this = $(''); options.open = true; // assume an immediate open } if (callback) { options.onComplete = callback; } $this.each(function () { $.data(this, colorbox, $.extend({}, $.data(this, colorbox) || defaults, options)); $(this).addClass(boxElement); }); if (($.isFunction(options.open) && options.open.call($this)) || options.open) { launch($this[0]); } return $this; }; // Initialize ColorBox: store common calculations, preload the interface graphics, append the html. // This preps ColorBox for a speedy open when clicked, and minimizes the burdon on the browser by only // having to run once, instead of each time colorbox is opened. publicMethod.init = function () { // Create & Append jQuery Objects $window = $(window); $box = $div().attr({id: colorbox, 'class': isIE ? prefix + (isIE6 ? 'IE6' : 'IE') : ''}); $overlay = $div("Overlay", isIE6 ? 'position:absolute' : '').hide(); $wrap = $div("Wrapper"); $content = $div("Content").append( $loaded = $div("LoadedContent", 'width:0; height:0; overflow:hidden'), $loadingOverlay = $div("LoadingOverlay").add($div("LoadingGraphic")), $title = $div("Title"), $current = $div("Current"), $next = $div("Next"), $prev = $div("Previous"), $slideshow = $div("Slideshow").bind(event_open, slideshow), $close = $div("Close") ); $wrap.append( // The 3x3 Grid that makes up ColorBox $div().append( $div("TopLeft"), $topBorder = $div("TopCenter"), $div("TopRight") ), $div(false, 'clear:left').append( $leftBorder = $div("MiddleLeft"), $content, $rightBorder = $div("MiddleRight") ), $div(false, 'clear:left').append( $div("BottomLeft"), $bottomBorder = $div("BottomCenter"), $div("BottomRight") ) ).children().children().css({'float': 'left'}); $loadingBay = $div(false, 'position:absolute; width:9999px; visibility:hidden; display:none'); $('body').prepend($overlay, $box.append($wrap, $loadingBay)); $content.children() .hover(function () { $(this).addClass('hover'); }, function () { $(this).removeClass('hover'); }).addClass('hover'); // Cache values needed for size calculations interfaceHeight = $topBorder.height() + $bottomBorder.height() + $content.outerHeight(true) - $content.height();//Subtraction needed for IE6 interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(true) - $content.width(); loadedHeight = $loaded.outerHeight(true); loadedWidth = $loaded.outerWidth(true); // Setting padding to remove the need to do size conversions during the animation step. $box.css({"padding-bottom": interfaceHeight, "padding-right": interfaceWidth}).hide(); // Setup button events. // Anonymous functions here keep the public method from being cached, thereby allowing them to be redefined on the fly. $next.click(function () { publicMethod.next(); }); $prev.click(function () { publicMethod.prev(); }); $close.click(function () { publicMethod.close(); }); $groupControls = $next.add($prev).add($current).add($slideshow); // Adding the 'hover' class allowed the browser to load the hover-state // background graphics in case the images were not part of a sprite. The class can now can be removed. $content.children().removeClass('hover'); $overlay.click(function () { if (settings.overlayClose) { publicMethod.close(); } }); // Set Navigation Key Bindings $(document).bind('keydown.' + prefix, function (e) { var key = e.keyCode; if (open && settings.escKey && key === 27) { e.preventDefault(); publicMethod.close(); } if (open && settings.arrowKey && $related[1]) { if (key === 37) { e.preventDefault(); $prev.click(); } else if (key === 39) { e.preventDefault(); $next.click(); } } }); }; publicMethod.remove = function () { $box.add($overlay).remove(); $('.' + boxElement).removeData(colorbox).removeClass(boxElement); }; publicMethod.position = function (speed, loadedCallback) { var top = 0, left = 0; $window.unbind('resize.' + prefix); // remove the modal so that it doesn't influence the document width/height $box.hide(); if (settings.fixed && !isIE6) { $box.css({position: 'fixed'}); } else { top = $window.scrollTop(); left = $window.scrollLeft(); $box.css({position: 'absolute'}); } // keeps the top and left positions within the browser's viewport. if (settings.right !== false) { left += Math.max($window.width() - settings.w - loadedWidth - interfaceWidth - setSize(settings.right, 'x'), 0); } else if (settings.left !== false) { left += setSize(settings.left, 'x'); } else { left += Math.round(Math.max($window.width() - settings.w - loadedWidth - interfaceWidth, 0) / 2); } if (settings.bottom !== false) { top += Math.max(document.documentElement.clientHeight - settings.h - loadedHeight - interfaceHeight - setSize(settings.bottom, 'y'), 0); } else if (settings.top !== false) { top += setSize(settings.top, 'y'); } else { top += Math.round(Math.max(document.documentElement.clientHeight - settings.h - loadedHeight - interfaceHeight, 0) / 2); } $box.show(); // setting the speed to 0 to reduce the delay between same-sized content. speed = ($box.width() === settings.w + loadedWidth && $box.height() === settings.h + loadedHeight) ? 0 : speed || 0; // this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly, // but it has to be shrank down around the size of div#colorbox when it's done. If not, // it can invoke an obscure IE bug when using iframes. $wrap[0].style.width = $wrap[0].style.height = "9999px"; function modalDimensions(that) { // loading overlay height has to be explicitly set for IE6. $topBorder[0].style.width = $bottomBorder[0].style.width = $content[0].style.width = that.style.width; $loadingOverlay[0].style.height = $loadingOverlay[1].style.height = $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height; } $box.dequeue().animate({width: settings.w + loadedWidth, height: settings.h + loadedHeight, top: top, left: left}, { duration: speed, complete: function () { modalDimensions(this); active = false; // shrink the wrapper down to exactly the size of colorbox to avoid a bug in IE's iframe implementation. $wrap[0].style.width = (settings.w + loadedWidth + interfaceWidth) + "px"; $wrap[0].style.height = (settings.h + loadedHeight + interfaceHeight) + "px"; if (loadedCallback) { loadedCallback(); } setTimeout(function(){ // small delay before binding onresize due to an IE8 bug. $window.bind('resize.' + prefix, publicMethod.position); }, 1); }, step: function () { modalDimensions(this); } }); }; publicMethod.resize = function (options) { if (open) { options = options || {}; if (options.width) { settings.w = setSize(options.width, 'x') - loadedWidth - interfaceWidth; } if (options.innerWidth) { settings.w = setSize(options.innerWidth, 'x'); } $loaded.css({width: settings.w}); if (options.height) { settings.h = setSize(options.height, 'y') - loadedHeight - interfaceHeight; } if (options.innerHeight) { settings.h = setSize(options.innerHeight, 'y'); } if (!options.innerHeight && !options.height) { var $child = $loaded.wrapInner("
    ").children(); // temporary wrapper to get an accurate estimate of just how high the total content should be. settings.h = $child.height(); $child.replaceWith($child.children()); // ditch the temporary wrapper div used in height calculation } $loaded.css({height: settings.h}); publicMethod.position(settings.transition === "none" ? 0 : settings.speed); } }; publicMethod.prep = function (object) { if (!open) { return; } var callback, speed = settings.transition === "none" ? 0 : settings.speed; $loaded.remove(); $loaded = $div('LoadedContent').append(object); function getWidth() { settings.w = settings.w || $loaded.width(); settings.w = settings.mw && settings.mw < settings.w ? settings.mw : settings.w; return settings.w; } function getHeight() { settings.h = settings.h || $loaded.height(); settings.h = settings.mh && settings.mh < settings.h ? settings.mh : settings.h; return settings.h; } $loaded.hide() .appendTo($loadingBay.show())// content has to be appended to the DOM for accurate size calculations. .css({width: getWidth(), overflow: settings.scrolling ? 'auto' : 'hidden'}) .css({height: getHeight()})// sets the height independently from the width in case the new width influences the value of height. .prependTo($content); $loadingBay.hide(); // floating the IMG removes the bottom line-height and fixed a problem where IE miscalculates the width of the parent element as 100% of the document width. //$(photo).css({'float': 'none', marginLeft: 'auto', marginRight: 'auto'}); $(photo).css({'float': 'none'}); // Hides SELECT elements in IE6 because they would otherwise sit on top of the overlay. if (isIE6) { $('select').not($box.find('select')).filter(function () { return this.style.visibility !== 'hidden'; }).css({'visibility': 'hidden'}).one(event_cleanup, function () { this.style.visibility = 'inherit'; }); } callback = function () { var prev, prevSrc, next, nextSrc, total = $related.length, iframe, complete; if (!open) { return; } function removeFilter() { if (isIE) { $box[0].style.removeAttribute('filter'); } } complete = function () { clearTimeout(loadingTimer); $loadingOverlay.hide(); trigger(event_complete, settings.onComplete); }; if (isIE) { //This fadeIn helps the bicubic resampling to kick-in. if (photo) { $loaded.fadeIn(100); } } $title.html(settings.title).add($loaded).show(); if (total > 1) { // handle grouping if (typeof settings.current === "string") { $current.html(settings.current.replace('{current}', index + 1).replace('{total}', total)).show(); } $next[(settings.loop || index < total - 1) ? "show" : "hide"]().html(settings.next); $prev[(settings.loop || index) ? "show" : "hide"]().html(settings.previous); prev = index ? $related[index - 1] : $related[total - 1]; next = index < total - 1 ? $related[index + 1] : $related[0]; if (settings.slideshow) { $slideshow.show(); } // Preloads images within a rel group if (settings.preloading) { nextSrc = $.data(next, colorbox).href || next.href; prevSrc = $.data(prev, colorbox).href || prev.href; nextSrc = $.isFunction(nextSrc) ? nextSrc.call(next) : nextSrc; prevSrc = $.isFunction(prevSrc) ? prevSrc.call(prev) : prevSrc; if (isImage(nextSrc)) { $('')[0].src = nextSrc; } if (isImage(prevSrc)) { $('')[0].src = prevSrc; } } } else { $groupControls.hide(); } if (settings.iframe) { iframe = $(''); // Append the new element to the tooltip elems.bgiframe.appendTo(tooltip); // Update BGIFrame on tooltip move tooltip.bind('tooltipmove'+namespace, self.adjust); }, adjust: function() { var dimensions = api.get('dimensions'), // Determine current tooltip dimensions plugin = api.plugins.tip, tip = elems.tip, tipAdjust, offset; // Adjust border offset offset = parseInt(tooltip.css('border-left-width'), 10) || 0; offset = { left: -offset, top: -offset }; // Adjust for tips plugin if(plugin && tip) { tipAdjust = (plugin.corner.precedance === 'x') ? ['width', 'left'] : ['height', 'top']; offset[ tipAdjust[1] ] -= tip[ tipAdjust[0] ](); } // Update bgiframe elems.bgiframe.css(offset).css(dimensions); }, destroy: function() { // Remove iframe elems.bgiframe.remove(); // Remove bound events tooltip.unbind(namespace); } }); self.init(); } PLUGINS.bgiframe = function(api) { var browser = $.browser, self = api.plugins.bgiframe; // Proceed only if the browser is IE6 and offending elements are present if($('select, object').length < 1 || !(browser.msie && (''+browser.version).charAt(0) === '6')) { return FALSE; } return 'object' === typeof self ? self : (api.plugins.bgiframe = new BGIFrame(api)); }; // Plugin needs to be initialized on render PLUGINS.bgiframe.initialize = 'render'; })); }( window, document ));SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/jquery.ui.autocomplete.js0000644000000000000000000004131612612410632030554 0ustar00rootroot00000000000000/* * jQuery UI Autocomplete 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Autocomplete * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * jquery.ui.position.js */ (function( $, undefined ) { // used to prevent race conditions with remote data sources var requestIndex = 0; $.widget( "ui.autocomplete", { options: { appendTo: "body", autoFocus: false, delay: 300, minLength: 1, position: { my: "left top", at: "left bottom", collision: "none" }, source: null }, pending: 0, _create: function() { var self = this, doc = this.element[ 0 ].ownerDocument, suppressKeyPress; this.element .addClass( "ui-autocomplete-input" ) .attr( "autocomplete", "off" ) // TODO verify these actually work as intended .attr({ role: "textbox", "aria-autocomplete": "list", "aria-haspopup": "true" }) .bind( "keydown.autocomplete", function( event ) { if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) { return; } suppressKeyPress = false; var keyCode = $.ui.keyCode; switch( event.keyCode ) { case keyCode.PAGE_UP: self._move( "previousPage", event ); break; case keyCode.PAGE_DOWN: self._move( "nextPage", event ); break; case keyCode.UP: self._move( "previous", event ); // prevent moving cursor to beginning of text field in some browsers event.preventDefault(); break; case keyCode.DOWN: self._move( "next", event ); // prevent moving cursor to end of text field in some browsers event.preventDefault(); break; case keyCode.ENTER: case keyCode.NUMPAD_ENTER: // when menu is open and has focus if ( self.menu.active ) { // #6055 - Opera still allows the keypress to occur // which causes forms to submit suppressKeyPress = true; event.preventDefault(); } //passthrough - ENTER and TAB both select the current element case keyCode.TAB: if ( !self.menu.active ) { return; } self.menu.select( event ); break; case keyCode.ESCAPE: self.element.val( self.term ); self.close( event ); break; default: // keypress is triggered before the input value is changed clearTimeout( self.searching ); self.searching = setTimeout(function() { // only search if the value has changed if ( self.term != self.element.val() ) { self.selectedItem = null; self.search( null, event ); } }, self.options.delay ); break; } }) .bind( "keypress.autocomplete", function( event ) { if ( suppressKeyPress ) { suppressKeyPress = false; event.preventDefault(); } }) .bind( "focus.autocomplete", function() { if ( self.options.disabled ) { return; } self.selectedItem = null; self.previous = self.element.val(); }) .bind( "blur.autocomplete", function( event ) { if ( self.options.disabled ) { return; } clearTimeout( self.searching ); // clicks on the menu (or a button to trigger a search) will cause a blur event self.closing = setTimeout(function() { self.close( event ); self._change( event ); }, 150 ); }); this._initSource(); this.response = function() { return self._response.apply( self, arguments ); }; this.menu = $( "
      " ) .addClass( "ui-autocomplete" ) .appendTo( $( this.options.appendTo || "body", doc )[0] ) // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown) .mousedown(function( event ) { // clicking on the scrollbar causes focus to shift to the body // but we can't detect a mouseup or a click immediately afterward // so we have to track the next mousedown and close the menu if // the user clicks somewhere outside of the autocomplete var menuElement = self.menu.element[ 0 ]; if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { setTimeout(function() { $( document ).one( 'mousedown', function( event ) { if ( event.target !== self.element[ 0 ] && event.target !== menuElement && !$.ui.contains( menuElement, event.target ) ) { self.close(); } }); }, 1 ); } // use another timeout to make sure the blur-event-handler on the input was already triggered setTimeout(function() { clearTimeout( self.closing ); }, 13); }) .menu({ focus: function( event, ui ) { var item = ui.item.data( "item.autocomplete" ); if ( false !== self._trigger( "focus", event, { item: item } ) ) { // use value to match what will end up in the input, if it was a key event if ( /^key/.test(event.originalEvent.type) ) { self.element.val( item.value ); } } }, selected: function( event, ui ) { var item = ui.item.data( "item.autocomplete" ), previous = self.previous; // only trigger when focus was lost (click on menu) if ( self.element[0] !== doc.activeElement ) { self.element.focus(); self.previous = previous; // #6109 - IE triggers two focus events and the second // is asynchronous, so we need to reset the previous // term synchronously and asynchronously :-( setTimeout(function() { self.previous = previous; self.selectedItem = item; }, 1); } if ( false !== self._trigger( "select", event, { item: item } ) ) { self.element.val( item.value ); } // reset the term after the select event // this allows custom select handling to work properly self.term = self.element.val(); self.close( event ); self.selectedItem = item; }, blur: function( event, ui ) { // don't set the value of the text field if it's already correct // this prevents moving the cursor unnecessarily if ( self.menu.element.is(":visible") && ( self.element.val() !== self.term ) ) { self.element.val( self.term ); } } }) .zIndex( this.element.zIndex() + 1 ) // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 .css({ top: 0, left: 0 }) .hide() .data( "menu" ); if ( $.fn.bgiframe ) { this.menu.element.bgiframe(); } // turning off autocomplete prevents the browser from remembering the // value when navigating through history, so we re-enable autocomplete // if the page is unloaded before the widget is destroyed. #7790 self.beforeunloadHandler = function() { self.element.removeAttr( "autocomplete" ); }; $( window ).bind( "beforeunload", self.beforeunloadHandler ); }, destroy: function() { this.element .removeClass( "ui-autocomplete-input" ) .removeAttr( "autocomplete" ) .removeAttr( "role" ) .removeAttr( "aria-autocomplete" ) .removeAttr( "aria-haspopup" ); this.menu.element.remove(); $( window ).unbind( "beforeunload", this.beforeunloadHandler ); $.Widget.prototype.destroy.call( this ); }, _setOption: function( key, value ) { $.Widget.prototype._setOption.apply( this, arguments ); if ( key === "source" ) { this._initSource(); } if ( key === "appendTo" ) { this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] ) } if ( key === "disabled" && value && this.xhr ) { this.xhr.abort(); } }, _initSource: function() { var self = this, array, url; if ( $.isArray(this.options.source) ) { array = this.options.source; this.source = function( request, response ) { response( $.ui.autocomplete.filter(array, request.term) ); }; } else if ( typeof this.options.source === "string" ) { url = this.options.source; this.source = function( request, response ) { if ( self.xhr ) { self.xhr.abort(); } self.xhr = $.ajax({ url: url, data: request, dataType: "json", context: { autocompleteRequest: ++requestIndex }, success: function( data, status ) { if ( this.autocompleteRequest === requestIndex ) { response( data ); } }, error: function() { if ( this.autocompleteRequest === requestIndex ) { response( [] ); } } }); }; } else { this.source = this.options.source; } }, search: function( value, event ) { value = value != null ? value : this.element.val(); // always save the actual value, not the one passed as an argument this.term = this.element.val(); if ( value.length < this.options.minLength ) { return this.close( event ); } clearTimeout( this.closing ); if ( this._trigger( "search", event ) === false ) { return; } return this._search( value ); }, _search: function( value ) { this.pending++; this.element.addClass( "ui-autocomplete-loading" ); this.source( { term: value }, this.response ); }, _response: function( content ) { if ( !this.options.disabled && content && content.length ) { content = this._normalize( content ); this._suggest( content ); this._trigger( "open" ); } else { this.close(); } this.pending--; if ( !this.pending ) { this.element.removeClass( "ui-autocomplete-loading" ); } }, close: function( event ) { clearTimeout( this.closing ); if ( this.menu.element.is(":visible") ) { this.menu.element.hide(); this.menu.deactivate(); this._trigger( "close", event ); } }, _change: function( event ) { if ( this.previous !== this.element.val() ) { this._trigger( "change", event, { item: this.selectedItem } ); } }, _normalize: function( items ) { // assume all items have the right format when the first item is complete if ( items.length && items[0].label && items[0].value ) { return items; } return $.map( items, function(item) { if ( typeof item === "string" ) { return { label: item, value: item }; } return $.extend({ label: item.label || item.value, value: item.value || item.label }, item ); }); }, _suggest: function( items ) { var ul = this.menu.element .empty() .zIndex( this.element.zIndex() + 1 ); this._renderMenu( ul, items ); // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate this.menu.deactivate(); this.menu.refresh(); // size and position menu ul.show(); this._resizeMenu(); ul.position( $.extend({ of: this.element }, this.options.position )); if ( this.options.autoFocus ) { this.menu.next( new $.Event("mouseover") ); } }, _resizeMenu: function() { var ul = this.menu.element; ul.outerWidth( Math.max( // Firefox wraps long text (possibly a rounding bug) // so we add 1px to avoid the wrapping (#7513) ul.width( "" ).outerWidth() + 1, this.element.outerWidth() ) ); }, _renderMenu: function( ul, items ) { var self = this; $.each( items, function( index, item ) { self._renderItem( ul, item ); }); }, _renderItem: function( ul, item) { return $( "
    • " ) .data( "item.autocomplete", item ) .append( $( "
      " ).text( item.label ) ) .appendTo( ul ); }, _move: function( direction, event ) { if ( !this.menu.element.is(":visible") ) { this.search( null, event ); return; } if ( this.menu.first() && /^previous/.test(direction) || this.menu.last() && /^next/.test(direction) ) { this.element.val( this.term ); this.menu.deactivate(); return; } this.menu[ direction ]( event ); }, widget: function() { return this.menu.element; } }); $.extend( $.ui.autocomplete, { escapeRegex: function( value ) { return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); }, filter: function(array, term) { var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); return $.grep( array, function(value) { return matcher.test( value.label || value.value || value ); }); } }); }( jQuery )); /* * jQuery UI Menu (not officially released) * * This widget isn't yet finished and the API is subject to change. We plan to finish * it for the next release. You're welcome to give it a try anyway and give us feedback, * as long as you're okay with migrating your code later on. We can help with that, too. * * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Menu * * Depends: * jquery.ui.core.js * jquery.ui.widget.js */ (function($) { $.widget("ui.menu", { _create: function() { var self = this; this.element .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") .attr({ role: "listbox", "aria-activedescendant": "ui-active-menuitem" }) .click(function( event ) { if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) { return; } // temporary event.preventDefault(); self.select( event ); }); this.refresh(); }, refresh: function() { var self = this; // don't refresh list items that are already adapted var items = this.element.children("li:not(.ui-menu-item):has(a)") .addClass("ui-menu-item") .attr("role", "menuitem"); items.children("a") .addClass("ui-corner-all") .attr("tabindex", -1) // mouseenter doesn't work with event delegation .mouseenter(function( event ) { self.activate( event, $(this).parent() ); }) .mouseleave(function() { self.deactivate(); }); }, activate: function( event, item ) { this.deactivate(); if (this.hasScroll()) { var offset = item.offset().top - this.element.offset().top, scroll = this.element.scrollTop(), elementHeight = this.element.height(); if (offset < 0) { this.element.scrollTop( scroll + offset); } else if (offset >= elementHeight) { this.element.scrollTop( scroll + offset - elementHeight + item.height()); } } this.active = item.eq(0) .children("a") .addClass("ui-state-hover") .attr("id", "ui-active-menuitem") .end(); this._trigger("focus", event, { item: item }); }, deactivate: function() { if (!this.active) { return; } this.active.children("a") .removeClass("ui-state-hover") .removeAttr("id"); this._trigger("blur"); this.active = null; }, next: function(event) { this.move("next", ".ui-menu-item:first", event); }, previous: function(event) { this.move("prev", ".ui-menu-item:last", event); }, first: function() { return this.active && !this.active.prevAll(".ui-menu-item").length; }, last: function() { return this.active && !this.active.nextAll(".ui-menu-item").length; }, move: function(direction, edge, event) { if (!this.active) { this.activate(event, this.element.children(edge)); return; } var next = this.active[direction + "All"](".ui-menu-item").eq(0); if (next.length) { this.activate(event, next); } else { this.activate(event, this.element.children(edge)); } }, // TODO merge with previousPage nextPage: function(event) { if (this.hasScroll()) { // TODO merge with no-scroll-else if (!this.active || this.last()) { this.activate(event, this.element.children(".ui-menu-item:first")); return; } var base = this.active.offset().top, height = this.element.height(), result = this.element.children(".ui-menu-item").filter(function() { var close = $(this).offset().top - base - height + $(this).height(); // TODO improve approximation return close < 10 && close > -10; }); // TODO try to catch this earlier when scrollTop indicates the last page anyway if (!result.length) { result = this.element.children(".ui-menu-item:last"); } this.activate(event, result); } else { this.activate(event, this.element.children(".ui-menu-item") .filter(!this.active || this.last() ? ":first" : ":last")); } }, // TODO merge with nextPage previousPage: function(event) { if (this.hasScroll()) { // TODO merge with no-scroll-else if (!this.active || this.first()) { this.activate(event, this.element.children(".ui-menu-item:last")); return; } var base = this.active.offset().top, height = this.element.height(); result = this.element.children(".ui-menu-item").filter(function() { var close = $(this).offset().top - base + height - $(this).height(); // TODO improve approximation return close < 10 && close > -10; }); // TODO try to catch this earlier when scrollTop indicates the last page anyway if (!result.length) { result = this.element.children(".ui-menu-item:first"); } this.activate(event, result); } else { this.activate(event, this.element.children(".ui-menu-item") .filter(!this.active || this.first() ? ":last" : ":first")); } }, hasScroll: function() { return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight"); }, select: function( event ) { this._trigger("selected", event, { item: this.active }); } }); }(jQuery)); SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/jquery.ui.selectable.js0000644000000000000000000001545512612410632030163 0ustar00rootroot00000000000000/* * jQuery UI Selectable 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Selectables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function( $, undefined ) { $.widget("ui.selectable", $.ui.mouse, { options: { appendTo: 'body', autoRefresh: true, distance: 0, filter: '*', tolerance: 'touch' }, _create: function() { var self = this; this.element.addClass("ui-selectable"); this.dragged = false; // cache selectee children based on filter var selectees; this.refresh = function() { selectees = $(self.options.filter, self.element[0]); selectees.addClass("ui-selectee"); selectees.each(function() { var $this = $(this); var pos = $this.offset(); $.data(this, "selectable-item", { element: this, $element: $this, left: pos.left, top: pos.top, right: pos.left + $this.outerWidth(), bottom: pos.top + $this.outerHeight(), startselected: false, selected: $this.hasClass('ui-selected'), selecting: $this.hasClass('ui-selecting'), unselecting: $this.hasClass('ui-unselecting') }); }); }; this.refresh(); this.selectees = selectees.addClass("ui-selectee"); this._mouseInit(); this.helper = $("
      "); }, destroy: function() { this.selectees .removeClass("ui-selectee") .removeData("selectable-item"); this.element .removeClass("ui-selectable ui-selectable-disabled") .removeData("selectable") .unbind(".selectable"); this._mouseDestroy(); return this; }, _mouseStart: function(event) { var self = this; this.opos = [event.pageX, event.pageY]; if (this.options.disabled) return; var options = this.options; this.selectees = $(options.filter, this.element[0]); this._trigger("start", event); $(options.appendTo).append(this.helper); // position helper (lasso) this.helper.css({ "left": event.clientX, "top": event.clientY, "width": 0, "height": 0 }); if (options.autoRefresh) { this.refresh(); } this.selectees.filter('.ui-selected').each(function() { var selectee = $.data(this, "selectable-item"); selectee.startselected = true; if (!event.metaKey && !event.ctrlKey) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } }); $(event.target).parents().andSelf().each(function() { var selectee = $.data(this, "selectable-item"); if (selectee) { var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected'); selectee.$element .removeClass(doSelect ? "ui-unselecting" : "ui-selected") .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); selectee.unselecting = !doSelect; selectee.selecting = doSelect; selectee.selected = doSelect; // selectable (UN)SELECTING callback if (doSelect) { self._trigger("selecting", event, { selecting: selectee.element }); } else { self._trigger("unselecting", event, { unselecting: selectee.element }); } return false; } }); }, _mouseDrag: function(event) { var self = this; this.dragged = true; if (this.options.disabled) return; var options = this.options; var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); this.selectees.each(function() { var selectee = $.data(this, "selectable-item"); //prevent helper from being selected if appendTo: selectable if (!selectee || selectee.element == self.element[0]) return; var hit = false; if (options.tolerance == 'touch') { hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); } else if (options.tolerance == 'fit') { hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); } if (hit) { // SELECT if (selectee.selected) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; } if (selectee.unselecting) { selectee.$element.removeClass('ui-unselecting'); selectee.unselecting = false; } if (!selectee.selecting) { selectee.$element.addClass('ui-selecting'); selectee.selecting = true; // selectable SELECTING callback self._trigger("selecting", event, { selecting: selectee.element }); } } else { // UNSELECT if (selectee.selecting) { if ((event.metaKey || event.ctrlKey) && selectee.startselected) { selectee.$element.removeClass('ui-selecting'); selectee.selecting = false; selectee.$element.addClass('ui-selected'); selectee.selected = true; } else { selectee.$element.removeClass('ui-selecting'); selectee.selecting = false; if (selectee.startselected) { selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; } // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } } if (selectee.selected) { if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { selectee.$element.removeClass('ui-selected'); selectee.selected = false; selectee.$element.addClass('ui-unselecting'); selectee.unselecting = true; // selectable UNSELECTING callback self._trigger("unselecting", event, { unselecting: selectee.element }); } } } }); return false; }, _mouseStop: function(event) { var self = this; this.dragged = false; var options = this.options; $('.ui-unselecting', this.element[0]).each(function() { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass('ui-unselecting'); selectee.unselecting = false; selectee.startselected = false; self._trigger("unselected", event, { unselected: selectee.element }); }); $('.ui-selecting', this.element[0]).each(function() { var selectee = $.data(this, "selectable-item"); selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); selectee.selecting = false; selectee.selected = true; selectee.startselected = true; self._trigger("selected", event, { selected: selectee.element }); }); this._trigger("stop", event); this.helper.remove(); return false; } }); $.extend($.ui.selectable, { version: "1.8.18" }); })(jQuery); SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/jquery.ui.position.js0000644000000000000000000002104312612410632027712 0ustar00rootroot00000000000000/* * jQuery UI Position 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Position */ (function( $, undefined ) { $.ui = $.ui || {}; var horizontalPositions = /left|center|right/, verticalPositions = /top|center|bottom/, center = "center", support = {}, _position = $.fn.position, _offset = $.fn.offset; $.fn.position = function( options ) { if ( !options || !options.of ) { return _position.apply( this, arguments ); } // make a copy, we don't want to modify arguments options = $.extend( {}, options ); var target = $( options.of ), targetElem = target[0], collision = ( options.collision || "flip" ).split( " " ), offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], targetWidth, targetHeight, basePosition; if ( targetElem.nodeType === 9 ) { targetWidth = target.width(); targetHeight = target.height(); basePosition = { top: 0, left: 0 }; // TODO: use $.isWindow() in 1.9 } else if ( targetElem.setTimeout ) { targetWidth = target.width(); targetHeight = target.height(); basePosition = { top: target.scrollTop(), left: target.scrollLeft() }; } else if ( targetElem.preventDefault ) { // force left top to allow flipping options.at = "left top"; targetWidth = targetHeight = 0; basePosition = { top: options.of.pageY, left: options.of.pageX }; } else { targetWidth = target.outerWidth(); targetHeight = target.outerHeight(); basePosition = target.offset(); } // force my and at to have valid horizontal and veritcal positions // if a value is missing or invalid, it will be converted to center $.each( [ "my", "at" ], function() { var pos = ( options[this] || "" ).split( " " ); if ( pos.length === 1) { pos = horizontalPositions.test( pos[0] ) ? pos.concat( [center] ) : verticalPositions.test( pos[0] ) ? [ center ].concat( pos ) : [ center, center ]; } pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center; pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center; options[ this ] = pos; }); // normalize collision option if ( collision.length === 1 ) { collision[ 1 ] = collision[ 0 ]; } // normalize offset option offset[ 0 ] = parseInt( offset[0], 10 ) || 0; if ( offset.length === 1 ) { offset[ 1 ] = offset[ 0 ]; } offset[ 1 ] = parseInt( offset[1], 10 ) || 0; if ( options.at[0] === "right" ) { basePosition.left += targetWidth; } else if ( options.at[0] === center ) { basePosition.left += targetWidth / 2; } if ( options.at[1] === "bottom" ) { basePosition.top += targetHeight; } else if ( options.at[1] === center ) { basePosition.top += targetHeight / 2; } basePosition.left += offset[ 0 ]; basePosition.top += offset[ 1 ]; return this.each(function() { var elem = $( this ), elemWidth = elem.outerWidth(), elemHeight = elem.outerHeight(), marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0, marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0, collisionWidth = elemWidth + marginLeft + ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ), collisionHeight = elemHeight + marginTop + ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ), position = $.extend( {}, basePosition ), collisionPosition; if ( options.my[0] === "right" ) { position.left -= elemWidth; } else if ( options.my[0] === center ) { position.left -= elemWidth / 2; } if ( options.my[1] === "bottom" ) { position.top -= elemHeight; } else if ( options.my[1] === center ) { position.top -= elemHeight / 2; } // prevent fractions if jQuery version doesn't support them (see #5280) if ( !support.fractions ) { position.left = Math.round( position.left ); position.top = Math.round( position.top ); } collisionPosition = { left: position.left - marginLeft, top: position.top - marginTop }; $.each( [ "left", "top" ], function( i, dir ) { if ( $.ui.position[ collision[i] ] ) { $.ui.position[ collision[i] ][ dir ]( position, { targetWidth: targetWidth, targetHeight: targetHeight, elemWidth: elemWidth, elemHeight: elemHeight, collisionPosition: collisionPosition, collisionWidth: collisionWidth, collisionHeight: collisionHeight, offset: offset, my: options.my, at: options.at }); } }); if ( $.fn.bgiframe ) { elem.bgiframe(); } elem.offset( $.extend( position, { using: options.using } ) ); }); }; $.ui.position = { fit: { left: function( position, data ) { var win = $( window ), over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(); position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left ); }, top: function( position, data ) { var win = $( window ), over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(); position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top ); } }, flip: { left: function( position, data ) { if ( data.at[0] === center ) { return; } var win = $( window ), over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(), myOffset = data.my[ 0 ] === "left" ? -data.elemWidth : data.my[ 0 ] === "right" ? data.elemWidth : 0, atOffset = data.at[ 0 ] === "left" ? data.targetWidth : -data.targetWidth, offset = -2 * data.offset[ 0 ]; position.left += data.collisionPosition.left < 0 ? myOffset + atOffset + offset : over > 0 ? myOffset + atOffset + offset : 0; }, top: function( position, data ) { if ( data.at[1] === center ) { return; } var win = $( window ), over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(), myOffset = data.my[ 1 ] === "top" ? -data.elemHeight : data.my[ 1 ] === "bottom" ? data.elemHeight : 0, atOffset = data.at[ 1 ] === "top" ? data.targetHeight : -data.targetHeight, offset = -2 * data.offset[ 1 ]; position.top += data.collisionPosition.top < 0 ? myOffset + atOffset + offset : over > 0 ? myOffset + atOffset + offset : 0; } } }; // offset setter from jQuery 1.4 if ( !$.offset.setOffset ) { $.offset.setOffset = function( elem, options ) { // set position first, in-case top/left are set even on static elem if ( /static/.test( $.curCSS( elem, "position" ) ) ) { elem.style.position = "relative"; } var curElem = $( elem ), curOffset = curElem.offset(), curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0, curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0, props = { top: (options.top - curOffset.top) + curTop, left: (options.left - curOffset.left) + curLeft }; if ( 'using' in options ) { options.using.call( elem, props ); } else { curElem.css( props ); } }; $.fn.offset = function( options ) { var elem = this[ 0 ]; if ( !elem || !elem.ownerDocument ) { return null; } if ( options ) { return this.each(function() { $.offset.setOffset( this, options ); }); } return _offset.call( this ); }; } // fraction support test (older versions of jQuery don't support fractions) (function () { var body = document.getElementsByTagName( "body" )[ 0 ], div = document.createElement( "div" ), testElement, testElementParent, testElementStyle, offset, offsetTotal; //Create a "fake body" for testing based on method used in jQuery.support testElement = document.createElement( body ? "div" : "body" ); testElementStyle = { visibility: "hidden", width: 0, height: 0, border: 0, margin: 0, background: "none" }; if ( body ) { $.extend( testElementStyle, { position: "absolute", left: "-1000px", top: "-1000px" }); } for ( var i in testElementStyle ) { testElement.style[ i ] = testElementStyle[ i ]; } testElement.appendChild( div ); testElementParent = body || document.documentElement; testElementParent.insertBefore( testElement, testElementParent.firstChild ); div.style.cssText = "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;"; offset = $( div ).offset( function( _, offset ) { return offset; }).offset(); testElement.innerHTML = ""; testElementParent.removeChild( testElement ); offsetTotal = offset.top + offset.left + ( body ? 2000 : 0 ); support.fractions = offsetTotal > 21 && offsetTotal < 22; })(); }( jQuery )); SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/jquery.ui.draggable.js0000644000000000000000000007440212612410632027765 0ustar00rootroot00000000000000/* * jQuery UI Draggable 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Draggables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function( $, undefined ) { $.widget("ui.draggable", $.ui.mouse, { widgetEventPrefix: "drag", options: { addClasses: true, appendTo: "parent", axis: false, connectToSortable: false, containment: false, cursor: "auto", cursorAt: false, grid: false, handle: false, helper: "original", iframeFix: false, opacity: false, refreshPositions: false, revert: false, revertDuration: 500, scope: "default", scroll: true, scrollSensitivity: 20, scrollSpeed: 20, snap: false, snapMode: "both", snapTolerance: 20, stack: false, zIndex: false }, _create: function() { if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) this.element[0].style.position = 'relative'; (this.options.addClasses && this.element.addClass("ui-draggable")); (this.options.disabled && this.element.addClass("ui-draggable-disabled")); this._mouseInit(); }, destroy: function() { if(!this.element.data('draggable')) return; this.element .removeData("draggable") .unbind(".draggable") .removeClass("ui-draggable" + " ui-draggable-dragging" + " ui-draggable-disabled"); this._mouseDestroy(); return this; }, _mouseCapture: function(event) { var o = this.options; // among others, prevent a drag on a resizable-handle if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) return false; //Quit if we're not on a valid handle this.handle = this._getHandle(event); if (!this.handle) return false; if ( o.iframeFix ) { $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { $('
      ') .css({ width: this.offsetWidth+"px", height: this.offsetHeight+"px", position: "absolute", opacity: "0.001", zIndex: 1000 }) .css($(this).offset()) .appendTo("body"); }); } return true; }, _mouseStart: function(event) { var o = this.options; //Create and append the visible helper this.helper = this._createHelper(event); //Cache the helper size this._cacheHelperProportions(); //If ddmanager is used for droppables, set the global draggable if($.ui.ddmanager) $.ui.ddmanager.current = this; /* * - Position generation - * This block generates everything position related - it's the core of draggables. */ //Cache the margins of the original element this._cacheMargins(); //Store the helper's css position this.cssPosition = this.helper.css("position"); this.scrollParent = this.helper.scrollParent(); //The element's absolute position on the page minus margins this.offset = this.positionAbs = this.element.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left }; $.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); //Generate the original position this.originalPosition = this.position = this._generatePosition(event); this.originalPageX = event.pageX; this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); //Set a containment if given in the options if(o.containment) this._setContainment(); //Trigger event + callbacks if(this._trigger("start", event) === false) { this._clear(); return false; } //Recache the helper size this._cacheHelperProportions(); //Prepare the droppable offsets if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, event); this.helper.addClass("ui-draggable-dragging"); this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); return true; }, _mouseDrag: function(event, noPropagation) { //Compute the helpers position this.position = this._generatePosition(event); this.positionAbs = this._convertPositionTo("absolute"); //Call plugins and callbacks and use the resulting position if something is returned if (!noPropagation) { var ui = this._uiHash(); if(this._trigger('drag', event, ui) === false) { this._mouseUp({}); return false; } this.position = ui.position; } if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); return false; }, _mouseStop: function(event) { //If we are using droppables, inform the manager about the drop var dropped = false; if ($.ui.ddmanager && !this.options.dropBehaviour) dropped = $.ui.ddmanager.drop(this, event); //if a drop comes from outside (a sortable) if(this.dropped) { dropped = this.dropped; this.dropped = false; } //if the original element is removed, don't bother to continue if helper is set to "original" if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original") return false; if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { var self = this; $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { if(self._trigger("stop", event) !== false) { self._clear(); } }); } else { if(this._trigger("stop", event) !== false) { this._clear(); } } return false; }, _mouseUp: function(event) { if (this.options.iframeFix === true) { $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers } //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); return $.ui.mouse.prototype._mouseUp.call(this, event); }, cancel: function() { if(this.helper.is(".ui-draggable-dragging")) { this._mouseUp({}); } else { this._clear(); } return this; }, _getHandle: function(event) { var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; $(this.options.handle, this.element) .find("*") .andSelf() .each(function() { if(this == event.target) handle = true; }); return handle; }, _createHelper: function(event) { var o = this.options; var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); if(!helper.parents('body').length) helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) helper.css("position", "absolute"); return helper; }, _adjustOffsetFromHelper: function(obj) { if (typeof obj == 'string') { obj = obj.split(' '); } if ($.isArray(obj)) { obj = {left: +obj[0], top: +obj[1] || 0}; } if ('left' in obj) { this.offset.click.left = obj.left + this.margins.left; } if ('right' in obj) { this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; } if ('top' in obj) { this.offset.click.top = obj.top + this.margins.top; } if ('bottom' in obj) { this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } }, _getParentOffset: function() { //Get the offsetParent and cache its position this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); // This is a special case where we need to modify a offset calculated on start, since the following happened: // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix po = { top: 0, left: 0 }; return { top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) }; }, _getRelativeOffset: function() { if(this.cssPosition == "relative") { var p = this.element.position(); return { top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; } }, _cacheMargins: function() { this.margins = { left: (parseInt(this.element.css("marginLeft"),10) || 0), top: (parseInt(this.element.css("marginTop"),10) || 0), right: (parseInt(this.element.css("marginRight"),10) || 0), bottom: (parseInt(this.element.css("marginBottom"),10) || 0) }; }, _cacheHelperProportions: function() { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, _setContainment: function() { var o = this.options; if(o.containment == 'parent') o.containment = this.helper[0].parentNode; if(o.containment == 'document' || o.containment == 'window') this.containment = [ o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top ]; if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { var c = $(o.containment); var ce = c[0]; if(!ce) return; var co = c.offset(); var over = ($(ce).css("overflow") != 'hidden'); this.containment = [ (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom ]; this.relative_container = c; } else if(o.containment.constructor == Array) { this.containment = o.containment; } }, _convertPositionTo: function(d, pos) { if(!pos) pos = this.position; var mod = d == "absolute" ? 1 : -1; var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); return { top: ( pos.top // The absolute mouse position + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) ), left: ( pos.left // The absolute mouse position + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) ) }; }, _generatePosition: function(event) { var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); var pageX = event.pageX; var pageY = event.pageY; /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ if(this.originalPosition) { //If we are not dragging yet, we won't check for options var containment; if(this.containment) { if (this.relative_container){ var co = this.relative_container.offset(); containment = [ this.containment[0] + co.left, this.containment[1] + co.top, this.containment[2] + co.left, this.containment[3] + co.top ]; } else { containment = this.containment; } if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; } if(o.grid) { //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; } } return { top: ( pageY // The absolute mouse position - this.offset.click.top // Click offset (relative to the element) - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) ), left: ( pageX // The absolute mouse position - this.offset.click.left // Click offset (relative to the element) - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) ) }; }, _clear: function() { this.helper.removeClass("ui-draggable-dragging"); if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); //if($.ui.ddmanager) $.ui.ddmanager.current = null; this.helper = null; this.cancelHelperRemoval = false; }, // From now on bulk stuff - mainly helpers _trigger: function(type, event, ui) { ui = ui || this._uiHash(); $.ui.plugin.call(this, type, [event, ui]); if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins return $.Widget.prototype._trigger.call(this, type, event, ui); }, plugins: {}, _uiHash: function(event) { return { helper: this.helper, position: this.position, originalPosition: this.originalPosition, offset: this.positionAbs }; } }); $.extend($.ui.draggable, { version: "1.8.18" }); $.ui.plugin.add("draggable", "connectToSortable", { start: function(event, ui) { var inst = $(this).data("draggable"), o = inst.options, uiSortable = $.extend({}, ui, { item: inst.element }); inst.sortables = []; $(o.connectToSortable).each(function() { var sortable = $.data(this, 'sortable'); if (sortable && !sortable.options.disabled) { inst.sortables.push({ instance: sortable, shouldRevert: sortable.options.revert }); sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). sortable._trigger("activate", event, uiSortable); } }); }, stop: function(event, ui) { //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper var inst = $(this).data("draggable"), uiSortable = $.extend({}, ui, { item: inst.element }); $.each(inst.sortables, function() { if(this.instance.isOver) { this.instance.isOver = 0; inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' if(this.shouldRevert) this.instance.options.revert = true; //Trigger the stop of the sortable this.instance._mouseStop(event); this.instance.options.helper = this.instance.options._helper; //If the helper has been the original item, restore properties in the sortable if(inst.options.helper == 'original') this.instance.currentItem.css({ top: 'auto', left: 'auto' }); } else { this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance this.instance._trigger("deactivate", event, uiSortable); } }); }, drag: function(event, ui) { var inst = $(this).data("draggable"), self = this; var checkPos = function(o) { var dyClick = this.offset.click.top, dxClick = this.offset.click.left; var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; var itemHeight = o.height, itemWidth = o.width; var itemTop = o.top, itemLeft = o.left; return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); }; $.each(inst.sortables, function(i) { //Copy over some variables to allow calling the sortable's native _intersectsWith this.instance.positionAbs = inst.positionAbs; this.instance.helperProportions = inst.helperProportions; this.instance.offset.click = inst.offset.click; if(this.instance._intersectsWith(this.instance.containerCache)) { //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once if(!this.instance.isOver) { this.instance.isOver = 1; //Now we fake the start of dragging for the sortable instance, //by cloning the list group item, appending it to the sortable and using it as inst.currentItem //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it this.instance.options.helper = function() { return ui.helper[0]; }; event.target = this.instance.currentItem[0]; this.instance._mouseCapture(event, true); this.instance._mouseStart(event, true, true); //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes this.instance.offset.click.top = inst.offset.click.top; this.instance.offset.click.left = inst.offset.click.left; this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; inst._trigger("toSortable", event); inst.dropped = this.instance.element; //draggable revert needs that //hack so receive/update callbacks work (mostly) inst.currentItem = inst.element; this.instance.fromOutside = inst; } //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable if(this.instance.currentItem) this.instance._mouseDrag(event); } else { //If it doesn't intersect with the sortable, and it intersected before, //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval if(this.instance.isOver) { this.instance.isOver = 0; this.instance.cancelHelperRemoval = true; //Prevent reverting on this forced stop this.instance.options.revert = false; // The out event needs to be triggered independently this.instance._trigger('out', event, this.instance._uiHash(this.instance)); this.instance._mouseStop(event, true); this.instance.options.helper = this.instance.options._helper; //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size this.instance.currentItem.remove(); if(this.instance.placeholder) this.instance.placeholder.remove(); inst._trigger("fromSortable", event); inst.dropped = false; //draggable revert needs that } }; }); } }); $.ui.plugin.add("draggable", "cursor", { start: function(event, ui) { var t = $('body'), o = $(this).data('draggable').options; if (t.css("cursor")) o._cursor = t.css("cursor"); t.css("cursor", o.cursor); }, stop: function(event, ui) { var o = $(this).data('draggable').options; if (o._cursor) $('body').css("cursor", o._cursor); } }); $.ui.plugin.add("draggable", "opacity", { start: function(event, ui) { var t = $(ui.helper), o = $(this).data('draggable').options; if(t.css("opacity")) o._opacity = t.css("opacity"); t.css('opacity', o.opacity); }, stop: function(event, ui) { var o = $(this).data('draggable').options; if(o._opacity) $(ui.helper).css('opacity', o._opacity); } }); $.ui.plugin.add("draggable", "scroll", { start: function(event, ui) { var i = $(this).data("draggable"); if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); }, drag: function(event, ui) { var i = $(this).data("draggable"), o = i.options, scrolled = false; if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { if(!o.axis || o.axis != 'x') { if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; } if(!o.axis || o.axis != 'y') { if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; } } else { if(!o.axis || o.axis != 'x') { if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); } if(!o.axis || o.axis != 'y') { if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } } if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(i, event); } }); $.ui.plugin.add("draggable", "snap", { start: function(event, ui) { var i = $(this).data("draggable"), o = i.options; i.snapElements = []; $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { var $t = $(this); var $o = $t.offset(); if(this != i.element[0]) i.snapElements.push({ item: this, width: $t.outerWidth(), height: $t.outerHeight(), top: $o.top, left: $o.left }); }); }, drag: function(event, ui) { var inst = $(this).data("draggable"), o = inst.options; var d = o.snapTolerance; var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; for (var i = inst.snapElements.length - 1; i >= 0; i--){ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; //Yes, I know, this is insane ;) if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); inst.snapElements[i].snapping = false; continue; } if(o.snapMode != 'inner') { var ts = Math.abs(t - y2) <= d; var bs = Math.abs(b - y1) <= d; var ls = Math.abs(l - x2) <= d; var rs = Math.abs(r - x1) <= d; if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; } var first = (ts || bs || ls || rs); if(o.snapMode != 'outer') { var ts = Math.abs(t - y1) <= d; var bs = Math.abs(b - y2) <= d; var ls = Math.abs(l - x1) <= d; var rs = Math.abs(r - x2) <= d; if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; } if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); inst.snapElements[i].snapping = (ts || bs || ls || rs || first); }; } }); $.ui.plugin.add("draggable", "stack", { start: function(event, ui) { var o = $(this).data("draggable").options; var group = $.makeArray($(o.stack)).sort(function(a,b) { return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); }); if (!group.length) { return; } var min = parseInt(group[0].style.zIndex) || 0; $(group).each(function(i) { this.style.zIndex = min + i; }); this[0].style.zIndex = min + group.length; } }); $.ui.plugin.add("draggable", "zIndex", { start: function(event, ui) { var t = $(ui.helper), o = $(this).data("draggable").options; if(t.css("zIndex")) o._zIndex = t.css("zIndex"); t.css('zIndex', o.zIndex); }, stop: function(event, ui) { var o = $(this).data("draggable").options; if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); } }); })(jQuery); SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/jquery.ui.droppable.js0000644000000000000000000002367312612410632030031 0ustar00rootroot00000000000000/* * jQuery UI Droppable 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Droppables * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * jquery.ui.mouse.js * jquery.ui.draggable.js */ (function( $, undefined ) { $.widget("ui.droppable", { widgetEventPrefix: "drop", options: { accept: '*', activeClass: false, addClasses: true, greedy: false, hoverClass: false, scope: 'default', tolerance: 'intersect' }, _create: function() { var o = this.options, accept = o.accept; this.isover = 0; this.isout = 1; this.accept = $.isFunction(accept) ? accept : function(d) { return d.is(accept); }; //Store the droppable's proportions this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; // Add the reference and positions to the manager $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; $.ui.ddmanager.droppables[o.scope].push(this); (o.addClasses && this.element.addClass("ui-droppable")); }, destroy: function() { var drop = $.ui.ddmanager.droppables[this.options.scope]; for ( var i = 0; i < drop.length; i++ ) if ( drop[i] == this ) drop.splice(i, 1); this.element .removeClass("ui-droppable ui-droppable-disabled") .removeData("droppable") .unbind(".droppable"); return this; }, _setOption: function(key, value) { if(key == 'accept') { this.accept = $.isFunction(value) ? value : function(d) { return d.is(value); }; } $.Widget.prototype._setOption.apply(this, arguments); }, _activate: function(event) { var draggable = $.ui.ddmanager.current; if(this.options.activeClass) this.element.addClass(this.options.activeClass); (draggable && this._trigger('activate', event, this.ui(draggable))); }, _deactivate: function(event) { var draggable = $.ui.ddmanager.current; if(this.options.activeClass) this.element.removeClass(this.options.activeClass); (draggable && this._trigger('deactivate', event, this.ui(draggable))); }, _over: function(event) { var draggable = $.ui.ddmanager.current; if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); this._trigger('over', event, this.ui(draggable)); } }, _out: function(event) { var draggable = $.ui.ddmanager.current; if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); this._trigger('out', event, this.ui(draggable)); } }, _drop: function(event,custom) { var draggable = custom || $.ui.ddmanager.current; if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element var childrenIntersection = false; this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { var inst = $.data(this, 'droppable'); if( inst.options.greedy && !inst.options.disabled && inst.options.scope == draggable.options.scope && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) ) { childrenIntersection = true; return false; } }); if(childrenIntersection) return false; if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { if(this.options.activeClass) this.element.removeClass(this.options.activeClass); if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); this._trigger('drop', event, this.ui(draggable)); return this.element; } return false; }, ui: function(c) { return { draggable: (c.currentItem || c.element), helper: c.helper, position: c.position, offset: c.positionAbs }; } }); $.extend($.ui.droppable, { version: "1.8.18" }); $.ui.intersect = function(draggable, droppable, toleranceMode) { if (!droppable.offset) return false; var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; var l = droppable.offset.left, r = l + droppable.proportions.width, t = droppable.offset.top, b = t + droppable.proportions.height; switch (toleranceMode) { case 'fit': return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); break; case 'intersect': return (l < x1 + (draggable.helperProportions.width / 2) // Right Half && x2 - (draggable.helperProportions.width / 2) < r // Left Half && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half break; case 'pointer': var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); return isOver; break; case 'touch': return ( (y1 >= t && y1 <= b) || // Top edge touching (y2 >= t && y2 <= b) || // Bottom edge touching (y1 < t && y2 > b) // Surrounded vertically ) && ( (x1 >= l && x1 <= r) || // Left edge touching (x2 >= l && x2 <= r) || // Right edge touching (x1 < l && x2 > r) // Surrounded horizontally ); break; default: return false; break; } }; /* This manager tracks offsets of draggables and droppables */ $.ui.ddmanager = { current: null, droppables: { 'default': [] }, prepareOffsets: function(t, event) { var m = $.ui.ddmanager.droppables[t.options.scope] || []; var type = event ? event.type : null; // workaround for #2317 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); droppablesLoop: for (var i = 0; i < m.length; i++) { if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables m[i].offset = m[i].element.offset(); m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; } }, drop: function(draggable, event) { var dropped = false; $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { if(!this.options) return; if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) dropped = this._drop.call(this, event) || dropped; if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { this.isout = 1; this.isover = 0; this._deactivate.call(this, event); } }); return dropped; }, dragStart: function( draggable, event ) { //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() { if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); }); }, drag: function(draggable, event) { //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); //Run through all droppables and check their positions based on specific tolerance options $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { if(this.options.disabled || this.greedyChild || !this.visible) return; var intersects = $.ui.intersect(draggable, this, this.options.tolerance); var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); if(!c) return; var parentInstance; if (this.options.greedy) { var parent = this.element.parents(':data(droppable):eq(0)'); if (parent.length) { parentInstance = $.data(parent[0], 'droppable'); parentInstance.greedyChild = (c == 'isover' ? 1 : 0); } } // we just moved into a greedy child if (parentInstance && c == 'isover') { parentInstance['isover'] = 0; parentInstance['isout'] = 1; parentInstance._out.call(parentInstance, event); } this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; this[c == "isover" ? "_over" : "_out"].call(this, event); // we just moved out of a greedy child if (parentInstance && c == 'isout') { parentInstance['isout'] = 0; parentInstance['isover'] = 1; parentInstance._over.call(parentInstance, event); } }); }, dragStop: function( draggable, event ) { draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" ); //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); } }; })(jQuery); SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/script.js0000644000000000000000000000032112612413171025415 0ustar00rootroot00000000000000This directory holds sources for minified javascript files, for Debian policy compliance reasons. # interfaces/Config/templates/staticcfg/js/script.js jQuery v1.7.2 jQuery UI 1.8.18 jQuery Tools v1.2.6 qTip2 SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/jquery.ui.button.js0000644000000000000000000002611512612410632027366 0ustar00rootroot00000000000000/* * jQuery UI Button 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Button * * Depends: * jquery.ui.core.js * jquery.ui.widget.js */ (function( $, undefined ) { var lastActive, startXPos, startYPos, clickDragged, baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", stateClasses = "ui-state-hover ui-state-active ", typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", formResetHandler = function() { var buttons = $( this ).find( ":ui-button" ); setTimeout(function() { buttons.button( "refresh" ); }, 1 ); }, radioGroup = function( radio ) { var name = radio.name, form = radio.form, radios = $( [] ); if ( name ) { if ( form ) { radios = $( form ).find( "[name='" + name + "']" ); } else { radios = $( "[name='" + name + "']", radio.ownerDocument ) .filter(function() { return !this.form; }); } } return radios; }; $.widget( "ui.button", { options: { disabled: null, text: true, label: null, icons: { primary: null, secondary: null } }, _create: function() { this.element.closest( "form" ) .unbind( "reset.button" ) .bind( "reset.button", formResetHandler ); if ( typeof this.options.disabled !== "boolean" ) { this.options.disabled = !!this.element.propAttr( "disabled" ); } else { this.element.propAttr( "disabled", this.options.disabled ); } this._determineButtonType(); this.hasTitle = !!this.buttonElement.attr( "title" ); var self = this, options = this.options, toggleButton = this.type === "checkbox" || this.type === "radio", hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ), focusClass = "ui-state-focus"; if ( options.label === null ) { options.label = this.buttonElement.html(); } this.buttonElement .addClass( baseClasses ) .attr( "role", "button" ) .bind( "mouseenter.button", function() { if ( options.disabled ) { return; } $( this ).addClass( "ui-state-hover" ); if ( this === lastActive ) { $( this ).addClass( "ui-state-active" ); } }) .bind( "mouseleave.button", function() { if ( options.disabled ) { return; } $( this ).removeClass( hoverClass ); }) .bind( "click.button", function( event ) { if ( options.disabled ) { event.preventDefault(); event.stopImmediatePropagation(); } }); this.element .bind( "focus.button", function() { // no need to check disabled, focus won't be triggered anyway self.buttonElement.addClass( focusClass ); }) .bind( "blur.button", function() { self.buttonElement.removeClass( focusClass ); }); if ( toggleButton ) { this.element.bind( "change.button", function() { if ( clickDragged ) { return; } self.refresh(); }); // if mouse moves between mousedown and mouseup (drag) set clickDragged flag // prevents issue where button state changes but checkbox/radio checked state // does not in Firefox (see ticket #6970) this.buttonElement .bind( "mousedown.button", function( event ) { if ( options.disabled ) { return; } clickDragged = false; startXPos = event.pageX; startYPos = event.pageY; }) .bind( "mouseup.button", function( event ) { if ( options.disabled ) { return; } if ( startXPos !== event.pageX || startYPos !== event.pageY ) { clickDragged = true; } }); } if ( this.type === "checkbox" ) { this.buttonElement.bind( "click.button", function() { if ( options.disabled || clickDragged ) { return false; } $( this ).toggleClass( "ui-state-active" ); self.buttonElement.attr( "aria-pressed", self.element[0].checked ); }); } else if ( this.type === "radio" ) { this.buttonElement.bind( "click.button", function() { if ( options.disabled || clickDragged ) { return false; } $( this ).addClass( "ui-state-active" ); self.buttonElement.attr( "aria-pressed", "true" ); var radio = self.element[ 0 ]; radioGroup( radio ) .not( radio ) .map(function() { return $( this ).button( "widget" )[ 0 ]; }) .removeClass( "ui-state-active" ) .attr( "aria-pressed", "false" ); }); } else { this.buttonElement .bind( "mousedown.button", function() { if ( options.disabled ) { return false; } $( this ).addClass( "ui-state-active" ); lastActive = this; $( document ).one( "mouseup", function() { lastActive = null; }); }) .bind( "mouseup.button", function() { if ( options.disabled ) { return false; } $( this ).removeClass( "ui-state-active" ); }) .bind( "keydown.button", function(event) { if ( options.disabled ) { return false; } if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) { $( this ).addClass( "ui-state-active" ); } }) .bind( "keyup.button", function() { $( this ).removeClass( "ui-state-active" ); }); if ( this.buttonElement.is("a") ) { this.buttonElement.keyup(function(event) { if ( event.keyCode === $.ui.keyCode.SPACE ) { // TODO pass through original event correctly (just as 2nd argument doesn't work) $( this ).click(); } }); } } // TODO: pull out $.Widget's handling for the disabled option into // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can // be overridden by individual plugins this._setOption( "disabled", options.disabled ); this._resetButton(); }, _determineButtonType: function() { if ( this.element.is(":checkbox") ) { this.type = "checkbox"; } else if ( this.element.is(":radio") ) { this.type = "radio"; } else if ( this.element.is("input") ) { this.type = "input"; } else { this.type = "button"; } if ( this.type === "checkbox" || this.type === "radio" ) { // we don't search against the document in case the element // is disconnected from the DOM var ancestor = this.element.parents().filter(":last"), labelSelector = "label[for='" + this.element.attr("id") + "']"; this.buttonElement = ancestor.find( labelSelector ); if ( !this.buttonElement.length ) { ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); this.buttonElement = ancestor.filter( labelSelector ); if ( !this.buttonElement.length ) { this.buttonElement = ancestor.find( labelSelector ); } } this.element.addClass( "ui-helper-hidden-accessible" ); var checked = this.element.is( ":checked" ); if ( checked ) { this.buttonElement.addClass( "ui-state-active" ); } this.buttonElement.attr( "aria-pressed", checked ); } else { this.buttonElement = this.element; } }, widget: function() { return this.buttonElement; }, destroy: function() { this.element .removeClass( "ui-helper-hidden-accessible" ); this.buttonElement .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) .removeAttr( "role" ) .removeAttr( "aria-pressed" ) .html( this.buttonElement.find(".ui-button-text").html() ); if ( !this.hasTitle ) { this.buttonElement.removeAttr( "title" ); } $.Widget.prototype.destroy.call( this ); }, _setOption: function( key, value ) { $.Widget.prototype._setOption.apply( this, arguments ); if ( key === "disabled" ) { if ( value ) { this.element.propAttr( "disabled", true ); } else { this.element.propAttr( "disabled", false ); } return; } this._resetButton(); }, refresh: function() { var isDisabled = this.element.is( ":disabled" ); if ( isDisabled !== this.options.disabled ) { this._setOption( "disabled", isDisabled ); } if ( this.type === "radio" ) { radioGroup( this.element[0] ).each(function() { if ( $( this ).is( ":checked" ) ) { $( this ).button( "widget" ) .addClass( "ui-state-active" ) .attr( "aria-pressed", "true" ); } else { $( this ).button( "widget" ) .removeClass( "ui-state-active" ) .attr( "aria-pressed", "false" ); } }); } else if ( this.type === "checkbox" ) { if ( this.element.is( ":checked" ) ) { this.buttonElement .addClass( "ui-state-active" ) .attr( "aria-pressed", "true" ); } else { this.buttonElement .removeClass( "ui-state-active" ) .attr( "aria-pressed", "false" ); } } }, _resetButton: function() { if ( this.type === "input" ) { if ( this.options.label ) { this.element.val( this.options.label ); } return; } var buttonElement = this.buttonElement.removeClass( typeClasses ), buttonText = $( "", this.element[0].ownerDocument ) .addClass( "ui-button-text" ) .html( this.options.label ) .appendTo( buttonElement.empty() ) .text(), icons = this.options.icons, multipleIcons = icons.primary && icons.secondary, buttonClasses = []; if ( icons.primary || icons.secondary ) { if ( this.options.text ) { buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); } if ( icons.primary ) { buttonElement.prepend( "" ); } if ( icons.secondary ) { buttonElement.append( "" ); } if ( !this.options.text ) { buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); if ( !this.hasTitle ) { buttonElement.attr( "title", buttonText ); } } } else { buttonClasses.push( "ui-button-text-only" ); } buttonElement.addClass( buttonClasses.join( " " ) ); } }); $.widget( "ui.buttonset", { options: { items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" }, _create: function() { this.element.addClass( "ui-buttonset" ); }, _init: function() { this.refresh(); }, _setOption: function( key, value ) { if ( key === "disabled" ) { this.buttons.button( "option", key, value ); } $.Widget.prototype._setOption.apply( this, arguments ); }, refresh: function() { var rtl = this.element.css( "direction" ) === "rtl"; this.buttons = this.element.find( this.options.items ) .filter( ":ui-button" ) .button( "refresh" ) .end() .not( ":ui-button" ) .button() .end() .map(function() { return $( this ).button( "widget" )[ 0 ]; }) .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) .filter( ":first" ) .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) .end() .filter( ":last" ) .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) .end() .end(); }, destroy: function() { this.element.removeClass( "ui-buttonset" ); this.buttons .map(function() { return $( this ).button( "widget" )[ 0 ]; }) .removeClass( "ui-corner-left ui-corner-right" ) .end() .button( "destroy" ); $.Widget.prototype.destroy.call( this ); } }); }( jQuery ) ); SABnzbd-0.7.20/interfaces/Config/templates/staticcfg/js/src/jquery.ui.sortable.js0000644000000000000000000011634312612410632027671 0ustar00rootroot00000000000000/* * jQuery UI Sortable 1.8.18 * * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * http://docs.jquery.com/UI/Sortables * * Depends: * jquery.ui.core.js * jquery.ui.mouse.js * jquery.ui.widget.js */ (function( $, undefined ) { $.widget("ui.sortable", $.ui.mouse, { widgetEventPrefix: "sort", ready: false, options: { appendTo: "parent", axis: false, connectWith: false, containment: false, cursor: 'auto', cursorAt: false, dropOnEmpty: true, forcePlaceholderSize: false, forceHelperSize: false, grid: false, handle: false, helper: "original", items: '> *', opacity: false, placeholder: false, revert: false, scroll: true, scrollSensitivity: 20, scrollSpeed: 20, scope: "default", tolerance: "intersect", zIndex: 1000 }, _create: function() { var o = this.options; this.containerCache = {}; this.element.addClass("ui-sortable"); //Get the items this.refresh(); //Let's determine if the items are being displayed horizontally this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; //Let's determine the parent's offset this.offset = this.element.offset(); //Initialize mouse events for interaction this._mouseInit(); //We're ready to go this.ready = true }, destroy: function() { $.Widget.prototype.destroy.call( this ); this.element .removeClass("ui-sortable ui-sortable-disabled"); this._mouseDestroy(); for ( var i = this.items.length - 1; i >= 0; i-- ) this.items[i].item.removeData(this.widgetName + "-item"); return this; }, _setOption: function(key, value){ if ( key === "disabled" ) { this.options[ key ] = value; this.widget() [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" ); } else { // Don't call widget base _setOption for disable as it adds ui-state-disabled class $.Widget.prototype._setOption.apply(this, arguments); } }, _mouseCapture: function(event, overrideHandle) { var that = this; if (this.reverting) { return false; } if(this.options.disabled || this.options.type == 'static') return false; //We have to refresh the items data once first this._refreshItems(event); //Find out if the clicked node (or one of its parents) is a actual item in this.items var currentItem = null, self = this, nodes = $(event.target).parents().each(function() { if($.data(this, that.widgetName + '-item') == self) { currentItem = $(this); return false; } }); if($.data(event.target, that.widgetName + '-item') == self) currentItem = $(event.target); if(!currentItem) return false; if(this.options.handle && !overrideHandle) { var validHandle = false; $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); if(!validHandle) return false; } this.currentItem = currentItem; this._removeCurrentsFromItems(); return true; }, _mouseStart: function(event, overrideHandle, noActivation) { var o = this.options, self = this; this.currentContainer = this; //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture this.refreshPositions(); //Create and append the visible helper this.helper = this._createHelper(event); //Cache the helper size this._cacheHelperProportions(); /* * - Position generation - * This block generates everything position related - it's the core of draggables. */ //Cache the margins of the original element this._cacheMargins(); //Get the next scrolling parent this.scrollParent = this.helper.scrollParent(); //The element's absolute position on the page minus margins this.offset = this.currentItem.offset(); this.offset = { top: this.offset.top - this.margins.top, left: this.offset.left - this.margins.left }; // Only after we got the offset, we can change the helper's position to absolute // TODO: Still need to figure out a way to make relative sorting possible this.helper.css("position", "absolute"); this.cssPosition = this.helper.css("position"); $.extend(this.offset, { click: { //Where the click happened, relative to the element left: event.pageX - this.offset.left, top: event.pageY - this.offset.top }, parent: this._getParentOffset(), relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper }); //Generate the original position this.originalPosition = this._generatePosition(event); this.originalPageX = event.pageX; this.originalPageY = event.pageY; //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); //Cache the former DOM position this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way if(this.helper[0] != this.currentItem[0]) { this.currentItem.hide(); } //Create the placeholder this._createPlaceholder(); //Set a containment if given in the options if(o.containment) this._setContainment(); if(o.cursor) { // cursor option if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); $('body').css("cursor", o.cursor); } if(o.opacity) { // opacity option if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); this.helper.css("opacity", o.opacity); } if(o.zIndex) { // zIndex option if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); this.helper.css("zIndex", o.zIndex); } //Prepare scrolling if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') this.overflowOffset = this.scrollParent.offset(); //Call callbacks this._trigger("start", event, this._uiHash()); //Recache the helper size if(!this._preserveHelperProportions) this._cacheHelperProportions(); //Post 'activate' events to possible containers if(!noActivation) { for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); } } //Prepare possible droppables if($.ui.ddmanager) $.ui.ddmanager.current = this; if ($.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, event); this.dragging = true; this.helper.addClass("ui-sortable-helper"); this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position return true; }, _mouseDrag: function(event) { //Compute the helpers position this.position = this._generatePosition(event); this.positionAbs = this._convertPositionTo("absolute"); if (!this.lastPositionAbs) { this.lastPositionAbs = this.positionAbs; } //Do scrolling if(this.options.scroll) { var o = this.options, scrolled = false; if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; } else { if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); } if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) $.ui.ddmanager.prepareOffsets(this, event); } //Regenerate the absolute position used for position checks this.positionAbs = this._convertPositionTo("absolute"); //Set the helper position if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; //Rearrange for (var i = this.items.length - 1; i >= 0; i--) { //Cache variables and intersection, continue if no intersection var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); if (!intersection) continue; if(itemElement != this.currentItem[0] //cannot intersect with itself && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true) //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container ) { this.direction = intersection == 1 ? "down" : "up"; if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { this._rearrange(event, item); } else { break; } this._trigger("change", event, this._uiHash()); break; } } //Post events to containers this._contactContainers(event); //Interconnect with droppables if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); //Call callbacks this._trigger('sort', event, this._uiHash()); this.lastPositionAbs = this.positionAbs; return false; }, _mouseStop: function(event, noPropagation) { if(!event) return; //If we are using droppables, inform the manager about the drop if ($.ui.ddmanager && !this.options.dropBehaviour) $.ui.ddmanager.drop(this, event); if(this.options.revert) { var self = this; var cur = self.placeholder.offset(); self.reverting = true; $(this.helper).animate({ left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) }, parseInt(this.options.revert, 10) || 500, function() { self._clear(event); }); } else { this._clear(event, noPropagation); } return false; }, cancel: function() { var self = this; if(this.dragging) { this._mouseUp({ target: null }); if(this.options.helper == "original") this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); else this.currentItem.show(); //Post deactivating events to containers for (var i = this.containers.length - 1; i >= 0; i--){ this.containers[i]._trigger("deactivate", null, self._uiHash(this)); if(this.containers[i].containerCache.over) { this.containers[i]._trigger("out", null, self._uiHash(this)); this.containers[i].containerCache.over = 0; } } } if (this.placeholder) { //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); $.extend(this, { helper: null, dragging: false, reverting: false, _noFinalSort: null }); if(this.domPosition.prev) { $(this.domPosition.prev).after(this.currentItem); } else { $(this.domPosition.parent).prepend(this.currentItem); } } return this; }, serialize: function(o) { var items = this._getItemsAsjQuery(o && o.connected); var str = []; o = o || {}; $(items).each(function() { var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); }); if(!str.length && o.key) { str.push(o.key + '='); } return str.join('&'); }, toArray: function(o) { var items = this._getItemsAsjQuery(o && o.connected); var ret = []; o = o || {}; items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); return ret; }, /* Be careful with the following core functions */ _intersectsWith: function(item) { var x1 = this.positionAbs.left, x2 = x1 + this.helperProportions.width, y1 = this.positionAbs.top, y2 = y1 + this.helperProportions.height; var l = item.left, r = l + item.width, t = item.top, b = t + item.height; var dyClick = this.offset.click.top, dxClick = this.offset.click.left; var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; if( this.options.tolerance == "pointer" || this.options.forcePointerForContainers || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) ) { return isOverElement; } else { return (l < x1 + (this.helperProportions.width / 2) // Right Half && x2 - (this.helperProportions.width / 2) < r // Left Half && t < y1 + (this.helperProportions.height / 2) // Bottom Half && y2 - (this.helperProportions.height / 2) < b ); // Top Half } }, _intersectsWithPointer: function(item) { var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), isOverElement = isOverElementHeight && isOverElementWidth, verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); if (!isOverElement) return false; return this.floating ? ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); }, _intersectsWithSides: function(item) { var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), verticalDirection = this._getDragVerticalDirection(), horizontalDirection = this._getDragHorizontalDirection(); if (this.floating && horizontalDirection) { return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); } else { return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); } }, _getDragVerticalDirection: function() { var delta = this.positionAbs.top - this.lastPositionAbs.top; return delta != 0 && (delta > 0 ? "down" : "up"); }, _getDragHorizontalDirection: function() { var delta = this.positionAbs.left - this.lastPositionAbs.left; return delta != 0 && (delta > 0 ? "right" : "left"); }, refresh: function(event) { this._refreshItems(event); this.refreshPositions(); return this; }, _connectWith: function() { var options = this.options; return options.connectWith.constructor == String ? [options.connectWith] : options.connectWith; }, _getItemsAsjQuery: function(connected) { var self = this; var items = []; var queries = []; var connectWith = this._connectWith(); if(connectWith && connected) { for (var i = connectWith.length - 1; i >= 0; i--){ var cur = $(connectWith[i]); for (var j = cur.length - 1; j >= 0; j--){ var inst = $.data(cur[j], this.widgetName); if(inst && inst != this && !inst.options.disabled) { queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]); } }; }; } queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]); for (var i = queries.length - 1; i >= 0; i--){ queries[i][0].each(function() { items.push(this); }); }; return $(items); }, _removeCurrentsFromItems: function() { var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); for (var i=0; i < this.items.length; i++) { for (var j=0; j < list.length; j++) { if(list[j] == this.items[i].item[0]) this.items.splice(i,1); }; }; }, _refreshItems: function(event) { this.items = []; this.containers = [this]; var items = this.items; var self = this; var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; var connectWith = this._connectWith(); if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down for (var i = connectWith.length - 1; i >= 0; i--){ var cur = $(connectWith[i]); for (var j = cur.length - 1; j >= 0; j--){ var inst = $.data(cur[j], this.widgetName); if(inst && inst != this && !inst.options.disabled) { queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); this.containers.push(inst); } }; }; } for (var i = queries.length - 1; i >= 0; i--) { var targetData = queries[i][1]; var _queries = queries[i][0]; for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { var item = $(_queries[j]); item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager) items.push({ item: item, instance: targetData, width: 0, height: 0, left: 0, top: 0 }); }; }; }, refreshPositions: function(fast) { //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change if(this.offsetParent && this.helper) { this.offset.parent = this._getParentOffset(); } for (var i = this.items.length - 1; i >= 0; i--){ var item = this.items[i]; //We ignore calculating positions of all connected containers when we're not over them if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) continue; var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; if (!fast) { item.width = t.outerWidth(); item.height = t.outerHeight(); } var p = t.offset(); item.left = p.left; item.top = p.top; }; if(this.options.custom && this.options.custom.refreshContainers) { this.options.custom.refreshContainers.call(this); } else { for (var i = this.containers.length - 1; i >= 0; i--){ var p = this.containers[i].element.offset(); this.containers[i].containerCache.left = p.left; this.containers[i].containerCache.top = p.top; this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); }; } return this; }, _createPlaceholder: function(that) { var self = that || this, o = self.options; if(!o.placeholder || o.placeholder.constructor == String) { var className = o.placeholder; o.placeholder = { element: function() { var el = $(document.createElement(self.currentItem[0].nodeName)) .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder") .removeClass("ui-sortable-helper")[0]; if(!className) el.style.visibility = "hidden"; return el; }, update: function(container, p) { // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified if(className && !o.forcePlaceholderSize) return; //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); }; if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); }; } }; } //Create the placeholder self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem)); //Append it after the actual current item self.currentItem.after(self.placeholder); //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) o.placeholder.update(self, self.placeholder); }, _contactContainers: function(event) { // get innermost container that intersects with item var innermostContainer = null, innermostIndex = null; for (var i = this.containers.length - 1; i >= 0; i--){ // never consider a container that's located within the item itself if($.ui.contains(this.currentItem[0], this.containers[i].element[0])) continue; if(this._intersectsWith(this.containers[i].containerCache)) { // if we've already found a container and it's more "inner" than this, then continue if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0])) continue; innermostContainer = this.containers[i]; innermostIndex = i; } else { // container doesn't intersect. trigger "out" event if necessary if(this.containers[i].containerCache.over) { this.containers[i]._trigger("out", event, this._uiHash(this)); this.containers[i].containerCache.over = 0; } } } // if no intersecting containers found, return if(!innermostContainer) return; // move the item into the container if it's not there already if(this.containers.length === 1) { this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); this.containers[innermostIndex].containerCache.over = 1; } else if(this.currentContainer != this.containers[innermostIndex]) { //When entering a new container, we will find the item with the least distance and append our item near it var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; for (var j = this.items.length - 1; j >= 0; j--) { if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; if(Math.abs(cur - base) < dist) { dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; } } if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled return; this.currentContainer = this.containers[innermostIndex]; itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); this._trigger("change", event, this._uiHash()); this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); //Update the placeholder this.options.placeholder.update(this.currentContainer, this.placeholder); this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); this.containers[innermostIndex].containerCache.over = 1; } }, _createHelper: function(event) { var o = this.options; var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); if(helper[0] == this.currentItem[0]) this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); return helper; }, _adjustOffsetFromHelper: function(obj) { if (typeof obj == 'string') { obj = obj.split(' '); } if ($.isArray(obj)) { obj = {left: +obj[0], top: +obj[1] || 0}; } if ('left' in obj) { this.offset.click.left = obj.left + this.margins.left; } if ('right' in obj) { this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; } if ('top' in obj) { this.offset.click.top = obj.top + this.margins.top; } if ('bottom' in obj) { this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; } }, _getParentOffset: function() { //Get the offsetParent and cache its position this.offsetParent = this.helper.offsetParent(); var po = this.offsetParent.offset(); // This is a special case where we need to modify a offset calculated on start, since the following happened: // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { po.left += this.scrollParent.scrollLeft(); po.top += this.scrollParent.scrollTop(); } if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix po = { top: 0, left: 0 }; return { top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) }; }, _getRelativeOffset: function() { if(this.cssPosition == "relative") { var p = this.currentItem.position(); return { top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() }; } else { return { top: 0, left: 0 }; } }, _cacheMargins: function() { this.margins = { left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), top: (parseInt(this.currentItem.css("marginTop"),10) || 0) }; }, _cacheHelperProportions: function() { this.helperProportions = { width: this.helper.outerWidth(), height: this.helper.outerHeight() }; }, _setContainment: function() { var o = this.options; if(o.containment == 'parent') o.containment = this.helper[0].parentNode; if(o.containment == 'document' || o.containment == 'window') this.containment = [ 0 - this.offset.relative.left - this.offset.parent.left, 0 - this.offset.relative.top - this.offset.parent.top, $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top ]; if(!(/^(document|window|parent)$/).test(o.containment)) { var ce = $(o.containment)[0]; var co = $(o.containment).offset(); var over = ($(ce).css("overflow") != 'hidden'); this.containment = [ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top ]; } }, _convertPositionTo: function(d, pos) { if(!pos) pos = this.position; var mod = d == "absolute" ? 1 : -1; var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); return { top: ( pos.top // The absolute mouse position + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) ), left: ( pos.left // The absolute mouse position + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) ) }; }, _generatePosition: function(event) { var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); // This is another very weird special case that only happens for relative elements: // 1. If the css position is relative // 2. and the scroll parent is the document or similar to the offset parent // we have to refresh the relative offset during the scroll so there are no jumps if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { this.offset.relative = this._getRelativeOffset(); } var pageX = event.pageX; var pageY = event.pageY; /* * - Position constraining - * Constrain the position to a mix of grid, containment. */ if(this.originalPosition) { //If we are not dragging yet, we won't check for options if(this.containment) { if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; } if(o.grid) { var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; } } return { top: ( pageY // The absolute mouse position - this.offset.click.top // Click offset (relative to the element) - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) ), left: ( pageX // The absolute mouse position - this.offset.click.left // Click offset (relative to the element) - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) ) }; }, _rearrange: function(event, i, a, hardRefresh) { a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling)); //Various things done here to improve the performance: // 1. we create a setTimeout, that calls refreshPositions // 2. on the instance, we have a counter variable, that get's higher after every append // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same // 4. this lets only the last addition to the timeout stack through this.counter = this.counter ? ++this.counter : 1; var self = this, counter = this.counter; window.setTimeout(function() { if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove },0); }, _clear: function(event, noPropagation) { this.reverting = false; // We delay all events that have to be triggered to after the point where the placeholder has been removed and // everything else normalized again var delayedTriggers = [], self = this; // We first have to update the dom position of the actual currentItem // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); this._noFinalSort = null; if(this.helper[0] == this.currentItem[0]) { for(var i in this._storedCSS) { if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; } this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); } else { this.currentItem.show(); } if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); for (var i = this.containers.length - 1; i >= 0; i--){ if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) { delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i])); delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i])); } }; }; //Post events to containers for (var i = this.containers.length - 1; i >= 0; i--){ if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); if(this.containers[i].containerCache.over) { delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); this.containers[i].containerCache.over = 0; } } //Do what was originally in plugins if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index this.dragging = false; if(this.cancelHelperRemoval) { if(!noPropagation) { this._trigger("beforeStop", event, this._uiHash()); for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events this._trigger("stop", event, this._uiHash()); } return false; } if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! this.placeholder[0].parentNode.removeChild(this.placeholder[0]); if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; if(!noPropagation) { for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events this._trigger("stop", event, this._uiHash()); } this.fromOutside = false; return true; }, _trigger: function() { if ($.Widget.prototype._trigger.apply(this, arguments) === false) { this.cancel(); } }, _uiHash: function(inst) { var self = inst || this; return { helper: self.helper, placeholder: self.placeholder || $([]), position: self.position, originalPosition: self.originalPosition, offset: self.positionAbs, item: self.currentItem, sender: inst ? inst.element : null }; } }); $.extend($.ui.sortable, { version: "1.8.18" }); })(jQuery); SABnzbd-0.7.20/interfaces/Mobile/0000755000000000000000000000000012613775512016424 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Mobile/templates/0000755000000000000000000000000012613775512020422 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Mobile/templates/static/0000755000000000000000000000000012613775512021711 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Mobile/templates/static/javascripts/0000755000000000000000000000000012613775512024242 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Mobile/templates/static/javascripts/src/0000755000000000000000000000000012613775512025031 5ustar00rootroot00000000000000SABnzbd-0.7.20/interfaces/Mobile/templates/static/javascripts/src/mobile.js0000644000000000000000000000033312612413171026622 0ustar00rootroot00000000000000This directory holds sources for minified javascript files, for Debian policy compliance reasons. # interfaces/Mobile/templates/static/javascripts/mobile.js jQuery JavaScript Library v1.4 jQTouch jQuery plugin b2 r109 SABnzbd-0.7.20/interfaces/Mobile/templates/static/javascripts/src/jqtouch.js0000644000000000000000000005517012612410632027040 0ustar00rootroot00000000000000/* _/ _/_/ _/_/_/_/_/ _/ _/ _/ _/ _/_/ _/ _/ _/_/_/ _/_/_/ _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/_/ _/ _/ _/_/ _/_/_/ _/_/_/ _/ _/ _/ _/ Created by David Kaneda Documentation and issue tracking on Google Code Special thanks to Jonathan Stark and pinch/zoom (c) 2009 by jQTouch project members. See LICENSE.txt for license. $Revision$ $Date$ $LastChangedBy$ */ (function($) { $.jQTouch = function(options) { // Set support values $.support.WebKitCSSMatrix = (typeof WebKitCSSMatrix == "object"); $.support.touch = (typeof Touch == "object"); $.support.WebKitAnimationEvent = (typeof WebKitTransitionEvent == "object"); // Initialize internal variables var $body, $head=$('head'), hist=[], newPageCount=0, jQTSettings={}, hashCheck, currentPage, orientation, isMobileWebKit = RegExp(" Mobile/").test(navigator.userAgent), tapReady=true, lastAnimationTime=0, touchSelectors=[], publicObj={}, extensions=$.jQTouch.prototype.extensions, defaultAnimations=['slide','flip','slideup','swap','cube','pop','dissolve','fade','back'], animations=[], hairextensions=''; // Get the party started init(options); function init(options) { var defaults = { addGlossToIcon: true, backSelector: '.back, .cancel, .goback', cacheGetRequests: true, cubeSelector: '.cube', dissolveSelector: '.dissolve', fadeSelector: '.fade', fixedViewport: true, flipSelector: '.flip', formSelector: 'form', fullScreen: true, fullScreenClass: 'fullscreen', icon: null, touchSelector: 'a, .touch', popSelector: '.pop', preloadImages: false, slideSelector: 'body > * > ul li a', slideupSelector: '.slideup', startupScreen: null, statusBar: 'default', // other options: black-translucent, black submitSelector: '.submit', swapSelector: '.swap', useAnimations: true, useFastTouch: true // Experimental. }; jQTSettings = $.extend({}, defaults, options); // Preload images if (jQTSettings.preloadImages) { for (var i = jQTSettings.preloadImages.length - 1; i >= 0; i--){ (new Image()).src = jQTSettings.preloadImages[i]; }; } // Set icon if (jQTSettings.icon) { var precomposed = (jQTSettings.addGlossToIcon) ? '' : '-precomposed'; hairextensions += ''; } // Set startup screen if (jQTSettings.startupScreen) { hairextensions += ''; } // Set viewport if (jQTSettings.fixedViewport) { hairextensions += ''; } // Set full-screen if (jQTSettings.fullScreen) { hairextensions += ''; if (jQTSettings.statusBar) { hairextensions += ''; } } if (hairextensions) $head.append(hairextensions); // Initialize on document load: $(document).ready(function(){ // Add extensions for (var i in extensions) { var fn = extensions[i]; if ($.isFunction(fn)) { $.extend(publicObj, fn(publicObj)); } } // Add animations for (var i in defaultAnimations) { var name = defaultAnimations[i]; var selector = jQTSettings[name + 'Selector']; if (typeof(selector) == 'string') { addAnimation({name:name, selector:selector}); } } touchSelectors.push('input'); touchSelectors.push(jQTSettings.touchSelector); touchSelectors.push(jQTSettings.backSelector); touchSelectors.push(jQTSettings.submitSelector); $(touchSelectors.join(', ')).css('-webkit-touch-callout', 'none'); $(jQTSettings.backSelector).tap(liveTap); $(jQTSettings.submitSelector).tap(submitParentForm); $body = $('body'); if (jQTSettings.fullScreenClass && window.navigator.standalone == true) { $body.addClass(jQTSettings.fullScreenClass + ' ' + jQTSettings.statusBar); } // Create custom live events $body .bind('touchstart', handleTouch) .bind('orientationchange', updateOrientation) .trigger('orientationchange') .submit(submitForm); if (jQTSettings.useFastTouch && $.support.touch) { $body.click(function(e){ var $el = $(e.target); if ($el.attr('target') == '_blank' || $el.attr('rel') == 'external' || $el.is('input[type="checkbox"]')) { return true; } else { return false; } }); // This additionally gets rid of form focusses $body.mousedown(function(e){ var timeDiff = (new Date()).getTime() - lastAnimationTime; if (timeDiff < 200) { return false; } }); } // Make sure exactly one child of body has "current" class if ($('body > .current').length == 0) { currentPage = $('body > *:first'); } else { currentPage = $('body > .current:first'); $('body > .current').removeClass('current'); } // Go to the top of the "current" page $(currentPage).addClass('current'); location.hash = $(currentPage).attr('id'); addPageToHistory(currentPage); scrollTo(0, 0); dumbLoopStart(); }); } // PUBLIC FUNCTIONS function goBack(to) { // Init the param if (hist.length > 1) { var numberOfPages = Math.min(parseInt(to || 1, 10), hist.length-1); // Search through the history for an ID if( isNaN(numberOfPages) && typeof(to) === "string" && to != '#' ) { for( var i=1, length=hist.length; i < length; i++ ) { if( '#' + hist[i].id === to ) { numberOfPages = i; break; } } } // If still nothing, assume one if( isNaN(numberOfPages) || numberOfPages < 1 ) { numberOfPages = 1; }; // Grab the current page for the "from" info var animation = hist[0].animation; var fromPage = hist[0].page; // Remove all pages in front of the target page hist.splice(0, numberOfPages); // Grab the target page var toPage = hist[0].page; // Make the animations animatePages(fromPage, toPage, animation, true); return publicObj; } else { console.error('No pages in history.'); return false; } } function goTo(toPage, animation) { var fromPage = hist[0].page; if (typeof(toPage) === 'string') { toPage = $(toPage); } if (typeof(animation) === 'string') { for (var i = animations.length - 1; i >= 0; i--){ if (animations[i].name === animation) { animation = animations[i]; break; } } } if (animatePages(fromPage, toPage, animation)) { addPageToHistory(toPage, animation); return publicObj; } else { console.error('Could not animate pages.'); return false; } } function getOrientation() { return orientation; } // PRIVATE FUNCTIONS function liveTap(e){ // Grab the clicked element var $el = $(e.target); if ($el.attr('nodeName')!=='A'){ $el = $el.parent('a'); } var target = $el.attr('target'), hash = $el.attr('hash'), animation=null; if (tapReady == false || !$el.length) { console.warn('Not able to tap element.') return false; } if ($el.attr('target') == '_blank' || $el.attr('rel') == 'external') { return true; } // Figure out the animation to use for (var i = animations.length - 1; i >= 0; i--){ if ($el.is(animations[i].selector)) { animation = animations[i]; break; } }; // User clicked an internal link, fullscreen mode if (target == '_webapp') { window.location = $el.attr('href'); } // User clicked a back button else if ($el.is(jQTSettings.backSelector)) { goBack(hash); } // Branch on internal or external href else if (hash && hash!='#') { $el.addClass('active'); goTo($(hash).data('referrer', $el), animation); } else { $el.addClass('loading active'); showPageByHref($el.attr('href'), { animation: animation, callback: function(){ $el.removeClass('loading'); setTimeout($.fn.unselect, 250, $el); }, $referrer: $el }); } return false; } function addPageToHistory(page, animation) { // Grab some info var pageId = page.attr('id'); // Prepend info to page history hist.unshift({ page: page, animation: animation, id: pageId }); } function animatePages(fromPage, toPage, animation, backwards) { // Error check for target page if(toPage.length === 0){ $.fn.unselect(); console.error('Target element is missing.'); return false; } // Collapse the keyboard $(':focus').blur(); // Make sure we are scrolled up to hide location bar scrollTo(0, 0); // Define callback to run after animation completes var callback = function(event){ if (animation) { toPage.removeClass('in reverse ' + animation.name); fromPage.removeClass('current out reverse ' + animation.name); } else { fromPage.removeClass('current'); } toPage.trigger('pageAnimationEnd', { direction: 'in' }); fromPage.trigger('pageAnimationEnd', { direction: 'out' }); clearInterval(dumbLoop); currentPage = toPage; location.hash = currentPage.attr('id'); dumbLoopStart(); var $originallink = toPage.data('referrer'); if ($originallink) { $originallink.unselect(); } lastAnimationTime = (new Date()).getTime(); tapReady = true; } fromPage.trigger('pageAnimationStart', { direction: 'out' }); toPage.trigger('pageAnimationStart', { direction: 'in' }); if ($.support.WebKitAnimationEvent && animation && jQTSettings.useAnimations) { toPage.one('webkitAnimationEnd', callback); tapReady = false; toPage.addClass(animation.name + ' in current ' + (backwards ? ' reverse' : '')); fromPage.addClass(animation.name + ' out' + (backwards ? ' reverse' : '')); } else { toPage.addClass('current'); callback(); } return true; } function dumbLoopStart() { dumbLoop = setInterval(function(){ var curid = currentPage.attr('id'); if (location.hash == '') { location.hash = '#' + curid; } else if (location.hash != '#' + curid) { try { goBack(location.hash) } catch(e) { console.error('Unknown hash change.'); } } }, 100); } function insertPages(nodes, animation) { var targetPage = null; $(nodes).each(function(index, node){ var $node = $(this); if (!$node.attr('id')) { $node.attr('id', 'page-' + (++newPageCount)); } $node.appendTo($body); if ($node.hasClass('current') || !targetPage ) { targetPage = $node; } }); if (targetPage !== null) { goTo(targetPage, animation); return targetPage; } else { return false; } } function showPageByHref(href, options) { var defaults = { data: null, method: 'GET', animation: null, callback: null, $referrer: null }; var settings = $.extend({}, defaults, options); if (href != '#') { $.ajax({ url: href, data: settings.data, type: settings.method, success: function (data, textStatus) { var firstPage = insertPages(data, settings.animation); if (firstPage) { if (settings.method == 'GET' && jQTSettings.cacheGetRequests && settings.$referrer) { settings.$referrer.attr('href', '#' + firstPage.attr('id')); } if (settings.callback) { settings.callback(true); } } }, error: function (data) { if (settings.$referrer) settings.$referrer.unselect(); if (settings.callback) { settings.callback(false); } } }); } else if ($referrer) { $referrer.unselect(); } } function submitForm(e, callback){ var $form = (typeof(e)==='string') ? $(e) : $(e.target); if ($form.length && $form.is(jQTSettings.formSelector) && $form.attr('action')) { showPageByHref($form.attr('action'), { data: $form.serialize(), method: $form.attr('method') || "POST", animation: animations[0] || null, callback: callback }); return false; } return true; } function submitParentForm(e){ var $form = $(this).closest('form'); if ($form.length) { evt = jQuery.Event("submit"); evt.preventDefault(); $form.trigger(evt); return false; } return true; } function addAnimation(animation) { if (typeof(animation.selector) == 'string' && typeof(animation.name) == 'string') { animations.push(animation); $(animation.selector).tap(liveTap); touchSelectors.push(animation.selector); } } function updateOrientation() { orientation = window.innerWidth < window.innerHeight ? 'profile' : 'landscape'; $body.removeClass('profile landscape').addClass(orientation).trigger('turn', {orientation: orientation}); // scrollTo(0, 0); } function handleTouch(e) { var $el = $(e.target); // Only handle touchSelectors if (!$(e.target).is(touchSelectors.join(', '))) { var $link = $(e.target).closest('a'); if ($link.length){ $el = $link; } else { return; } } if (event) { var hoverTimeout = null, startX = event.changedTouches[0].clientX, startY = event.changedTouches[0].clientY, startTime = (new Date).getTime(), deltaX = 0, deltaY = 0, deltaT = 0; // Let's bind these after the fact, so we can keep some internal values $el.bind('touchmove', touchmove).bind('touchend', touchend); hoverTimeout = setTimeout(function(){ $el.makeActive(); }, 100); } // Private touch functions (TODO: insert dirty joke) function touchmove(e) { updateChanges(); var absX = Math.abs(deltaX); var absY = Math.abs(deltaY); // Check for swipe if (absX > absY && (absX > 35) && deltaT < 1000) { $el.trigger('swipe', {direction: (deltaX < 0) ? 'left' : 'right'}).unbind('touchmove touchend'); } else if (absY > 1) { $el.removeClass('active'); } clearTimeout(hoverTimeout); } function touchend(){ updateChanges(); if (deltaY === 0 && deltaX === 0) { $el.makeActive(); // New approach: // Fake the double click? // TODO: Try with all click events (no tap) // if (deltaT < 40) // { // setTimeout(function(){ // $el.trigger('touchstart') // .trigger('touchend'); // }, 0); // } $el.trigger('tap'); } else { $el.removeClass('active'); } $el.unbind('touchmove touchend'); clearTimeout(hoverTimeout); } function updateChanges(){ var first = event.changedTouches[0] || null; deltaX = first.pageX - startX; deltaY = first.pageY - startY; deltaT = (new Date).getTime() - startTime; } } // End touch handler // Public jQuery Fns $.fn.unselect = function(obj) { if (obj) { obj.removeClass('active'); } else { $('.active').removeClass('active'); } } $.fn.makeActive = function(){ return $(this).addClass('active'); } $.fn.swipe = function(fn) { if ($.isFunction(fn)) { return this.each(function(i, el){ $(el).bind('swipe', fn); }); } } $.fn.tap = function(fn){ if ($.isFunction(fn)) { var tapEvent = (jQTSettings.useFastTouch && $.support.touch) ? 'tap' : 'click'; return $(this).live(tapEvent, fn); } else { $(this).trigger('tap'); } } publicObj = { getOrientation: getOrientation, goBack: goBack, goTo: goTo, addAnimation: addAnimation, submitForm: submitForm } return publicObj; } // Extensions directly manipulate the jQTouch object, before it's initialized. $.jQTouch.prototype.extensions = []; $.jQTouch.addExtension = function(extension){ $.jQTouch.prototype.extensions.push(extension); } })(jQuery);SABnzbd-0.7.20/interfaces/Mobile/templates/static/javascripts/src/jquery.js0000644000000000000000000054164012612410632026704 0ustar00rootroot00000000000000/*! * jQuery JavaScript Library v1.4.4pre * http://jquery.com/ * * Copyright 2010, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2010, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Thu Oct 21 23:18:47 2010 -0400 */ (function( window, undefined ) { // Use the correct document accordingly with window argument (sandbox) var document = window.document; var jQuery = (function() { // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context ); }, // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, // A central reference to the root jQuery(document) rootjQuery, // A simple way to check for HTML strings or ID strings // (both of which we optimize for) quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, // Is it a simple selector isSimple = /^.[^:#\[\.,]*$/, // Check if a string has a non-whitespace character in it rnotwhite = /\S/, rwhite = /\s/, // Used for trimming whitespace trimLeft = /^\s+/, trimRight = /\s+$/, // Check for non-word characters rnonword = /\W/, // Check for digits rdigit = /\d/, // Match a standalone tag rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, // JSON RegExp rvalidchars = /^[\],:{}\s]*$/, rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, // Useragent RegExp rwebkit = /(webkit)[ \/]([\w.]+)/, ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/, rmsie = /(msie) ([\w.]+)/, rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, // Keep a UserAgent string for use with jQuery.browser userAgent = navigator.userAgent, // For matching the engine and version of the browser browserMatch, // Has the ready events already been bound? readyBound = false, // The functions to execute on DOM ready readyList = [], // The ready event handler DOMContentLoaded, // Save a reference to some core methods toString = Object.prototype.toString, hasOwn = Object.prototype.hasOwnProperty, push = Array.prototype.push, slice = Array.prototype.slice, trim = String.prototype.trim, indexOf = Array.prototype.indexOf, // [[Class]] -> type pairs class2type = {}; jQuery.fn = jQuery.prototype = { init: function( selector, context ) { var match, elem, ret, doc; // Handle $(""), $(null), or $(undefined) if ( !selector ) { return this; } // Handle $(DOMElement) if ( selector.nodeType ) { this.context = this[0] = selector; this.length = 1; return this; } // The body element only exists once, optimize finding it if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = "body"; this.length = 1; return this; } // Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? match = quickExpr.exec( selector ); // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { // HANDLE: $(html) -> $(array) if ( match[1] ) { doc = (context ? context.ownerDocument || context : document); // If a single string is passed in and it's a single tag // just do a createElement and skip the rest ret = rsingleTag.exec( selector ); if ( ret ) { if ( jQuery.isPlainObject( context ) ) { selector = [ document.createElement( ret[1] ) ]; jQuery.fn.attr.call( selector, context, true ); } else { selector = [ doc.createElement( ret[1] ) ]; } } else { ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; } return jQuery.merge( this, selector ); // HANDLE: $("#id") } else { elem = document.getElementById( match[2] ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id !== match[2] ) { return rootjQuery.find( selector ); } // Otherwise, we inject the element directly into the jQuery object this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; } // HANDLE: $("TAG") } else if ( !context && !rnonword.test( selector ) ) { this.selector = selector; this.context = document; selector = document.getElementsByTagName( selector ); return jQuery.merge( this, selector ); // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return (context || rootjQuery).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return jQuery( context ).find( selector ); } // HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { return rootjQuery.ready( selector ); } if (selector.selector !== undefined) { this.selector = selector.selector; this.context = selector.context; } return jQuery.makeArray( selector, this ); }, // Start with an empty selector selector: "", // The current version of jQuery being used jquery: "1.4.4pre", // The default length of a jQuery object is 0 length: 0, // The number of elements contained in the matched element set size: function() { return this.length; }, toArray: function() { return slice.call( this, 0 ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { return num == null ? // Return a 'clean' array this.toArray() : // Return just the object ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] ); }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems, name, selector ) { // Build a new jQuery matched element set var ret = jQuery(); if ( jQuery.isArray( elems ) ) { push.apply( ret, elems ); } else { jQuery.merge( ret, elems ); } // Add the old object onto the stack (as a reference) ret.prevObject = this; ret.context = this.context; if ( name === "find" ) { ret.selector = this.selector + (this.selector ? " " : "") + selector; } else if ( name ) { ret.selector = this.selector + "." + name + "(" + selector + ")"; } // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. // (You can seed the arguments with an array of args, but this is // only used internally.) each: function( callback, args ) { return jQuery.each( this, callback, args ); }, ready: function( fn ) { // Attach the listeners jQuery.bindReady(); // If the DOM is already ready if ( jQuery.isReady ) { // Execute the function immediately fn.call( document, jQuery ); // Otherwise, remember the function for later } else if ( readyList ) { // Add the function to the wait list readyList.push( fn ); } return this; }, eq: function( i ) { return i === -1 ? this.slice( i ) : this.slice( i, +i + 1 ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ), "slice", slice.call(arguments).join(",") ); }, map: function( callback ) { return this.pushStack( jQuery.map(this, function( elem, i ) { return callback.call( elem, i, elem ); })); }, end: function() { return this.prevObject || jQuery(null); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: [].sort, splice: [].splice }; // Give the init function the jQuery prototype for later instantiation jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { // copy reference to target object var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray, clone; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target i = 2; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && jQuery.isArray(src) ? src : []; } else { clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend({ noConflict: function( deep ) { window.$ = _$; if ( deep ) { window.jQuery = _jQuery; } return jQuery; }, // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Handle when the DOM is ready ready: function( wait ) { // A third-party is pushing the ready event forwards if ( wait === true ) { jQuery.readyWait--; } // Make sure that the DOM is not already loaded if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready, 1 ); } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute if ( readyList ) { // Execute all of them var fn, i = 0; while ( (fn = readyList[ i++ ]) ) { fn.call( document, jQuery ); } // Reset the list of functions readyList = null; } // Trigger any bound ready events if ( jQuery.fn.triggerHandler ) { jQuery( document ).triggerHandler( "ready" ); } } }, bindReady: function() { if ( readyBound ) { return; } readyBound = true; // Catch cases where $(document).ready() is called after the // browser event has already occurred. if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready return setTimeout( jQuery.ready, 1 ); } // Mozilla, Opera and webkit nightlies currently support this event if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); // A fallback to window.onload, that will always work window.addEventListener( "load", jQuery.ready, false ); // If IE event model is used } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes document.attachEvent("onreadystatechange", DOMContentLoaded); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); // If IE and not a frame // continually check to see if the document is ready var toplevel = false; try { toplevel = window.frameElement == null; } catch(e) {} if ( document.documentElement.doScroll && toplevel ) { doScrollCheck(); } } }, // See test/unit/core.js for details concerning isFunction. // Since version 1.3, DOM methods and functions like alert // aren't supported. They return false on IE (#2968). isFunction: function( obj ) { return jQuery.type(obj) === "function"; }, isArray: Array.isArray || function( obj ) { return jQuery.type(obj) === "array"; }, // A crude way of determining if an object is a window isWindow: function( obj ) { return obj && typeof obj === "object" && "setInterval" in obj; }, isNaN: function( obj ) { return obj == null || !rdigit.test( obj ) || isNaN( obj ); }, type: function( obj ) { return obj == null ? String( obj ) : class2type[ toString.call(obj) ] || "object"; }, isPlainObject: function( obj ) { // Must be an Object. // Because of IE, we also have to check the presence of the constructor property. // Make sure that DOM nodes and window objects don't pass through, as well if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { return false; } // Not own constructor property must be Object if ( obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } // Own properties are enumerated firstly, so to speed up, // if last one is own, then all properties are own. var key; for ( key in obj ) {} return key === undefined || hasOwn.call( obj, key ); }, isEmptyObject: function( obj ) { for ( var name in obj ) { return false; } return true; }, error: function( msg ) { throw msg; }, parseJSON: function( data ) { if ( typeof data !== "string" || !data ) { return null; } // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js if ( rvalidchars.test(data.replace(rvalidescape, "@") .replace(rvalidtokens, "]") .replace(rvalidbraces, "")) ) { // Try to use the native JSON parser first return window.JSON && window.JSON.parse ? window.JSON.parse( data ) : (new Function("return " + data))(); } else { jQuery.error( "Invalid JSON: " + data ); } }, noop: function() {}, // Evalulates a script in a global context globalEval: function( data ) { if ( data && rnotwhite.test(data) ) { // Inspired by code by Andrea Giammarchi // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html var head = document.getElementsByTagName("head")[0] || document.documentElement, script = document.createElement("script"); script.type = "text/javascript"; if ( jQuery.support.scriptEval ) { script.appendChild( document.createTextNode( data ) ); } else { script.text = data; } // Use insertBefore instead of appendChild to circumvent an IE6 bug. // This arises when a base node is used (#2709). head.insertBefore( script, head.firstChild ); head.removeChild( script ); } }, nodeName: function( elem, name ) { return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); }, // args is for internal usage only each: function( object, callback, args ) { var name, i = 0, length = object.length, isObj = length === undefined || jQuery.isFunction(object); if ( args ) { if ( isObj ) { for ( name in object ) { if ( callback.apply( object[ name ], args ) === false ) { break; } } } else { for ( ; i < length; ) { if ( callback.apply( object[ i++ ], args ) === false ) { break; } } } // A special, fast, case for the most common use of each } else { if ( isObj ) { for ( name in object ) { if ( callback.call( object[ name ], name, object[ name ] ) === false ) { break; } } } else { for ( var value = object[0]; i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} } } return object; }, // Use native String.trim function wherever possible trim: trim ? function( text ) { return text == null ? "" : trim.call( text ); } : // Otherwise use our own trimming functionality function( text ) { return text == null ? "" : text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); }, // results is for internal usage only makeArray: function( array, results ) { var ret = results || []; if ( array != null ) { // The window, strings (and functions) also have 'length' // The extra typeof function check is to prevent crashes // in Safari 2 (See: #3039) // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 var type = jQuery.type(array); if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { push.call( ret, array ); } else { jQuery.merge( ret, array ); } } return ret; }, inArray: function( elem, array ) { if ( array.indexOf ) { return array.indexOf( elem ); } for ( var i = 0, length = array.length; i < length; i++ ) { if ( array[ i ] === elem ) { return i; } } return -1; }, merge: function( first, second ) { var i = first.length, j = 0; if ( typeof second.length === "number" ) { for ( var l = second.length; j < l; j++ ) { first[ i++ ] = second[ j ]; } } else { while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ]; } } first.length = i; return first; }, grep: function( elems, callback, inv ) { var ret = [], retVal; inv = !!inv; // Go through the array, only saving the items // that pass the validator function for ( var i = 0, length = elems.length; i < length; i++ ) { retVal = !!callback( elems[ i ], i ); if ( inv !== retVal ) { ret.push( elems[ i ] ); } } return ret; }, // arg is for internal usage only map: function( elems, callback, arg ) { var ret = [], value; // Go through the array, translating each of the items to their // new value (or values). for ( var i = 0, length = elems.length; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret[ ret.length ] = value; } } return ret.concat.apply( [], ret ); }, // A global GUID counter for objects guid: 1, proxy: function( fn, proxy, thisObject ) { if ( arguments.length === 2 ) { if ( typeof proxy === "string" ) { thisObject = fn; fn = thisObject[ proxy ]; proxy = undefined; } else if ( proxy && !jQuery.isFunction( proxy ) ) { thisObject = proxy; proxy = undefined; } } if ( !proxy && fn ) { proxy = function() { return fn.apply( thisObject || this, arguments ); }; } // Set the guid of unique handler to the same of original handler, so it can be removed if ( fn ) { proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; } // So proxy can be declared as an argument return proxy; }, // Mutifunctional method to get and set values to a collection // The value/s can be optionally by executed if its a function access: function( elems, key, value, exec, fn, pass ) { var length = elems.length; // Setting many attributes if ( typeof key === "object" ) { for ( var k in key ) { jQuery.access( elems, k, key[k], exec, fn, value ); } return elems; } // Setting one attribute if ( value !== undefined ) { // Optionally, function values get executed if exec is true exec = !pass && exec && jQuery.isFunction(value); for ( var i = 0; i < length; i++ ) { fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); } return elems; } // Getting an attribute return length ? fn( elems[0], key ) : undefined; }, now: function() { return (new Date()).getTime(); }, // Use of jQuery.browser is frowned upon. // More details: http://docs.jquery.com/Utilities/jQuery.browser uaMatch: function( ua ) { ua = ua.toLowerCase(); var match = rwebkit.exec( ua ) || ropera.exec( ua ) || rmsie.exec( ua ) || ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || []; return { browser: match[1] || "", version: match[2] || "0" }; }, browser: {} }); // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); }); browserMatch = jQuery.uaMatch( userAgent ); if ( browserMatch.browser ) { jQuery.browser[ browserMatch.browser ] = true; jQuery.browser.version = browserMatch.version; } // Deprecated, use jQuery.browser.webkit instead if ( jQuery.browser.webkit ) { jQuery.browser.safari = true; } if ( indexOf ) { jQuery.inArray = function( elem, array ) { return indexOf.call( array, elem ); }; } // Verify that \s matches non-breaking spaces // (IE fails on this test) if ( !rwhite.test( "\xA0" ) ) { trimLeft = /^[\s\xA0]+/; trimRight = /[\s\xA0]+$/; } // All jQuery objects should point back to these rootjQuery = jQuery(document); // Cleanup functions for the document ready method if ( document.addEventListener ) { DOMContentLoaded = function() { document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); jQuery.ready(); }; } else if ( document.attachEvent ) { DOMContentLoaded = function() { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( document.readyState === "complete" ) { document.detachEvent( "onreadystatechange", DOMContentLoaded ); jQuery.ready(); } }; } // The DOM ready check for Internet Explorer function doScrollCheck() { if ( jQuery.isReady ) { return; } try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch(e) { setTimeout( doScrollCheck, 1 ); return; } // and execute any waiting functions jQuery.ready(); } // Expose jQuery to the global object return (window.jQuery = window.$ = jQuery); })(); (function() { jQuery.support = {}; var root = document.documentElement, script = document.createElement("script"), div = document.createElement("div"), id = "script" + jQuery.now(); div.style.display = "none"; div.innerHTML = "
      a"; var all = div.getElementsByTagName("*"), a = div.getElementsByTagName("a")[0], select = document.createElement("select"), opt = select.appendChild( document.createElement("option") ); // Can't get basic test support if ( !all || !all.length || !a ) { return; } jQuery.support = { // IE strips leading whitespace when .innerHTML is used leadingWhitespace: div.firstChild.nodeType === 3, // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables tbody: !div.getElementsByTagName("tbody").length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE htmlSerialize: !!div.getElementsByTagName("link").length, // Get the style information from getAttribute // (IE uses .cssText insted) style: /red/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) hrefNormalized: a.getAttribute("href") === "/a", // Make sure that element opacity exists // (IE uses filter instead) // Use a regex to work around a WebKit issue. See #5145 opacity: /^0.55$/.test( a.style.opacity ), // Verify style float existence // (IE uses styleFloat instead of cssFloat) cssFloat: !!a.style.cssFloat, // Make sure that if no value is specified for a checkbox // that it defaults to "on". // (WebKit defaults to "" instead) checkOn: div.getElementsByTagName("input")[0].value === "on", // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, // Will be defined later deleteExpando: true, optDisabled: false, checkClone: false, scriptEval: false, noCloneEvent: true, boxModel: null, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, reliableHiddenOffsets: true }; // Make sure that the options inside disabled selects aren't marked as disabled // (WebKit marks them as diabled) select.disabled = true; jQuery.support.optDisabled = !opt.disabled; script.type = "text/javascript"; try { script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); } catch(e) {} root.insertBefore( script, root.firstChild ); // Make sure that the execution of code works by injecting a script // tag with appendChild/createTextNode // (IE doesn't support this, fails, and uses .text instead) if ( window[ id ] ) { jQuery.support.scriptEval = true; delete window[ id ]; } // Test to see if it's possible to delete an expando from an element // Fails in Internet Explorer try { delete script.test; } catch(e) { jQuery.support.deleteExpando = false; } root.removeChild( script ); if ( div.attachEvent && div.fireEvent ) { div.attachEvent("onclick", function click() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) jQuery.support.noCloneEvent = false; div.detachEvent("onclick", click); }); div.cloneNode(true).fireEvent("onclick"); } div = document.createElement("div"); div.innerHTML = ""; var fragment = document.createDocumentFragment(); fragment.appendChild( div.firstChild ); // WebKit doesn't clone checked state correctly in fragments jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; // Figure out if the W3C box model works as expected // document.body must exist before we can do this jQuery(function() { var div = document.createElement("div"); div.style.width = div.style.paddingLeft = "1px"; document.body.appendChild( div ); jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; if ( "zoom" in div.style ) { // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving // them layout // (IE < 8 does this) div.style.display = "inline"; div.style.zoom = 1; jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; // Check if elements with layout shrink-wrap their children // (IE 6 does this) div.style.display = ""; div.innerHTML = "
      "; jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; } div.innerHTML = "
      t
      "; var tds = div.getElementsByTagName("td"); // Check if table cells still have offsetWidth/Height when they are set // to display:none and there are still other visible table cells in a // table row; if so, offsetWidth/Height are not reliable for use when // determining if an element has been hidden directly using // display:none (it is still safe to use offsets if a parent element is // hidden; don safety goggles and see bug #4512 for more information). // (only IE 8 fails this test) jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; tds[0].style.display = ""; tds[1].style.display = "none"; // Check if empty table cells still have offsetWidth/Height // (IE < 8 fail this test) jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; div.innerHTML = ""; document.body.removeChild( div ).style.display = "none"; div = tds = null; }); // Technique from Juriy Zaytsev // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ var eventSupported = function( eventName ) { var el = document.createElement("div"); eventName = "on" + eventName; var isSupported = (eventName in el); if ( !isSupported ) { el.setAttribute(eventName, "return;"); isSupported = typeof el[eventName] === "function"; } el = null; return isSupported; }; jQuery.support.submitBubbles = eventSupported("submit"); jQuery.support.changeBubbles = eventSupported("change"); // release memory in IE root = script = div = all = a = null; })(); jQuery.props = { "for": "htmlFor", "class": "className", readonly: "readOnly", maxlength: "maxLength", cellspacing: "cellSpacing", rowspan: "rowSpan", colspan: "colSpan", tabindex: "tabIndex", usemap: "useMap", frameborder: "frameBorder" }; var windowData = {}, rbrace = /^(?:\{.*\}|\[.*\])$/; jQuery.extend({ cache: {}, // Please use with caution uuid: 0, // Unique for each copy of jQuery on the page expando: "jQuery" + jQuery.now(), // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { "embed": true, // Ban all objects except for Flash (which handle expandos) "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", "applet": true }, data: function( elem, name, data ) { if ( !jQuery.acceptData( elem ) ) { return; } elem = elem == window ? windowData : elem; var isNode = elem.nodeType, id = isNode ? elem[ jQuery.expando ] : null, cache = jQuery.cache, thisCache; if ( isNode && !id && typeof name === "string" && data === undefined ) { return; } // Get the data from the object directly if ( !isNode ) { cache = elem; // Compute a unique ID for the element } else if ( !id ) { elem[ jQuery.expando ] = id = ++jQuery.uuid; } // Avoid generating a new cache unless none exists and we // want to manipulate it. if ( typeof name === "object" ) { if ( isNode ) { cache[ id ] = jQuery.extend(cache[ id ], name); } else { jQuery.extend( cache, name ); } } else if ( isNode && !cache[ id ] ) { cache[ id ] = {}; } thisCache = isNode ? cache[ id ] : cache; // Prevent overriding the named cache with undefined values if ( data !== undefined ) { thisCache[ name ] = data; } return typeof name === "string" ? thisCache[ name ] : thisCache; }, removeData: function( elem, name ) { if ( !jQuery.acceptData( elem ) ) { return; } elem = elem == window ? windowData : elem; var isNode = elem.nodeType, id = isNode ? elem[ jQuery.expando ] : elem, cache = jQuery.cache, thisCache = isNode ? cache[ id ] : id; // If we want to remove a specific section of the element's data if ( name ) { if ( thisCache ) { // Remove the section of cache data delete thisCache[ name ]; // If we've removed all the data, remove the element's cache if ( isNode && jQuery.isEmptyObject(thisCache) ) { jQuery.removeData( elem ); } } // Otherwise, we want to remove all of the element's data } else { if ( isNode && jQuery.support.deleteExpando ) { delete elem[ jQuery.expando ]; } else if ( elem.removeAttribute ) { elem.removeAttribute( jQuery.expando ); // Completely remove the data cache } else if ( isNode ) { delete cache[ id ]; // Remove all fields from the object } else { for ( var n in elem ) { delete elem[ n ]; } } } }, // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { if ( elem.nodeName ) { var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; if ( match ) { return !(match === true || elem.getAttribute("classid") !== match); } } return true; } }); jQuery.fn.extend({ data: function( key, value ) { var data = null; if ( typeof key === "undefined" ) { if ( this.length ) { var attr = this[0].attributes, name; data = jQuery.data( this[0] ); for ( var i = 0, l = attr.length; i < l; i++ ) { name = attr[i].name; if ( name.indexOf( "data-" ) === 0 ) { name = name.substr( 5 ); dataAttr( this[0], name, data[ name ] ); } } } return data; } else if ( typeof key === "object" ) { return this.each(function() { jQuery.data( this, key ); }); } var parts = key.split("."); parts[1] = parts[1] ? "." + parts[1] : ""; if ( value === undefined ) { data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); // Try to fetch any internally stored data first if ( data === undefined && this.length ) { data = jQuery.data( this[0], key ); data = dataAttr( this[0], key, data ); } return data === undefined && parts[1] ? this.data( parts[0] ) : data; } else { return this.each(function() { var $this = jQuery( this ), args = [ parts[0], value ]; $this.triggerHandler( "setData" + parts[1] + "!", args ); jQuery.data( this, key, value ); $this.triggerHandler( "changeData" + parts[1] + "!", args ); }); } }, removeData: function( key ) { return this.each(function() { jQuery.removeData( this, key ); }); } }); function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { data = elem.getAttribute( "data-" + key ); if ( typeof data === "string" ) { try { data = data === "true" ? true : data === "false" ? false : data === "null" ? null : !jQuery.isNaN( data ) ? parseFloat( data ) : rbrace.test( data ) ? jQuery.parseJSON( data ) : data; } catch( e ) {} // Make sure we set the data so it isn't changed later jQuery.data( elem, key, data ); } else { data = undefined; } } return data; } jQuery.extend({ queue: function( elem, type, data ) { if ( !elem ) { return; } type = (type || "fx") + "queue"; var q = jQuery.data( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( !data ) { return q || []; } if ( !q || jQuery.isArray(data) ) { q = jQuery.data( elem, type, jQuery.makeArray(data) ); } else { q.push( data ); } return q; }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), fn = queue.shift(); // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift("inprogress"); } fn.call(elem, function() { jQuery.dequeue(elem, type); }); } } }); jQuery.fn.extend({ queue: function( type, data ) { if ( typeof type !== "string" ) { data = type; type = "fx"; } if ( data === undefined ) { return jQuery.queue( this[0], type ); } return this.each(function( i ) { var queue = jQuery.queue( this, type, data ); if ( type === "fx" && queue[0] !== "inprogress" ) { jQuery.dequeue( this, type ); } }); }, dequeue: function( type ) { return this.each(function() { jQuery.dequeue( this, type ); }); }, // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; type = type || "fx"; return this.queue( type, function() { var elem = this; setTimeout(function() { jQuery.dequeue( elem, type ); }, time ); }); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); } }); var rclass = /[\n\t]/g, rspaces = /\s+/, rreturn = /\r/g, rspecialurl = /^(?:href|src|style)$/, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, rradiocheck = /^(?:radio|checkbox)$/i; jQuery.fn.extend({ attr: function( name, value ) { return jQuery.access( this, name, value, true, jQuery.attr ); }, removeAttr: function( name, fn ) { return this.each(function(){ jQuery.attr( this, name, "" ); if ( this.nodeType === 1 ) { this.removeAttribute( name ); } }); }, addClass: function( value ) { if ( jQuery.isFunction(value) ) { return this.each(function(i) { var self = jQuery(this); self.addClass( value.call(this, i, self.attr("class")) ); }); } if ( value && typeof value === "string" ) { var classNames = (value || "").split( rspaces ); for ( var i = 0, l = this.length; i < l; i++ ) { var elem = this[i]; if ( elem.nodeType === 1 ) { if ( !elem.className ) { elem.className = value; } else { var className = " " + elem.className + " ", setClass = elem.className; for ( var c = 0, cl = classNames.length; c < cl; c++ ) { if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { setClass += " " + classNames[c]; } } elem.className = jQuery.trim( setClass ); } } } } return this; }, removeClass: function( value ) { if ( jQuery.isFunction(value) ) { return this.each(function(i) { var self = jQuery(this); self.removeClass( value.call(this, i, self.attr("class")) ); }); } if ( (value && typeof value === "string") || value === undefined ) { var classNames = (value || "").split( rspaces ); for ( var i = 0, l = this.length; i < l; i++ ) { var elem = this[i]; if ( elem.nodeType === 1 && elem.className ) { if ( value ) { var className = (" " + elem.className + " ").replace(rclass, " "); for ( var c = 0, cl = classNames.length; c < cl; c++ ) { className = className.replace(" " + classNames[c] + " ", " "); } elem.className = jQuery.trim( className ); } else { elem.className = ""; } } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isBool = typeof stateVal === "boolean"; if ( jQuery.isFunction( value ) ) { return this.each(function(i) { var self = jQuery(this); self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); }); } return this.each(function() { if ( type === "string" ) { // toggle individual class names var className, i = 0, self = jQuery(this), state = stateVal, classNames = value.split( rspaces ); while ( (className = classNames[ i++ ]) ) { // check each className given, space seperated list state = isBool ? state : !self.hasClass( className ); self[ state ? "addClass" : "removeClass" ]( className ); } } else if ( type === "undefined" || type === "boolean" ) { if ( this.className ) { // store className if set jQuery.data( this, "__className__", this.className ); } // toggle whole className this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || ""; } }); }, hasClass: function( selector ) { var className = " " + selector + " "; for ( var i = 0, l = this.length; i < l; i++ ) { if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { return true; } } return false; }, val: function( value ) { if ( !arguments.length ) { var elem = this[0]; if ( elem ) { if ( jQuery.nodeName( elem, "option" ) ) { // attributes.value is undefined in Blackberry 4.7 but // uses .value. See #6932 var val = elem.attributes.value; return !val || val.specified ? elem.value : elem.text; } // We need to handle select boxes special if ( jQuery.nodeName( elem, "select" ) ) { var index = elem.selectedIndex, values = [], options = elem.options, one = elem.type === "select-one"; // Nothing was selected if ( index < 0 ) { return null; } // Loop through all the selected options for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { var option = options[ i ]; // Don't return options that are disabled or in a disabled optgroup if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { // Get the specific value for the option value = jQuery(option).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; } // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { return elem.getAttribute("value") === null ? "on" : elem.value; } // Everything else, we just grab the value return (elem.value || "").replace(rreturn, ""); } return undefined; } var isFunction = jQuery.isFunction(value); return this.each(function(i) { var self = jQuery(this), val = value; if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { val = value.call(this, i, self.val()); } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( jQuery.isArray(val) ) { val = jQuery.map(val, function (value) { return value == null ? "" : value + ""; }); } if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { this.checked = jQuery.inArray( self.val(), val ) >= 0; } else if ( jQuery.nodeName( this, "select" ) ) { var values = jQuery.makeArray(val); jQuery( "option", this ).each(function() { this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; }); if ( !values.length ) { this.selectedIndex = -1; } } else { this.value = val; } }); } }); jQuery.extend({ attrFn: { val: true, css: true, html: true, text: true, data: true, width: true, height: true, offset: true }, attr: function( elem, name, value, pass ) { // don't set attributes on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { return undefined; } if ( pass && name in jQuery.attrFn ) { return jQuery(elem)[name](value); } var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), // Whether we are setting (or getting) set = value !== undefined; // Try to normalize/fix the name name = notxml && jQuery.props[ name ] || name; // Only do all the following if this is a node (faster for style) if ( elem.nodeType === 1 ) { // These attributes require special treatment var special = rspecialurl.test( name ); // Safari mis-reports the default selected property of an option // Accessing the parent's selectedIndex property fixes it if ( name === "selected" && !jQuery.support.optSelected ) { var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; // Make sure that it also works with optgroups, see #5701 if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } } // If applicable, access the attribute via the DOM 0 way // 'in' checks fail in Blackberry 4.7 #6931 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { if ( set ) { // We can't allow the type property to be changed (since it causes problems in IE) if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { jQuery.error( "type property can't be changed" ); } if ( value === null ) { if ( elem.nodeType === 1 ) { elem.removeAttribute( name ); } } else { elem[ name ] = value; } } // browsers index elements by id/name on forms, give priority to attributes. if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { return elem.getAttributeNode( name ).nodeValue; } // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ if ( name === "tabIndex" ) { var attributeNode = elem.getAttributeNode( "tabIndex" ); return attributeNode && attributeNode.specified ? attributeNode.value : rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? 0 : undefined; } return elem[ name ]; } if ( !jQuery.support.style && notxml && name === "style" ) { if ( set ) { elem.style.cssText = "" + value; } return elem.style.cssText; } if ( set ) { // convert the value to a string (all browsers do this but IE) see #1070 elem.setAttribute( name, "" + value ); } // Ensure that missing attributes return undefined // Blackberry 4.7 returns "" from getAttribute #6938 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { return undefined; } var attr = !jQuery.support.hrefNormalized && notxml && special ? // Some attributes require a special call on IE elem.getAttribute( name, 2 ) : elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined return attr === null ? undefined : attr; } } }); var rnamespaces = /\.(.*)$/, rformElems = /^(?:textarea|input|select)$/i, rperiod = /\./g, rspace = / /g, rescape = /[^\w\s.|`]/g, fcleanup = function( nm ) { return nm.replace(rescape, "\\$&"); }, focusCounts = { focusin: 0, focusout: 0 }; /* * A number of helper functions used for managing events. * Many of the ideas behind this code originated from * Dean Edwards' addEvent library. */ jQuery.event = { // Bind an event to an element // Original by Dean Edwards add: function( elem, types, handler, data ) { if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // For whatever reason, IE has trouble passing the window object // around, causing it to be cloned in the process if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { elem = window; } if ( handler === false ) { handler = returnFalse; } var handleObjIn, handleObj; if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; } // Make sure that the function being executed has a unique ID if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure var elemData = jQuery.data( elem ); // If no elemData is found then we must be trying to bind to one of the // banned noData elements if ( !elemData ) { return; } // Use a key less likely to result in collisions for plain JS objects. // Fixes bug #7150. var eventKey = elem.nodeType ? "events" : "__events__", events = elemData[ eventKey ], eventHandle = elemData.handle; if ( typeof events === "function" ) { // On plain objects events is a fn that holds the the data // which prevents this data from being JSON serialized // the function does not need to be called, it just contains the data eventHandle = events.handle; events = events.events; } else if ( !events ) { if ( !elem.nodeType ) { // On plain objects, create a fn that acts as the holder // of the values to avoid JSON serialization of event data elemData[ eventKey ] = elemData = function(){}; } elemData.events = events = {}; } if ( !eventHandle ) { elemData.handle = eventHandle = function() { // Handle the second event of a trigger and when // an event is called after a page has unloaded return typeof jQuery !== "undefined" && !jQuery.event.triggered ? jQuery.event.handle.apply( eventHandle.elem, arguments ) : undefined; }; } // Add elem as a property of the handle function // This is to prevent a memory leak with non-native events in IE. eventHandle.elem = elem; // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); types = types.split(" "); var type, i = 0, namespaces; while ( (type = types[ i++ ]) ) { handleObj = handleObjIn ? jQuery.extend({}, handleObjIn) : { handler: handler, data: data }; // Namespaced event handlers if ( type.indexOf(".") > -1 ) { namespaces = type.split("."); type = namespaces.shift(); handleObj.namespace = namespaces.slice(0).sort().join("."); } else { namespaces = []; handleObj.namespace = ""; } handleObj.type = type; if ( !handleObj.guid ) { handleObj.guid = handler.guid; } // Get the current list of functions bound to this event var handlers = events[ type ], special = jQuery.event.special[ type ] || {}; // Init the event handler queue if ( !handlers ) { handlers = events[ type ] = []; // Check for a special event handler // Only use addEventListener/attachEvent if the special // events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { // Bind the global event handler to the element if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle, false ); } else if ( elem.attachEvent ) { elem.attachEvent( "on" + type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add the function to the element's handler list handlers.push( handleObj ); // Keep track of which events have been used, for global triggering jQuery.event.global[ type ] = true; } // Nullify elem to prevent memory leaks in IE elem = null; }, global: {}, // Detach an event or set of events from an element remove: function( elem, types, handler, pos ) { // don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } if ( handler === false ) { handler = returnFalse; } var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, eventKey = elem.nodeType ? "events" : "__events__", elemData = jQuery.data( elem ), events = elemData && elemData[ eventKey ]; if ( !elemData || !events ) { return; } if ( typeof events === "function" ) { elemData = events; events = events.events; } // types is actually an event object here if ( types && types.type ) { handler = types.handler; types = types.type; } // Unbind all events for the element if ( !types || typeof types === "string" && types.charAt(0) === "." ) { types = types || ""; for ( type in events ) { jQuery.event.remove( elem, type + types ); } return; } // Handle multiple events separated by a space // jQuery(...).unbind("mouseover mouseout", fn); types = types.split(" "); while ( (type = types[ i++ ]) ) { origType = type; handleObj = null; all = type.indexOf(".") < 0; namespaces = []; if ( !all ) { // Namespaced event handlers namespaces = type.split("."); type = namespaces.shift(); namespace = new RegExp("(^|\\.)" + jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); } eventType = events[ type ]; if ( !eventType ) { continue; } if ( !handler ) { for ( j = 0; j < eventType.length; j++ ) { handleObj = eventType[ j ]; if ( all || namespace.test( handleObj.namespace ) ) { jQuery.event.remove( elem, origType, handleObj.handler, j ); eventType.splice( j--, 1 ); } } continue; } special = jQuery.event.special[ type ] || {}; for ( j = pos || 0; j < eventType.length; j++ ) { handleObj = eventType[ j ]; if ( handler.guid === handleObj.guid ) { // remove the given handler for the given type if ( all || namespace.test( handleObj.namespace ) ) { if ( pos == null ) { eventType.splice( j--, 1 ); } if ( special.remove ) { special.remove.call( elem, handleObj ); } } if ( pos != null ) { break; } } } // remove generic event handler if no more handlers exist if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } ret = null; delete events[ type ]; } } // Remove the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { var handle = elemData.handle; if ( handle ) { handle.elem = null; } delete elemData.events; delete elemData.handle; if ( typeof elemData === "function" ) { jQuery.removeData( elem, eventKey ); } else if ( jQuery.isEmptyObject( elemData ) ) { jQuery.removeData( elem ); } } }, // bubbling is internal trigger: function( event, data, elem /*, bubbling */ ) { // Event object or event type var type = event.type || event, bubbling = arguments[3]; if ( !bubbling ) { event = typeof event === "object" ? // jQuery.Event object event[ jQuery.expando ] ? event : // Object literal jQuery.extend( jQuery.Event(type), event ) : // Just the event type (string) jQuery.Event(type); if ( type.indexOf("!") >= 0 ) { event.type = type = type.slice(0, -1); event.exclusive = true; } // Handle a global trigger if ( !elem ) { // Don't bubble custom events when global (to avoid too much overhead) event.stopPropagation(); // Only trigger if we've ever bound an event for it if ( jQuery.event.global[ type ] ) { jQuery.each( jQuery.cache, function() { if ( this.events && this.events[type] ) { jQuery.event.trigger( event, data, this.handle.elem ); } }); } } // Handle triggering a single element // don't do events on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { return undefined; } // Clean up in case it is reused event.result = undefined; event.target = elem; // Clone the incoming data, if any data = jQuery.makeArray( data ); data.unshift( event ); } event.currentTarget = elem; // Trigger the event, it is assumed that "handle" is a function var handle = elem.nodeType ? jQuery.data( elem, "handle" ) : (jQuery.data( elem, "__events__" ) || {}).handle; if ( handle ) { handle.apply( elem, data ); } var parent = elem.parentNode || elem.ownerDocument; // Trigger an inline bound script try { if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { event.result = false; event.preventDefault(); } } // prevent IE from throwing an error for some elements with some event types, see #3533 } catch (inlineError) {} if ( !event.isPropagationStopped() && parent ) { jQuery.event.trigger( event, data, parent, true ); } else if ( !event.isDefaultPrevented() ) { var target = event.target, old, targetType = type.replace(rnamespaces, ""), isClick = jQuery.nodeName(target, "a") && targetType === "click", special = jQuery.event.special[ targetType ] || {}; if ( (!special._default || special._default.call( elem, event ) === false) && !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { try { if ( target[ targetType ] ) { // Make sure that we don't accidentally re-trigger the onFOO events old = target[ "on" + targetType ]; if ( old ) { target[ "on" + targetType ] = null; } jQuery.event.triggered = true; target[ targetType ](); } // prevent IE from throwing an error for some elements with some event types, see #3533 } catch (triggerError) {} if ( old ) { target[ "on" + targetType ] = old; } jQuery.event.triggered = false; } } }, handle: function( event ) { var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments ); event = args[0] = jQuery.event.fix( event || window.event ); event.currentTarget = this; // Namespaced event handlers all = event.type.indexOf(".") < 0 && !event.exclusive; if ( !all ) { namespaces = event.type.split("."); event.type = namespaces.shift(); namespace_sort = namespaces.slice(0).sort(); namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); } event.namespace = event.namespace || namespace_sort.join("."); events = jQuery.data(this, this.nodeType ? "events" : "__events__"); if ( typeof events === "function" ) { events = events.events; } handlers = (events || {})[ event.type ]; if ( events && handlers ) { // Clone the handlers to prevent manipulation handlers = handlers.slice(0); for ( var j = 0, l = handlers.length; j < l; j++ ) { var handleObj = handlers[ j ]; // Filter the functions by class if ( all || namespace_re.test( handleObj.namespace ) ) { // Pass in a reference to the handler function itself // So that we can later remove it event.handler = handleObj.handler; event.data = handleObj.data; event.handleObj = handleObj; var ret = handleObj.handler.apply( this, args ); if ( ret !== undefined ) { event.result = ret; if ( ret === false ) { event.preventDefault(); event.stopPropagation(); } } if ( event.isImmediatePropagationStopped() ) { break; } } } } return event.result; }, props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), fix: function( event ) { if ( event[ jQuery.expando ] ) { return event; } // store a copy of the original event object // and "clone" to set read-only properties var originalEvent = event; event = jQuery.Event( originalEvent ); for ( var i = this.props.length, prop; i; ) { prop = this.props[ --i ]; event[ prop ] = originalEvent[ prop ]; } // Fix target property, if necessary if ( !event.target ) { event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either } // check if target is a textnode (safari) if ( event.target.nodeType === 3 ) { event.target = event.target.parentNode; } // Add relatedTarget, if necessary if ( !event.relatedTarget && event.fromElement ) { event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; } // Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && event.clientX != null ) { var doc = document.documentElement, body = document.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); } // Add which for key events if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { event.which = event.charCode != null ? event.charCode : event.keyCode; } // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) if ( !event.metaKey && event.ctrlKey ) { event.metaKey = event.ctrlKey; } // Add which for click: 1 === left; 2 === middle; 3 === right // Note: button is not normalized, so don't use it if ( !event.which && event.button !== undefined ) { event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); } return event; }, // Deprecated, use jQuery.guid instead guid: 1E8, // Deprecated, use jQuery.proxy instead proxy: jQuery.proxy, special: { ready: { // Make sure the ready event is setup setup: jQuery.bindReady, teardown: jQuery.noop }, live: { add: function( handleObj ) { jQuery.event.add( this, liveConvert( handleObj.origType, handleObj.selector ), jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); }, remove: function( handleObj ) { jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); } }, beforeunload: { setup: function( data, namespaces, eventHandle ) { // We only want to do this special case on windows if ( jQuery.isWindow( this ) ) { this.onbeforeunload = eventHandle; } }, teardown: function( namespaces, eventHandle ) { if ( this.onbeforeunload === eventHandle ) { this.onbeforeunload = null; } } } } }; jQuery.removeEvent = document.removeEventListener ? function( elem, type, handle ) { if ( elem.removeEventListener ) { elem.removeEventListener( type, handle, false ); } } : function( elem, type, handle ) { if ( elem.detachEvent ) { elem.detachEvent( "on" + type, handle ); } }; jQuery.Event = function( src ) { // Allow instantiation without the 'new' keyword if ( !this.preventDefault ) { return new jQuery.Event( src ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Event type } else { this.type = src; } // timeStamp is buggy for some events on Firefox(#3843) // So we won't rely on the native value this.timeStamp = jQuery.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; function returnFalse() { return false; } function returnTrue() { return true; } // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { preventDefault: function() { this.isDefaultPrevented = returnTrue; var e = this.originalEvent; if ( !e ) { return; } // if preventDefault exists run it on the original event if ( e.preventDefault ) { e.preventDefault(); // otherwise set the returnValue property of the original event to false (IE) } else { e.returnValue = false; } }, stopPropagation: function() { this.isPropagationStopped = returnTrue; var e = this.originalEvent; if ( !e ) { return; } // if stopPropagation exists run it on the original event if ( e.stopPropagation ) { e.stopPropagation(); } // otherwise set the cancelBubble property of the original event to true (IE) e.cancelBubble = true; }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); }, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse }; // Checks if an event happened on an element within another element // Used in jQuery.event.special.mouseenter and mouseleave handlers var withinElement = function( event ) { // Check if mouse(over|out) are still within the same parent element var parent = event.relatedTarget; // Firefox sometimes assigns relatedTarget a XUL element // which we cannot access the parentNode property of try { // Traverse up the tree while ( parent && parent !== this ) { parent = parent.parentNode; } if ( parent !== this ) { // set the correct event type event.type = event.data; // handle event if we actually just moused on to a non sub-element jQuery.event.handle.apply( this, arguments ); } // assuming we've left the element since we most likely mousedover a xul element } catch(e) { } }, // In case of event delegation, we only need to rename the event.type, // liveHandler will take care of the rest. delegate = function( event ) { event.type = event.data; jQuery.event.handle.apply( this, arguments ); }; // Create mouseenter and mouseleave events jQuery.each({ mouseenter: "mouseover", mouseleave: "mouseout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { setup: function( data ) { jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); }, teardown: function( data ) { jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); } }; }); // submit delegation if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function( data, namespaces ) { if ( this.nodeName.toLowerCase() !== "form" ) { jQuery.event.add(this, "click.specialSubmit", function( e ) { var elem = e.target, type = elem.type; if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { e.liveFired = undefined; return trigger( "submit", this, arguments ); } }); jQuery.event.add(this, "keypress.specialSubmit", function( e ) { var elem = e.target, type = elem.type; if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { e.liveFired = undefined; return trigger( "submit", this, arguments ); } }); } else { return false; } }, teardown: function( namespaces ) { jQuery.event.remove( this, ".specialSubmit" ); } }; } // change delegation, happens here so we have bind. if ( !jQuery.support.changeBubbles ) { var changeFilters, getVal = function( elem ) { var type = elem.type, val = elem.value; if ( type === "radio" || type === "checkbox" ) { val = elem.checked; } else if ( type === "select-multiple" ) { val = elem.selectedIndex > -1 ? jQuery.map( elem.options, function( elem ) { return elem.selected; }).join("-") : ""; } else if ( elem.nodeName.toLowerCase() === "select" ) { val = elem.selectedIndex; } return val; }, testChange = function testChange( e ) { var elem = e.target, data, val; if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { return; } data = jQuery.data( elem, "_change_data" ); val = getVal(elem); // the current data will be also retrieved by beforeactivate if ( e.type !== "focusout" || elem.type !== "radio" ) { jQuery.data( elem, "_change_data", val ); } if ( data === undefined || val === data ) { return; } if ( data != null || val ) { e.type = "change"; e.liveFired = undefined; return jQuery.event.trigger( e, arguments[1], elem ); } }; jQuery.event.special.change = { filters: { focusout: testChange, beforedeactivate: testChange, click: function( e ) { var elem = e.target, type = elem.type; if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { return testChange.call( this, e ); } }, // Change has to be called before submit // Keydown will be called before keypress, which is used in submit-event delegation keydown: function( e ) { var elem = e.target, type = elem.type; if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || type === "select-multiple" ) { return testChange.call( this, e ); } }, // Beforeactivate happens also before the previous element is blurred // with this event you can't trigger a change event, but you can store // information beforeactivate: function( e ) { var elem = e.target; jQuery.data( elem, "_change_data", getVal(elem) ); } }, setup: function( data, namespaces ) { if ( this.type === "file" ) { return false; } for ( var type in changeFilters ) { jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); } return rformElems.test( this.nodeName ); }, teardown: function( namespaces ) { jQuery.event.remove( this, ".specialChange" ); return rformElems.test( this.nodeName ); } }; changeFilters = jQuery.event.special.change.filters; // Handle when the input is .focus()'d changeFilters.focus = changeFilters.beforeactivate; } function trigger( type, elem, args ) { args[0].type = type; return jQuery.event.handle.apply( elem, args ); } // Create "bubbling" focus and blur events if ( document.addEventListener ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { jQuery.event.special[ fix ] = { setup: function() { if ( focusCounts[fix]++ === 0 ) { document.addEventListener( orig, handler, true ); } }, teardown: function() { if ( --focusCounts[fix] === 0 ) { document.removeEventListener( orig, handler, true ); } } }; function handler( e ) { e = jQuery.event.fix( e ); e.type = fix; return jQuery.event.trigger( e, null, e.target ); } }); } jQuery.each(["bind", "one"], function( i, name ) { jQuery.fn[ name ] = function( type, data, fn ) { // Handle object literals if ( typeof type === "object" ) { for ( var key in type ) { this[ name ](key, data, type[key], fn); } return this; } if ( jQuery.isFunction( data ) || data === false ) { fn = data; data = undefined; } var handler = name === "one" ? jQuery.proxy( fn, function( event ) { jQuery( this ).unbind( event, handler ); return fn.apply( this, arguments ); }) : fn; if ( type === "unload" && name !== "one" ) { this.one( type, data, fn ); } else { for ( var i = 0, l = this.length; i < l; i++ ) { jQuery.event.add( this[i], type, handler, data ); } } return this; }; }); jQuery.fn.extend({ unbind: function( type, fn ) { // Handle object literals if ( typeof type === "object" && !type.preventDefault ) { for ( var key in type ) { this.unbind(key, type[key]); } } else { for ( var i = 0, l = this.length; i < l; i++ ) { jQuery.event.remove( this[i], type, fn ); } } return this; }, delegate: function( selector, types, data, fn ) { return this.live( types, data, fn, selector ); }, undelegate: function( selector, types, fn ) { if ( arguments.length === 0 ) { return this.unbind( "live" ); } else { return this.die( types, null, fn, selector ); } }, trigger: function( type, data ) { return this.each(function() { jQuery.event.trigger( type, data, this ); }); }, triggerHandler: function( type, data ) { if ( this[0] ) { var event = jQuery.Event( type ); event.preventDefault(); event.stopPropagation(); jQuery.event.trigger( event, data, this[0] ); return event.result; } }, toggle: function( fn ) { // Save reference to arguments for access in closure var args = arguments, i = 1; // link all the functions, so any of them can unbind this click handler while ( i < args.length ) { jQuery.proxy( fn, args[ i++ ] ); } return this.click( jQuery.proxy( fn, function( event ) { // Figure out which function to execute var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); // Make sure that clicks stop event.preventDefault(); // and execute the function return args[ lastToggle ].apply( this, arguments ) || false; })); }, hover: function( fnOver, fnOut ) { return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } }); var liveMap = { focus: "focusin", blur: "focusout", mouseenter: "mouseover", mouseleave: "mouseout" }; jQuery.each(["live", "die"], function( i, name ) { jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { var type, i = 0, match, namespaces, preType, selector = origSelector || this.selector, context = origSelector ? this : jQuery( this.context ); if ( typeof types === "object" && !types.preventDefault ) { for ( var key in types ) { context[ name ]( key, data, types[key], selector ); } return this; } if ( jQuery.isFunction( data ) ) { fn = data; data = undefined; } types = (types || "").split(" "); while ( (type = types[ i++ ]) != null ) { match = rnamespaces.exec( type ); namespaces = ""; if ( match ) { namespaces = match[0]; type = type.replace( rnamespaces, "" ); } if ( type === "hover" ) { types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); continue; } preType = type; if ( type === "focus" || type === "blur" ) { types.push( liveMap[ type ] + namespaces ); type = type + namespaces; } else { type = (liveMap[ type ] || type) + namespaces; } if ( name === "live" ) { // bind live handler for ( var j = 0, l = context.length; j < l; j++ ) { jQuery.event.add( context[j], "live." + liveConvert( type, selector ), { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); } } else { // unbind live handler context.unbind( "live." + liveConvert( type, selector ), fn ); } } return this; }; }); function liveHandler( event ) { var stop, maxLevel, elems = [], selectors = [], related, match, handleObj, elem, j, i, l, data, close, namespace, ret, events = jQuery.data( this, this.nodeType ? "events" : "__events__" ); if ( typeof events === "function" ) { events = events.events; } // Make sure we avoid non-left-click bubbling in Firefox (#3861) if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) { return; } if ( event.namespace ) { namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); } event.liveFired = this; var live = events.live.slice(0); for ( j = 0; j < live.length; j++ ) { handleObj = live[j]; if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { selectors.push( handleObj.selector ); } else { live.splice( j--, 1 ); } } match = jQuery( event.target ).closest( selectors, event.currentTarget ); for ( i = 0, l = match.length; i < l; i++ ) { close = match[i]; for ( j = 0; j < live.length; j++ ) { handleObj = live[j]; if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) { elem = close.elem; related = null; // Those two events require additional checking if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { event.type = handleObj.preType; related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; } if ( !related || related !== elem ) { elems.push({ elem: elem, handleObj: handleObj, level: close.level }); } } } } for ( i = 0, l = elems.length; i < l; i++ ) { match = elems[i]; if ( maxLevel && match.level > maxLevel ) { break; } event.currentTarget = match.elem; event.data = match.handleObj.data; event.handleObj = match.handleObj; ret = match.handleObj.origHandler.apply( match.elem, arguments ); if ( ret === false || event.isPropagationStopped() ) { maxLevel = match.level; if ( ret === false ) { stop = false; } } } return stop; } function liveConvert( type, selector ) { return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); } jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error").split(" "), function( i, name ) { // Handle event binding jQuery.fn[ name ] = function( data, fn ) { if ( fn == null ) { fn = data; data = null; } return arguments.length > 0 ? this.bind( name, data, fn ) : this.trigger( name ); }; if ( jQuery.attrFn ) { jQuery.attrFn[ name ] = true; } }); // Prevent memory leaks in IE // Window isn't included so as not to unbind existing unload events // More info: // - http://isaacschlueter.com/2006/10/msie-memory-leaks/ if ( window.attachEvent && !window.addEventListener ) { jQuery(window).bind("unload", function() { for ( var id in jQuery.cache ) { if ( jQuery.cache[ id ].handle ) { // Try/Catch is to handle iframes being unloaded, see #4280 try { jQuery.event.remove( jQuery.cache[ id ].handle.elem ); } catch(e) {} } } }); } /*! * Sizzle CSS Selector Engine - v1.0 * Copyright 2009, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */ (function(){ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, done = 0, toString = Object.prototype.toString, hasDuplicate = false, baseHasDuplicate = true; // Here we check if the JavaScript engine is using some sort of // optimization where it does not always call our comparision // function. If that is the case, discard the hasDuplicate value. // Thus far that includes Google Chrome. [0, 0].sort(function(){ baseHasDuplicate = false; return 0; }); var Sizzle = function(selector, context, results, seed) { results = results || []; context = context || document; var origContext = context; if ( context.nodeType !== 1 && context.nodeType !== 9 ) { return []; } if ( !selector || typeof selector !== "string" ) { return results; } var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context), soFar = selector, ret, cur, pop, i; // Reset the position of the chunker regexp (start from head) do { chunker.exec(""); m = chunker.exec(soFar); if ( m ) { soFar = m[3]; parts.push( m[1] ); if ( m[2] ) { extra = m[3]; break; } } } while ( m ); if ( parts.length > 1 && origPOS.exec( selector ) ) { if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { set = posProcess( parts[0] + parts[1], context ); } else { set = Expr.relative[ parts[0] ] ? [ context ] : Sizzle( parts.shift(), context ); while ( parts.length ) { selector = parts.shift(); if ( Expr.relative[ selector ] ) { selector += parts.shift(); } set = posProcess( selector, set ); } } } else { // Take a shortcut and set the context if the root selector is an ID // (but not if it'll be faster if the inner selector is an ID) if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { ret = Sizzle.find( parts.shift(), context, contextXML ); context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; } if ( context ) { ret = seed ? { expr: parts.pop(), set: makeArray(seed) } : Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; if ( parts.length > 0 ) { checkSet = makeArray(set); } else { prune = false; } while ( parts.length ) { cur = parts.pop(); pop = cur; if ( !Expr.relative[ cur ] ) { cur = ""; } else { pop = parts.pop(); } if ( pop == null ) { pop = context; } Expr.relative[ cur ]( checkSet, pop, contextXML ); } } else { checkSet = parts = []; } } if ( !checkSet ) { checkSet = set; } if ( !checkSet ) { Sizzle.error( cur || selector ); } if ( toString.call(checkSet) === "[object Array]" ) { if ( !prune ) { results.push.apply( results, checkSet ); } else if ( context && context.nodeType === 1 ) { for ( i = 0; checkSet[i] != null; i++ ) { if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { results.push( set[i] ); } } } else { for ( i = 0; checkSet[i] != null; i++ ) { if ( checkSet[i] && checkSet[i].nodeType === 1 ) { results.push( set[i] ); } } } } else { makeArray( checkSet, results ); } if ( extra ) { Sizzle( extra, origContext, results, seed ); Sizzle.uniqueSort( results ); } return results; }; Sizzle.uniqueSort = function(results){ if ( sortOrder ) { hasDuplicate = baseHasDuplicate; results.sort(sortOrder); if ( hasDuplicate ) { for ( var i = 1; i < results.length; i++ ) { if ( results[i] === results[i-1] ) { results.splice(i--, 1); } } } } return results; }; Sizzle.matches = function(expr, set){ return Sizzle(expr, null, null, set); }; Sizzle.matchesSelector = function(node, expr){ return Sizzle(expr, null, null, [node]).length > 0; }; Sizzle.find = function(expr, context, isXML){ var set; if ( !expr ) { return []; } for ( var i = 0, l = Expr.order.length; i < l; i++ ) { var type = Expr.order[i], match; if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { var left = match[1]; match.splice(1,1); if ( left.substr( left.length - 1 ) !== "\\" ) { match[1] = (match[1] || "").replace(/\\/g, ""); set = Expr.find[ type ]( match, context, isXML ); if ( set != null ) { expr = expr.replace( Expr.match[ type ], "" ); break; } } } } if ( !set ) { set = context.getElementsByTagName("*"); } return {set: set, expr: expr}; }; Sizzle.filter = function(expr, set, inplace, not){ var old = expr, result = [], curLoop = set, match, anyFound, isXMLFilter = set && set[0] && Sizzle.isXML(set[0]); while ( expr && set.length ) { for ( var type in Expr.filter ) { if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { var filter = Expr.filter[ type ], found, item, left = match[1]; anyFound = false; match.splice(1,1); if ( left.substr( left.length - 1 ) === "\\" ) { continue; } if ( curLoop === result ) { result = []; } if ( Expr.preFilter[ type ] ) { match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); if ( !match ) { anyFound = found = true; } else if ( match === true ) { continue; } } if ( match ) { for ( var i = 0; (item = curLoop[i]) != null; i++ ) { if ( item ) { found = filter( item, match, i, curLoop ); var pass = not ^ !!found; if ( inplace && found != null ) { if ( pass ) { anyFound = true; } else { curLoop[i] = false; } } else if ( pass ) { result.push( item ); anyFound = true; } } } } if ( found !== undefined ) { if ( !inplace ) { curLoop = result; } expr = expr.replace( Expr.match[ type ], "" ); if ( !anyFound ) { return []; } break; } } } // Improper expression if ( expr === old ) { if ( anyFound == null ) { Sizzle.error( expr ); } else { break; } } old = expr; } return curLoop; }; Sizzle.error = function( msg ) { throw "Syntax error, unrecognized expression: " + msg; }; var Expr = Sizzle.selectors = { order: [ "ID", "NAME", "TAG" ], match: { ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/, POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ }, leftMatch: {}, attrMap: { "class": "className", "for": "htmlFor" }, attrHandle: { href: function(elem){ return elem.getAttribute("href"); } }, relative: { "+": function(checkSet, part){ var isPartStr = typeof part === "string", isTag = isPartStr && !/\W/.test(part), isPartStrNotTag = isPartStr && !isTag; if ( isTag ) { part = part.toLowerCase(); } for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { if ( (elem = checkSet[i]) ) { while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? elem || false : elem === part; } } if ( isPartStrNotTag ) { Sizzle.filter( part, checkSet, true ); } }, ">": function(checkSet, part){ var isPartStr = typeof part === "string", elem, i = 0, l = checkSet.length; if ( isPartStr && !/\W/.test(part) ) { part = part.toLowerCase(); for ( ; i < l; i++ ) { elem = checkSet[i]; if ( elem ) { var parent = elem.parentNode; checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; } } } else { for ( ; i < l; i++ ) { elem = checkSet[i]; if ( elem ) { checkSet[i] = isPartStr ? elem.parentNode : elem.parentNode === part; } } if ( isPartStr ) { Sizzle.filter( part, checkSet, true ); } } }, "": function(checkSet, part, isXML){ var doneName = done++, checkFn = dirCheck, nodeCheck; if ( typeof part === "string" && !/\W/.test(part) ) { part = part.toLowerCase(); nodeCheck = part; checkFn = dirNodeCheck; } checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); }, "~": function(checkSet, part, isXML){ var doneName = done++, checkFn = dirCheck, nodeCheck; if ( typeof part === "string" && !/\W/.test(part) ) { part = part.toLowerCase(); nodeCheck = part; checkFn = dirNodeCheck; } checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); } }, find: { ID: function(match, context, isXML){ if ( typeof context.getElementById !== "undefined" && !isXML ) { var m = context.getElementById(match[1]); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 return m && m.parentNode ? [m] : []; } }, NAME: function(match, context){ if ( typeof context.getElementsByName !== "undefined" ) { var ret = [], results = context.getElementsByName(match[1]); for ( var i = 0, l = results.length; i < l; i++ ) { if ( results[i].getAttribute("name") === match[1] ) { ret.push( results[i] ); } } return ret.length === 0 ? null : ret; } }, TAG: function(match, context){ return context.getElementsByTagName(match[1]); } }, preFilter: { CLASS: function(match, curLoop, inplace, result, not, isXML){ match = " " + match[1].replace(/\\/g, "") + " "; if ( isXML ) { return match; } for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { if ( elem ) { if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) { if ( !inplace ) { result.push( elem ); } } else if ( inplace ) { curLoop[i] = false; } } } return false; }, ID: function(match){ return match[1].replace(/\\/g, ""); }, TAG: function(match, curLoop){ return match[1].toLowerCase(); }, CHILD: function(match){ if ( match[1] === "nth" ) { // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); // calculate the numbers (first)n+(last) including if they are negative match[2] = (test[1] + (test[2] || 1)) - 0; match[3] = test[3] - 0; } // TODO: Move to normal caching system match[0] = done++; return match; }, ATTR: function(match, curLoop, inplace, result, not, isXML){ var name = match[1].replace(/\\/g, ""); if ( !isXML && Expr.attrMap[name] ) { match[1] = Expr.attrMap[name]; } if ( match[2] === "~=" ) { match[4] = " " + match[4] + " "; } return match; }, PSEUDO: function(match, curLoop, inplace, result, not){ if ( match[1] === "not" ) { // If we're dealing with a complex expression, or a simple one if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { match[3] = Sizzle(match[3], null, null, curLoop); } else { var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); if ( !inplace ) { result.push.apply( result, ret ); } return false; } } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { return true; } return match; }, POS: function(match){ match.unshift( true ); return match; } }, filters: { enabled: function(elem){ return elem.disabled === false && elem.type !== "hidden"; }, disabled: function(elem){ return elem.disabled === true; }, checked: function(elem){ return elem.checked === true; }, selected: function(elem){ // Accessing this property makes selected-by-default // options in Safari work properly elem.parentNode.selectedIndex; return elem.selected === true; }, parent: function(elem){ return !!elem.firstChild; }, empty: function(elem){ return !elem.firstChild; }, has: function(elem, i, match){ return !!Sizzle( match[3], elem ).length; }, header: function(elem){ return (/h\d/i).test( elem.nodeName ); }, text: function(elem){ return "text" === elem.type; }, radio: function(elem){ return "radio" === elem.type; }, checkbox: function(elem){ return "checkbox" === elem.type; }, file: function(elem){ return "file" === elem.type; }, password: function(elem){ return "password" === elem.type; }, submit: function(elem){ return "submit" === elem.type; }, image: function(elem){ return "image" === elem.type; }, reset: function(elem){ return "reset" === elem.type; }, button: function(elem){ return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; }, input: function(elem){ return (/input|select|textarea|button/i).test(elem.nodeName); } }, setFilters: { first: function(elem, i){ return i === 0; }, last: function(elem, i, match, array){ return i === array.length - 1; }, even: function(elem, i){ return i % 2 === 0; }, odd: function(elem, i){ return i % 2 === 1; }, lt: function(elem, i, match){ return i < match[3] - 0; }, gt: function(elem, i, match){ return i > match[3] - 0; }, nth: function(elem, i, match){ return match[3] - 0 === i; }, eq: function(elem, i, match){ return match[3] - 0 === i; } }, filter: { PSEUDO: function(elem, match, i, array){ var name = match[1], filter = Expr.filters[ name ]; if ( filter ) { return filter( elem, i, match, array ); } else if ( name === "contains" ) { return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; } else if ( name === "not" ) { var not = match[3]; for ( var j = 0, l = not.length; j < l; j++ ) { if ( not[j] === elem ) { return false; } } return true; } else { Sizzle.error( "Syntax error, unrecognized expression: " + name ); } }, CHILD: function(elem, match){ var type = match[1], node = elem; switch (type) { case 'only': case 'first': while ( (node = node.previousSibling) ) { if ( node.nodeType === 1 ) { return false; } } if ( type === "first" ) { return true; } node = elem; case 'last': while ( (node = node.nextSibling) ) { if ( node.nodeType === 1 ) { return false; } } return true; case 'nth': var first = match[2], last = match[3]; if ( first === 1 && last === 0 ) { return true; } var doneName = match[0], parent = elem.parentNode; if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { var count = 0; for ( node = parent.firstChild; node; node = node.nextSibling ) { if ( node.nodeType === 1 ) { node.nodeIndex = ++count; } } parent.sizcache = doneName; } var diff = elem.nodeIndex - last; if ( first === 0 ) { return diff === 0; } else { return ( diff % first === 0 && diff / first >= 0 ); } } }, ID: function(elem, match){ return elem.nodeType === 1 && elem.getAttribute("id") === match; }, TAG: function(elem, match){ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; }, CLASS: function(elem, match){ return (" " + (elem.className || elem.getAttribute("class")) + " ") .indexOf( match ) > -1; }, ATTR: function(elem, match){ var name = match[1], result = Expr.attrHandle[ name ] ? Expr.attrHandle[ name ]( elem ) : elem[ name ] != null ? elem[ name ] : elem.getAttribute( name ), value = result + "", type = match[2], check = match[4]; return result == null ? type === "!=" : type === "=" ? value === check : type === "*=" ? value.indexOf(check) >= 0 : type === "~=" ? (" " + value + " ").indexOf(check) >= 0 : !check ? value && result !== false : type === "!=" ? value !== check : type === "^=" ? value.indexOf(check) === 0 : type === "$=" ? value.substr(value.length - check.length) === check : type === "|=" ? value === check || value.substr(0, check.length + 1) === check + "-" : false; }, POS: function(elem, match, i, array){ var name = match[2], filter = Expr.setFilters[ name ]; if ( filter ) { return filter( elem, i, match, array ); } } } }; var origPOS = Expr.match.POS, fescape = function(all, num){ return "\\" + (num - 0 + 1); }; for ( var type in Expr.match ) { Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); } var makeArray = function(array, results) { array = Array.prototype.slice.call( array, 0 ); if ( results ) { results.push.apply( results, array ); return results; } return array; }; // Perform a simple check to determine if the browser is capable of // converting a NodeList to an array using builtin methods. // Also verifies that the returned array holds DOM nodes // (which is not the case in the Blackberry browser) try { Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; // Provide a fallback method if it does not work } catch(e){ makeArray = function(array, results) { var ret = results || [], i = 0; if ( toString.call(array) === "[object Array]" ) { Array.prototype.push.apply( ret, array ); } else { if ( typeof array.length === "number" ) { for ( var l = array.length; i < l; i++ ) { ret.push( array[i] ); } } else { for ( ; array[i]; i++ ) { ret.push( array[i] ); } } } return ret; }; } var sortOrder, siblingCheck; if ( document.documentElement.compareDocumentPosition ) { sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; return 0; } if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { return a.compareDocumentPosition ? -1 : 1; } return a.compareDocumentPosition(b) & 4 ? -1 : 1; }; } else { sortOrder = function( a, b ) { var ap = [], bp = [], aup = a.parentNode, bup = b.parentNode, cur = aup, al, bl; // The nodes are identical, we can exit early if ( a === b ) { hasDuplicate = true; return 0; // If the nodes are siblings (or identical) we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); // If no parents were found then the nodes are disconnected } else if ( !aup ) { return -1; } else if ( !bup ) { return 1; } // Otherwise they're somewhere else in the tree so we need // to build up a full list of the parentNodes for comparison while ( cur ) { ap.unshift( cur ); cur = cur.parentNode; } cur = bup; while ( cur ) { bp.unshift( cur ); cur = cur.parentNode; } al = ap.length; bl = bp.length; // Start walking down the tree looking for a discrepancy for ( var i = 0; i < al && i < bl; i++ ) { if ( ap[i] !== bp[i] ) { return siblingCheck( ap[i], bp[i] ); } } // We ended someplace up the tree so do a sibling check return i === al ? siblingCheck( a, bp[i], -1 ) : siblingCheck( ap[i], b, 1 ); }; siblingCheck = function( a, b, ret ) { if ( a === b ) { return ret; } var cur = a.nextSibling; while ( cur ) { if ( cur === b ) { return -1; } cur = cur.nextSibling; } return 1; }; } // Utility function for retreiving the text value of an array of DOM nodes Sizzle.getText = function( elems ) { var ret = "", elem; for ( var i = 0; elems[i]; i++ ) { elem = elems[i]; // Get the text from text nodes and CDATA nodes if ( elem.nodeType === 3 || elem.nodeType === 4 ) { ret += elem.nodeValue; // Traverse everything else, except comment nodes } else if ( elem.nodeType !== 8 ) { ret += Sizzle.getText( elem.childNodes ); } } return ret; }; // Check to see if the browser returns elements by name when // querying by getElementById (and provide a workaround) (function(){ // We're going to inject a fake input element with a specified name var form = document.createElement("div"), id = "script" + (new Date()).getTime(); form.innerHTML = ""; // Inject it into the root element, check its status, and remove it quickly var root = document.documentElement; root.insertBefore( form, root.firstChild ); // The workaround has to do additional checks after a getElementById // Which slows things down for other browsers (hence the branching) if ( document.getElementById( id ) ) { Expr.find.ID = function(match, context, isXML){ if ( typeof context.getElementById !== "undefined" && !isXML ) { var m = context.getElementById(match[1]); return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; } }; Expr.filter.ID = function(elem, match){ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); return elem.nodeType === 1 && node && node.nodeValue === match; }; } root.removeChild( form ); root = form = null; // release memory in IE })(); (function(){ // Check to see if the browser returns only elements // when doing getElementsByTagName("*") // Create a fake element var div = document.createElement("div"); div.appendChild( document.createComment("") ); // Make sure no comments are found if ( div.getElementsByTagName("*").length > 0 ) { Expr.find.TAG = function(match, context){ var results = context.getElementsByTagName(match[1]); // Filter out possible comments if ( match[1] === "*" ) { var tmp = []; for ( var i = 0; results[i]; i++ ) { if ( results[i].nodeType === 1 ) { tmp.push( results[i] ); } } results = tmp; } return results; }; } // Check to see if an attribute returns normalized href attributes div.innerHTML = ""; if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && div.firstChild.getAttribute("href") !== "#" ) { Expr.attrHandle.href = function(elem){ return elem.getAttribute("href", 2); }; } div = null; // release memory in IE })(); if ( document.querySelectorAll ) { (function(){ var oldSizzle = Sizzle, div = document.createElement("div"); div.innerHTML = "

      "; // Safari can't handle uppercase or unicode characters when // in quirks mode. if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { return; } Sizzle = function(query, context, extra, seed){ context = context || document; // Only use querySelectorAll on non-XML documents // (ID selectors don't work in non-HTML documents) if ( !seed && !Sizzle.isXML(context) ) { if ( context.nodeType === 9 ) { try { return makeArray( context.querySelectorAll(query), extra ); } catch(qsaError) {} // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { var old = context.id, id = context.id = "__sizzle__"; try { return makeArray( context.querySelectorAll( "#" + id + " " + query ), extra ); } catch(pseudoError) { } finally { if ( old ) { context.id = old; } else { context.removeAttribute( "id" ); } } } } return oldSizzle(query, context, extra, seed); }; for ( var prop in oldSizzle ) { Sizzle[ prop ] = oldSizzle[ prop ]; } div = null; // release memory in IE })(); } (function(){ var html = document.documentElement, matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector, pseudoWorks = false; try { // This should fail with an exception // Gecko does not error, returns false instead matches.call( document.documentElement, ":sizzle" ); } catch( pseudoError ) { pseudoWorks = true; } if ( matches ) { Sizzle.matchesSelector = function( node, expr ) { try { if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) ) { return matches.call( node, expr ); } } catch(e) {} return Sizzle(expr, null, null, [node]).length > 0; }; } })(); (function(){ var div = document.createElement("div"); div.innerHTML = "
      "; // Opera can't find a second classname (in 9.6) // Also, make sure that getElementsByClassName actually exists if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { return; } // Safari caches class attributes, doesn't catch changes (in 3.2) div.lastChild.className = "e"; if ( div.getElementsByClassName("e").length === 1 ) { return; } Expr.order.splice(1, 0, "CLASS"); Expr.find.CLASS = function(match, context, isXML) { if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { return context.getElementsByClassName(match[1]); } }; div = null; // release memory in IE })(); function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { for ( var i = 0, l = checkSet.length; i < l; i++ ) { var elem = checkSet[i]; if ( elem ) { elem = elem[dir]; var match = false; while ( elem ) { if ( elem.sizcache === doneName ) { match = checkSet[elem.sizset]; break; } if ( elem.nodeType === 1 && !isXML ){ elem.sizcache = doneName; elem.sizset = i; } if ( elem.nodeName.toLowerCase() === cur ) { match = elem; break; } elem = elem[dir]; } checkSet[i] = match; } } } function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { for ( var i = 0, l = checkSet.length; i < l; i++ ) { var elem = checkSet[i]; if ( elem ) { elem = elem[dir]; var match = false; while ( elem ) { if ( elem.sizcache === doneName ) { match = checkSet[elem.sizset]; break; } if ( elem.nodeType === 1 ) { if ( !isXML ) { elem.sizcache = doneName; elem.sizset = i; } if ( typeof cur !== "string" ) { if ( elem === cur ) { match = true; break; } } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { match = elem; break; } } elem = elem[dir]; } checkSet[i] = match; } } } Sizzle.contains = document.documentElement.contains ? function(a, b){ return a !== b && (a.contains ? a.contains(b) : true); } : function(a, b){ return !!(a.compareDocumentPosition(b) & 16); }; Sizzle.isXML = function(elem){ // documentElement is verified for cases where it doesn't yet exist // (such as loading iframes in IE - #4833) var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; return documentElement ? documentElement.nodeName !== "HTML" : false; }; var posProcess = function(selector, context){ var tmpSet = [], later = "", match, root = context.nodeType ? [context] : context; // Position selectors must be done after the filter // And so must :not(positional) so we move all PSEUDOs to the end while ( (match = Expr.match.PSEUDO.exec( selector )) ) { later += match[0]; selector = selector.replace( Expr.match.PSEUDO, "" ); } selector = Expr.relative[selector] ? selector + "*" : selector; for ( var i = 0, l = root.length; i < l; i++ ) { Sizzle( selector, root[i], tmpSet ); } return Sizzle.filter( later, tmpSet ); }; // EXPOSE jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.filters; jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; })(); var runtil = /Until$/, rparentsprev = /^(?:parents|prevUntil|prevAll)/, // Note: This RegExp should be improved, or likely pulled from Sizzle rmultiselector = /,/, isSimple = /^.[^:#\[\.,]*$/, slice = Array.prototype.slice, POS = jQuery.expr.match.POS; jQuery.fn.extend({ find: function( selector ) { var ret = this.pushStack( "", "find", selector ), length = 0; for ( var i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique for ( var n = length; n < ret.length; n++ ) { for ( var r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; } } } } } return ret; }, has: function( target ) { var targets = jQuery( target ); return this.filter(function() { for ( var i = 0, l = targets.length; i < l; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { return true; } } }); }, not: function( selector ) { return this.pushStack( winnow(this, selector, false), "not", selector); }, filter: function( selector ) { return this.pushStack( winnow(this, selector, true), "filter", selector ); }, is: function( selector ) { return !!selector && jQuery.filter( selector, this ).length > 0; }, closest: function( selectors, context ) { var ret = [], i, l, cur = this[0]; if ( jQuery.isArray( selectors ) ) { var match, matches = {}, selector, level = 1; if ( cur && selectors.length ) { for ( i = 0, l = selectors.length; i < l; i++ ) { selector = selectors[i]; if ( !matches[selector] ) { matches[selector] = jQuery.expr.match.POS.test( selector ) ? jQuery( selector, context || this.context ) : selector; } } while ( cur && cur.ownerDocument && cur !== context ) { for ( selector in matches ) { match = matches[selector]; if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { ret.push({ selector: selector, elem: cur, level: level }); } } cur = cur.parentNode; level++; } } return ret; } var pos = POS.test( selectors ) ? jQuery( selectors, context || this.context ) : null; for ( i = 0, l = this.length; i < l; i++ ) { cur = this[i]; while ( cur ) { if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { ret.push( cur ); break; } else { cur = cur.parentNode; if ( !cur || !cur.ownerDocument || cur === context ) { break; } } } } ret = ret.length > 1 ? jQuery.unique(ret) : ret; return this.pushStack( ret, "closest", selectors ); }, // Determine the position of an element within // the matched set of elements index: function( elem ) { if ( !elem || typeof elem === "string" ) { return jQuery.inArray( this[0], // If it receives a string, the selector is used // If it receives nothing, the siblings are used elem ? jQuery( elem ) : this.parent().children() ); } // Locate the position of the desired element return jQuery.inArray( // If it receives a jQuery object, the first element is used elem.jquery ? elem[0] : elem, this ); }, add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context || this.context ) : jQuery.makeArray( selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? all : jQuery.unique( all ) ); }, andSelf: function() { return this.add( this.prevObject ); } }); // A painfully simple check to see if an element is disconnected // from a document (should be improved, where feasible). function isDisconnected( node ) { return !node || !node.parentNode || node.parentNode.nodeType === 11; } jQuery.each({ parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return jQuery.dir( elem, "parentNode" ); }, parentsUntil: function( elem, i, until ) { return jQuery.dir( elem, "parentNode", until ); }, next: function( elem ) { return jQuery.nth( elem, 2, "nextSibling" ); }, prev: function( elem ) { return jQuery.nth( elem, 2, "previousSibling" ); }, nextAll: function( elem ) { return jQuery.dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return jQuery.dir( elem, "previousSibling" ); }, nextUntil: function( elem, i, until ) { return jQuery.dir( elem, "nextSibling", until ); }, prevUntil: function( elem, i, until ) { return jQuery.dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return jQuery.sibling( elem.parentNode.firstChild, elem ); }, children: function( elem ) { return jQuery.sibling( elem.firstChild ); }, contents: function( elem ) { return jQuery.nodeName( elem, "iframe" ) ? elem.contentDocument || elem.contentWindow.document : jQuery.makeArray( elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var ret = jQuery.map( this, fn, until ); if ( !runtil.test( name ) ) { selector = until; } if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret ); } ret = this.length > 1 ? jQuery.unique( ret ) : ret; if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { ret = ret.reverse(); } return this.pushStack( ret, name, slice.call(arguments).join(",") ); }; }); jQuery.extend({ filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } return elems.length === 1 ? jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : jQuery.find.matches(expr, elems); }, dir: function( elem, dir, until ) { var matched = [], cur = elem[dir]; while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { if ( cur.nodeType === 1 ) { matched.push( cur ); } cur = cur[dir]; } return matched; }, nth: function( cur, result, dir, elem ) { result = result || 1; var num = 0; for ( ; cur; cur = cur[dir] ) { if ( cur.nodeType === 1 && ++num === result ) { break; } } return cur; }, sibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { r.push( n ); } } return r; } }); // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem, i ) { return (elem === qualifier) === keep; }); } else if ( typeof qualifier === "string" ) { var filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); if ( isSimple.test( qualifier ) ) { return jQuery.filter(qualifier, filtered, !keep); } else { qualifier = jQuery.filter( qualifier, filtered ); } } return jQuery.grep(elements, function( elem, i ) { return (jQuery.inArray( elem, qualifier ) >= 0) === keep; }); } var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rleadingWhitespace = /^\s+/, rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, rtagName = /<([\w:]+)/, rtbody = /\s]+\/)>/g, wrapMap = { option: [ 1, "" ], legend: [ 1, "
      ", "
      " ], thead: [ 1, "", "
      " ], tr: [ 2, "", "
      " ], td: [ 3, "", "
      " ], col: [ 2, "", "
      " ], area: [ 1, "", "" ], _default: [ 0, "", "" ] }; wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; // IE can't serialize and
      $T('webAuth') $T('opt-web_username'):
      $T('explain-web_username')


      $T('opt-web_password')
      $T('explain-web_password')
      $T('httpsSupport') $T('restartRequired')


      $T('explain-enable_https')

      $T('opt-https_port'):
      $T('explain-https_port')


      $T('opt-https_cert'):
      $T('explain-https_cert')


      $T('opt-https_key'):
      $T('explain-https_key')
      $T('tuning') $T('opt-refresh_rate'):
      $T('explain-refresh_rate')


      $T('opt-bandwidth_limit'):
      $T('explain-bandwidth_limit')


      $T('opt-cache_limitstr'):
      $T('explain-cache_limitstr')


      $T('opt-cleanup_list'):
      $T('explain-cleanup_list')