Mercurial > p > roundup > code
changeset 6638:e1588ae185dc issue2550923_computed_property
merge from default branch. Fix travis.ci so CI builds don't error out
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Thu, 21 Apr 2022 16:54:17 -0400 |
| parents | 85db90cc1705 (current diff) e657826186c6 (diff) |
| children | ca90f7270cd4 |
| files | CHANGES.txt doc/customizing.txt roundup/backends/rdbms_common.py roundup/cgi/templating.py roundup/hyperdb.py roundup/instance.py |
| diffstat | 78 files changed, 9417 insertions(+), 4633 deletions(-) [+] |
line wrap: on
line diff
--- a/.travis.yml Fri Oct 08 00:37:16 2021 -0400 +++ b/.travis.yml Thu Apr 21 16:54:17 2022 -0400 @@ -16,12 +16,13 @@ # - default # - maint-1.6 -dist: - - bionic +dist: focal +# - pypy3 python: - 2.7 - - 3.9-dev + - 3.10.0 + - 3.9 - 3.8 - 3.6 - nightly @@ -33,11 +34,12 @@ jobs: allow_failures: # nightly not ready for prime time yet. - python: nightly + - python: pypy3 addons: apt: - sources: - - sourceline: ppa:xapian-backports/ppa + #sources: + # - sourceline: ppa:xapian-backports/ppa packages: # Required to build/install the xapian-binding @@ -48,8 +50,12 @@ - gpgsm before_install: - # Sphinx required to build the xapian python bindings - - pip install sphinx==1.8.5 + - echo "$TRAVIS_PYTHON_VERSION" + # Sphinx required to build the xapian python bindings. Use 1.8.5 on + # older python and newest on newer. + - if [[ $TRAVIS_PYTHON_VERSION == "2."* ]]; then pip install sphinx==1.8.5; fi + - if [[ $TRAVIS_PYTHON_VERSION == '3.'* ]] ; then pip install sphinx; fi + - if [[ $TRAVIS_PYTHON_VERSION == "nightly" ]]; then pip install sphinx; fi - XAPIAN_VER=$(dpkg -l libxapian-dev | tail -n 1 | awk '{print $3}' | cut -d '-' -f 1) - cd /tmp - curl -s -O https://oligarchy.co.uk/xapian/$XAPIAN_VER/xapian-bindings-$XAPIAN_VER.tar.xz @@ -59,12 +65,13 @@ - if [[ $TRAVIS_PYTHON_VERSION == "2."* ]]; then ./configure --prefix=$VIRTUAL_ENV --with-python; fi - if [[ $TRAVIS_PYTHON_VERSION == "3."* ]]; then ./configure --prefix=$VIRTUAL_ENV --with-python3; fi - if [[ $TRAVIS_PYTHON_VERSION == "nightly" ]]; then ./configure --prefix=$VIRTUAL_ENV --with-python3; fi + - if [[ $TRAVIS_PYTHON_VERSION == "pypy3" ]]; then ./configure --prefix=$VIRTUAL_ENV --with-python3; fi - make && make install - PATH=$VIRTUAL_ENV/bin:$PATH # libgpg-error - - LIBGPG_ERROR_VERSION=1.32 + - LIBGPG_ERROR_VERSION=1.43 - cd /tmp - curl -s -O https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-$LIBGPG_ERROR_VERSION.tar.bz2 - tar -jxvf libgpg-error-$LIBGPG_ERROR_VERSION.tar.bz2 @@ -73,7 +80,7 @@ - make && make install # libassuan - - LIBASSUAN_VERSION=2.5.1 + - LIBASSUAN_VERSION=2.5.5 - cd /tmp - curl -s -O https://www.gnupg.org/ftp/gcrypt/libassuan/libassuan-$LIBASSUAN_VERSION.tar.bz2 - tar -jxvf libassuan-$LIBASSUAN_VERSION.tar.bz2 @@ -82,7 +89,7 @@ - make && make install # gpgme - - GPGME_VERSION=1.11.1 + - GPGME_VERSION=1.16.0 - cd /tmp - curl -s -O https://www.gnupg.org/ftp/gcrypt/gpgme/gpgme-$GPGME_VERSION.tar.bz2 - tar -jxf gpgme-$GPGME_VERSION.tar.bz2 @@ -100,24 +107,31 @@ - pip install gpg pytz whoosh pyjwt requests - pip install pytest-cov codecov - if [[ $TRAVIS_PYTHON_VERSION != "3.4"* ]]; then pip install docutils; fi - - if [[ $TRAVIS_PYTHON_VERSION != "3.4"* ]]; then pip install mistune; fi + - if [[ $TRAVIS_PYTHON_VERSION != "3.4"* ]]; then pip install mistune==0.8.4; fi - if [[ $TRAVIS_PYTHON_VERSION != "3.4"* && $TRAVIS_PYTHON_VERSION != "2."* ]]; then pip install Markdown; fi - pip install markdown2 - - pip install brotli zstd + - pip install brotli + # zstd fails to build under python nightly aborting test. + # allow testing to still happen if the optional package doesn't install. + - pip install zstd || true before_script: # set up mysql database - sudo sed -i -e '/^\[mysqld\]/,/^\[mysql/s/^max_allowed_packet.*/max_allowed_packet = 500M/' /etc/mysql/my.cnf - cat /etc/mysql/my.cnf - sudo service mysql restart - - mysql -u root -e 'GRANT ALL ON rounduptest.* TO rounduptest@localhost IDENTIFIED BY "rounduptest";' + - mysql -u root -e 'CREATE USER "rounduptest"@"localhost" IDENTIFIED WITH mysql_native_password BY "rounduptest"; GRANT ALL on rounduptest.* TO "rounduptest"@"localhost";' + # Disable fsync for speed, don't care about data durability when testing + - sudo sed -i -e '$a\fsync = off' /etc/postgresql/*/*/postgresql.conf - sudo service postgresql restart; sleep 30 # set up postgresql database - psql -c "CREATE ROLE rounduptest WITH CREATEDB LOGIN PASSWORD 'rounduptest';" -U postgres # HACK: workaround mysql bug: http://bugs.mysql.com/bug.php?id=74901 # needed for test_mysql.mysqlDBTest.testFilteringSpecialChars + # plus others. Otherwise we get: + # COLLATION 'utf8_bin' is not valid for CHARACTER SET 'utf8mb4' - sed -i 's/CREATE DATABASE \%s/CREATE DATABASE \%s COLLATE utf8_general_ci/' roundup/backends/back_mysql.py # build the .mo translation files and install them into a tree @@ -141,6 +155,7 @@ - if [[ "$TRAVIS_PYTHON_VERSION" == "2."* ]]; then py.test -v --maxfail=20 test/ --cov=roundup; fi + - ./setup.py build_doc after_success: - codecov
--- a/CHANGES.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/CHANGES.txt Thu Apr 21 16:54:17 2022 -0400 @@ -22,9 +22,62 @@ Previously it used to accept only TLS v1.1. 1.1 is deprecated by chrome. I don't expect this to be a major problem since a front end server (apache, Nginx...) is usually customer facing and - terminates SSL. + terminates SSL. (John Rouillard) - Fix hang when valid user without authorization for REST tries to use - the rest interface. + the rest interface. (John Rouillard) +- Remove Content-Type and make sure no content is returned by OPTIONS + request in REST interface. (John Rouillard) +- In write_html set the Content-Length when response is not + encoded/compressed. (John Rouillard) +- In REST interface do not raise UsageError for invalid api version. + Return json error with proper message. Fixes crash. (John Rouillard) +- In REST interface, allow extensions on URI less than 6 characters in + length. All other paths with a . in then will be passed through + without change. This allows items like a JWT to be passed as a path + element. (John Rouillard) +- issue2551167 - pip install in containerized environments puts + template and locale files under site-packages where roundup can't find + them. Change code to find them under site-packages. +- REST replace hard coded list of child endpoints for /rest/ with list + pulled from registered endpoints. So newly added endpoints are + shown. (John Rouillard) +- issue2551107 - Handle representation of long int in history params + for python3. Causes SyntaxError crash when showing history due to + long int e.g. 2345L. This is not a problem for roundup trackers + created using 1.2.0 or newer. The fix may have predated the 1.2.0 + release but where the fix actually landed (representing id as a + string and not as an int) is unknown. +- issue2551175 - Make ETag content-encoding aware. HTTP ETag headers + now include a suffix indicating the content-encoding used to send + the data per rfc7232. Properly validate any form of ETag suffixed or + non-suffixed for If-Match. +- issue2551178 - fix Traceback in Apache WSGI - during file upload +- issue2551179 - make roundup-demo initialize templates using + config_ini.ini overrides. Needed for jinja to set template lang etc. + Recognize minimal template when presented with a full + path. (John Kristensen (jerrykan) and John Rouillard) +- handle configparser.InterpolationSyntaxError raised if value + has a single %. Seems to afect python 3 only. Reported by + nomicon on IRC. (John Rouillard) +- add random delay to session database retry code between 0 and .125 + seconds. This seems to help reduce stalled connections when a + number of connections are made at the same time. Log remaining + retries once 5 of them have been used. (John Rouillard) +- issue2551169 - setup.py enters endless loop on gentoo linux python2 + installation. Fixed. +- issue2551185 - must set PYTHONPATH=... python2 setup.py install + --prefix=/tmp/r2. Force insert --old-and-unmangable to get it + to use a classic installer and not an easy install. This only + affects python2. +- issue2551186 - Python versions >= 3.3 no longer use socket.sslerror. + Andrew (kragacles) patched uses of socket.sslerror in mailgy.py. + Patch adapted to allow trapping sslerror under both python2 and 3. + (John Rouillard) +- issue2551142 - postgresql reworked to use savepoint/"rollback to" + rather than commit()/rollback(). Using savepoint should be faster. +- issue2551196 - Unset labelprop of a Multilink can lead to Python + error when using context/history. (reported and initial patch: Nagy + Gabor, John Rouillard) Features: @@ -42,6 +95,50 @@ responsive templates already have this feature. - issue2550917 - Add a: "Welcome user, you have logged in" ok_message on login. (Ashley Burke) +- enable HTTP/1.1 for roundup-server. This enables keep-alive for + faster response/loading. Also eliminates stalls when the front end web + server uses http 1.1 but the roundup-server uses 1.0. New option + "-V HTTP/1.0" can turn it off. (John Rouillard) +- issue2551163 - add scripts/Docker/Dockerfile to provide basic support for + containerization. See installation.txt for details. (John Rouillard) +- issue2551163 - add scripts/Docker/docker-compose.yml to get a + mysql/roundup deployment. (Norbert Schlemmer, modified by John + Rouilard) +- REST add openapi_doc decorator to add openapi_doc to + endpoints. Decorate a couple of examples. (John Rouillard) +- REST when incorrect method is used, report allowed methods in error + message as well as in an Allow header. (John Rouillard) +- REST change response to invalid attribute specified in path. Return + 400 code not 405 code for this case and improve error. (John + Rouillard) +- REST correct values for some Access-Control-Allow-Methods and + Access-Control-Allow-Headers headers. (John Rouillard) +- issue2550991 - define default cache control settings for javascript + and css assets. (John Rouillard) +- issue2551181 - fragments can be appended to designators. So + issue23#msg24 could jump to the element with id msg24 in issue 23. + Before this patch you would have two links issue23 and msg24 + separated by # (John Rouillard). +- added small utility script to dump dbm based tracker databases + (e.g. db/sessions). (John Rouillard) +- issue2551182 - Enhance configuration module to allow loading values + from an external file. Secrets (passwords, secrets) can specify + file using file:// or file:///. The first line of the file is used + as the secret. This allows committing config.ini to a VCS. (John + Rouillard) +- Added xapian indexer to Docker container. (John Rouillard) +- Add support for indexer type native-fts to use FTS5 for sqlite + databases. (John Rouillard) +- Add support for indexer type native-fts to use PostreSQL's full text + search. (John Rouillard) +- Add better error display to the user. Needed to expose errors in fts5 + search syntax to the user while also displaying the template page + structure. (John Rouillard) +- issue2551189 - increase size of words in full text index. + Many terms (like exception names or symbolic constants) are larger + than 25. Also German words are long. Since there is little chance of + fixing German to shorten their words, change indexer maxlength to 50. + (Thomas Arendsen Hein provided patch; patch reworked John Rouillard) 2021-07-13 2.1.0
--- a/doc/admin_guide.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/admin_guide.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,11 @@ +.. meta:: + :description language=en: + How to administer, backup, upgrade a Roundup installation. + System and user security, configuring web compression, + documentation on using roundup-server and running + roundup-admin. + + ==================== Administration Guide ==================== @@ -268,6 +276,175 @@ mechanism allows the admin to allow use of brotli and zstd for dynamic content, but not for static content. +Configuring native-fts Full Text Search +======================================= + +Roundup release 2.2.0 supports database-native full text search. +SQLite (minimum version 3.9.0) with FTS5 and PostgreSQL (minimum +version 11.0) with websearch_to_tsvector are supported. + +To enable this method, change the ``indexer`` setting in the tracker's +config.ini to ``native-fts``. Then reindex using ``roundup-admin -i +tracker_home reindex``. The amount of time it takes to reindex +depends on the amount of data in your tracker, the speed of your +disks, etc. It can take hours. + +SQLite details +-------------- + +The SQLite native-fts changes the full text search query a little bit. +For the other search methods, the search terms are split on white +space and each item in the index: a field (e.g. title), message +content and file content is searched for all the terms. If any term is +missing that item is ignored. Once the items are found they are mapped +to an issue and the normal issue index is displayed. + +When using FTS5, the search terms can use the full text search query +language described at: +https://www.sqlite.org/fts5.html#full_text_query_syntax. This +supports: + + * plain word search (joined with and similar to other search methods) + * phrase search with terms enclosed in quotes (``"``) + * proximity search with varying distances using ``NEAR()`` + * boolean operations by grouping with parentheses and using ``AND`` + and ``OR`` + * exclusion using ``NOT`` + * prefix searching by prefixing the term with``^`` + +All of the data that is indexed is in a single column, so when column +specifiers are used they usually result in an error which is detected +and an enhanced error message is produced. + +Unlike the native, xapian and whoosh indexers, there are no stopwords, +and there is no limit to the length of terms that are indexed. Keeping +these would break proximity and phrase searching. This may be helpful +or problematic for your particular tracker. + +To support the most languages available, the unicode61 tokenizer is +used without porter stemming. Using the ``indexer_language`` setting +to enable stemming for ``english`` is not available in this +implementation. Also ranking information is not used in this +implementation. These are areas for improvement. + +PostgreSQL info +--------------- + +The PostgreSQL native-fts changes the full text search query a little +bit. When using PostgreSQL full text search, two different query +languages are supported. + +1. websearch - described at the end of + `Parsing Queries`_ under websearch_to_tsquery. This is the default. + +2. tsquery - described at the beginning of `Parsing Queries`_ with + to_tsquery. It is enabled by starting the search phrase with ``ts:``. + +.. _Parsing Queries: \ + https://www.postgresql.org/docs/14/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES + +Websearch provides a more natural style of search and supports: + +* plain word search (stemmed in most cases) +* phrase search with terms enclosed in quotes (``"``) +* exclusion by prefixing a term/phrase with ``-`` +* alternative/or searching with ``or`` between terms +* ignores non-word characters including punctuation + +Tsquery supports: + +* a strict query syntax +* plain word search +* phrase search with the ``<->`` operator or enclosing the phrase in + ``'`` single quotes (note this will use a stemmer on the terms + in the phrase). +* proximity search with varying distances using ``<N>`` +* boolean operations by grouping with parentheses and using ``&`` + and ``|`` +* exclusion using ``!`` +* prefix searching using ``:*`` at the end of the prefix + +All of the data that is indexed is in a single column and input +weighing is not used. + +Depending on the FTS configuration (determined by the +``indexer_language`` setting), stopwords are supported. PostgreSQL +takes the stopwords into account when calculating the data needed for +proximity/near searches. Like SQLite FTS, there is no limit to the +length of terms that are indexed. Again this may be helpful or +problematic for your particular tracker. + +The config.ini ``indexer_language`` setting is used to define the +configuration used for indexing. For example with the default +``english`` setting a snowball stemmer (english_stem) is used. So +words like 'drive' and 'driving' and 'drive-in' will all match a +search for 'drive' but will not match 'driver'. + +The indexer_language is used as the configuration name for every call +to the text search functions (to_tsvector, to_tsquery). Changing this +requires reindexing. + +The `configuration list can be obtained using using psql's`_ +``\dF`` command. + +.. _configuration list can be obtained using using psql's: \ + https://www.postgresql.org/docs/current/textsearch-psql.html + +Roundup includes a hardcoded list for all languages supported by +PostgreSQL 14.1. The list includes 5 custom "languages" +``custom1`` ... ``custom5`` to allow you to set up your `own textsearch +configuration`_ using one of the custom names. Depending on your +PostgreSQL version, we may allow an invalid language to be configured. +You will see an error about ``text search configuration ... does not +exist``. + +.. _own textsearch configuration: \ + https://www.postgresql.org/docs/14/textsearch-configuration.html + +It may be possible to append to this list using the tracker's +interfaces.py. For details, see ``test/test_indexer.py`` in the +roundup distribution and search for ``valid_langs``. If you succeed +please email roundup-users AT lists.sourceforge.net with a description +of your success. + +After changing the configuration language, you must reindex the +tracker since the index must match the configuration language used for +querying. + +Also there are various `dictionaries`_ that allow you to: + + * add stopwords + * override stemming for a term + * add synonyms (e.g. a search for "pg" can also match 'psql' + "postgresql") + * add terms that expand/contract the search space (Thesaurus + dictionary) + * additional transforms + +.. _dictionaries: https://www.postgresql.org/docs/14/textsearch-dictionaries.html + +Use of these is beyond this documentation. Please visit the +appropriate PostgreSQL documents. The following my also be helpful: + +* http://rachbelaid.com/postgres-full-text-search-is-good-enough/ + +Ranking information is not used in this implementation. Also stop +words set in config.ini are ignored. These are areas for improvement. + +Cleaning up old native indexes +------------------------------ + +If you are happy with the database fts indexing, you can save some space by +removing the data from the native text indexing tables. This requires +using the ``sqlite3`` or ``psql`` commands to execute SQL to delete the +rows in the ``__textids`` and ``__words`` tables. You can do this with +the following SQL commands:: + + delete from __words; + delete from __textids; + +Note this deletes data from the tables and does *not* delete the +table. Users and Security ==================
--- a/doc/customizing.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/customizing.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,11 @@ +.. meta:: + :description language=en: + How to customize and extend the Roundup Issue + Tracker. Includes many cookbook and how-to + examples. Reference for the design and internals + needed to understand and extend the examples to meet + new needs. + :tocdepth: 2 =================== @@ -576,6 +584,71 @@ then the above ``db.config.detectors['QA_RECIPIENTS']`` will still work. +Unlike values in the tracker's main ``config.ini``, the values defined +in these config files are not validated. For example: a setting that +is supposed to be an integer value (e.g. 4) could be the word +"foo". If you are writing Python code that uses these settings, you +should expect to handle invalid values. + +Also, incorrect values aren't discovered until the config setting is +used. This can be long after the tracker is started and the error may +not be seen in the logs. + +It is possible to validate these settings. Validation involves calling +the ``update_options`` method on the configuration option. This can be +done from the ``init()`` function in the Python files implementing +extensions_ or detectors_. + +As an example, adding the following to an extension:: + + from roundup.configuration import SecretMandatoryOption + + def init(instance): + instance.config.ext.update_option('RECAPTCHA_SECRET', + SecretMandatoryOption,description="Secret securing reCaptcha.") + +similarly for a detector:: + + from roundup.configuration import MailAddressOption + + def init(db): + try: + db.config.detectors.update_option('QA_RECIPIENTS', + MailAddressOption, + description="Email used for QA comment followup.") + except KeyError: + # COMMENT_EMAIL setting is not found, but it's optional + # so continue + pass + +will allow reading the secret from a file or append the tracker domain +to an email address if it does not have a domain. + +Running ``roundup-admin -i tracker_home display user1`` will validate +the settings for both config.ini`s. Otherwise detector options are not +validated until the first request to the web interface (or email +gateway). + +There are 4 arguments for ``update_option``: + +1. config setting name - string (positional, mandatory) +2. option type - Option derived class from configuration.py + (positional, mandatory) +3. default value - string (optional, named default) +4. description - string (optional, named description) + +The first argument is the config setting name as described at the +beginning of this section. + +The second argument is a class in the roundup.configuration module. +There are a number of these classes: BooleanOption, +IntegerNumberOption, RegExpOption.... Please see the configuration +module for all Option validators and their descriptions. You can also +define your own custom validator in `interfaces.py`_. + +The third and fourth arguments are strings and are optional. They are +printed if there is an error and may help the user correct the problem. + .. index:: ! schema Tracker Schema @@ -2149,16 +2222,29 @@ 4. ``/@@file/`` +Two additional url's are used for the API's. +The `REST api`_ is accessed via: + +5. ``/rest/`` + +.. _`REST api`: rest.html + +and the `XMLRPC api`_ is available at: + +6. ``/rest/`` + +.. _`XMLRPC api`: xmlrpc.html + All other URLs depend on the classes configured in Roundup database. Each class receives two URLs - one for the class itself and another for specific items of that class. Example for class URL: -5. ``/issue`` +7. ``/issue`` This is usually used to show listings of class items. The URL for for specific object of issue class with id 1 will look like: -6. ``/issue1`` +8. ``/issue1`` Determining web context @@ -5866,12 +5952,19 @@ return check for cl in 'issue', 'file', 'msg': p = db.security.addPermission(name='View', klass=cl, - check=checker(cl)) + check=checker(cl), + description='User can view only if creator.') db.security.addPermissionToRole('User', p) p = db.security.addPermission(name='Edit', klass=cl, - check=checker(cl)) + check=checker(cl), + description='User can edit only if creator.') db.security.addPermissionToRole('User', p) db.security.addPermissionToRole('User', 'Create', cl) + # This allows the interface to get the names of the properties + # in the issue. Used for selecting sorting and grouping + # on the index page. + p = db.security.addPermission(name='Search', klass='issue') + db.security.addPermissionToRole ('User', p) Moderating user registration @@ -6228,3 +6321,4 @@ .. _`directions in the rest interface documentation`: rest.html#enabling-the-rest-api .. _`xmlrpc interface documentation`: xmlrpc.html#through-roundup .. _`zxcvbn`: https://github.com/dwolfhub/zxcvbn-python +
--- a/doc/features.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/features.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,9 @@ +.. meta:: + :description language=en: + Features of using the Roundup Issue Tracker. Describes + all access methods, configuration and workflow capabilities. + Links to detailed documentation. + ================ Roundup Features ================
--- a/doc/glossary.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/glossary.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,8 @@ +.. meta:: + :description language=en: + Definitions of terms used in the Roundup Issue Tracker + documentation. + ================ Roundup Glossary ================
--- a/doc/index.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/index.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,7 @@ +.. meta:: + :description language=en: + Table of contents for documentation on the Roundup Issue Tracker. + ======================================================= Roundup: an Issue-Tracking System for Knowledge Workers =======================================================
--- a/doc/installation.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/installation.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,10 @@ +.. meta:: + :description language=en: + Everything about installing the Roundup issue tracker web and + mail interfaces and configuring a tracker. How to download and + demonstrate Roundup using using command line or + Docker. Optional software that adds functionality to Roundup. + .. index:: Installation ================== @@ -5,7 +12,7 @@ ================== .. contents:: - :depth: 2 + :depth: 3 :local: @@ -42,15 +49,6 @@ installed for Roundup installation to work. Debian and derivatives, are known to require this. -If you are using the Roundup Windows installer on a 64 bit system and -you get the error message:: - - "No Python installation found in the registry" - -you need to install a 32 bit version of python. The 64 bit versions -use a different registry key that the installer doesn't detect. See: -https://issues.roundup-tracker.org/issue2550718 for details. - Optional Components =================== @@ -89,6 +87,8 @@ The Whoosh_ full-text indexer is also supported and will be used by default if it is available (and Xapian is not installed). This is recommended if you are anticipating a large number of issues (> 5000). + It is also the only search backend that implements fuzzy search. It + matches any word that has a 1 character difference from the search term. You may install Whoosh at any time, even after a tracker has been installed and used. You will need to run the "roundup-admin reindex" @@ -145,10 +145,12 @@ =============== .. note:: - Some systems, such as Debian and NetBSD, already have Roundup + Some systems, such as Gentoo and NetBSD, already have Roundup installed. Try running the command "roundup-admin" with no arguments, and if it runs you may skip the `Basic Installation Steps`_ below and go straight to `configuring your first tracker`_. + However they may install an old version, so you are probably + beter off installing it from the roundup web site or pypi. Download the latest version from https://www.roundup-tracker.org/. @@ -216,6 +218,152 @@ choose to do this, you may have to change Python's search path (sys.path) yourself. +Docker Support +~~~~~~~~~~~~~~ + +If you don't want to install it natively, you can create a Docker +container. This installs roundup using the `stand-alone web server`_ +method. This is an http only install so we suggest putting an https +terminating proxy in front of it. + +This is a work in progress and patches to improve it are welcome. You +can find the docker config files under the `scripts/Docker` directory +of the source tree. + +The dockerized Roundup includes database drivers for anydbm, sqlite, +MySQL and Postgresql (Postgresl is untested). It also includes +additional libraries that are listed in +`scripts/Docker/requirements.txt`. + +Email support is a work in progress. Outgoing email should work given +an external SMTP server. Reciving email should work by using a +scheduled (cron) job to access email: + +* `As a regular job using a mailbox source`_ +* `As a regular job using a POP source`_ +* `As a regular job using an IMAP source`_ + +Patches for better email support are welcome. + +If you want to use a MySQL backend, the `docker-compose.yml` file will +deploy a Roundup container and a MySQL container backend for use with +Roundup. + +Building a Docker Container +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To build a docker container using the code in the current directory, +run this build command from the top of the source tree:: + + docker build -t roundup-app -f scripts/Docker/Dockerfile . + +You can also build a container using the newest Roundup release on +PyPI, by running:: + + docker build -t roundup-app --build-arg="source=pypi" \ + -f scripts/Docker/Dockerfile . + +The docker declares a single volume mounted at +``/usr/src/app/tracker`` inside the container. You will mount your +tracker home directory at this location. + + +Configuring Roundup in the Container +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Once the docker is created using one of the build commands above, run +an interactive session it with:: + + docker run -it --rm -p 9017:8080 \ + -v $PWD/tracker:/usr/src/app/tracker roundup-app:latest + +The ``-v`` option maps a directory from the host into the docker +container. Note that uid 1000 is used by roundup. So the uid of the +directory (and all files under it) must be uid 1000. This example +assumes your tracker configs are in the tracker subdirectory. Replace +``$PWD/tracker`` with the full path name to the directory where the +tracker home(s) are to be stored. + +The ``-p`` option maps an external port (9017) to proxy the roundup +server running at port 8080 to the outside. + +If the tracker directory is empty, the docker container will prompt +you to install a tracker template and prompt you for the database +type. + +Then you need to configure the tracker by editing +``template/config.ini``. Make sure that the tracker web setting ends +in ``/issues/`` See `Configuring your first tracker` and the top of +``config.ini`` for other settings. + +Once you have configured the tracker, run another interactive session +with:: + + docker run --rm -it -p 9017:8080 \ + -v $PWD/tracker:/usr/src/app/tracker roundup-app:latest + +this will initialize the database and attempt to start the server. If +that is successful, use control-c to exit the server. + +Now start the server non-interactively (note no `-it` option) with:: + + docker run -p 9017:8080 \ + -v $PWD/tracker:/usr/src/app/tracker roundup-app:latest + +Your tracker will be available at: ``http://yourhost:9017/issues/``. + +If you need to access your container while the server is running you +can use:: + + docker exec -it c0d5 sh + +where ``c0d5`` is the id prefix for the running container obtained +from ``docker container ls``. + +If you add ``-e SHELL_DEBUG=1`` to the docker command, it sets the +``SHELL_DEBUG`` environment variable which will enable debugging +output from the startup script. + +Non-Guided Installation +''''''''''''''''''''''' + +If you got a tracker installed using the automatic setup above, you +can skip this section. To manually install and initialize the +trackers, you can get a shell without starting the roundup-server +using:: + + docker run -it \ + -v $PWD/tracker:/usr/src/app/tracker \ + --entrypoint sh roundup-app:latest + +Now you can configure your tracker using ``roundup-admin -i tracker`` +using the directions for `Configuring your first tracker`. + +Defining Multiple Trackers +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you want to run multiple trackers, create a subdirectory for each +tracker home under the volume mount point (``$PWD/tracker``). Then +invoke ``docker run`` passing the roundup-server tracker +specifications like:: + + docker run --rm -p 9017:8080 \ + -v /.../issue.tracker:/usr/src/app/tracker \ + roundup-app:latest tracker1=tracker/tracker1_home \ + tracker2=tracker/tracker2_home + +This will set up two trackers that can be reached at +``http://yourhost:9017/tracker1/`` and ``http://yourhost:9017/tracker2/``. +The arguments after roundup-app:latest are tracker paths that are +passed to roundup-server. + +Docker-compose Deployment +^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you want to run using the mysql backend, you can use docker-compose +with ``scripts/Docker/docker-compose.yml``. This will run Roundup and +MySQL in containers. Directions for building using docker-compose are +at the top of the yml file. Configuring your first tracker ------------------------------ @@ -362,6 +510,10 @@ Installed SQLite should be the latest version available (3.3.8 is known to work, 3.1.3 is known to have problems). + + Roundup supports using sqlite's full text search capability. This + can improve searching if you are not installing another indexer like + xapian or whoosh. It works best with English text. **postgresql** Backend for popular RDBMS PostgreSQL. You must read doc/postgresql.txt for additional installation steps and requirements. You must also configure @@ -388,14 +540,9 @@ There are multiple web interfaces to choose from: -1. `web server cgi-bin`_ -2. `cgi-bin for limited-access hosting`_ -3. `stand-alone web server`_ -4. `Zope product - ZRoundup`_ -5. `Apache HTTP Server with mod_wsgi`_ -6. `Apache HTTP Server with mod_python`_ (deprecated) -7. `Nginx HTTP Server`_ -8. `WSGI Variations`_ +.. contents:: + :depth: 1 + :local: You may need to give the web server user permission to access the tracker home - see the `UNIX environment steps`_ for information. You may also need to @@ -941,6 +1088,23 @@ } +FastCGI (Cherokee, Hiawatha, lighttpd) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Hiawatha and lighttpd web servers can run Roundup using FastCGI. +Cherokee can run FastCGI but it also supports wsgi directly using a +uWSGI, Gnuicorn etc. + +To run Roundup suing FastCGI, the flup_ package can be used under +Python 2 and Python 3. We don't have a detailed config for this, but +the basic idea can be found at: +https://flask.palletsprojects.com/en/2.0.x/deploying/fastcgi/ + +If you have deployed Roundup using FastCGI and flup we welcome example +configuration files and instructions. + +.. _flup: https://pypi.org/project/flup/ + WSGI Variations ~~~~~~~~~~~~~~~ @@ -1539,7 +1703,7 @@ ``-d`` option to allow database creation. Once you've unpacked roundup's source, if you have pytest installed, -run ``python -m pytest /test`` in the source directory and make sure +run ``python -m pytest test`` in the source directory and make sure there are no errors. If there are errors, please let us know! .. _`table of contents`: index.html
--- a/doc/overview.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/overview.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,9 @@ +.. meta:: + :description language=en: + Original proposal for the Roundup Issue Tracker. The problem + it solves, and guiding principles. Presents the + components of Roundup and how they interact. + ======================================================= Roundup: an Issue-Tracking System for Knowledge Workers =======================================================
--- a/doc/rest.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/rest.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,9 @@ +.. meta:: + :description language=en: + Documentation on the RESTful interface to the Roundup Issue + Tracker. + + .. index:: pair: api; Representational state transfer pair: api; rest @@ -227,7 +233,12 @@ ETag header or an @etag property. This needs to be submitted with ``DELETE``, ``PUT`` and ``PATCH`` operations on the item using an ``If-Match`` header or an ``"@etag`` property in the data payload if -the method supports a payload. +the method supports a payload. The ETag header value will include a +suffix (starting with '-') indicating the Content-Encoding used to +respond to the request. If the response was uncompressed, there will +be no suffix. The ``@etag`` property never includes the suffix. Any +ETag value suffixed or not can be sent in an ``If-Match`` header as +the suffix is ignored during comparison. The exact details of returned data is determined by the value of the ``@verbose`` query parameter. The various supported values and their @@ -708,8 +719,7 @@ /, you get a web page that includes metadata about the message. With the slash you get a text/plain (in most cases) data stream. -Also you can use the url: - +Also you can use the url: ``https://.../demo/rest/data/msg/11?@verbose=3`` and the content property (if the data is utf-8 compatible) now looks like:: @@ -1857,6 +1867,8 @@ @Routing.route("/jwt/issue", 'POST') @_data_decorator def generate_jwt(self, input): + """Create a JSON Web Token (jwt) + """ import jwt import datetime from roundup.anypy.strings import b2s @@ -1879,6 +1891,11 @@ else: raise Unauthorised(denialmsg) + # verify we have input data. + if not input: + raise UsageError("Missing data payload. " + "Verify Content-Type is sent") + # If we reach this point we have validated that the user has # logged in with a password using basic auth. all_roles = list(self.db.security.role.items()) @@ -1910,7 +1927,7 @@ newroles = [] if 'roles' in input: - for role in input['roles'].value: + for role in [ r.lower() for r in input['roles'].value ]: if role not in rolenames: raise UsageError("Role %s is not valid."%role) if role in user_roles:
--- a/doc/upgrading.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/upgrading.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,9 @@ +.. meta:: + :description language=en: + Critical documentation on how to upgrade the Roundup Issue + Tracker. Actions that must or can be taken when upgrading from + one version to another are documented here. + .. index:: Upgrading ====================================== @@ -29,10 +35,44 @@ Migrating from 2.1.0 to 2.x.y ============================= -Check Compression Settings --------------------------- - -Read the `administration guide`_ section on 'Configuring Compression'. +Rdbms version change from 6 to 7 (required) +------------------------------------------- + +This release includes two changes that require updates to the database +schema: + + 1. The size of words included in the Roundup FTS indexers have been + increased from 25 to 50. This requires changes to the database + columns used by the native indexer. This also affect the whoosh + and xapian indexers. + 2. Some databases that include native full-text search (native-fts + indexer) searching are now supported. + +You should run the ``roundup-admin migrate`` command for your +tracker once you've installed the latest codebase. + +Do this before you use the web, command-line or mail interface +and before any users access the tracker. + +If successful, this command will respond with either "Tracker +updated" (if you've not previously run it on an RDBMS backend) or +"No migration action required" (if you have run it, or have used +another interface to the tracker, or are using anydbm). + +See `below for directions on enabling native-fts`_. + +.. _below for directions on enabling native-fts: \ + #enhanced-full-text-search-optional + +The increase in indexed word length also affects whoosh and xapian +backends. You may want to run ``roundup-admin -i tracker_home +reindex`` if you want to index or search for longer words in your full +text searches. Re-indexing make take some time. + +Check compression settings (optional) +------------------------------------- + +Read the `administration guide`_ section on `Configuring Compression`_. Upgrade tracker's config.ini file. Use:: @@ -44,13 +84,102 @@ compression settings as you want. Then replace ``config.ini`` with the ``newconfig.ini`` file. -Search Added to User Index Page -------------------------------- +Search added to user index page (optional) +------------------------------------------ A search form and count of number of hits has been added to the ``user.index.html`` template page in the classic template. You may want to merge the search form and footer into your template. +Enhanced full-text search (optional) +------------------------------------ + +SQLite's `FTS5 full-text search engine`_ is available as is +`PostgreSQL's full text search`_. Both require a schema upgrade so you +should run:: + + roundup-admin -i tracker_home migrate + +to create FTS specific tables before restarting the roundup-web or +email interfaces. + +SQLite 3.9.0+ or PostgreSQL 11.0+ are required to use this feature. +When using SQLite, all full text search fields will allow searching +using the MATCH query format described at: +https://www.sqlite.org/fts5.html#full_text_query_syntax. When using +PostgreSQL either the websearch_to_tsquery or to_tsquery formats +described on +https://www.postgresql.org/docs/14/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES +can be used. The default is websearch. Prefixing the search with +``ts:`` enables tsquery mode. + +A list of words behaves almost the same as the default text search +(`native`). So the search string `fts search` will find all issues +that have both of those words (an AND search) in a text-field (like +title) or in a message (or file) attached to the issue. + +One thing to note is that native-fts searches do not ignore words +longer than 50 characters or less than 2 characters. Also SQLite does +not filter out common words (i.e. there is no stopword list). So words +like "and", "or", "then", "with" ... are included in the FTS5 search. + +You must explicitly enable this search mechanism by changing the +``indexer`` setting in ``config.ini`` to ``native-fts``. Native-fts +must be explicitly chosen. This is different from Xapian or Whoosh +indexers, which are chosen if they are installed in the Python +environment. This prevents the existing native indexing from being +discarded if ``indexer`` is not set. + +Next re-index your data with ``roundup-admin -i tracker_home +reindex``. This can take a while depending on the size of the tracker. + +You may want to update your ``config.ini`` by following the directions +above to get the latest documentation. + +See the `administration guide notes on native-fts`_ for further details. + +Adding error reporting templates (optional) +------------------------------------------- + +Currently some internal errors result in a bare html page with an +error message. The usual chrome supplied by page.html is not shown. +For example query language syntax errors for full text search methods +will display a bare HTML error page. + +If you add an ``_generic.400.html`` template to the html directory, you +can display the error inside of the layout provided by the ``page.html`` +template. This can make fixing the error and navigation easier. You +can use the ``_generic.404.html`` template to create a +``_generic.400.html`` by modifying the title and body text. You can test +the 400 template by appending ``@template=400`` to the url for the +tracker. + +Change passwords using crypt module (optional) +---------------------------------------------- + +The crypt module is being removed from the standard library. Any +stored password using crypt encoding will fail to verify once the +crypt module is removed (expected in Python 3.13 see +pep-0594). Automatic migration of passwords (if enabled in config.ini) +re-encrypts old passwords using something other than crypt if a user +logs in using the web interface. + +You can find users with passwords still encrypted using crypt by +running:: + + roundup-admin -i <tracker_home> table password,id,username + +Look for lines starting with ``{CRYPT}``. You can reset the user's +password using:: + + roundup-admin -i <tracker_home> + roundup> set user16 password=somenewpassword + +changing ``16`` to the id in the second column of the table output. +The example uses interactive mode (indicated by the ``roundup>`` +prompt). This prevents the new password from showing up in the output +of ps or shell history. The new password will be encrypted using the +default encryption method (usually pbkdf2). Migrating from 2.0.0 to 2.1.0 ============================= @@ -3264,3 +3393,7 @@ .. _`security documentation`: security.html .. _`administration guide`: admin_guide.html .. _`xmlrpc guide`: xmlrpc.html +.. _FTS5 full-text search engine: https://www.sqlite.org/fts5.html +.. _PostgreSQL's full text search: https://www.postgresql.org/docs/current/textsearch.html +.. _`administration guide notes on native-fts`: admin_guide.html#configuring-native-fts-full-text-search +.. _Configuring Compression: admin_guide.html#configuring-compression
--- a/doc/user_guide.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/user_guide.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,8 @@ +.. meta:: + :description language=en: + Describes how to interact with and use a tracker with the + Roundup Issue Tracker. + ========== User Guide ========== @@ -370,6 +375,24 @@ @filters=status,keyword& @columns=title,status,fixer +Full text search using the xapian, whoosh and native indexers treats +the search query as a series of space separated words. Any word less +than 2 characters or more than 50 characters is discarded. Also a +stoplist is used to remove common words like "with", "and" +etc. Additional stoplist words can be added in the tracker's +config.ini file. Once filtering of the word list is done, each indexed +item (e.g. title, file or message content ...) is searched and if all +the terms are found in the item the item is returned. Then the items +are mapped to an issue and the list of matching issues is generated. + +Other searching backends such as native-fts can be used in which case +the filtering above is not used. The search query can support +structure such as quoted phrases, matching one term or another rather +than both (or search), prefixes etc. In this case you should look at +the `documentation for configuring the native-fts`_ backend to find +the supported format and features. + +.. _`documentation for configuring the native-fts`: admin_guide.html#configuring-native-fts-full-text-search Access Controls ---------------
--- a/doc/xmlrpc.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/doc/xmlrpc.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,3 +1,8 @@ +.. meta:: + :description language=en: + Documentation on the XMLRPC interface to the Roundup Issue + Tracker. Includes sample clients. + .. index:: triple: api; xml; remote procedure call pair: api; xmlrpc
--- a/locale/GNUmakefile Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/GNUmakefile Thu Apr 21 16:54:17 2022 -0400 @@ -6,7 +6,7 @@ MSGFMT ?= msgfmt MSGMERGE ?= msgmerge XGETTEXT ?= xgettext -PYTHON ?= python +PYTHON ?= python3 TEMPLATE=roundup.pot @@ -22,10 +22,13 @@ help: @echo "$(MAKE) - build MO files. Run this before sdist" + @echo "$(MAKE) dist - same as above" @echo "$(MAKE) template - update message template from sources" + @echo "$(MAKE) diff - see template differences in vi" + @echo "$(MAKE) pytest - create locale files to run pytest" @echo "$(MAKE) locale.po - update message file from template" @echo "$(MAKE) locale.mo - compile individual message file" - @echo "$(MAKE) help - this text"\ + @echo "$(MAKE) help - this text" # This will rebuild all MO files without updating their corresponding PO # files first. Run before creating Roundup distribution (hence the name). @@ -37,7 +40,7 @@ done template: - test -d $(PYTHON_BUILD) || (echo "Missing build directory. ln -s lib to build library"; exit 1) + test -d $(PYTHON_BUILD) || (echo "Missing build directory $(PYTHON_BUILD). ln -s lib to build library"; exit 1) ${XPOT} -n -o $(TEMPLATE) $(SOURCES) ${RUN_PYTHON} ../roundup/cgi/TAL/talgettext.py -u $(TEMPLATE) \ @@ -50,7 +53,7 @@ --copyright-holder="See Roundup README.txt" \ -o $(TEMPLATE) $(SOURCES) -local_install: dist +pytest local_install: dist for file in $(MO_FILES); do \ lang=`basename $$file .mo`; \ mkdir -p locale/$$lang/LC_MESSAGES; \ @@ -59,7 +62,7 @@ # helps to check template file before check in diff: - svn diff roundup.pot|grep -v '^[-+]#'|vim -Rv - + hg diff roundup.pot|grep -v '^[-+]#'| vi -Rv - %.po: $(TEMPLATE) ${MSGMERGE} -U --suffix=.bak $@ $<
--- a/locale/de.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/de.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Roundup 1.5.0\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2016-04-11 09:13+0200\n" "Last-Translator: Tobias Herp <tobias.herp@gmx.de>\n" "Language-Team: German Translators <roundup-devel@lists.sourceforge.net>\n" @@ -30,19 +30,19 @@ msgid "You may not retire the admin or anonymous user" msgstr "Sie können den Administrator oder den Gast-Benutzer nicht löschen" -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "Die Klasse \"%(classname)s\" existiert nicht" # ../roundup/admin.py:93 :97 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "Der Parameter \"%(arg)s\" entspricht nicht dem Format Eigenschaft=Wert" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -51,7 +51,7 @@ "Problem: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -100,12 +100,12 @@ " roundup-admin help <Befehl> -- Hilfe zu einem Befehl anzeigen\n" " roundup-admin help all -- sämtliche Hilfen anzeigen\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "Befehle:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -113,7 +113,7 @@ "Befehle können abgekürzt werden, solange sie eindeutig bleiben, \n" "z.B. l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -239,12 +239,12 @@ "\n" "Befehlshilfe:\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s:" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -264,22 +264,22 @@ " all -- sämtlichen Hilfetext anzeigen\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "Zum Thema \"%(topic)s\" existiert leider kein Hilfetext" # ../roundup/admin.py:336 :382 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "Vorlagen:" # ../roundup/admin.py:339 :393 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "Datenbanken:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -334,23 +334,23 @@ # ../roundup/admin.py:358 :483 :562 :612 :682 :703 :731 :802 :869 :940 :988 # :1010 :1037 :1098 :1156 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "Zu wenig Parameter übergeben" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "Das angegebene Tracker-Verzeichnis \"%(parent)s\" existiert nicht" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -361,22 +361,22 @@ "installiert zu sein! Eine erneute Installation löscht sämtliche Daten!\n" "Wirklich löschen? Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "Vorlagensatz auswählen [classic]:" -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "Datenbank auswählen [anydbm]" -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "Fehler in der Konfiguration: \"%s\"" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, fuzzy, python-format msgid "" "\n" @@ -388,11 +388,11 @@ " Sie sollten nun die Konfigurationsdatei des Trackers bearbeiten:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... passen sie zumindest folgende Optionen an:" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -418,7 +418,7 @@ " Anschließend MÜSSEN Sie \"roundup-admin initialise\" ausführen.\n" "---------------------------------------------------------------------------\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 #, fuzzy msgid "" "Usage: genconfig <filename>\n" @@ -431,7 +431,7 @@ " Standardwerten in die Datei <filename>.\n" " " -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 #, fuzzy msgid "" "Usage: updateconfig <filename>\n" @@ -446,7 +446,7 @@ " " #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -464,23 +464,23 @@ " Die Funktion dbinit.init() wird aufgerufen\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "Administratorpasswort: " -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " Wiederholen: " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "Tracker-Verzeichnis existiert nicht" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "Tracker-Instanz wurde nicht installiert" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -490,7 +490,7 @@ "Eine erneute Initialisierung löscht sämtliche Daten!\n" "Wirklich löschen? Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -511,7 +511,7 @@ " " # ../roundup/admin.py:516 :531 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" @@ -519,21 +519,21 @@ "hier nicht ausgewertet." # ../roundup/admin.py:539 :951 :1000 :1022 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "" "Es existiert kein Eintrag der Klasse %(classname)s mit der ID \"%(nodeid)s\"" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "" "Die Eigenschaft \"%(propname)s\" ist für die Klasse \"%(classname)s\" nicht " "definiert" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -570,7 +570,7 @@ "(\"1,2,3\").\n" " " -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -592,20 +592,20 @@ " " # ../roundup/admin.py:631 :669 :822 :834 :888 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "Die Klasse \"%(classname)s\" hat keine Eigenschaft \"%(propname)s\"" # ../roundup/admin.py:631 :669 :822 :834 :888 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "Die Klasse \"%(classname)s\" hat keine Eigenschaft \"%(propname)s\"" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -623,7 +623,7 @@ " als ID oder als Bezeichner (\"msg23\") spezifiziert werden.\n" " " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -637,17 +637,17 @@ " Zeigt sämtliche Eigenschaften der Klasse auf.\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (Schlüsseleigenschaft)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -668,12 +668,12 @@ " gewählten Eintrags an.\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -691,31 +691,31 @@ " werden mit den Werten initialisiert\n" " " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (Passwort):" -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (Wiederholen):" -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "Bitte erneut versuchen..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "%(propname)s (%(proptype)s): " -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "Sie müssen einen Wert für \"%(propname)s\" angeben." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -746,16 +746,16 @@ "aufgelistet.\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "Sie haben zuviele Argumente übergeben" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "%(nodeid)4s: %(value)s" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -818,17 +818,17 @@ "\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "\"%(spec)s\" entspricht nicht dem Format Eigenschaft:Breite" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -843,7 +843,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -868,7 +868,7 @@ " geschrieben.\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -887,7 +887,7 @@ " verworfen.\n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -908,7 +908,7 @@ " kann zudem wiederverwendet werden.\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -928,14 +928,14 @@ " " # ../roundup/admin.py:539 :951 :1000 :1022 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "" "Es existiert kein Eintrag der Klasse %(classname)s mit der ID \"%(nodeid)s\"" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -964,7 +964,7 @@ " Exportverzeichnis geschrieben.\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -995,7 +995,7 @@ " Exportverzeichnis geschrieben.\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -1039,7 +1039,7 @@ " verbergen).\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -1047,7 +1047,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1086,11 +1086,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "Ungültiges Format" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1106,12 +1106,12 @@ " normalerweise automatisch.\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "Der Eintrag \"%(designator)s\" existiert nicht" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1123,48 +1123,48 @@ " Zeigt die Berechtigungen einer oder aller Rollen an.\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "Die Rolle \"%(role)s\" existiert nicht " -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "Neue Web-Benutzer erhalten die Rollen \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "Neue Web-Benutzer erhalten die Rolle \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "Neue E-Mail-Benutzer erhalten die Rollen \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "Neue E-Mail-Benutzer erhalten die Rolle \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "Rolle \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr "%(description)s (%(name)s einzig für \"%(klass)s\")" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" " %(description)s (%(name)s für \"%(klass)s\": ausschließlich %(properties)s)" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1172,17 +1172,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr "%(description)s (%(name)s einzig für \"%(klass)s\")" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 #, fuzzy msgid "" "Usage: migrate\n" @@ -1226,42 +1226,42 @@ " es nicht nötig ist; also gewöhnen Sie es sich einfach an.\n" " " -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 msgid "Tracker updated" msgstr "Tracker aktualisiert" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "Keine Migration notwendig" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "Der Befehl \"%(command)s\" existiert nicht (siehe \"help commands\")" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "Zur Abkürzung \"%(command)s\" passen mehrere Befehle: %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "Tracker-Verzeichnis: " # ../roundup/admin.py:1263 :1269 :1289 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "Fehler: %(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "Fehler: Die Tracker-Instanz konnte nicht geöffnet werden: %(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1270,34 +1270,34 @@ "Roundup %s ist bereit.\n" "Schreiben Sie \"help\", um zur Hilfe zu gelangen." -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "Bemerkung: Befehlsverlauf/-bearbeitung möglicherweise nicht verfügbar" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "roundup> " -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "beenden..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "Es gibt noch ungespeicherte Änderungen. Änderungen speichern (y/N)?" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "Konnte den Datenbanktyp nicht ermitteln" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, fuzzy, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " @@ -1306,7 +1306,7 @@ "Konnte die Datenbank nicht öffnen - das erforderliche Modul '%s' ist nicht " "verfügbar" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1322,53 +1322,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "Datenbank nur zum Lesen geöffnet" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "erstellt" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "Link gelöscht" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "verlinkt" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "geändert" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "verborgen" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "wiederhergestellt" @@ -1614,22 +1636,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "Ungültiger Benutzername" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "Sie sind nicht berechtigt, sich anzumelden" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, python-format msgid "You do not have permission to view %(class)s" msgstr "Sie sind nicht berechtigt, Einträge der Klasse \"%(class)s\" zu lesen" @@ -1735,154 +1762,154 @@ "Admistratoren wurden benachrichtigt.</p>\n" "</body></html>" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "Formular-Fehler: " -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "Zeichensatz nicht erkannt: %r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "Gast-Benutzer sind nicht berechtigt, das Web-Interface zu benutzen." -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, fuzzy, python-format -msgid "Invalid Origin %s" -msgstr "Ungültiger Benutzername" - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 +#, python-format +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format -msgid "Invalid HOST %s" -msgstr "Ungültige Anforderung" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +msgid "Invalid Origin %s" +msgstr "Ungültiger Benutzername" + +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, fuzzy, python-format +msgid "Invalid HOST %s" +msgstr "Ungültige Anforderung" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "Sie sind nicht berechtigt, diese Seite anzuzeigen." -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)sBenötigte Zeit: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " @@ -1891,6 +1918,13 @@ "%(starttag)sCache benutzt: %(cache_hits)d, verfehlt: %(cache_misses)d. " "Einträge laden: %(get_items)fs; filtern: %(filtering)fs.%(endtag)s\n" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1966,18 +2000,18 @@ msgstr "Eintrag speichern" #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[verborgen]" @@ -2003,18 +2037,24 @@ msgid "The linked class %(classname)s no longer exists" msgstr "Die verlinkte Klasse \"%(classname)s\" existiert nicht mehr" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:905 :926 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>Der verknüpfte Eintrag existiert nicht mehr</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (kein Wert)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" @@ -2023,46 +2063,46 @@ "<strong><em>Dieses Ereignis kann nicht im Verlauf angezeigt werden!</em></" "strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=\"4\"><strong>Bitte beachten:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "Verlauf" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>Datum</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "Verlauf" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>Datum</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>Benutzer</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>Aktion</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>Argumente</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "Kopie von %(class)s %(id)s" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "Nein" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "Ja" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -2070,19 +2110,19 @@ "Der voreingestellte Wert einer DateHTML-Eigenschaft muss entweder ein\n" "DateHTML-Objekt sein oder ein Datum repräsentieren." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "" "Versuch, das Attribut %(attr)s eines nicht vorhandenen Werts abzufragen" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "" "Versuch, das Attribut %(attr)s eines nicht vorhandenen Werts abzufragen" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- nichts ausgewählt -</option>" @@ -2100,11 +2140,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "Ungültige Anforderung" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "Ungültige Anforderung" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -2270,23 +2322,23 @@ msgid "\"%s\" not a node designator" msgstr "\"%s\" ist kein gültiger Bezeichner" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "Keine Eigenschaft: %s" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "Eigenschaft %s: %r ist kein %s." -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "Sie können für die Eigenschaft %s nur IDs eingeben" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "%r ist keine Eigenschaft von %s" @@ -2300,44 +2352,44 @@ "WARNUNG: Das Verzeichnis '%s'\n" "\tenthält Vorlagen im alten Format, die ignoriert werden." -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "Nachricht signiert mit unbekanntem Schlüssel: %s" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "Nachricht signiert mit abgelaufenem Schlüssel: %s" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "Nachricht signiert mit zurückgezogenem Schlüssel: %s" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "Ungültige PGP-Signatur festgestellt." -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "Neuer Kommentar" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "Unbekannte Version von multipart/encrypted." -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "Kann Ihre Nachricht nicht entschlüsseln" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "Keine PGP-Signatur in Nachricht gefunden" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -2345,7 +2397,7 @@ "\n" "Mails an Roundup müssen eine Subject-Zeile haben (Betreff)!\n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2374,7 +2426,7 @@ "\n" "Der Betreff war: '%(subject)s'\n" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -2390,7 +2442,7 @@ "Gültige Klassen sind: %(validname)s\n" "Die Betreffzeile war: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -2420,7 +2472,7 @@ "Die Betreffzeile (Subject) war:\n" " '%(subject)s'\n" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -2439,7 +2491,7 @@ "Die Betreffzeile (Subject) war:\n" " '%(subject)s'\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2455,7 +2507,7 @@ "Die Betreffzeile (Subject) war:\n" " '%(subject)s'\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -2468,21 +2520,21 @@ "\n" "Unbekannte Adresse: %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "Sie haben keinen Zugriff auf diesen Tracker." -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "Sie sind nicht berechtigt, die Klasse \"%(classname)s\" zu bearbeiten" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "Sie sind nicht berechtigt, ein \"%(classname)s\" zu erzeugen" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2497,7 +2549,7 @@ "\n" "Die Betreffzeile war: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 #, fuzzy msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" @@ -2505,7 +2557,7 @@ "Dieser Tracker wurde konfiguriert, E-Mail-Nachrichten nur PGP-signiert oder\n" "verschlüsselt entgegenzunehmen." -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" @@ -2515,16 +2567,16 @@ "Dieser Tracker wurde konfiguriert, E-Mail-Nachrichten nur PGP-signiert oder\n" "verschlüsselt entgegenzunehmen." -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "Sie sind nicht berechtigt, Dateien zu erzeugen." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "Sie sind nicht berechtigt, Dateien zu %(classname)s hinzuzufügen." -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2535,11 +2587,11 @@ "konnte\n" "keinen entsprechenden Teil (\"text/plain\") finden.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "Sie sind nicht berechtigt, Nachrichten zu erzeugen" -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2550,12 +2602,12 @@ "Die Mail-Nachricht wurde von einem Detektor zurückgewiesen.\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "Sie sind nicht berechtigt, Kommentare zu %(classname)s hinzuzufügen." -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" @@ -2563,7 +2615,7 @@ "%(classname)s\n" "zu bearbeiten." -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" @@ -2571,7 +2623,7 @@ "%(classname)s\n" "zu bearbeiten." -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2582,7 +2634,7 @@ "Es gab ein Problem mit Ihrer Nachricht:\n" " %(message)s\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2595,7 +2647,7 @@ "Sie sich an %(mailadmin)s und bitten Sie um Korrektur der\n" "fehlerhaften Klasse: %(current_class)s\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2608,22 +2660,39 @@ "Sie sich an %(mailadmin)s und bitten Sie um Korrektur der\n" "fehlerhaften Eigenschaften: %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "entspricht nicht der Form [arg=wert,wert,...;arg=wert,wert,...]" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "Ungültiger Benutzername" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2921,7 +2990,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "WARNUNG: erzeuge temporäres SSL-Zertifikat" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2929,56 +2998,56 @@ "<html><head><title>Roundup Tracker-Liste</title></head>\n" "<body><h1>Roundup Tracker-Liste</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "" "WARNUNG: die Option \"-g\" wird ignoriert, da Sie nicht Administrator sind" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "Die Gruppe kann nicht gewechselt werden - das Modul grp fehlt" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "Die Gruppe %(group)s existiert nicht" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "" "Dieser Prozess kann nicht unter dem Administrator-Konto (\"root\") laufen!" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "" "WARNUNG: die Option \"-u\" wird ignoriert, da Sie nicht Administrator sind" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "Der Benutzer kann nicht gewechselt werden - das Modul pwd fehlt" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "Der Benutzer %(user)s existiert nicht" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" "Der Multiprozessmodus \"%s\" ist nicht verfügbar, Einprozessmodus aktiviert" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "Start des Servers auf Port %s schlug fehl. Port bereits verwendet." -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2994,7 +3063,7 @@ " Zudem müssen Sie die Logfile-Option aktivieren.\n" " \"roundup-server -c help\" zeigt eine weitere Hilfe zum Thema." -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -3008,9 +3077,10 @@ " die Prozess-ID in die Datei PIDDatei.\n" " Die Option -l muss dann auch angegeben werden." -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -3033,6 +3103,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -3124,21 +3197,21 @@ " URLs Probleme bereiten könnten. Am besten verwenden Sie nur Buchstaben, \n" " Zahlen und \"-_\".\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "Instanzen müssen als Tracker-Name=Tracker-Verzeichnis angegeben werden" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "Konfiguration in der Datei %s gespeichert" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "Auf diesem Betriebssystem kann der Server nicht als Hintergrundprozess laufen" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Der Roundup-Server wurde unter %(HOST)s:%(PORT)s gestartet" @@ -3277,6 +3350,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3293,6 +3367,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3309,6 +3384,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -4141,6 +4217,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4687,7 +4764,7 @@ msgid "User listing" msgstr "Benutzerliste" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4695,13 +4772,13 @@ msgid "Username" msgstr "Benutzername" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "Name" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4710,26 +4787,26 @@ msgid "Organisation" msgstr "Organisation" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "E-Mail-Adresse" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "Telefonnummer" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "Entfernen" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4885,67 +4962,67 @@ # priority translations: #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "Fehler (KRITISCH)" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "Fehler (dringend)" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "Fehler" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "Anforderung" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "Wunsch" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "ungelesen" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "zurückgestellt" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "in Diskussion" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "Beispiel erbeten" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "in Arbeit" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "im Test" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "erledigt (provisorisch)" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "erledigt"
--- a/locale/en.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/en.po Thu Apr 21 16:54:17 2022 -0400 @@ -11,7 +11,7 @@ msgstr "" "Project-Id-Version: Roundup 0.7.0\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2004-11-20 13:47+0200\n" "Language-Team: English\n" "Language: \n" @@ -28,25 +28,25 @@ msgid "You may not retire the admin or anonymous user" msgstr "" -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "" -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" "\n" msgstr "" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -74,17 +74,17 @@ " roundup-admin help all -- all available help\n" msgstr "" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 msgid "Commands: " msgstr "" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." msgstr "" -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -151,12 +151,12 @@ "Command help:\n" msgstr "" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -168,20 +168,20 @@ " " msgstr "" -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "" -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "" -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -207,23 +207,23 @@ " " msgstr "" -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -231,20 +231,20 @@ "Erase it? Y/N: " msgstr "" -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 msgid "Select template" msgstr "" -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 msgid "Select backend" msgstr "" -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -253,11 +253,11 @@ " %(config_file)s" msgstr "" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr "" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -274,7 +274,7 @@ "---------------------------------------------------------------------------\n" msgstr "" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 msgid "" "Usage: genconfig <filename>\n" " Generate a new tracker config file (ini style) with default\n" @@ -282,7 +282,7 @@ " " msgstr "" -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 msgid "" "Usage: updateconfig <filename>\n" " Generate an updated tracker config file (ini style) in\n" @@ -292,7 +292,7 @@ msgstr "" #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -303,30 +303,30 @@ " " msgstr "" -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "" -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr "" -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" "Erase it? Y/N: " msgstr "" -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 msgid "" "Usage: get property designator[,designator]*\n" " Get the given property of one or more designator(s).\n" @@ -339,23 +339,23 @@ " " msgstr "" -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 msgid "" "Usage: set items property=value property=value ...\n" " Set the given properties of one or more items(s).\n" @@ -376,7 +376,7 @@ " " msgstr "" -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 msgid "" "Usage: filter classname propname=value ...\n" " Find the nodes of the given class with a given property value.\n" @@ -389,19 +389,19 @@ " " msgstr "" -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "" -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -412,7 +412,7 @@ " " msgstr "" -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -421,17 +421,17 @@ " " msgstr "" -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, python-format msgid "%(key)s: %(value)s\n" msgstr "" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 msgid "" "Usage: display designator[,designator]*\n" "\n" @@ -445,12 +445,12 @@ " " msgstr "" -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -462,31 +462,31 @@ " " msgstr "" -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "" -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr "" -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "" -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "" -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "" -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -502,16 +502,16 @@ " " msgstr "" -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -543,17 +543,17 @@ " " msgstr "" -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -568,7 +568,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -582,7 +582,7 @@ " " msgstr "" -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -594,7 +594,7 @@ " " msgstr "" -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 msgid "" "Usage: retire designator[,designator]*\n" " Retire the node specified by designator.\n" @@ -607,7 +607,7 @@ " " msgstr "" -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 msgid "" "Usage: restore designator[,designator]*\n" " Restore the retired node specified by designator.\n" @@ -619,12 +619,12 @@ " " msgstr "" -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -640,7 +640,7 @@ " " msgstr "" -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -657,7 +657,7 @@ " " msgstr "" -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -680,7 +680,7 @@ " " msgstr "" -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -688,7 +688,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -710,11 +710,11 @@ " " msgstr "" -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -724,12 +724,12 @@ " " msgstr "" -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 msgid "" "Usage: security [Role name]\n" "\n" @@ -737,46 +737,46 @@ " " msgstr "" -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, python-format msgid "No such Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, python-format msgid "Role \"%(name)s\":\n" msgstr "" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr "" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -784,17 +784,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr "" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, python-format msgid " %(description)s (%(name)s)\n" msgstr "" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -818,82 +818,82 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 msgid "Tracker updated" msgstr "" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "" -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" "Type \"help\" for help." msgstr "" -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "" -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "" -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -907,53 +907,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "" @@ -1182,22 +1204,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, python-format msgid "You do not have permission to view %(class)s" msgstr "" @@ -1281,160 +1308,167 @@ "</body></html>" msgstr "" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "" -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, python-format -msgid "Invalid Origin %s" -msgstr "" - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 +#, python-format +msgid "Invalid Origin %s" +msgstr "" + +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "" -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " "items: %(get_items)f secs. Filtering: %(filtering)f secs.%(endtag)s\n" msgstr "" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1500,18 +1534,18 @@ msgstr "" #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "" @@ -1537,79 +1571,85 @@ msgid "The linked class %(classname)s no longer exists" msgstr "" -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" "strong>" msgstr "" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "" - #: ../roundup/cgi/templating.py:1379 -msgid "<th>User</th>" -msgstr "" - -#: ../roundup/cgi/templating.py:1380 -msgid "<th>Action</th>" +msgid "History" msgstr "" #: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "" + +#: ../roundup/cgi/templating.py:1382 +msgid "<th>User</th>" +msgstr "" + +#: ../roundup/cgi/templating.py:1383 +msgid "<th>Action</th>" +msgstr "" + +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." msgstr "" -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "" @@ -1627,10 +1667,21 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 msgid "Valid languages: " msgstr "" +#: ../roundup/configuration.py:504 +msgid "Expected languages: " +msgstr "" + #: ../roundup/date.py:395 #, python-format msgid "" @@ -1789,23 +1840,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -1817,49 +1868,49 @@ "\tcontains old-style template - ignored" msgstr "" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 msgid "Unsigned Message" msgstr "" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" msgstr "" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -1876,7 +1927,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -1887,7 +1938,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -1904,7 +1955,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -1915,7 +1966,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -1925,7 +1976,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -1934,21 +1985,21 @@ "Unknown address: %(from_address)s\n" msgstr "" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "" -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -1958,38 +2009,38 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "" -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" "not find a text/plain part to use.\n" msgstr "" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "" -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -1997,22 +2048,22 @@ "%(error)s\n" msgstr "" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2020,7 +2071,7 @@ " %(message)s\n" msgstr "" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, python-format msgid "" "\n" @@ -2029,7 +2080,7 @@ " %(clsname)s\n" msgstr "" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2038,22 +2089,39 @@ " %(errors)s\n" msgstr "" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, python-format +msgid "Invalid attribute %s" +msgstr "" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2273,58 +2341,58 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, python-format msgid "Error: %(type)s: %(value)s" msgstr "" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "" -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2334,7 +2402,7 @@ " specifics." msgstr "" -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2343,9 +2411,10 @@ " specified if -d is used." msgstr "" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2368,6 +2437,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -2406,20 +2478,20 @@ " any url-unsafe characters like spaces, as these confuse IE.\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "" @@ -2551,6 +2623,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -2567,6 +2640,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -2583,6 +2657,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -3398,6 +3473,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -3931,7 +4007,7 @@ msgid "User listing" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -3939,13 +4015,13 @@ msgid "Username" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -3954,26 +4030,26 @@ msgid "Organisation" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4122,67 +4198,67 @@ msgstr "" #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr ""
--- a/locale/es.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/es.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Roundup 1.3.3\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 10:45+0100\n" "Last-Translator: Ramiro Morales <rm0@gmx.net>\n" "Language-Team: Spanish Translators <roundup-devel@lists.sourceforge.net>\n" @@ -29,19 +29,19 @@ msgstr "Ni el usuario admin ni el usuario anónimo pueden ser retirados" # ../roundup/admin.py:85 :955 :1004 :1026 -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "la clase \"%(classname)s\" no existe" # ../roundup/admin.py:95 :99 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "el argumento \"%(arg)s\" no es de la forma nombrepropiedad=valor" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -50,7 +50,7 @@ "Problema: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -106,12 +106,12 @@ " roundup-admin help <comando> -- ayuda específica a un comando\n" " roundup-admin help all -- toda la ayuda disponible\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "Comandos:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -119,7 +119,7 @@ "Los comandos pueden ser abreviados siempre y cuando la abreviación\n" "coincida con sólo un comando, ej. l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -264,12 +264,12 @@ "\n" "Ayuda sobre comandos:\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s:" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -289,22 +289,22 @@ " all -- toda la ayuda disponible\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "Lo siento, no hay ayuda para \"%(topic)s\"" # ../roundup/admin.py:338 :387 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "Plantillas:" # ../roundup/admin.py:341 :398 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "Motor de almacenamiento" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -362,25 +362,25 @@ # ../roundup/admin.py:360 :442 :503 :582 :632 :688 :709 :737 :808 :875 :946 # :994 :1016 :1043 :1106 :1173 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "No se proveyó una cantidad suficiente de argumentos" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "" "El directorio padre \"%(parent)s\" del directorio base de la instancia no " "existe" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -391,22 +391,22 @@ "Si Ud. lo reinstala, perderá toda la información relacionada al mismo!\n" "Elimino la misma? Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "Seleccione la plantilla [classic]: " -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "Selecccione el motor de almacenamiento [anydbm]: " -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "Error en opciones de configuración: \"%s\"" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -419,11 +419,11 @@ " Ud. debe ahora editar el fichero de configuración del tracker:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... como mínimo, debe configurar las siguientes opciones:" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -451,7 +451,7 @@ " completado los pasos arriba descriptos.\n" "---------------------------------------------------------------------------\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 #, fuzzy msgid "" "Usage: genconfig <filename>\n" @@ -465,7 +465,7 @@ " con valores por defecto en el fichero <fichero>.\n" " " -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 #, fuzzy msgid "" "Usage: updateconfig <filename>\n" @@ -481,7 +481,7 @@ " " #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -500,23 +500,23 @@ " Ejecuta la función de inicialización dbinit.init() del tracker\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "Contraseña de administración: " -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " Confirmar: " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "El directorio base de la instancia no existe" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "La instancia no ha sido instalada" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -526,7 +526,7 @@ "Si la reinicializa, perderá toda la información!\n" "Eliminar la misma? Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -547,7 +547,7 @@ " " # ../roundup/admin.py:536 :551 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" @@ -555,18 +555,18 @@ "no puede usarse." # ../roundup/admin.py:559 :957 :1006 :1028 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "no existe nodo de clase %(classname)s llamado \"%(nodeid)s\"" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "no existe propiedad de clase %(classname)s llamado \"%(propname)s\"" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -601,7 +601,7 @@ " asociados como números separados por comas (\"1,2,3\").\n" " " -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -626,20 +626,20 @@ " " # ../roundup/admin.py:675 :828 :840 :894 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "%(classname)s no posee la propiedad \"%(propname)s\"" # ../roundup/admin.py:675 :828 :840 :894 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "%(classname)s no posee la propiedad \"%(propname)s\"" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -660,7 +660,7 @@ " enlazado o su valor clave.\n" " " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -674,17 +674,17 @@ " Visualiza las propiedades para una cierta clase.\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (propiedad de clave)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -705,12 +705,12 @@ "especificado.\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -729,31 +729,31 @@ " nombre=valor provistos en la línea de comandos luego del comando\n" " \"create\" para establecer valores de propiedad(es). " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (Contraseña): " -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (Nuevamente): " -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "Lo lamento, intente nuevamente..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "%(propname)s (%(proptype)s): " -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "debe proveer la propiedad \"%(propname)s\"." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -783,16 +783,16 @@ "clase.\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "Demasiados argumentos" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "%(nodeid)4s: %(value)s" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -856,17 +856,17 @@ " caracteres.\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "\"%(spec)s\" no es de la forma nombre:longitud" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -881,7 +881,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -906,7 +906,7 @@ " son automáticamente escritos si resultan exitosos.\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -928,7 +928,7 @@ " no introduciría cambios en la base de datos.\n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -949,7 +949,7 @@ " reusado.\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -969,13 +969,13 @@ " " # ../roundup/admin.py:559 :957 :1006 :1028 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "no existe nodo de clase %(classname)s llamado \"%(nodeid)s\"" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -1003,7 +1003,7 @@ " directorio de destino especificado (dir_exportación).\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -1032,7 +1032,7 @@ " directorio de destino especificado.\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -1077,7 +1077,7 @@ " tediosamente, retirar toda los datos viejos.)\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -1085,7 +1085,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1124,11 +1124,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "Formato inválido" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1144,12 +1144,12 @@ " Es un comando que por lo general se ejecuta automáticamente.\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "no existe un ítem llamado \"%(designator)s\"" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1161,49 +1161,49 @@ " Muestra los permisos disponibles para uno o todos los Roles.\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "No existe un Rol llamado \"%(role)s\"" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "Los nuevos usuarios creados vía Web obtiene los Roles \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "Los nuevos usuarios creados vía Web obtienen el Rol \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "" "Los nuevos usuarios creados vía e-mail obtienen los Roles \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "Los nuevos usuarios creados vía e-mail obtienen el Rol \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "Rol \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s para \"%(klass)s\" solamente)" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" " %(description)s (%(name)s para \"%(klass)s\": %(properties)s solamente)" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1211,17 +1211,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s para \"%(klass)s\" solamente)" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -1245,45 +1245,45 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 #, fuzzy msgid "Tracker updated" msgstr "Directorio base del tracker" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" "Comando desconocido \"%(command)s\" (tipee \"help commands\" para obtener " "una lista)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "Coinciden mas de un comando \"%(command)s\": %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "Ingrese directorio base del tracker: " # ../roundup/admin.py:1296 :1302 :1322 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "Error: %(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "Error: No se pudo abrir el tracker: %(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1292,41 +1292,41 @@ "Roundup %s listo para comandos.\n" "Tipee \"help\" para ayuda." -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "Nota: historia y edición de comandos no disponible" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "roundup> " -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "salir..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "Hay cambios sin guardar. Debo guardar los mismos (y/N)? " -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1340,53 +1340,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "crea" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "desenlaza" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "enlaza" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "asigna" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "retira" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "restaura" @@ -1629,23 +1651,28 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + # ../roundup/cgi/actions.py:891 :895 -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "nombre de usuario ó contraseña inválidos" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "Ud. no tiene permiso para ingresar al sistema" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, fuzzy, python-format msgid "You do not have permission to view %(class)s" msgstr "Ud. no posee los permisos necesarios para editar %(class)s" @@ -1750,155 +1777,155 @@ "p>\n" "</body></html>" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "Error de formulario" -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "Conjunto de caracteres desconocido: %r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "Los usuarios anonimos no tienen permitido usar esta interfaz Web" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 +#: ../roundup/cgi/client.py:1289 #, python-format msgid "Missing header: %s" msgstr "" -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 #, python-format msgid "csrf Referer header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1258 +#: ../roundup/cgi/client.py:1300 #, python-format msgid "Invalid Referer %s, %s" msgstr "" -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format msgid "csrf Origin header check failed for user%s. Value=%s" msgstr "" # ../roundup/cgi/actions.py:891 :895 -#: ../roundup/cgi/client.py:1274 +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format msgid "Invalid Origin %s" msgstr "nombre de usuario ó contraseña inválidos" -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 #, python-format msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1289 -#, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 -#, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 -#, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" -msgstr "" - #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "Ud. no tiene permitido ver este fichero" -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)sTiempo transcurrido: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " @@ -1907,6 +1934,13 @@ "%(starttag)sAciertos Cache: %(cache_hits)d, no aciertos %(cache_misses)d. " "Cargando items: %(get_items)f secs. Filtrado: %(filtering)f secs.%(endtag)s\n" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1986,18 +2020,18 @@ # ../roundup/cgi/templating.py:673 :792 :1166 :1187 :1231 :1253 :1287 :1326 # :1377 :1394 :1470 :1490 :1503 :1520 :1530 :1580 :1755 #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[oculto]" @@ -2023,18 +2057,24 @@ msgid "The linked class %(classname)s no longer exists" msgstr "La clase relacionada %(classname)s ya no existe" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:903 :924 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>El nodo relacionado ya no existe</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (sin valor)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" @@ -2043,46 +2083,46 @@ "<strong><em>Este evento no es soportado por la visualización de historia!</" "em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>Nota:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "Historia" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>Fecha</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "Historia" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>Fecha</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>Usuario</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>Acción</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>Args</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "Copia de %(class)s %(id)s" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "No" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "Si" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -2090,17 +2130,17 @@ "el valor por defecto para DateHTMLProperty debe ser un DateHTMLProperty o " "una cadena que represente una fecha." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "Se intentó buscar %(attr)s en un valor faltante" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "Se intentó buscar %(attr)s en un valor faltante" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- sin selección -</option>" @@ -2118,11 +2158,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "Formato inválido" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "Formato inválido" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -2289,23 +2341,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -2319,44 +2371,44 @@ "ATENCIÓN: El directorio '%s'\n" "\tcontiene una plantilla con el viejo formato - se ignorará" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "Nuevo mensaje" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -2364,7 +2416,7 @@ "\n" "Todos los e-mails enviados a trackers Roundup deben incluir un Asunto:!\n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2394,7 +2446,7 @@ "\n" "El asunto que Ud. envió es: '%(subject)s'\n" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -2411,7 +2463,7 @@ "Nombres válidos de clases son: %(validname)s\n" "El asunto que Ud. envió es: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -2441,7 +2493,7 @@ "\n" "El asunto que Ud. envió es: '%(subject)s'\n" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -2459,7 +2511,7 @@ "\n" "El asunto que Ud. envió es: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2474,7 +2526,7 @@ "\n" "El asunto que Ud. envió es: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -2487,21 +2539,21 @@ "\n" "Dirección desconocida: %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "Ud. no posee los permisos necesarios para acceder a este tracker." -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "Ud. no tiene permitido editar %(classname)s." -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "Ud. no tiene permitido crear %(classname)s." -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2517,27 +2569,27 @@ "\n" "El Asunto que Ud. envió es: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "Ud. no tiene permitida la creación de ficheros." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "Ud. no tiene permitido agregar ficheros a %(classname)s." -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2549,11 +2601,11 @@ "podido localizar una parte MIME text/plain en su mensaje que pueda ser " "usada.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "Ud. no tiene permitido crear mensajes." -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2564,26 +2616,26 @@ "El mensaje de e-mail ha sido rechazado por un detector.\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "Ud. no tiene permitido agregar mensajes a %(classname)s." -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" "Ud. no tiene permitido editar la propiedad %(prop)s de la clase " "%(classname)s." -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" "Ud. no tiene permitido editar la propiedad %(prop)s de la clase " "%(classname)s." -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2594,7 +2646,7 @@ "Ha habido un problema con el mensaje que envíó:\n" " %(message)s\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2608,7 +2660,7 @@ "incorrecta:\n" " %(current_class)s\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2622,22 +2674,40 @@ "incorrectas:\n" " %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "no es de la forma [arg=valor,valor,...;arg=valor,valor,...]" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +# ../roundup/cgi/actions.py:891 :895 +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "nombre de usuario ó contraseña inválidos" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2935,7 +3005,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "ATENCION: generando certificado SLL temporario" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2943,53 +3013,53 @@ "<html><head><title>Índice de trackers Roundup</title></head>\n" "<body><h1>Índice de trackers Roundup</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "ATENCIÓN: ignorando argumento \"-g\" , Ud. no es root" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "No puede cambiar grupos - el módulo grp no está presente" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "El grupo %(group)s no existe" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "No puede ejecutarse como root!" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "ATENCIÓN: ignorando argumento \"-u\", Ud. no es root" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "No puedo cambiar usuarios - no existe el módulo pwd" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "El usuario %(user)s no existe" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" "El modo multiproceso \"%s\" no está disponible, conmutado a proceso simple" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "Imposible asociarse al puerto %s, el mismo ya está en uso." -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -3011,7 +3081,7 @@ "para\n" " Servicios Web." -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -3026,9 +3096,10 @@ " PID del servidor en el fichero especificado por PIDfile.\n" " La opción -l *debe* ser especificada si se usa la opción -d." -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -3051,6 +3122,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -3155,22 +3229,22 @@ " caracteres tales como espacios, dado que los mismos confunden a Internet " "Explorer.\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "Las Instancias debe ser de la forma nombre=directorio base" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "Configuración guardada en %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "Lo siento, no puede ejecutar el servidor como un demonio en este Sistema " "Operativo" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "servidor Roundup iniciado en %(HOST)s:%(PORT)s" @@ -3308,6 +3382,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3324,6 +3399,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3340,6 +3416,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -4170,6 +4247,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4720,7 +4798,7 @@ msgid "User listing" msgstr "Listado de usuarios" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4728,13 +4806,13 @@ msgid "Username" msgstr "Nombre de usuario" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "Nombre real" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4743,26 +4821,26 @@ msgid "Organisation" msgstr "Organización" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "Dirección de e-mail" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "Nro. telefónico" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "Retirar" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4916,67 +4994,67 @@ # priority translations: #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "critical" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "urgent" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "bug" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "feature" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "wish" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "unread" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "deferred" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "chatting" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "need-eg" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "in-progress" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "testing" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "done-cbb" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "resuelto"
--- a/locale/fr.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/fr.po Thu Apr 21 16:54:17 2022 -0400 @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: Roundup 1.4.6\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:19+0100\n" "Last-Translator: Stephane Raimbault <stephane.raimbault@gmail.com>\n" "Language-Team: GNOME French Team <gnomefr@traduc.org>\n" @@ -33,20 +33,20 @@ # ../roundup/admin.py:85 :979 :1028 :1050 # ../roundup/admin.py:1052 ../roundup/admin.py:85:981 :1030:1052 -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "aucune classe nommée « %(classname)s »" # ../roundup/admin.py:95 :99 # ../roundup/admin.py:95 ../roundup/admin.py:99 ../roundup/admin.py:95:99 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "l'argument « %(arg)s » n'est pas au format nom-de-propriété=valeur" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -55,7 +55,7 @@ "Problème : %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -111,12 +111,12 @@ " roundup-admin help <commande> -- l'aide sur une commande\n" " roundup-admin help all -- toute l'aide disponible\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "Commandes :" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -125,7 +125,7 @@ "où l'abréviation ne correspond qu'à une seule commande,\n" "par ex. : l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -263,12 +263,12 @@ "\n" "Aide sur les commandes :\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s :" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -288,24 +288,24 @@ " all -- toute l'aide disponible\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "Désolé, aucune aide n'est disponible au sujet de « %(topic)s »" # ../roundup/admin.py:338 :394 # ../roundup/admin.py:340 ../roundup/admin.py:396 ../roundup/admin.py:340:396 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "Modèles :" # ../roundup/admin.py:341 :405 # ../roundup/admin.py:343 ../roundup/admin.py:407 ../roundup/admin.py:343:407 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "Moteurs de stockage :" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 #, fuzzy msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" @@ -364,23 +364,23 @@ # :1018 :1040 :1067 :1134 :1204 # ../roundup/admin.py:1207 ../roundup/admin.py:369:466 :1020:1042 :1069:1136 # :1207 :527:606 :656:714 :735:763 :834:901:972 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "Pas suffisamment d'arguments fournis" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "Le répertoire parent « %(parent)s » de l'instance de base n'existe pas" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -392,22 +392,22 @@ "Si vous le réinstallez, vous perdrez toutes les données !\n" "Supprimer le pisteur (Y/N) ? " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "Sélection du modèle [classic] : " -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "Sélection du moteur de stockage [anydbm]: " -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "Erreur dans les paramètres de la configuration : « %s »" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -420,11 +420,11 @@ " Vous devez maintenant modifier le fichier de configuration du pisteur :\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ou au minimum, vous devez définir les options suivantes :" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -456,7 +456,7 @@ " que vous avez réalisé les étapes précédentes.\n" "---------------------------------------------------------------------------\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 #, fuzzy msgid "" "Usage: genconfig <filename>\n" @@ -469,7 +469,7 @@ " (au format ini) avec des valeurs par défaut dans\n" " <nomfichier>" -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 #, fuzzy msgid "" "Usage: updateconfig <filename>\n" @@ -484,7 +484,7 @@ " <nomfichier>" #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -503,23 +503,23 @@ " Exécute la fonction d'initialisation dbinit.init() du pisteur.\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "Mot de passe administrateur : " -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " Confirmez : " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "Le répertoire racine de l'instance n'existe pas" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "L'instance n'a pas été installée" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -529,7 +529,7 @@ "Si vous la réinitialisez, vous perdrez toutes les données !\n" "Supprimez la base de données (Y/N) ? " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -551,7 +551,7 @@ # ../roundup/admin.py:558 :573 # ../roundup/admin.py:560 ../roundup/admin.py:575 ../roundup/admin.py:560:575 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" @@ -560,19 +560,19 @@ # ../roundup/admin.py:581 :981 :1030 :1052 # ../roundup/admin.py:1054 ../roundup/admin.py:583:983 :1032:1054 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "le noeud « %(nodeid)s » de classe « %(classname)s » n'existe pas" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "" "la propriété « %(propname)s » n'existe pas pour la classe « %(classname)s »" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -607,7 +607,7 @@ " ce lien sont indiqués comme des nombres séparés par des\n" " virgules (par ex. « 1,2,3 »)." -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -631,21 +631,21 @@ # ../roundup/admin.py:699 :852 :864 :918 # ../roundup/admin.py:920 ../roundup/admin.py:701:854 :866:920 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "%(classname)s n'a pas de propriété « %(propname)s »" # ../roundup/admin.py:699 :852 :864 :918 # ../roundup/admin.py:920 ../roundup/admin.py:701:854 :866:920 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "%(classname)s n'a pas de propriété « %(propname)s »" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -664,7 +664,7 @@ " noeud lié, ou sa valeur de clé.\n" " " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -678,17 +678,17 @@ " Cette commande énumère les propriétés de la classe nommée.\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s : %(value)s (propriété clé)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s : %(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -709,12 +709,12 @@ " des noeuds indiqués.\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s : %(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -734,31 +734,31 @@ " « create ».\n" " " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (mot de passe) : " -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (à nouveau) : " -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "Désolé, essayez à nouveau..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "%(propname)s (%(proptype)s) : " -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "vous devez renseigner la propriété « %(propname)s »." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -788,16 +788,16 @@ " propriété pour chaque instance de cette classe.\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "Trop d'arguments fournis" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "%(nodeid)4s : %(value)s" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -859,17 +859,17 @@ " donnera une colonne « Name » large de 4 caractères.\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "« %(spec)s » ne correspond pas au format « nom:largeur »" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -884,7 +884,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -909,7 +909,7 @@ " automatiquement validées si elles réussissent.\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -932,7 +932,7 @@ " base de données.\n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -953,7 +953,7 @@ " valeur de clé peut être ré-utilisée.\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -975,13 +975,13 @@ # ../roundup/admin.py:581 :981 :1030 :1052 # ../roundup/admin.py:1054 ../roundup/admin.py:583:983 :1032:1054 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "le noeud « %(nodeid)s » de classe « %(classname)s » n'existe pas" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 #, fuzzy msgid "" "Usage: export [[-]class[,class]] export_dir\n" @@ -1008,7 +1008,7 @@ " format aux valeurs séparées par des doubles-points.\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 #, fuzzy msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" @@ -1036,7 +1036,7 @@ " format aux valeurs séparées par des doubles-points.\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -1081,7 +1081,7 @@ " plus péniblement, « abandonnez » toutes les anciennes données).\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -1089,7 +1089,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1131,11 +1131,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "Format non valide" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1151,12 +1151,12 @@ " Cette opération est normalement effectuer automatiquement.\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "pas d'élément « %(designator)s »" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1168,48 +1168,48 @@ " Affiche les permissions disponible pour un ou plusieurs rôles.\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "Ce rôle « %(role)s » n'existe pas" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "Les nouveaux utilisateurs Web ont les rôles « %(role)s »" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "Les nouveaux utilisateurs Web ont le rôle « %(role)s »" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "Les nouveaux utilisateurs Courriel ont les rôles « %(role)s »" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "Les nouveaux utilisateurs Courriel ont le rôle « %(role)s »" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "Rôle « %(name)s » :" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s pour « %(klass)s » uniquement)" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" " %(description)s (%(name)s pour « %(klass)s » : %(properties)s uniquement)" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1217,17 +1217,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s pour « %(klass)s » uniquement)" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -1251,44 +1251,44 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 #, fuzzy msgid "Tracker updated" msgstr "Accueil de Tracker" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "Commande inconnue « %(command)s » (« help commands » pour la liste)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "Plusieurs commandes correspondent à « %(command)s » : %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "Saisissez le répertoire racine du pisteur : " # ../roundup/admin.py:1332 :1338 :1358 # ../roundup/admin.py:1335:1341:1361 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "Erreur : %(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "Erreur : impossible d'ouvrir le pisteur, %(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1297,41 +1297,41 @@ "Roundup %s est prêt pour la saisie.\n" "Saisissez « help » pour l'aide." -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "Note : l'historique et l'édition des commandes n'est pas disponible" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "roundup> " -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "sortie..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "Des changements n'ont pas été enregistrés, les valider (y/N) ?" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1345,53 +1345,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "créer" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "détacher" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "attacher" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "assigner" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "retiré" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "restauré" @@ -1640,24 +1662,29 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + # ../roundup/cgi/actions.py:930 :934 # ../roundup/cgi/actions.py:930:934 -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "Tentative de connexion non valide" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "Vous n'avez la permission de vous connecter" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, fuzzy, python-format msgid "You do not have permission to view %(class)s" msgstr "Vous n'avez pas la permission de modifier %(class)s" @@ -1763,157 +1790,157 @@ "Les administrateurs du pisteur ont été notifiés du problème.</p>\n" "</body></html>" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "Erreur de formulaire : " -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "Jeu de caractères non reconnu : %r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "" "Les utilisateurs anonymes ne sont pas autorisés à utiliser l'interface Web" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 +#: ../roundup/cgi/client.py:1289 #, python-format msgid "Missing header: %s" msgstr "" -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 #, python-format msgid "csrf Referer header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1258 +#: ../roundup/cgi/client.py:1300 #, python-format msgid "Invalid Referer %s, %s" msgstr "" -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format msgid "csrf Origin header check failed for user%s. Value=%s" msgstr "" # ../roundup/cgi/actions.py:930 :934 # ../roundup/cgi/actions.py:930:934 -#: ../roundup/cgi/client.py:1274 +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format msgid "Invalid Origin %s" msgstr "Tentative de connexion non valide" -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 #, python-format msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1289 -#, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 -#, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 -#, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" -msgstr "" - #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "Vous n'êtes pas autorisé à voir ce fichier" -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)sTemps écoulé: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " @@ -1923,6 +1950,13 @@ "Chargement d'éléments : %(get_items)f secondes. Filtrage : %(filtering)f " "secondes.%(endtag)s\n" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, fuzzy, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -2004,18 +2038,18 @@ # :1236:1257 :1304:1327 :1361:1400 :1453:1470 :1549:1569 :1587:1619 # :1629:1683 :1875 #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[masqué]" @@ -2041,19 +2075,25 @@ msgid "The linked class %(classname)s no longer exists" msgstr "La classe liée %(classname)s n'existe plus" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:940 :964 # ../roundup/cgi/templating.py:940:964 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>Le noeud lié n'existe plus</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s : (pas de valeur)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" @@ -2062,31 +2102,31 @@ "<strong><em>Cet évènement n'est pas géré par l'affichage de l'historique.</" "em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>Note :</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "Historique" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>Date</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "Historique" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>Date</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>Utilisateur</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>Action</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>Arguments</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "Copie de %(class)s %(id)s" @@ -2094,20 +2134,20 @@ # ../roundup/cgi/templating.py:1006 :1404 :1425 :1431 # ../roundup/cgi/templating.py:1431 ../roundup/cgi/templating.py:1006:1404 # :1425:1431 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "Non" # ../roundup/cgi/templating.py:1006 :1404 :1423 :1428 # ../roundup/cgi/templating.py:1428 ../roundup/cgi/templating.py:1006:1404 # :1423:1428 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "Oui" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -2115,17 +2155,17 @@ "la valeur par défaut pour DateHTMLProperty doit être soit DateHTMLProperty " "soit une représentation textuelle de la date." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "Tentative de recherche de %(attr)s sur une valeur manquante" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "Tentative de recherche de %(attr)s sur une valeur manquante" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- pas de sélection -</option>" @@ -2143,11 +2183,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "Format non valide" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "Format non valide" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -2314,23 +2366,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -2344,44 +2396,44 @@ "ATTENTION : le répertoire '%s'\n" "\tcontient des modèles obsolètes - ignoré" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "Nouveau message" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -2390,7 +2442,7 @@ "Les courriels envoyés au gestionnaire de ticket doivent comporter un " "sujet !\n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2420,7 +2472,7 @@ "\n" "Sujet original : '%(subject)s'\n" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, fuzzy, python-format msgid "" "\n" @@ -2437,7 +2489,7 @@ "Les noms de classes valides sont : %(validname)s\n" "Sujet original : « %(subject)s »\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, fuzzy, python-format msgid "" "\n" @@ -2467,7 +2519,7 @@ "\n" "Sujet original : '%(subject)s'\n" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, fuzzy, python-format msgid "" "\n" @@ -2485,7 +2537,7 @@ "\n" "Sujet original : « %(subject)s »\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2500,7 +2552,7 @@ "\n" "Sujet original : « %(subject)s »\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, fuzzy, python-format msgid "" "\n" @@ -2513,21 +2565,21 @@ "\n" "Addresse inconnue : %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "Vous n'êtes pas autorisé à accéder à ce pisteur." -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "Vous n'avez pas la permission de modifier %(classname)s" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "Vous n'avez pas la permission de créer %(classname)s" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2542,29 +2594,29 @@ "\n" "Le sujet était « %(subject)s »\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "Vous n'êtes pas autorisé à créer des fichiers." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "" "Vous n'avez pas la permission d'ajouter des fichiers à la classe " "%(classname)s." -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2575,11 +2627,11 @@ "trouvé\n" "de partie text/plain à utiliser.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "Vous n'avez pas la permission de créer des messages." -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2590,26 +2642,26 @@ "Le message a été rejeté par un détecteur.\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "Vous n'avez pas la permission d'ajouter des messages à %(classname)s." -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" "Vous n'avez pas la permission de modifier la propriété %(prop)s de la classe " "%(classname)s." -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" "Vous n'avez pas la permission de modifier la propriété %(prop)s de la classe " "%(classname)s." -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2620,7 +2672,7 @@ "Un problème a eu lieu à l'envoi de votre message :\n" " %(message)s\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2634,7 +2686,7 @@ "indiquée comme : \n" " %(current_class)s\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2648,22 +2700,41 @@ "corrigés :\n" " %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "pas de la forme [arg=value,value,...;arg=value,value,...]" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +# ../roundup/cgi/actions.py:930 :934 +# ../roundup/cgi/actions.py:930:934 +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "Tentative de connexion non valide" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2960,7 +3031,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2968,58 +3039,58 @@ "<html><head><title>Index des pisteurs Roundup</title></head>\n" "<body><h1>Index des pisteurs Roundup</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s : %(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "" "ATTENTION : le paramètre « -g » est ignoré, vous n'êtes pas superutilisateur " "(« root »)" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "Impossible de changer les groupes - le module grp n'est pas présent" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "Le groupe %(group)s n'existe pas" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "Impossible d'exécuter en tant que superutilisateur (\"root\")" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "" "ATTENTION: le paramètre \"-u\" est ignoré, vous n'êtes pas superutilisateur " "(\"root\")" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "" "Impossible de changer les utilisateurs - le module pwd n'est pas présent" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "L'utilisateur %(user)s n'existe pas" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" "Le mode multiprocessus \"%s\" n'existe pas, passage en mode processus unique" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "Impossible de s'attacher au port %s, le port est déjà utilisé" -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -3038,7 +3109,7 @@ " La commande « roundup-server -c help » donne les\n" " spécificités du service Windows." -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -3057,9 +3128,10 @@ "PID\n" " L'option -l option *doit* être spécifiée si -d est utilisé." -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -3082,6 +3154,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -3174,22 +3249,22 @@ " souhaité. Assurez-vous que « name » ne contienne pas de caractères\n" " inappropriés pour une URL, comme les espaces qui perturbe IE.\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "Les instances doivent être nom=base-du-pisteur" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "Configuration sauvegardée dans %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "Désolé, vous ne pouvez pas démarrer le serveur en tâche de fond avec ce " "système d'exploitation" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Le serveur Roundup est démarré sur %(HOST)s:%(PORT)s" @@ -3326,6 +3401,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3342,6 +3418,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3358,6 +3435,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -4193,6 +4271,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4745,7 +4824,7 @@ msgid "User listing" msgstr "Liste des utilisateurs" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4753,13 +4832,13 @@ msgid "Username" msgstr "Nom d'utilisateur" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "Nom réel" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4768,26 +4847,26 @@ msgid "Organisation" msgstr "Organisation" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "Adresse électronique" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "Numéro de téléphone" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "Retirer" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4941,68 +5020,68 @@ "dans le courriel." #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 #, fuzzy msgid "testing" msgstr "Liste des utilisateurs" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 #, fuzzy msgid "resolved" msgstr "non résolu"
--- a/locale/hu.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/hu.po Thu Apr 21 16:54:17 2022 -0400 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: Roundup 1.3.3\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:19+0100\n" "Last-Translator: kilo aka Gabor Kmetyko <kg_kilo@freemail.hu>\n" "Language-Team: Hungarian\n" @@ -30,26 +30,26 @@ msgstr "Az admin és anonymous felhasználókat nem lehet visszavonultatni" # ../roundup/admin.py:85 :981 :1030 :1052 -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "nincs \"%(classname)s\" osztály" # ../roundup/admin.py:95 :99 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "A(z) \"%(arg)s\" argumentum nem név=érték alakú" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" "\n" msgstr "Probléma: %(message)s\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -101,12 +101,12 @@ " roundup-admin help <command> -- parancs-specifikus segÃtség\n" " roundup-admin help all -- minden elérhetÅ‘ segÃtség\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "Parancsok:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -114,7 +114,7 @@ "A parancsok rövidÃthetÅ‘k mindaddig, amÃg csak egy parancsra illenek, pl. l " "== li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -181,12 +181,12 @@ "Command help:\n" msgstr "" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s:" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -206,22 +206,22 @@ " all -- minden elérhetÅ‘ segÃtség\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "Elnézést, \"%(topic)s\" témához nincs súgó" # ../roundup/admin.py:340 :396 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "Sablonok:" # ../roundup/admin.py:343 :407 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "Adatbázis hátterek:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -249,23 +249,23 @@ # ../roundup/admin.py:369 :466 :527 :606 :656 :714 :735 :763 :834 :901 :972 # :1020 :1042 :1069 :1136 :1207 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "Nincs megadva elég argumentum" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "Példány könyvtár szülÅ‘je (\"%(parent)s\") nem létezik" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -277,22 +277,22 @@ "Ha újra installálod, minden adat elveszik!\n" "Töröljem? Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "Sablon választása [classic]: " -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "Adatbázis háttér választása [anydbm]: " -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "Hiba a konfigurációs beállÃtásokban: \"%s\"" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -305,11 +305,11 @@ " Most kell szerkesztened a konfigurációs fájlt:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... legalább a következÅ‘ opciókat kell beállÃtani:" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -326,7 +326,7 @@ "---------------------------------------------------------------------------\n" msgstr "" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 #, fuzzy msgid "" "Usage: genconfig <filename>\n" @@ -340,7 +340,7 @@ " a <fájlnév> fájlba.\n" " " -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 #, fuzzy msgid "" "Usage: updateconfig <filename>\n" @@ -356,7 +356,7 @@ " " #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -374,23 +374,23 @@ " Végrehajtja az adatbázist inicializáló dbinit.init() rutint\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "Adminisztrátori jelszó: " -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " MegerÅ‘sÃtés " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "A példány könyvtára nem létezik" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "A példány nem lett installálva" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -400,7 +400,7 @@ "Újrainicializálás esetén minden adat elvész!\n" "Törli? Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -421,7 +421,7 @@ " " # ../roundup/admin.py:560 :575 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" @@ -429,18 +429,18 @@ "alkalmazható." # ../roundup/admin.py:583 :983 :1032 :1054 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "nincs \"%(nodeid)s\" %(classname)s csomópont" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "nincs \"%(propname)s\" %(classname)s tulajdonság" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 msgid "" "Usage: set items property=value property=value ...\n" " Set the given properties of one or more items(s).\n" @@ -461,7 +461,7 @@ " " msgstr "" -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 msgid "" "Usage: filter classname propname=value ...\n" " Find the nodes of the given class with a given property value.\n" @@ -475,20 +475,20 @@ msgstr "" # ../roundup/admin.py:701 :854 :866 :920 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "%(classname)s-nek nincs \"%(propname)s\" tulajdonsága" # ../roundup/admin.py:701 :854 :866 :920 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "%(classname)s-nek nincs \"%(propname)s\" tulajdonsága" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -499,7 +499,7 @@ " " msgstr "" -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -513,17 +513,17 @@ " Listázza az adott osztály tulajdonságait.\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (kulcs tulajdonság)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -544,12 +544,12 @@ " csomópont értékét.\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -561,31 +561,31 @@ " " msgstr "" -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (Jelszó): " -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (Ismét): " -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "Sajnálom, próbálja újra..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "%(propname)s (%(proptype)s): " -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "meg kell adni a(z) \"%(propname)s\" tulajdonságot." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -601,16 +601,16 @@ " " msgstr "" -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "Túl sok argumentum került megadásra" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "%(nodeid)4s: %(value)s" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -642,17 +642,17 @@ " " msgstr "" -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "\"%(spec)s\" nem név:hossz formátumú" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -667,7 +667,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -681,7 +681,7 @@ " " msgstr "" -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -693,7 +693,7 @@ " " msgstr "" -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 msgid "" "Usage: retire designator[,designator]*\n" " Retire the node specified by designator.\n" @@ -706,7 +706,7 @@ " " msgstr "" -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 msgid "" "Usage: restore designator[,designator]*\n" " Restore the retired node specified by designator.\n" @@ -719,13 +719,13 @@ msgstr "" # ../roundup/admin.py:583 :983 :1032 :1054 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "nincs \"%(nodeid)s\" %(classname)s csomópont" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -741,7 +741,7 @@ " " msgstr "" -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -758,7 +758,7 @@ " " msgstr "" -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -781,7 +781,7 @@ " " msgstr "" -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -789,7 +789,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -811,11 +811,11 @@ " " msgstr "" -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "Hibás formátum" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -825,12 +825,12 @@ " " msgstr "" -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "nincs ilyen elem: \"%(designator)s\"" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -842,47 +842,47 @@ " MegjelenÃti a megadott vagy az összes szerepkör jogosultságait.\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "Nincs ilyen szerepkör: \"%(role)s\"" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "Új web felhasználók ezeket a szerepköröket kapják: \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "Új web felhasználók ezt a szerepkört kapják \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "Új e-mail felhasználók ezeket a szerepköröket kapják: \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "Új e-mail felhasználók ezt a szerepkört kapják: \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "\"%(name)s\" szerepkör:" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -890,17 +890,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -924,46 +924,46 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 #, fuzzy msgid "Tracker updated" msgstr "HibakövetÅ‘" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" "\"%(command)s\": ismeretlen parancs (\"help commands\" parancsok " "listázásához)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "" "Több parancs is illeszkedik a megadott \"%(command)s\" parancsra: %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "Adja meg a hibakövetÅ‘ könyvtárát: " # ../roundup/admin.py:1335 :1341 :1361 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "Hiba: %(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "Hiba: HibakövetÅ‘ megnyitása sikertelen: %(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -972,41 +972,41 @@ "A Roundup %s fogadókész.\n" "SegÃtségért gépeljen \"help\"-et." -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "Megjegyzés: a parancsok története és szerkesztése nem elérhetÅ‘" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "roundup> " -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "kilépés..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "Vannak nem mentett változtatások. Elmenti Å‘ket (y/N)? " -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1024,53 +1024,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "létrehozás" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "törlés" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "kapcsolás" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "beállÃtás" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "visszavonult" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "visszaállÃtott" @@ -1309,23 +1331,28 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + # ../roundup/cgi/actions.py:930 :934 -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "Hibás bejelentkezés" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "Nincs jogosultsága bejelentkezni" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, fuzzy, python-format msgid "You do not have permission to view %(class)s" msgstr "Nincs jogosultsága szerkeszteni %(class)s-t" @@ -1423,155 +1450,155 @@ "A hibakövetÅ‘ karbantartói értesÃtést kaptak a problémáról.</p>\n" "</body></html>" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "Űrlap hiba: " -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "Ismeretlen karakterkészlet: %r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "Anonim felhasználók nem használhatják a webes felületet" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 +#: ../roundup/cgi/client.py:1289 #, python-format msgid "Missing header: %s" msgstr "" -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 #, python-format msgid "csrf Referer header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1258 +#: ../roundup/cgi/client.py:1300 #, python-format msgid "Invalid Referer %s, %s" msgstr "" -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format msgid "csrf Origin header check failed for user%s. Value=%s" msgstr "" # ../roundup/cgi/actions.py:930 :934 -#: ../roundup/cgi/client.py:1274 +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format msgid "Invalid Origin %s" msgstr "Hibás bejelentkezés" -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 #, python-format msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1289 -#, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 -#, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 -#, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" -msgstr "" - #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "Nem nézheti meg ezt a fájlt." -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)sEltelt idÅ‘: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " @@ -1580,6 +1607,13 @@ "%(starttag)sCache találatok: %(cache_hits)d, tévedés %(cache_misses)d. " "Elemek betöltése: %(get_items)f mp. Szűrés: %(filtering)f mp.%(endtag)s\n" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, fuzzy, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1656,18 +1690,18 @@ # ../roundup/cgi/templating.py:710 :829 :1236 :1257 :1304 :1327 :1361 :1400 # :1453 :1470 :1549 :1569 :1587 :1619 :1629 :1683 :1875 #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[rejtett]" @@ -1693,18 +1727,24 @@ msgid "The linked class %(classname)s no longer exists" msgstr "A csatolt %(classname)s osztály már nem létezik" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:940 :964 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>A csatolt bejegyzés már nem létezik</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (nincs érték)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" @@ -1712,48 +1752,48 @@ msgstr "" "<strong><em>Az elÅ‘zmények képernyÅ‘ nem kezeli ezt az eseményt!</em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>Megjegyzés:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "ElÅ‘zmények" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>Dátum</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "ElÅ‘zmények" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>Dátum</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>SzerzÅ‘</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>Művelet</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>Tulajdonságok</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "A(z) %(class)s %(id)s másolata" # ../roundup/cgi/templating.py:1006 :1404 :1425 :1431 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "Nem" # ../roundup/cgi/templating.py:1006 :1404 :1423 :1428 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "Igen" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -1761,17 +1801,17 @@ "a DateHTMLProperty alapértéke DateHTMLProperty vagy szöveges dátumleÃrás " "tÃpusú kell legyen." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "KÃsérlet %(attr)s keresésére egy hiányzó értéken" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "KÃsérlet %(attr)s keresésére egy hiányzó értéken" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- nincs kiválasztás -</option>" @@ -1789,11 +1829,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "Hibás formátum" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "Hibás formátum" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -1959,23 +2011,23 @@ msgstr "" # ../roundup/hyperdb.py:949:957 -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -1990,44 +2042,44 @@ "\trégi tÃpusú sablont tartalmaz - ignorálva" # ../roundup/mailgw.py:199:211 -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "Új üzenet" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -2036,7 +2088,7 @@ "A Roundup hibakövetÅ‘khöz küldött e-maileknek tartalmazniuk kell egy Subject: " "sort!\n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2053,7 +2105,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, fuzzy, python-format msgid "" "\n" @@ -2070,7 +2122,7 @@ "Az érvényes osztálynevek: %(validname)s\n" "A tárgy ez volt: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -2087,7 +2139,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, fuzzy, python-format msgid "" "\n" @@ -2105,7 +2157,7 @@ "\n" "A tárgy ez volt: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2120,7 +2172,7 @@ "\n" "A tárgy ez volt: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, fuzzy, python-format msgid "" "\n" @@ -2133,21 +2185,21 @@ "\n" "Ismeretlen cÃm: %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "Ehhez a hibakövetÅ‘höz hozzáférése nem engedélyezett." -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "Nincs jogosultsága %(classname)s szerkesztéséhez." -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "Nincs jogosultsága %(classname)s létrehozásához." -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2162,27 +2214,27 @@ "\n" "A tárgy ez volt: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "Nincs jogosultsága fájlok létrehozására." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "Nincs jogosultsága fájlok hozzáadására %(classname)s-hez." -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2192,11 +2244,11 @@ "A Roundup egyszerű szövegként tudja fogadni a kérelmet. Az üzenet értelmezÅ‘\n" "nem talált használható, egyszerű szöveg formátumú részt.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "Nincs jogosultsága üzenetek létrehozására." -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2207,24 +2259,24 @@ "A mail üzenetet a felderÃtÅ‘ visszutasÃtotta.\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "Nincs jogosultsága üzenet hozzáadására %(classname)s-hez." -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" "Nincs jogosultsága %(classname)s osztály %(prop)s tulajdonságát szerkeszteni." -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" "Nincs jogosultsága %(classname)s osztály %(prop)s tulajdonságát szerkeszteni." -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2235,7 +2287,7 @@ "Probléma volt az Ön által küldött üzenettel:\n" " %(message)s\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2248,7 +2300,7 @@ "%(mailadmin)s-nal és javÃttassa ki a hibásan megadott osztályt:\n" " %(current_class)s\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2261,22 +2313,40 @@ "%(mailadmin)s-nal és javÃttassa ki a hibás tulajdonságokat:\n" " %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "nem [arg=érték,érték,...;arg=érték,érték,...] formátumú" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +# ../roundup/cgi/actions.py:930 :934 +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "Hibás bejelentkezés" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2500,7 +2570,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2508,52 +2578,52 @@ "<html><head><title>Roundup hibakövetÅ‘k listája</title></head>\n" "<body><h1>Roundup hibakövetÅ‘k listája</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "FIGYELEM: \"-g\" opció figyelmen kÃvül hagyásra került, nem root" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "Nem lehet csoportot váltani - nincs meg a grp modul" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "%(group)s csoport nem létezik" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "Nem futhat root-ként!" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "FIGYELEM: \"-u\" opció figyelmen kÃvül hagyásra került, nem root" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "Felhasználóváltás nem sikerült - nincs pwd modul" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "A(z) %(user)s felhasználó nem létezik" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "\"%s\" többszálú mód nem érhetÅ‘ el, áttérés egyszálú módra" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "Nem sikerült a(z) %s portra csatlakozni, a port már használatban van." -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2563,7 +2633,7 @@ " specifics." msgstr "" -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2572,9 +2642,10 @@ " specified if -d is used." msgstr "" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2597,6 +2668,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -2635,21 +2709,21 @@ " any url-unsafe characters like spaces, as these confuse IE.\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "A példányoknak név=home formában kell lenniük" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "BeállÃtások elmentve ide: %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "Elnézést, ezen az operációs rendszeren a szerver nem indÃtható démonként" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Roundup server elindÃtva a(z) %(HOST)s:%(PORT)s gépen" @@ -2785,6 +2859,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -2801,6 +2876,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -2817,6 +2893,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -3638,6 +3715,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4184,7 +4262,7 @@ msgid "User listing" msgstr "Felhasználók listája" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4192,13 +4270,13 @@ msgid "Username" msgstr "Felhasználónév" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "Valódi név" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4207,26 +4285,26 @@ msgid "Organisation" msgstr "Szervezet" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "E-mail cÃm" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "Telefonszám" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "Visszavonulás" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4379,68 +4457,68 @@ # priority translations: #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "kritikus" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "sürgÅ‘s" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "hiba" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "szolgáltatás" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "óhaj" # status translations: #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "nem olvasott" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "elutasÃtva" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "megbeszélés" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "megerÅ‘sÃtésre vár" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "folyamatban" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "tesztelés" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "elkészült-lehetne jobb" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "megoldva"
--- a/locale/it.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/it.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: roundup cvs\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:20+0100\n" "Last-Translator: Marco Ghidinelli <marco.ghidinelli@ing.unibs.it>\n" "Language-Team: italian <it@li.org>\n" @@ -29,19 +29,19 @@ msgstr "Non è possibile ritirare l'utente amministratore o l'utente anonimo" # ../roundup/admin.py:1052 ../roundup/admin.py:85:981 :1030:1052 -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "classe \"%(classname)s\" mancante" # ../roundup/admin.py:95 ../roundup/admin.py:99 ../roundup/admin.py:95:99 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "argomento \"%(arg)s\" non nel formato nome=valore" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -50,7 +50,7 @@ "Problema: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -78,12 +78,12 @@ " roundup-admin help all -- all available help\n" msgstr "" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "Comandi:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -91,7 +91,7 @@ "I comandi possono essere abbreviati finchè l'abbreviazione rimane univoca\n" "es: l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -158,12 +158,12 @@ "Command help:\n" msgstr "" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s:" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -175,22 +175,22 @@ " " msgstr "" -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "Nessun aiuto per \"%(topic)s\"" # ../roundup/admin.py:340 ../roundup/admin.py:396 ../roundup/admin.py:340:396 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "Modelli predefiniti:" # ../roundup/admin.py:343 ../roundup/admin.py:407 ../roundup/admin.py:343:407 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "Back ends:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -218,23 +218,23 @@ # ../roundup/admin.py:1243 ../roundup/admin.py:369:466 :1020:1042 :1072:1171 # :1243 :527:606 :656:714 :735:763 :834:901 :972 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "Non sono stati forniti abbastanza argomenti" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "la directory radice dell'istanza \"%(parent)s\" non esiste" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -245,22 +245,22 @@ "Se verrà reinstallata, tutti i dati precedentemente salvati andranno persi\n" "Cancellare la directory specificata? Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "Seleziona il modello predefinito [classic]: " -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "Seleziona il backend [anydbm]: " -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "Erorre nei settaggi di configurazione: \"%s\"" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -269,11 +269,11 @@ " %(config_file)s" msgstr "" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... devono essere configurate almeno le seguenti opzioni:" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -290,7 +290,7 @@ "---------------------------------------------------------------------------\n" msgstr "" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 msgid "" "Usage: genconfig <filename>\n" " Generate a new tracker config file (ini style) with default\n" @@ -298,7 +298,7 @@ " " msgstr "" -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 msgid "" "Usage: updateconfig <filename>\n" " Generate an updated tracker config file (ini style) in\n" @@ -308,7 +308,7 @@ msgstr "" #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -319,30 +319,30 @@ " " msgstr "" -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "Password dell'amministratore" -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " Conferma: " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "La home dell'istanza non esiste" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "L'istanza non è stata installata" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" "Erase it? Y/N: " msgstr "" -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 msgid "" "Usage: get property designator[,designator]*\n" " Get the given property of one or more designator(s).\n" @@ -356,24 +356,24 @@ msgstr "" # ../roundup/admin.py:560 ../roundup/admin.py:575 ../roundup/admin.py:560:575 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" # ../roundup/admin.py:1054 ../roundup/admin.py:583:983 :1032:1054 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 msgid "" "Usage: set items property=value property=value ...\n" " Set the given properties of one or more items(s).\n" @@ -394,7 +394,7 @@ " " msgstr "" -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 msgid "" "Usage: filter classname propname=value ...\n" " Find the nodes of the given class with a given property value.\n" @@ -408,20 +408,20 @@ msgstr "" # ../roundup/admin.py:920 ../roundup/admin.py:701:854 :866:920 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "la classe %(classname)s non ha la proprietà \"%(propname)s\"" # ../roundup/admin.py:920 ../roundup/admin.py:701:854 :866:920 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "la classe %(classname)s non ha la proprietà \"%(propname)s\"" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -432,7 +432,7 @@ " " msgstr "" -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -441,17 +441,17 @@ " " msgstr "" -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s %(value)s (chiave)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s:·%(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 msgid "" "Usage: display designator[,designator]*\n" "\n" @@ -465,12 +465,12 @@ " " msgstr "" -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s:·%(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -482,31 +482,31 @@ " " msgstr "" -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s·(Password):·" -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (Ripeti password): " -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "Mi dispiace, riprova..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "%(propname)s (%(proptype)s): " -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "deve essere fornita la proprietà \"%(propname)s\"." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -522,16 +522,16 @@ " " msgstr "" -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -563,17 +563,17 @@ " " msgstr "" -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -588,7 +588,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -602,7 +602,7 @@ " " msgstr "" -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -614,7 +614,7 @@ " " msgstr "" -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 msgid "" "Usage: retire designator[,designator]*\n" " Retire the node specified by designator.\n" @@ -627,7 +627,7 @@ " " msgstr "" -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 msgid "" "Usage: restore designator[,designator]*\n" " Restore the retired node specified by designator.\n" @@ -640,13 +640,13 @@ msgstr "" # ../roundup/admin.py:1052 ../roundup/admin.py:85:981 :1030:1052 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "classe \"%(classname)s\" mancante" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -662,7 +662,7 @@ " " msgstr "" -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -679,7 +679,7 @@ " " msgstr "" -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -702,7 +702,7 @@ " " msgstr "" -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -710,7 +710,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -732,11 +732,11 @@ " " msgstr "" -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -746,12 +746,12 @@ " " msgstr "" -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 msgid "" "Usage: security [Role name]\n" "\n" @@ -759,46 +759,46 @@ " " msgstr "" -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "Non è presente il ruolo \"%(role)s\"" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "I nuovi utenti Web otterranno i ruoli \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "I nuovi utenti Web otterranno il ruolo \"%(role)s)\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "I nuovi utenti Email otterranno i ruoli \"%(role)s)\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "I nuovi utenti Email otterranno il ruolo \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "Ruolo \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr "" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -806,17 +806,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr "" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, python-format msgid " %(description)s (%(name)s)\n" msgstr "" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -840,83 +840,83 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 msgid "Tracker updated" msgstr "" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "" # ../roundup/admin.py:1371:1377 :1397 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" "Type \"help\" for help." msgstr "" -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "" -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "" -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -930,53 +930,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "crea" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "collega" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "scollega" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "assegna" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "ritira" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "ripristina" @@ -1218,23 +1240,28 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + # ../roundup/cgi/actions.py:931:935 -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "Login invalida" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "Non hai il permesso per eseguire la login" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, fuzzy, python-format msgid "You do not have permission to view %(class)s" msgstr "Non hai i permessi per modificare i %(class)s" @@ -1338,162 +1365,169 @@ "La notifica del problema è stata notificata al manutentore del tracker.</p>\n" "</body></html>" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "Errore nella Form: " -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "Codice di carattere sconosciuto: %r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "" "Gli utenti anonimi non hanno il permesso di utilizzare l'interfaccia web" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 +#: ../roundup/cgi/client.py:1289 #, python-format msgid "Missing header: %s" msgstr "" -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 #, python-format msgid "csrf Referer header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1258 +#: ../roundup/cgi/client.py:1300 #, python-format msgid "Invalid Referer %s, %s" msgstr "" -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format msgid "csrf Origin header check failed for user%s. Value=%s" msgstr "" # ../roundup/cgi/actions.py:931:935 -#: ../roundup/cgi/client.py:1274 +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format msgid "Invalid Origin %s" msgstr "Login invalida" -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 #, python-format msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1289 -#, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 -#, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 -#, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" -msgstr "" - #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "Non si dispone dei permessi per visualizzare questo file." -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)sTempo trascorso: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " "items: %(get_items)f secs. Filtering: %(filtering)f secs.%(endtag)s\n" msgstr "" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1570,18 +1604,18 @@ # ../roundup/cgi/templating.py:728:862 :1269:1298 :1318:1364 :1387:1423 # :1460:1513 :1530:1614 :1634:1652 :1684:1694 :1746:1935 #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[nascosto]" @@ -1607,18 +1641,24 @@ msgid "The linked class %(classname)s no longer exists" msgstr "La classe collegata %(classname)s non esiste più" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:973:997 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>Il Nodo collegato non esiste più</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (nessun valore)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" @@ -1627,50 +1667,50 @@ "<strong><em>Questo evento non è gestito dal visualizzatore dello storico!</" "em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>Note:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "Storico" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>Data</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "Storico" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>Data</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>Utente</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>Azione</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>Argomenti</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "Copia di %(class)s %(id)s" # ../roundup/cgi/templating.py:1491 ../roundup/cgi/templating.py:1039:1464 # :1485:1491 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "No" # ../roundup/cgi/templating.py:1488 ../roundup/cgi/templating.py:1039:1464 # :1483:1488 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "Sì" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -1678,17 +1718,17 @@ "Il valore predefinito per DateHTMLProperty deve essere DateHTMLProperty " "oppure una stringa rappresentante una data." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "Tentativo di visualizzare %(attr)s con un valore mancante" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "Tentativo di visualizzare %(attr)s con un valore mancante" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- nessuna selezione -</option>" @@ -1706,12 +1746,25 @@ msgid "Responding to form too quickly." msgstr "" +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + # ../roundup/cgi/actions.py:931:935 -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "Login invalida" +# ../roundup/cgi/actions.py:931:935 +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "Login invalida" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -1876,23 +1929,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -1906,44 +1959,44 @@ "ATTENZIONE: La directory '%s'\n" "\tcontene un template old-style - ignorato" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "Nuovo Messagggio" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -1951,7 +2004,7 @@ "\n" "Le Email al tracker Roundup devono includere il campo Oggetto: \n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -1978,7 +2031,7 @@ "\n" "Il campo \"Subject: \" (Oggetto) era: '%(subject)s'\n" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, fuzzy, python-format msgid "" "\n" @@ -1995,7 +2048,7 @@ "Classi valide sono: %(validname)s\n" "Il campo Subject: conteneva il valore \"%(subject)s\"\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, fuzzy, python-format msgid "" "\n" @@ -2022,7 +2075,7 @@ "\n" "Il campo \"Subject: \" (Oggetto) era: '%(subject)s'\n" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, fuzzy, python-format msgid "" "\n" @@ -2039,7 +2092,7 @@ "Subject precedente intatto.\n" "Il campo Subject: conteneva il valore \"%(subject)s\"\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2054,7 +2107,7 @@ "\n" "Il campo Subject: conteneva il valore \"%(subject)s\"\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, fuzzy, python-format msgid "" "\n" @@ -2067,21 +2120,21 @@ "\n" "Indirizzo sconosciuto: %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "Non si dispone di permessi sufficienti per accedere a questo tracker" -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "Non si dispone dei permessi sufficienti per modificare %(classname)s" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "Non si dispone dei permessi sufficienti per creare %(classname)s" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2096,28 +2149,28 @@ "\n" "Il Subject era: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "Non si dispone dei permessi necessari a creare file." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "" "Non si dispone dei permessi necessari per aggiungere file a %(classname)s" -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2127,11 +2180,11 @@ "Roundup richiede che i valori immessi siano in formato testo. Il parser dei " "messaggi non ha trovato alcuna parte text/plain da utilizzare.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "Non si disponde dei permessi necessari per creare messaggi." -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2142,26 +2195,26 @@ "La Mail è stata rifiutata da un detector.\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "Non si dispone dei permessi per aggiungere messaggi a %(classname)s" -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" "Non si dispone dei permessi necessari per modificare la proprietà %(prop)s " "della classe %(classname)s" -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" "Non si dispone dei permessi necessari per modificare la proprietà %(prop)s " "della classe %(classname)s" -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2172,7 +2225,7 @@ "Si è verificato un problema con il messaggio che hai inviato:\n" " %(message)s\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2185,7 +2238,7 @@ "%(mailadmin)s e segnala che la classe specificata come:\n" " %(current_class)s è scorretta.\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2198,22 +2251,40 @@ "%(mailadmin)s e segnala che la proprietà scorretta:\n" " %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "Non nel formato [arg=valore,valore,...;arg=valore,valore,...]" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +# ../roundup/cgi/actions.py:931:935 +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "Login invalida" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2446,7 +2517,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2454,54 +2525,54 @@ "<html><head><title>indice dei ticket Roundup</title></head>\n" "<body><h1>indice dei ticket Roundup</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s:·%(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "ATTENZIONE: ignoro il parametro \"-g\", non sei root" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "Non è possibile cambiare gruppo - nessun modulo grp" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "Il gruppo %(group)s non esiste" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "Non può essere eseguito come root!" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "Non è possibile cambiare utente - nessun modulo pwd" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "L'utente %(user)s non esiste" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" "La modalità multiprocesso \"%s\" non è disponibile, viene utilizzata quella " "a singolo processo" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "Impossibile bindare alla porta %s, la porta risulta già in uso." -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2511,7 +2582,7 @@ " specifics." msgstr "" -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2520,9 +2591,10 @@ " specified if -d is used." msgstr "" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2545,6 +2617,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -2583,22 +2658,22 @@ " any url-unsafe characters like spaces, as these confuse IE.\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "L'istanza deve essere nel formato nome=home" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "Configurazione salvata in %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "Spiacente, non è possibile utilizzare il server come demone su questo " "sistema operativo." -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Il server Roundup è stato attivato su %(HOST)s:%(PORT)s" @@ -2736,6 +2811,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -2752,6 +2828,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -2768,6 +2845,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -3595,6 +3673,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4140,7 +4219,7 @@ msgid "User listing" msgstr "Elenco Utenti" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4148,13 +4227,13 @@ msgid "Username" msgstr "Nome Utente" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "Nome Completo" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4163,26 +4242,26 @@ msgid "Organisation" msgstr "Organizzazione" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "Indirizzo di Email" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "Telefono" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "Dismetti" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4335,67 +4414,67 @@ "completare il processo di registrazione, visita il link indicato nella mail." #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "critico" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "urgente" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "bug" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr ""
--- a/locale/ja.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/ja.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Roundup 1.4.8\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:20+0100\n" "Last-Translator: Yasushi Iwata <iwata@know-net.co.jp>\n" "Language-Team: Yasushi Iwata <iwata@know-net.co.jp>\n" @@ -27,25 +27,25 @@ msgid "You may not retire the admin or anonymous user" msgstr "ユーザー admin 㨠anonymous を無効ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "" -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" "\n" msgstr "" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -73,17 +73,17 @@ " roundup-admin help all -- all available help\n" msgstr "" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 msgid "Commands: " msgstr "" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." msgstr "" -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -150,12 +150,12 @@ "Command help:\n" msgstr "" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -167,20 +167,20 @@ " " msgstr "" -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "" -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "" -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -206,23 +206,23 @@ " " msgstr "" -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -230,20 +230,20 @@ "Erase it? Y/N: " msgstr "" -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 msgid "Select template" msgstr "" -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 msgid "Select backend" msgstr "" -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -252,11 +252,11 @@ " %(config_file)s" msgstr "" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr "" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -273,7 +273,7 @@ "---------------------------------------------------------------------------\n" msgstr "" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 msgid "" "Usage: genconfig <filename>\n" " Generate a new tracker config file (ini style) with default\n" @@ -281,7 +281,7 @@ " " msgstr "" -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 msgid "" "Usage: updateconfig <filename>\n" " Generate an updated tracker config file (ini style) in\n" @@ -291,7 +291,7 @@ msgstr "" #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -302,30 +302,30 @@ " " msgstr "" -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "" -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr "" -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" "Erase it? Y/N: " msgstr "" -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 msgid "" "Usage: get property designator[,designator]*\n" " Get the given property of one or more designator(s).\n" @@ -338,23 +338,23 @@ " " msgstr "" -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 msgid "" "Usage: set items property=value property=value ...\n" " Set the given properties of one or more items(s).\n" @@ -375,7 +375,7 @@ " " msgstr "" -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 msgid "" "Usage: filter classname propname=value ...\n" " Find the nodes of the given class with a given property value.\n" @@ -388,19 +388,19 @@ " " msgstr "" -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "" -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -411,7 +411,7 @@ " " msgstr "" -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -420,17 +420,17 @@ " " msgstr "" -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, python-format msgid "%(key)s: %(value)s\n" msgstr "" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 msgid "" "Usage: display designator[,designator]*\n" "\n" @@ -444,12 +444,12 @@ " " msgstr "" -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -461,31 +461,31 @@ " " msgstr "" -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "" -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr "" -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "" -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "" -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "" -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -501,16 +501,16 @@ " " msgstr "" -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -542,17 +542,17 @@ " " msgstr "" -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -567,7 +567,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -581,7 +581,7 @@ " " msgstr "" -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -593,7 +593,7 @@ " " msgstr "" -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 msgid "" "Usage: retire designator[,designator]*\n" " Retire the node specified by designator.\n" @@ -606,7 +606,7 @@ " " msgstr "" -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 msgid "" "Usage: restore designator[,designator]*\n" " Restore the retired node specified by designator.\n" @@ -618,12 +618,12 @@ " " msgstr "" -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -639,7 +639,7 @@ " " msgstr "" -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -656,7 +656,7 @@ " " msgstr "" -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -679,7 +679,7 @@ " " msgstr "" -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -687,7 +687,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -709,11 +709,11 @@ " " msgstr "" -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -723,12 +723,12 @@ " " msgstr "" -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 msgid "" "Usage: security [Role name]\n" "\n" @@ -736,46 +736,46 @@ " " msgstr "" -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, python-format msgid "No such Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, python-format msgid "Role \"%(name)s\":\n" msgstr "" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr "" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -783,17 +783,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr "" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, python-format msgid " %(description)s (%(name)s)\n" msgstr "" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -817,82 +817,82 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 msgid "Tracker updated" msgstr "" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "" -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" "Type \"help\" for help." msgstr "" -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "" -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "" -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -906,53 +906,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "" @@ -1185,22 +1207,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, python-format msgid "You do not have permission to view %(class)s" msgstr "%(class)s を表示ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" @@ -1286,160 +1313,167 @@ "</body></html>" msgstr "" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "" -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, fuzzy, python-format -msgid "Invalid Origin %s" -msgstr "䏿£ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆ" - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 +#, python-format +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format -msgid "Invalid HOST %s" +msgid "Invalid Origin %s" msgstr "䏿£ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆ" -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, fuzzy, python-format +msgid "Invalid HOST %s" +msgstr "䏿£ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆ" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "" -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " "items: %(get_items)f secs. Filtering: %(filtering)f secs.%(endtag)s\n" msgstr "" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1509,18 +1543,18 @@ msgstr "æ–°è¦ç™»éŒ²" #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "" @@ -1546,63 +1580,69 @@ msgid "The linked class %(classname)s no longer exists" msgstr "リンク先ã®ã‚¯ãƒ©ã‚¹ %(classname)s ã¯å˜åœ¨ã—ã¾ã›ã‚“" -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>リンク先ã®ãƒŽãƒ¼ãƒ‰ã¯å˜åœ¨ã—ã¾ã›ã‚“</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" "strong>" msgstr "<strong><em>ã“ã®ã‚¤ãƒ™ãƒ³ãƒˆã¯å±¥æ´ã®ä¸ã«è¡¨ç¤ºã•れã¾ã›ã‚“!</em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>備考:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "å±¥æ´" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>日時</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "å±¥æ´" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>日時</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>ユーザー</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>アクション</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>引数</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "%(class)s %(id)s ã®ã‚³ãƒ”ー" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -1610,17 +1650,17 @@ "DateHTMLProperty ã®ãƒ‡ãƒ•ォルト値㯠DateHTMLProperty ã‚‚ã—ãã¯æ—¥ä»˜ã®æ–‡å—列表ç¾ã§" "ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“。" -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "å˜åœ¨ã—ãªã„値㮠%(attr)s 検索ãŒå®Ÿè¡Œã•れã¾ã—ãŸ" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "å˜åœ¨ã—ãªã„値㮠%(attr)s 検索ãŒå®Ÿè¡Œã•れã¾ã—ãŸ" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- æœªé¸æŠž -</option>" @@ -1638,11 +1678,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "䏿£ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆ" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "䏿£ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆ" + #: ../roundup/date.py:395 #, python-format msgid "" @@ -1801,23 +1853,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -1829,50 +1881,50 @@ "\tcontains old-style template - ignored" msgstr "" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "æ–°è¦ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" msgstr "" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -1889,7 +1941,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -1900,7 +1952,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -1917,7 +1969,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -1928,7 +1980,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -1938,7 +1990,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -1947,21 +1999,21 @@ "Unknown address: %(from_address)s\n" msgstr "" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "" -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -1971,38 +2023,38 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "" -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" "not find a text/plain part to use.\n" msgstr "" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "" -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2010,22 +2062,22 @@ "%(error)s\n" msgstr "" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "クラス %(class)s ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’ %(action)s ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2033,7 +2085,7 @@ " %(message)s\n" msgstr "" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, python-format msgid "" "\n" @@ -2042,7 +2094,7 @@ " %(clsname)s\n" msgstr "" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2051,22 +2103,39 @@ " %(errors)s\n" msgstr "" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "䏿£ãªãƒªã‚¯ã‚¨ã‚¹ãƒˆ" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2286,58 +2355,58 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, python-format msgid "Error: %(type)s: %(value)s" msgstr "" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "" -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2347,7 +2416,7 @@ " specifics." msgstr "" -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2356,9 +2425,10 @@ " specified if -d is used." msgstr "" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2381,6 +2451,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -2419,20 +2492,20 @@ " any url-unsafe characters like spaces, as these confuse IE.\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "" @@ -2570,6 +2643,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -2586,6 +2660,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -2602,6 +2677,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -3429,6 +3505,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -3976,7 +4053,7 @@ msgid "User listing" msgstr "ユーザー一覧" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -3984,13 +4061,13 @@ msgid "Username" msgstr "ユーザーå" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "åå‰" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -3999,26 +4076,26 @@ msgid "Organisation" msgstr "所属" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "メールアドレス" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "電話番å·" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "無効化" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4169,67 +4246,67 @@ "ã¨ã§ç™»éŒ²å‡¦ç†ãŒå®Œäº†ã—ã¾ã™ã€‚" #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "致命的ä¸å…·åˆ" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "è¦æ—©æœŸå¯¾å¿œ" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "ãƒã‚°" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "機能拡張案" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "è¦æœ›" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "未èª" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "ä¿ç•™" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "対応è°è«–ä¸" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "è¦è©³ç´°æƒ…å ±" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "対応作æ¥ä¸" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "テストä¸" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "暫定対応済ã¿" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "解決"
--- a/locale/lt.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/lt.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: roundup-1.1.2\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:21+0100\n" "Last-Translator: Nerijus Baliunas <nerijus@users.sourceforge.net>\n" "Language-Team: \n" @@ -29,19 +29,19 @@ msgstr "Negalite deaktyvuoti administratoriaus ar anoniminio vartotojo" # ../roundup/admin.py:85 :962 :1011 :1033 -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "nÄ—ra klasÄ—s \"%(classname)s\"" # ../roundup/admin.py:95 :99 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "argumentas \"%(arg)s\" nÄ—ra parinktis=reikÅ¡mÄ— formato" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -50,7 +50,7 @@ "Problema: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -100,12 +100,12 @@ " roundup-admin help <komanda> -- specifinÄ— pagalba komandoms\n" " roundup-admin help all -- visa įmanoma pagalba\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "Komandos:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -113,7 +113,7 @@ "Komandos gali bÅ«ti sutrumpintos, taÄiau sutrumpinimas turi atitikti tik\n" "vienÄ… komandÄ…, pvz. l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -246,12 +246,12 @@ "\n" "Komandų pagalba:\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s:" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -271,22 +271,22 @@ " all -- visa įmanoma pagalba\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "AtsipraÅ¡ome, pagalbos temai \"%(topic)s\" nÄ—ra" # ../roundup/admin.py:338 :387 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "Å ablonai:" # ../roundup/admin.py:341 :398 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "Duomenų saugyklos:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -336,23 +336,23 @@ # ../roundup/admin.py:360 :447 :508 :587 :637 :695 :716 :744 :815 :882 :953 # :1001 :1023 :1050 :1117 :1184 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "Paduota nepakankamai argumentų" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "Namų direktorijos tÄ—vinÄ— direktorija \"%(parent)s\" neegzistuoja" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -363,22 +363,22 @@ "Jei jÅ«s jį perdiegsite, prarasite visus duomenis!\n" "IÅ¡trinti jį? Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "Pasirinkite Å¡ablonÄ… [klasikinis]: " -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "Pasirinkite duomenų saugyklÄ… [anydbm]: " -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "Klaida konfigÅ«racijos nustatymuose: \"%s\"" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -391,11 +391,11 @@ " Dabar jÅ«s turÄ—tumÄ—te pakeisti tracker'io konfigÅ«racijos failÄ…:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... mažiausiai turÄ—tumÄ—te nustalyti Å¡ias parinktis:" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -424,7 +424,7 @@ " aukÅ¡Äiau minÄ—tus žingsnius.\n" "---------------------------------------------------------------------------\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 #, fuzzy msgid "" "Usage: genconfig <filename>\n" @@ -437,7 +437,7 @@ " įprastomis reikÅ¡mÄ—mis faile <failovardas>.\n" " " -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 #, fuzzy msgid "" "Usage: updateconfig <filename>\n" @@ -452,7 +452,7 @@ " " #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -470,23 +470,23 @@ " Vykdyti tracker'io inicializacijos funkcijÄ… dbinit.init()\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "Administratoriaus slaptažodis: " -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " Patvirtinkite: " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "Namų direktorija neegzistuoja" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "Egzempliorius nebuvo įdiegtas" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -496,7 +496,7 @@ "Jei jÅ«s jÄ… inicializuosite dar kartÄ…, prarasite visus duomenis!\n" "IÅ¡trinti duomenų bazÄ™? Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -516,7 +516,7 @@ " " # ../roundup/admin.py:541 :556 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" @@ -524,18 +524,18 @@ "-d netinkamas." # ../roundup/admin.py:564 :964 :1013 :1035 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "nÄ—ra tokio %(classname)s elemento \"%(nodeid)s\"" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "nÄ—ra tokio %(classname)s parinkties \"%(propname)s\"" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -570,7 +570,7 @@ " reikÅ¡mÄ—s (t.y. \"1,2,3\").\n" " " -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -593,20 +593,20 @@ " " # ../roundup/admin.py:682 :835 :847 :901 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "%(classname)s neturi parinkties \"%(propname)s\"" # ../roundup/admin.py:682 :835 :847 :901 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "%(classname)s neturi parinkties \"%(propname)s\"" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -625,7 +625,7 @@ " arba jo raktinÄ— reikÅ¡mÄ—.\n" " " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -639,17 +639,17 @@ " Å i komanda iÅ¡vardina duotos klasÄ—s parinktis.\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (key property)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -669,12 +669,12 @@ " Å i komanda iÅ¡vardina parinktis ir jų reikÅ¡mes duotam elementui.\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -693,31 +693,31 @@ " eilutÄ—je po \"create\" komandos.\n" " " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (Slaptažodis): " -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (Pakartoti): " -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "Bandykite dar kartÄ…..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "%(propname)s (%(proptype)s): " -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "turite pateikti parinktį \"%(propname)s\"." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -745,16 +745,16 @@ " parinkties sÄ…raÅ¡as kiekvienam klasÄ—s egzemplioriui.\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "Pateikta per daug argumentų" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "%(nodeid)4s: %(value)s" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -816,17 +816,17 @@ " pateiks 4 simbolių ilgio \"Name\" stulpelį.\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "\"%(spec)s\" ne vardas:plotis" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -841,7 +841,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -866,7 +866,7 @@ " iÅ¡saugomos, jei jos įvykdomos sÄ—kmingai.\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -888,7 +888,7 @@ " nepadarys jokių pakeitimų duomenų bazÄ—je.\n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -909,7 +909,7 @@ " kartÄ….\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -928,13 +928,13 @@ " " # ../roundup/admin.py:564 :964 :1013 :1035 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "nÄ—ra tokio %(classname)s elemento \"%(nodeid)s\"" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -962,7 +962,7 @@ " direktorijoje.\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -992,7 +992,7 @@ " direktorijoje.\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -1037,7 +1037,7 @@ " veiksmas).\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -1045,7 +1045,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1084,11 +1084,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "Netinkamas formatas" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1104,12 +1104,12 @@ " Paprastai tai įvyksta automatiÅ¡kai.\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "nÄ—ra elemento \"%(designator)s\"" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1121,47 +1121,47 @@ " Parodo vienos ar kelių rolių permisijas.\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "NÄ—ra tokios rolÄ—s \"%(role)s\"" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "Naujiems web vartotojams suteikiamos rolÄ—s \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "Naujiems web vartotojams suteikiama rolÄ— \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "Naujiems vartotojams per el. paÅ¡tÄ… suteikiamos rolÄ—s \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "Naujiems vartotojams per el. paÅ¡tÄ… suteikiama rolÄ— \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "RolÄ— \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s skirta tik \"%(klass)s\")" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr " %(description)s (%(name)s skirta tik \"%(klass)s\": %(properties)s)" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1169,17 +1169,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s skirta tik \"%(klass)s\")" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -1203,45 +1203,45 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 #, fuzzy msgid "Tracker updated" msgstr "Tracker'io namų direktorija" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" "Nežinoma komanda \"%(command)s\" (įveskite \"help commands\" komandų\n" "sÄ…raÅ¡ui gauti)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "Kelios komandos atitinka \"%(command)s\": %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "Ä®veskite tracker'io namų direktorijÄ…: " # ../roundup/admin.py:1312 :1318 :1338 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "Klaida: %(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "Klaida: Negaliu atidaryti tracker'io: %(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1250,41 +1250,41 @@ "Roundup %s pasiruošęs priimti duomenis.\n" "NorÄ—dami iÅ¡kviesti pagalbÄ… įveskite \"help\"." -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "Pastaba: komandų archyvas ir redagavimas neprieinami" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "roundup> " -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "iÅ¡eiti..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "Yra neiÅ¡saugotų pakeitimų. IÅ¡saugoti juos (y/N)? " -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1298,53 +1298,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "sukurti" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "atsieti" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "susieti" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "nustatyti" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "deaktyvuotas" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "aktyvuotas" @@ -1586,23 +1608,28 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + # ../roundup/cgi/actions.py:897 :901 -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "Neteisingas vartotojo vardas ar slaptažodis" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "Neturite prisijungimo teisių" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, fuzzy, python-format msgid "You do not have permission to view %(class)s" msgstr "Neturite leidimo redaguoti %(class)s" @@ -1706,155 +1733,155 @@ "Apie klaidÄ… pranešėme tracker'io administratoriui.</p>\n" "</body></html>" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "Formos klaida: " -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "Neatpažinta koduotÄ—: %r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "Anoniminiai vartotojai neturi teisių naudoti web interfeisÄ…" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 +#: ../roundup/cgi/client.py:1289 #, python-format msgid "Missing header: %s" msgstr "" -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 #, python-format msgid "csrf Referer header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1258 +#: ../roundup/cgi/client.py:1300 #, python-format msgid "Invalid Referer %s, %s" msgstr "" -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format msgid "csrf Origin header check failed for user%s. Value=%s" msgstr "" # ../roundup/cgi/actions.py:897 :901 -#: ../roundup/cgi/client.py:1274 +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format msgid "Invalid Origin %s" msgstr "Neteisingas vartotojo vardas ar slaptažodis" -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 #, python-format msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" -#: ../roundup/cgi/client.py:1289 -#, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 -#, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 -#, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" -msgstr "" - #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "JÅ«s neturite teisių žiÅ«rÄ—ti šį failÄ…." -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)sPraÄ—jÄ™s laikas: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " @@ -1864,6 +1891,13 @@ "%(cache_misses)d. Ä®keliami elementai: %(get_items)f sek. Filtruojama: " "%(filtering)f sek.%(endtag)s\n" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1938,18 +1972,18 @@ # ../roundup/cgi/templating.py:700 :819 :1193 :1214 :1258 :1280 :1314 :1353 # :1404 :1421 :1497 :1517 :1530 :1547 :1557 :1607 :1794 #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[paslÄ—pta]" @@ -1975,66 +2009,72 @@ msgid "The linked class %(classname)s no longer exists" msgstr "Susietos klasÄ—s %(classname)s nebÄ—ra" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:930 :951 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>Susieto elemento nebÄ—ra</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (no value)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" "strong>" msgstr "<strong><em>Å is įvykis nÄ—ra rodomas archyve!</em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>Pastaba:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "Archyvas" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>Data</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "Archyvas" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>Data</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>Vartotojas</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>Veiksmas</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>Argumentai</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "%(class)s %(id)s kopija" # ../roundup/cgi/templating.py:993 :1357 :1378 :1384 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "Ne" # ../roundup/cgi/templating.py:993 :1357 :1376 :1381 -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "Taip" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -2042,17 +2082,17 @@ "standartinÄ— DateHTMLProperty reikÅ¡mÄ— turi bÅ«ti arba DateHTMLProperty arba " "datos reprezentacija kaip simbolių eilutÄ—s." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "BandÄ—te pažiÅ«rÄ—ti %(attr)s neegzistuojanÄiai reikÅ¡mei" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "BandÄ—te pažiÅ«rÄ—ti %(attr)s neegzistuojanÄiai reikÅ¡mei" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- nepasirinkta -</option>" @@ -2070,11 +2110,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "Netinkamas formatas" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "Netinkamas formatas" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -2247,23 +2299,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -2277,44 +2329,44 @@ "PERSPÄ–JIMAS: direktorijoje '%s'\n" "\tseno tipo Å¡ablonas, praleistas" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "Naujas praneÅ¡imas" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -2322,7 +2374,7 @@ "\n" "LaiÅ¡kai Roundup'o tracker'iams privalo turÄ—ti temos (Subject:) eilutÄ™!\n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2349,7 +2401,7 @@ "\n" "Tema buvo: '%(subject)s'\n" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, fuzzy, python-format msgid "" "\n" @@ -2366,7 +2418,7 @@ "Teisingi klasių vardai yra: %(validname)s\n" "Tema buvo: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, fuzzy, python-format msgid "" "\n" @@ -2393,7 +2445,7 @@ "\n" "Tema buvo: '%(subject)s'\n" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, fuzzy, python-format msgid "" "\n" @@ -2410,7 +2462,7 @@ "\n" "Tema buvo: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2425,7 +2477,7 @@ "\n" "Tema buvo: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, fuzzy, python-format msgid "" "\n" @@ -2438,21 +2490,21 @@ "\n" "Nežinomas adresas: %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "Neturite teisių naudotis Å¡iuo tracker'iu." -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "Neturite leidimo redaguoti %(classname)s." -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "Neturite leidimo sukurti %(classname)s." -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2467,27 +2519,27 @@ "\n" "Tema buvo: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "Neturite teisių sukurti failÄ…." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "Neturite leidimo pridÄ—ti failų prie %(classname)s." -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2497,11 +2549,11 @@ "Roundup'ui reikia, kad laiÅ¡kas bÅ«tų tekstinis. LaiÅ¡kų analizatorius nerado\n" "text/plain dalies.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "Neturite leidimo sukurti praneÅ¡imų." -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2512,22 +2564,22 @@ "Detektorius atmetÄ— jÅ«sų laiÅ¡kÄ….\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "Neturite leidimo pridÄ—ti praneÅ¡imų prie %(classname)s." -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "Neturite leidimo redaguoti %(classname)s parinkties %(prop)s." -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "Neturite leidimo redaguoti %(classname)s parinkties %(prop)s." -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2537,7 +2589,7 @@ "\n" "JÅ«sų laiÅ¡ke %(message)s yra klaidų.\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2550,7 +2602,7 @@ "%(mailadmin)s, kad pataisytų neteisingÄ… klasÄ—s pavadinimÄ…:\n" " %(current_class)s\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2563,22 +2615,40 @@ "%(mailadmin)s, kad pataisytų neteisingus atributus:\n" " %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "ne tokios formos: [arg=reikÅ¡mÄ—,reikÅ¡mÄ—,...;arg=reikÅ¡mÄ—,reikÅ¡mÄ—,...]" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +# ../roundup/cgi/actions.py:897 :901 +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "Neteisingas vartotojo vardas ar slaptažodis" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2869,7 +2939,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2877,52 +2947,52 @@ "<html><head><title>Roundup tracker'io indeksas</title></head>\n" "<body><h1>Roundup tracker'io indeksas</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "PERSPÄ–JIMAS: \"-g\" argumentas ignoruojamas, nÄ—ra root teisių" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "Negaliu pakeisti grupių -- nÄ—ra grp modulio" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "GrupÄ—s %(group)s nÄ—ra" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "Negaliu paleisti root teisÄ—mis!" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "PERSPÄ–JIMAS: \"-u\" argumentas ignoruojamas, nÄ—ra root teisių" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "Negaliu pakesiti vartotojų - nÄ—ra pwd modulio" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "Vartotojo %(user)s nÄ—ra" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "MultiprocesinÄ— aplinka \"%s\" neprieinama, perjungiu į vienprocesinÄ™" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "Negaliu prijungti prie jungties %s, jungtis jau naudojama." -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2939,7 +3009,7 @@ " Ä®vedÄ™ \"roundup-server -c help\" pamatysite Windows Services\n" " specifikÄ…." -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2953,9 +3023,10 @@ " nurodytÄ… PIDfaile. Parinktis -l *privalo* bÅ«ti nurodyta\n" " jei naudojama -d." -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2978,6 +3049,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -3069,21 +3143,21 @@ " nesupras.\n" "\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "Egzempliorius turi bÅ«ti nurodomas taip: vardas=namų_direktorija" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "KonfigÅ«racija iÅ¡saugota %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "JÅ«s negalite paleisti serverio kaip daemon'o Å¡ioje operacinÄ—je sistemoje" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Roundup serveris paleistas ant %(HOST)s:%(PORT)s" @@ -3220,6 +3294,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3236,6 +3311,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3252,6 +3328,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -4083,6 +4160,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4631,7 +4709,7 @@ msgid "User listing" msgstr "Vartotojų sÄ…raÅ¡as" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4639,13 +4717,13 @@ msgid "Username" msgstr "Vartotojo vardas" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "Tikras vardas" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4654,26 +4732,26 @@ msgid "Organisation" msgstr "Organizacija" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "El. paÅ¡to adresas" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "Telefono numeris" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "Deaktyvuoti" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4826,67 +4904,67 @@ "pabaigtumÄ—te registracijoc procesÄ…, sekite nuorodÄ… atsiųstame laiÅ¡ke." #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "kritinis" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "skubus" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "klaida" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "nauja savybÄ—" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "pageidavimas" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "neskaityta" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "atidÄ—ta" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "vyksta pokalbis" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "reikia pvz." #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "eigoje" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "testuojama" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "atlikta - galÄ—tų bÅ«ti geriau" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "iÅ¡sprÄ™sta"
--- a/locale/nb.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/nb.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:21+0100\n" "Last-Translator: Christian Aastorp <christian.aastorp@gmail.com>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -30,18 +30,18 @@ msgid "You may not retire the admin or anonymous user" msgstr "Du kan ikke slette admin eller anonymous brukerne" -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "ingen slik klasse \"%(classname)s\"" -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "argumentet \"%(arg)s\" ikke propname=value" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -50,7 +50,7 @@ "Problem: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -100,12 +100,12 @@ " roundup-admin help <command> -- kommandospesifikk hjelp\n" " roundup-admin help all -- all tilgjengelig hjelp\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "Kommandoer:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -113,7 +113,7 @@ "Kommandoer kan forkortes så lenge som forkortelsen bare passer med en " "kommando, feks e.g. l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -249,12 +249,12 @@ "\n" "Kommandohjelp:\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s:" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -274,20 +274,20 @@ " all -- all tilgjengeli hjelp\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "Beklager, ingen hjelp for \"%(topic)s\"" -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "Maler:" -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "Back ends:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -334,23 +334,23 @@ "\t\tSe også hjelp for initops.\n" " " -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "For få parametre" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "Overordnet katalog \"%(parent)s\" finnes ikke" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -361,22 +361,22 @@ "Du vil miste alle data hvis du reinstallerer!\n" "Slette den? Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "Velg mal [classic]: " -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "Velg database backend [anydbm]: " -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "Feil i konfigurasjon \"%s\"" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -389,11 +389,11 @@ " Du bør redigere konfigurasjonsfilen for sporeren nå:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr "... du må spesifisere følgende opsjoner som et minimum:" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -421,7 +421,7 @@ " disse endringene.\n" "---------------------------------------------------------------------------\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 #, fuzzy msgid "" "Usage: genconfig <filename>\n" @@ -434,7 +434,7 @@ " i <filename>.\n" " " -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 #, fuzzy msgid "" "Usage: updateconfig <filename>\n" @@ -449,7 +449,7 @@ " " #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -467,23 +467,23 @@ " Kjør sporerens oppstartsfunksjon dbinit.init()\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "Admin passord:" -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " Bekreft: " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "Hjemmekatalogen finnes ikke" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "Sporeren er ikke installert" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -493,7 +493,7 @@ "Hvis du reinitialiserer den vil alle data bli slettet.\n" "Slette den? Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -514,24 +514,24 @@ "\t\tved angivelsene.\n" " " -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" "egneskapen %s er ikke multilenke eller lenke so -d lfagget kan ikke anvendes." -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "finnes ikke %(classname)s node \"%(nodeid)s\"" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "finnes ikke %(classname)s property \"%(propname)s\"" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -566,7 +566,7 @@ "som\n" " en kommaseparert liste (feks \"1,2,3\")." -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -586,19 +586,19 @@ " Verdien kan enten være nodeid-en til den lenkede noden, eller dens " "nøkkelverdi.n " -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "%(classname)s har ingen verdi \"%(propname)s\"" -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "%(classname)s har ingen verdi \"%(propname)s\"" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -615,7 +615,7 @@ " Verdien kan enten være nodeid-en til den lenkede noden, eller dens " "nøkkelverdi.n " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -629,17 +629,17 @@ " Lister egenskapene til gitt klasse.\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (key property)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -659,12 +659,12 @@ " Lister egenskapene og deres verdier for oppgitt node.\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -682,31 +682,31 @@ " på kommandolinjen ette \"create\"kommandoen.\n" " " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (Password): " -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (Again): " -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "Beklager, prøv en gang til..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "%(propname)s (%(proptype)s): " -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "du må oppgi \"%(propname)s\" egenskapen." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -735,16 +735,16 @@ " for alle klasseinstanser.\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "For mange argumenter" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "%(nodeid)4s: %(value)s" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -804,17 +804,17 @@ " resulterer i en fire bokstavaer bred \"Name\" kolonne.\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "\"%(spec)s\" ikke navn:bredde" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -829,7 +829,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -852,7 +852,7 @@ " permanent, hvis de lykkes.\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -871,7 +871,7 @@ " commited. \n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -891,7 +891,7 @@ " av list eller find-kommandoene, og at dens nøkkel kan gjenbrukes.\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -909,13 +909,13 @@ "\t Oppgitte noder blir tilgjengelige for brukerne igjen.\n" " " -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "finnes ikke %(classname)s node \"%(nodeid)s\"" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -942,7 +942,7 @@ "\t kolonseparerte filer som plasseres i angitt katalog.\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -971,7 +971,7 @@ " kolonseparerte filer som plasseres i angitt katalog.\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -1013,7 +1013,7 @@ " (eller, mer omstendelig glem alle gamle data).\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -1021,7 +1021,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1060,11 +1060,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "Ugyldig format" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1080,12 +1080,12 @@ " automatisk.\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "ingen slik enhet \"%(designator)s\"" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1097,47 +1097,47 @@ " Viser tillatelsene som er tilgjengelige for en eller alle roller.\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "Ingen slik rolle \"%(role)s\"" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "Nye web-brukere for rollene \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "Nye web-brukere for rollen \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "Nye epostbrukere for rollene \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "Nye epostbrukere for rollen \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "Rolle \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s bare for \"%(klass)s\")" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr " %(description)s (%(name)s bare for \"%(klass)s\": %(properties)s )" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1145,17 +1145,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s bare for \"%(klass)s\")" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 #, fuzzy msgid "" "Usage: migrate\n" @@ -1203,41 +1203,41 @@ " la det bli en vane.\n" " " -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 msgid "Tracker updated" msgstr "Sporer oppdatert" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "Ingen migrasjon krevet" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "Ukjent kommando \"%(command)s\" (\"help commands\" for liste)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "Multiple kommandoer matcher \"%(command)s\": %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "Oppgi sporers plassering:" -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "Feil: %(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "Feil: Kan ikke åpne sporer: %(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1246,34 +1246,34 @@ "Roundup %s er klar til bruk.\n" "Skriv \"help\" for hjelp." -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "Merk: kommandohistorikk og redigering utilgjengelig" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "roundup> " -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "exit..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "Det er ikkelagrede endringer. Lagre dem (y/N)? " -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "Kunne ikke identifisere databsetypen" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, fuzzy, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " @@ -1281,7 +1281,7 @@ msgstr "" "Kunne ikke åpne databasen - den påkrevde modulen '%s' er ikke tilgjengelig" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1296,53 +1296,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "Databsen åpnet bare for lesing" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "lag" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "fjern lenke" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "lenke" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "oppdater" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "glemt" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "brakt tilbake" @@ -1579,22 +1601,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "Ugylig login" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "Du har ikke tillatelse til å logge inn" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, python-format msgid "You do not have permission to view %(class)s" msgstr "Du har ikke tillatelse til å se på %(class)s" @@ -1692,154 +1719,154 @@ "</body></html>" msgstr "" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "Skjema feil:" -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "Ukjent tegnsett: %r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "Anonyme brukere får ikke benytte web-grensesnittet" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, fuzzy, python-format -msgid "Invalid Origin %s" -msgstr "Ugylig login" - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 +#, python-format +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format -msgid "Invalid HOST %s" -msgstr "Ugyldig forespørsel" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +msgid "Invalid Origin %s" +msgstr "Ugylig login" + +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, fuzzy, python-format +msgid "Invalid HOST %s" +msgstr "Ugyldig forespørsel" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "Du har ikke lov å se denne filen." -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)sMedgått tid: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " @@ -1848,6 +1875,13 @@ "%(starttag)sCache treff: %(cache_hits)d, ikke-treff %(cache_misses)d. Laster " "saker: %(get_items)f secs. Filtrerer: %(filtering)f secs.%(endtag)s\n" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1916,18 +1950,18 @@ msgstr "Legg til ny oppføring" #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[skjult]" @@ -1953,17 +1987,23 @@ msgid "The linked class %(classname)s no longer exists" msgstr "Den lenkede klassen %(classname)s finnes ikke lenger" -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>Den lenkede noden finnes ikke lenger</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (ingen verdi)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" @@ -1972,46 +2012,46 @@ "<strong><em>Denne hendelsen håndteres ikke av historievisningen!</em></" "strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>Noter:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "Historie" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>Dato</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "Historie" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>Dato</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>Bruker</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>Aksjon</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>Argumenter</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "Kopi av %(class)s %(id)s" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "Nei" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "Ja" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -2019,17 +2059,17 @@ "standard verdi for DateHTMLProperty må være enten DateHTMLProperty eller en " "streng represantasjon av tidspunkt." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "Forsøk på å slå opp %(attr)s på manglende verdi" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "Forsøk på å slå opp %(attr)s på manglende verdi" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- intet valg -</option>" @@ -2047,11 +2087,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "Ugyldig forespørsel" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "Ugyldig forespørsel" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -2215,23 +2267,23 @@ msgid "\"%s\" not a node designator" msgstr "\"%s\" ikke en node-benevnelse" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "Ikke et navn på egenskap: %s" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "egenskap %s: %r er ikke en %s." -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "du kan bare oppgi ID-verdier for egenskap %s" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "%r er ikke en egenskap ved %s" @@ -2245,44 +2297,44 @@ "ADVARSEL: katalog '%s'\n" "\tinneholder foreldet mal - ignorert" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "Melding signert med ukjent verdi: %s" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "Melding signert med utgått verdi: %s" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "Melding signert med tilbakekalt verdi: %s" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "Ugyldig PGP-signatur oppdaget." -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "Ny melding" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "Ukjent flerdeler(multipart)/koded versjon." -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "Ikke i stand til å dekryptere meldingne din." -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "Ingen PGP signatur funnet i melding." -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -2290,7 +2342,7 @@ "\n" "Epost til Roundup sporer må inneholde en verdi for Subjekt: linjen\n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2320,7 +2372,7 @@ "\n" "Subjekt var: '%(subject)s'\n" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -2337,7 +2389,7 @@ "Gyldige klassenavn er: %(validname)s\n" "Subjekt var: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -2364,7 +2416,7 @@ "\n" "Subjekt var: '%(subject)s'\n" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -2383,7 +2435,7 @@ "\n" "Subjekt var: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2398,7 +2450,7 @@ "\n" "Subjekt var: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -2411,21 +2463,21 @@ "\n" "Ukjent adresse: %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "Du har ikke adgang til denne sporeren." -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "Du har ikke tillatelse til å endre %(classname)s." -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "Du har ikke tillatelse til å opprette %(classname)s." -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2441,7 +2493,7 @@ "\n" "Subjekt var: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 #, fuzzy msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" @@ -2449,7 +2501,7 @@ "Denne sporeren er satt til å kreve at all epost entern er signert med PGP, \n" "eller kryptert." -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" @@ -2459,16 +2511,16 @@ "Denne sporeren er satt til å kreve at all epost entern er signert med PGP, \n" "eller kryptert." -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "Du har ikke lov å lage en filer." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "Du har ikke tillatelse til å legge filer til %(classname)s." -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2479,11 +2531,11 @@ "finne ren tekst\n" "å behandle.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "Du har ikke lov å lage en meldinger." -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2494,26 +2546,26 @@ "Epost ble returnert av en detektor.\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "Du har ikke tillatelse til å legge meldinger til %(classname)s." -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" "Du har ikke tillatelse til å redigere egenskapen %(prop)s til klassen " "%(classname)s." -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" "Du har ikke tillatelse til å redigere egenskapen %(prop)s til klassen " "%(classname)s." -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2524,7 +2576,7 @@ "Det var et problem med meldingen du sendte:\n" " %(message)s\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2537,7 +2589,7 @@ "og få problemet løst. Referansen er til feil klasse: \n" " %(current_class)s\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2550,22 +2602,39 @@ "og få problemet løst. Referansen er til feil egenskaper:\n" " %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "ikke på formen [arg=value,value,...;arg=value,value,...]" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "Ugylig login" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2865,7 +2934,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "ADVARSEL: genererer midlertidig SSL sertifikat" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2873,53 +2942,53 @@ "<html><head><title>Roundup saksliste</title></head>\n" "<body><h1>Roundup saksliste</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "ADVARSEL: ignorerer \"-g\" argument, ikke root" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "Kan ikke skifte gruppe, ingen grp modul" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "Gruppe %(group)s finnes ikke" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "Kan ikke kjøre som root" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "ADVARSEL: ignorerer \"-u\" argument, ikke root" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "Kan ikke skifte bruker , ingen pwd modul" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "Bruker %(user)s finnes ikke" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" "Multiprosess modus \"%s\" ikke tilgjengelig, fortsetter som enkeltprosess" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "Ikke mulig å binde til port %s, porten er allerede i bruk." -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2936,7 +3005,7 @@ " Skriv \"roundup-server -c help\" for å vise Windows Services\n" " informasjon." -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2950,9 +3019,10 @@ " serverens PID til filen indikert av PIDfile.\n" " -l optsjonen *må* brukes hvis -d brukes." -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2975,6 +3045,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -3068,21 +3141,21 @@ " Pass på at de ikke inneholder url-utrygge tegn som mellomrom, for de kan " "forvirre IE.\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "Instanser må være navn=home" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "Konfigurasjon lagret til %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "Beklager, du kan ikke kjøre servern som daemon under dette operativsystemet" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Roundup server startet på %(HOST)s:%(PORT)s" @@ -3220,6 +3293,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3236,6 +3310,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3252,6 +3327,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -4078,6 +4154,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4625,7 +4702,7 @@ msgid "User listing" msgstr "Brukerliste" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4633,13 +4710,13 @@ msgid "Username" msgstr "Brukernavn" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "Fullt navn" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4648,26 +4725,26 @@ msgid "Organisation" msgstr "Organisasjon" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "E-postadresse" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "Telefonnummer" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "Glem" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4818,67 +4895,67 @@ "registreringen, besøk linken i eposten." #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "kritisk" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "krise" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "feil" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "finesse" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "ønske" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "ulest" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "på vent" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "diskuteres" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "trenger eksempel" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "pågår" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "tester" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "utført slurvete" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "utført"
--- a/locale/roundup.pot Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/roundup.pot Thu Apr 21 16:54:17 2022 -0400 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -27,25 +27,25 @@ msgid "You may not retire the admin or anonymous user" msgstr "" -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "" -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" "\n" msgstr "" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -73,17 +73,17 @@ " roundup-admin help all -- all available help\n" msgstr "" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 msgid "Commands: " msgstr "" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." msgstr "" -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -148,12 +148,12 @@ "Command help:\n" msgstr "" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -165,20 +165,20 @@ " " msgstr "" -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "" -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "" -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -204,22 +204,22 @@ " " msgstr "" -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 ../roundup/admin.py:378:510 -#: :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 ../roundup/admin.py:404:536 +#: :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -227,20 +227,20 @@ "Erase it? Y/N: " msgstr "" -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 msgid "Select template" msgstr "" -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 msgid "Select backend" msgstr "" -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -249,11 +249,11 @@ " %(config_file)s" msgstr "" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr "" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -269,7 +269,7 @@ "---------------------------------------------------------------------------\n" msgstr "" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 msgid "" "Usage: genconfig <filename>\n" " Generate a new tracker config file (ini style) with default\n" @@ -277,7 +277,7 @@ " " msgstr "" -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 msgid "" "Usage: updateconfig <filename>\n" " Generate an updated tracker config file (ini style) in\n" @@ -287,7 +287,7 @@ msgstr "" #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -298,30 +298,30 @@ " " msgstr "" -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "" -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr "" -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" "Erase it? Y/N: " msgstr "" -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 msgid "" "Usage: get property designator[,designator]*\n" " Get the given property of one or more designator(s).\n" @@ -334,23 +334,23 @@ " " msgstr "" -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175 :1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201 :1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 msgid "" "Usage: set items property=value property=value ...\n" " Set the given properties of one or more items(s).\n" @@ -371,7 +371,7 @@ " " msgstr "" -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 msgid "" "Usage: filter classname propname=value ...\n" " Find the nodes of the given class with a given property value.\n" @@ -384,19 +384,19 @@ " " msgstr "" -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "" -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 ../roundup/admin.py:801:862 -#: :1024:1036 :1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 ../roundup/admin.py:827:888 +#: :1050:1062 :1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -407,7 +407,7 @@ " " msgstr "" -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -416,17 +416,17 @@ " " msgstr "" -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, python-format msgid "%(key)s: %(value)s\n" msgstr "" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 msgid "" "Usage: display designator[,designator]*\n" "\n" @@ -440,12 +440,12 @@ " " msgstr "" -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -457,31 +457,31 @@ " " msgstr "" -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "" -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr "" -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "" -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "" -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "" -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -497,16 +497,16 @@ " " msgstr "" -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -538,17 +538,17 @@ " " msgstr "" -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -563,7 +563,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -577,7 +577,7 @@ " " msgstr "" -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -589,7 +589,7 @@ " " msgstr "" -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 msgid "" "Usage: retire designator[,designator]*\n" " Retire the node specified by designator.\n" @@ -602,7 +602,7 @@ " " msgstr "" -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 msgid "" "Usage: restore designator[,designator]*\n" " Restore the retired node specified by designator.\n" @@ -614,12 +614,12 @@ " " msgstr "" -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -635,7 +635,7 @@ " " msgstr "" -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -652,7 +652,7 @@ " " msgstr "" -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -675,7 +675,7 @@ " " msgstr "" -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -683,7 +683,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -705,11 +705,11 @@ " " msgstr "" -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -719,12 +719,12 @@ " " msgstr "" -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 msgid "" "Usage: security [Role name]\n" "\n" @@ -732,46 +732,46 @@ " " msgstr "" -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, python-format msgid "No such Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, python-format msgid "Role \"%(name)s\":\n" msgstr "" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr "" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -779,17 +779,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr "" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, python-format msgid " %(description)s (%(name)s)\n" msgstr "" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -813,81 +813,82 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 msgid "Tracker updated" msgstr "" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "" -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678 :1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701 :1730 #, python-format msgid "Error: %(message)s" msgstr "" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" "Type \"help\" for help." msgstr "" -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "" -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "" -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/sessions_dbm.py:55 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 +#: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -900,53 +901,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392 :1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392 :1438 :1452:1470 :1516:2138 :2063 :2138:2158 :2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "" @@ -1174,22 +1197,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, python-format msgid "You do not have permission to view %(class)s" msgstr "" @@ -1273,160 +1301,167 @@ "</body></html>" msgstr "" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "" -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, python-format -msgid "Invalid Origin %s" -msgstr "" - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 +#, python-format +msgid "Invalid Origin %s" +msgstr "" + +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422 :1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464 :1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "" -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " "items: %(get_items)f secs. Filtering: %(filtering)f secs.%(endtag)s\n" msgstr "" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1492,18 +1527,18 @@ msgstr "" #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "" @@ -1529,78 +1564,84 @@ msgid "The linked class %(classname)s no longer exists" msgstr "" -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></strong>" msgstr "" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "" - #: ../roundup/cgi/templating.py:1379 -msgid "<th>User</th>" -msgstr "" - -#: ../roundup/cgi/templating.py:1380 -msgid "<th>Action</th>" +msgid "History" msgstr "" #: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "" + +#: ../roundup/cgi/templating.py:1382 +msgid "<th>User</th>" +msgstr "" + +#: ../roundup/cgi/templating.py:1383 +msgid "<th>Action</th>" +msgstr "" + +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039 :2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045 :2078 msgid "No" msgstr "" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039 :2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045 :2073 msgid "Yes" msgstr "" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." msgstr "" -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "" @@ -1618,10 +1659,21 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 msgid "Valid languages: " msgstr "" +#: ../roundup/configuration.py:504 +msgid "Expected languages: " +msgstr "" + #: ../roundup/date.py:395 #, python-format msgid "" @@ -1780,23 +1832,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -1808,49 +1860,49 @@ "\tcontains old-style template - ignored" msgstr "" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 msgid "Unsigned Message" msgstr "" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" msgstr "" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -1867,7 +1919,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -1878,7 +1930,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -1895,7 +1947,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -1906,7 +1958,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -1916,7 +1968,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -1925,21 +1977,21 @@ "Unknown address: %(from_address)s\n" msgstr "" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "" -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -1949,38 +2001,38 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "" -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" "not find a text/plain part to use.\n" msgstr "" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "" -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -1988,22 +2040,22 @@ "%(error)s\n" msgstr "" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "" -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2011,7 +2063,7 @@ " %(message)s\n" msgstr "" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, python-format msgid "" "\n" @@ -2020,7 +2072,7 @@ " %(clsname)s\n" msgstr "" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2029,22 +2081,39 @@ " %(errors)s\n" msgstr "" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, python-format +msgid "Invalid attribute %s" +msgstr "" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2263,58 +2332,58 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, python-format msgid "Error: %(type)s: %(value)s" msgstr "" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "" -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2324,7 +2393,7 @@ " specifics." msgstr "" -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2333,9 +2402,10 @@ " specified if -d is used." msgstr "" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2358,6 +2428,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -2396,20 +2469,20 @@ " any url-unsafe characters like spaces, as these confuse IE.\n" msgstr "" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "" @@ -2541,6 +2614,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -2557,6 +2631,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -2573,6 +2648,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -3388,6 +3464,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -3921,7 +3998,7 @@ msgid "User listing" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -3929,13 +4006,13 @@ msgid "Username" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -3944,26 +4021,26 @@ msgid "Organisation" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4112,67 +4189,67 @@ msgstr "" #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr ""
--- a/locale/ru.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/ru.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Roundup 1.3.2\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:21+0100\n" "Last-Translator: alexander smishlajev <alex@tycobka.lv>\n" "Language-Team: Russian\n" @@ -29,18 +29,18 @@ msgid "You may not retire the admin or anonymous user" msgstr "îÅÌØÚÑ ÕÄÁÌÑÔØ ÐÏÌØÚÏ×ÁÔÅÌÅÊ admin É anonymous." -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "ëÌÁÓÓ \"%(classname)s\" ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "ÁÒÇÕÍÅÎÔ \"%(arg)s\" ÄÏÌÖÅÎ ÉÍÅÔØ ×ÉÄ ÉÍÑ=ÚÎÁÞÅÎÉÅ" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -49,7 +49,7 @@ "ïÛÉÂËÁ: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -98,12 +98,12 @@ " roundup-admin help <command> -- ÓÐÒÁ×ËÁ ÐÏ ËÏÍÁÎÄÅ\n" " roundup-admin help all -- ×ÓÅ ÓÐÒÁ×ÏÞÎÙÅ ÓÏÏÂÝÅÎÉÑ\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "ëÏÍÁÎÄÙ:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -117,7 +117,7 @@ # ÎÏ ÍÎÅ ÜÔÏ ÓÏ×ÓÅÍ ÎÅ ÎÒÁ×ÉÔÓÑ. # # ÞÔÏ ÌÕÞÛÅ ÎÁÐÉÓÁÔØ ×ÍÅÓÔÏ "××ÅÓÔÉ Ó ÔÅÒÍÉÎÁÌÁ"? -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -248,12 +248,12 @@ "\n" "óÐÒÁ×ËÁ ÐÏ ËÏÍÁÎÄÁÍ:\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -273,20 +273,20 @@ " all -- ×ÓÅ ÓÐÒÁ×ËÉ\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "é×ÉÎÉÔÅ, ÓÐÒÁ×ËÁ \"%(topic)s\" ÎÅ ÓÕÝÅÓÔ×ÕÅÔ." -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "ûÁÂÌÏÎÙ:" -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "óÅÒ×ÅÒÙ:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" " Install a new Roundup tracker.\n" @@ -338,23 +338,23 @@ " óÍ.ÔÁËÖÅ \"help initopts\".\n" " " -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "îÅÄÏÓÔÁÔÏÞÎÏ ÁÒÇÕÍÅÎÔÏ×" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "ëÁÔÁÌÏÇ \"%(parent)s\" ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -365,22 +365,22 @@ "ðÏ×ÔÏÒÎÁÑ ÕÓÔÁÎÏ×ËÁ ÕÎÉÞÔÏÖÉÔ ×ÓÅ ×ÁÛÉ ÄÁÎÎÙÅ!\n" "õÄÁÌÉÔØ ÓÕÝÅÓÔ×ÕÀÝÉÊ ÔÒÅËÅÒ? Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "÷ÙÂÅÒÉÔÅ ÛÁÂÌÏÎ [classic]: " -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "÷ÙÂÅÒÉÔÅ ÓÅÒ×ÅÒ [anydbm]: " -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "ïÛÉÂËÁ × ÐÁÒÁÍÅÔÒÁÈ ËÏÎÆÉÇÕÒÁÃÉÉ: \"%s\"" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, python-format msgid "" "\n" @@ -393,12 +393,12 @@ " ôÅÐÅÒØ ×ÁÍ ÎÕÖÎÏ ÉÓÐÒÁ×ÉÔØ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÙÊ ÆÁÊÌ ÔÒÅËÅÒÁ:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... ËÁË ÍÉÎÉÍÕÍ, ×Ù ÄÏÌÖÎÙ ÕÓÔÁÎÏ×ÉÔØ ÎÁÓÔÒÏÊËÉ:" # õËÁÚÁÎÏ ÁÎÇÌÉÊÓËÏÅ ÎÁÚ×ÁÎÉÅ ÄÏËÕÍÅÎÔÁ -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, python-format msgid "" "\n" @@ -425,7 +425,7 @@ " ðÏÓÌÅ ÜÔÏÇÏ ×Ù ÄÏÌÖÎÙ ×ÙÐÏÌÎÉÔØ ËÏÍÁÎÄÕ \"roundup-admin initialise\".\n" "---------------------------------------------------------------------------\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 #, fuzzy msgid "" "Usage: genconfig <filename>\n" @@ -438,7 +438,7 @@ " ÉÓÐÏÌØÚÕÑ ÎÁÓÔÒÏÊËÉ ÐÏ ÕÍÏÌÞÁÎÉÀ.\n" " " -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 #, fuzzy msgid "" "Usage: updateconfig <filename>\n" @@ -454,7 +454,7 @@ # password #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -472,23 +472,23 @@ " éÎÉÃÉÁÌÉÚÁÃÉÑ ÔÒÅËÅÒÁ ÄÅÌÁÅÔÓÑ ÆÕÎËÃÉÅÊ dbinit.init()\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "ðÁÒÏÌØ ÁÄÍÉÎÉÓÔÒÁÔÏÒÁ: " -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " åÝÅ ÒÁÚ: " -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "äÏÍÁÛÎÉÊ ËÁÔÁÌÏÇ ÔÒÅËÅÒÁ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "ôÒÅËÅÒ ÎÅ ÕÓÔÁÎÏ×ÌÅÎ" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -498,7 +498,7 @@ "ðÏ×ÔÏÒÎÁÑ ÉÎÉÃÉÁÌÉÚÁÃÉÑ ÕÎÉÞÔÏÖÉÔ ×ÓÅ ×ÁÛÉ ÄÁÎÎÙÅ!\n" "õÄÁÌÉÔØ ÓÕÝÅÓÔ×ÕÀÝÕÀ ÂÁÚÕ? Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -519,24 +519,24 @@ " ÐÅÒÅÞÉÓÌÅÎÎÙÈ × ÓÐÉÓËÅ ÏÐÉÓÁÔÅÌÅÊ.\n" " " -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "" "ëÌÀÞ '-d' ÎÅÐÒÉÍÅÎÉÍ, ÐÏÔÏÍÕ ÞÔÏ ÔÉÐ ÁÔÒÉÂÕÔÁ %s - ÎÅ Link É ÎÅ Multilink" -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "÷ ËÌÁÓÓÅ %(classname)s ÎÅÔ ÏÂßÅËÔÁ \"%(nodeid)s\"" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "õ ËÌÁÓÓÁ %(classname)s ÎÅÔ ÁÔÒÉÂÕÔÁ \"%(propname)s\"" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -571,7 +571,7 @@ " ÁÔÒÉÂÕÔ. (îÁÐÒÉÍÅÒ, \"1,2,3\".)\n" " " -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -592,19 +592,19 @@ " ËÏÔÏÒÙÊ ÓÓÙÌÁÅÔÓÑ ÁÔÒÉÂÕÔ, ÉÌÉ ËÌÀÞÏÍ ÜÔÏÇÏ ÏÂßÅËÔÁ.\n" " " -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "ëÌÁÓÓ %(classname)s ÎÅ ÉÍÅÅÔ ÁÔÒÉÂÕÔÁ \"%(propname)s\"" -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "ëÌÁÓÓ %(classname)s ÎÅ ÉÍÅÅÔ ÁÔÒÉÂÕÔÁ \"%(propname)s\"" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -622,7 +622,7 @@ " ËÏÔÏÒÙÊ ÓÓÙÌÁÅÔÓÑ ÁÔÒÉÂÕÔ, ÉÌÉ ËÌÀÞÏÍ ÜÔÏÇÏ ÏÂßÅËÔÁ.\n" " " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -636,17 +636,17 @@ " ÷ÙÄÁÅÔ ÓÐÉÓÏË ÁÔÒÉÂÕÔÏ× ÕËÁÚÁÎÎÏÇÏ ËÌÁÓÓÁ.\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (ËÌÀÞÅ×ÏÊ ÁÔÒÉÂÕÔ)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s (ËÌÀÞÅ×ÏÊ ÁÔÒÉÂÕÔ)" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -667,12 +667,12 @@ " ÚÁÄÁÎÎÙÈ ÏÐÉÓÁÔÅÌÑÍÉ.\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -690,31 +690,31 @@ " ÜÔÏÇÏ ÏÂßÅËÔÁ ÕËÁÚÁÎÎÙÍÉ ÚÎÁÞÅÎÉÑÍÉ.\n" " " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr " %(propname)s (ÐÁÒÏÌØ): " -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr "%(propname)s (ÅÝÅ ÒÁÚ): " -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "ðÁÒÏÌÉ ÎÅ ÓÏ×ÐÁÌÉ. ðÏÐÒÏÂÕÊÔÅ ÅÝÅ ÒÁÚ." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "" -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "áÔÒÉÂÕÔ \"%(propname)s\" ÄÏÌÖÅÎ ÂÙÔØ ÚÁÐÏÌÎÅÎ." -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -743,16 +743,16 @@ " ×ÙÄÁÅÔ ÓÐÉÓÏË ÚÎÁÞÅÎÉÊ ÜÔÏÇÏ ÁÔÒÉÂÕÔÁ.\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "ðÏÄÁÎÏ ÓÌÉÛËÏÍ ÍÎÏÇÏ ÐÁÒÁÍÅÔÒÏ×" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -812,17 +812,17 @@ " ÏÂÒÅÚÁÅÔ ÚÎÁÞÅÎÉÑ ÓÔÏÌÂÃÁ \"Name\" ÄÏ ÞÅÔÙÒÅÈ ÓÉÍ×ÏÌÏ×.\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "úÎÁÞÅÎÉÅ \"%(spec)s\" ÄÏÌÖÎÏ ÂÙÔØ ÚÁÄÁÎÏ ËÁË ÉÍÑ:ÛÉÒÉÎÁ" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -837,7 +837,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -861,7 +861,7 @@ " Á×ÔÏÍÁÔÉÞÅÓËÉ, ÅÓÌÉ ÐÒÉ ×ÙÐÏÌÎÅÎÉÉ ËÏÍÁÎÄÙ ÎÅ ÐÒÏÉÚÏÛÌÏ ÏÛÉÂËÉ.\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -882,7 +882,7 @@ " ÂÙÌÏ × ÍÏÍÅÎÔ ÐÏÓÌÅÄÎÅÊ ÚÁÐÉÓÉ.\n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -904,7 +904,7 @@ " ÉÓÐÏÌØÚÏ×ÁÎÙ × ÄÒÕÇÉÈ ÏÂßÅËÔÁÈ.\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -923,13 +923,13 @@ " ÍÏÖÎÏ ÐÏÌØÚÏ×ÁÔØÓÑ ÓÎÏ×Á.\n" " " -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "÷ ËÌÁÓÓÅ %(classname)s ÎÅÔ ÏÂßÅËÔÁ \"%(nodeid)s\"" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 msgid "" "Usage: export [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files.\n" @@ -966,7 +966,7 @@ " exporttables.\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" " Export the database to colon-separated-value files, excluding the\n" @@ -1004,7 +1004,7 @@ " ÐÏÌÎÏÓÔØÀ, ÉÓÐÏÌØÚÕÊÔÅ ËÏÍÁÎÄÕ export.\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -1048,7 +1048,7 @@ " ÉÚ ÓÕÝÅÓÔ×ÕÀÝÅÊ ÂÁÚÙ ×ÓÅ ÏÂßÅËÔÙ).\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -1056,7 +1056,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1096,11 +1096,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1116,12 +1116,12 @@ " ÄÁÎÎÙÈ. ïÂÙÞÎÏ ÐÏÓÔÒÏÅÎÉÅ ÉÎÄÅËÓÏ× ÐÒÏÉÓÈÏÄÉÔ Á×ÔÏÍÁÔÉÞÅÓËÉ.\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "ÏÂßÅËÔ \"%(designator)s\" ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1134,49 +1134,49 @@ " ÒÏÌÑÍ.\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "òÏÌØ \"%(role)s\" ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "îÏ×ÙÅ ÐÏÌØÚÏ×ÁÔÅÌÉ web ÐÏÌÕÞÁÀÔ ÒÏÌÉ \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "îÏ×ÙÅ ÐÏÌØÚÏ×ÁÔÅÌÉ web ÐÏÌÕÞÁÀÔ ÒÏÌØ \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "îÏ×ÙÅ ÐÏÌØÚÏ×ÁÔÅÌÉ email ÐÏÌÕÞÁÀÔ ÒÏÌÉ \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "îÏ×ÙÅ ÐÏÌØÚÏ×ÁÔÅÌÉ email ÐÏÌÕÞÁÀÔ ÒÏÌØ \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "òÏÌØ \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s ÔÏÌØËÏ ÄÌÑ ËÌÁÓÓÁ \"%(klass)s\")" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr "" " %(description)s (%(name)s ÄÌÑ ËÌÁÓÓÁ \"%(klass)s\": ÔÏÌØËÏ Ó×ÏÊÓÔ×Á " "%(properties)s)" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1184,17 +1184,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s ÔÏÌØËÏ ÄÌÑ ËÌÁÓÓÁ \"%(klass)s\")" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s ÔÏÌØËÏ ÄÌÑ ËÌÁÓÓÁ \"%(klass)s\")" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -1218,43 +1218,43 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 #, fuzzy msgid "Tracker updated" msgstr "ãÅÎÔÒ ÕÐÒÁ×ÌÅÎÉÑ ÚÁÄÁÎÉÑÍÉ" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "" "ëÏÍÁÎÄÁ \"%(command)s\" ÎÅÉÚ×ÅÓÔÎÁ. (\"help commands\" ×ÙÄÁÅÔ ÓÐÉÓÏË ËÏÍÁÎÄ)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "\"%(command)s\" ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ÎÅÓËÏÌØËÉÍ ËÏÍÁÎÄÁÍ: %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "äÏÍÁÛÎÉÊ ËÁÔÁÌÏÇ ÔÒÅËÅÒÁ: " -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "ïÛÉÂËÁ: %(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "ïÛÉÂËÁ: ôÒÅËÅÒ ÎÅ ÏÔËÒÙ×ÁÅÔÓÑ: %(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1263,41 +1263,41 @@ "Roundup %s Ë ×ÁÛÉÍ ÕÓÌÕÇÁÍ.\n" "÷×ÅÄÉÔÅ \"help\" ÄÌÑ ÓÐÒÁ×ËÉ." -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "ðÒÉÍÅÞÁÎÉÅ: ÒÁÂÏÔÁÅÔ ÒÅÄÁËÔÏÒ É ÉÓÔÏÒÉÑ ËÏÍÁÎÄ" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "" -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "ÐÒÉÈÏÄÉÔÅ Ë ÎÁÍ ÅÝÅ..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "ïÊ, ÔÕÔ ÎÅÓÏÈÒÁÎÅÎÎÙÅ ÉÚÍÅÎÅÎÉÑ. úÁÐÉÓÁÔØ × ÂÁÚÕ ÄÁÎÎÙÈ (y/N)? " -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1311,53 +1311,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "ÓÏÚÄÁÎÉÅ" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "ÏÔ×ÑÚËÁ" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "ÐÒÉ×ÑÚËÁ" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "ÕÓÔÁÎÏ×ËÁ" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "ÚÁÐÒÅÝÅÎÉÅ" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "×ÏÓÓÔÁÎÏ×ÌÅÎÉÅ" @@ -1597,22 +1619,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÏÌØ ÉÌÉ ÉÍÑ ÐÏÌØÚÏ×ÁÔÅÌÑ." -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÎÁ ÒÁÂÏÔÕ Ó ÓÉÓÔÅÍÏÊ" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, fuzzy, python-format msgid "You do not have permission to view %(class)s" msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÒÅÄÁËÔÉÒÏ×ÁÔØ %(class)s" @@ -1718,154 +1745,154 @@ "áÄÍÉÎÉÓÔÒÁÔÏÒÕ ÔÒÅËÅÒÁ ÏÔÏÓÌÁÎÏ ÓÏÏÂÝÅÎÉÅ Ï ÏÛÉÂËÅ.</p>\n" "</body></html>" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "ïÛÉÂËÁ ÆÏÒÍÙ: " -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "ëÏÄÉÒÏ×ËÁ %r ÎÅ ÒÁÓÐÏÚÎÁÎÁ" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "áÎÏÎÉÍÎÙÍ ÐÏÌØÚÏ×ÁÔÅÌÑÍ ÎÅ ÒÁÚÒÅÛÅÎÏ ÐÏÌØÚÏ×ÁÔØÓÑ ×ÅÂ-ÉÎÔÅÒÆÅÊÓÏÍ." -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, fuzzy, python-format -msgid "Invalid Origin %s" -msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÏÌØ ÉÌÉ ÉÍÑ ÐÏÌØÚÏ×ÁÔÅÌÑ." - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 +#, fuzzy, python-format +msgid "Invalid Origin %s" +msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÏÌØ ÉÌÉ ÉÍÑ ÐÏÌØÚÏ×ÁÔÅÌÑ." + +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÎÁ ÐÒÏÓÍÏÔÒ ÜÔÏÇÏ ÆÁÊÌÁ." -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "%(starttag)súÁÔÒÁÞÅÎÎÏÅ ×ÒÅÍÑ: %(seconds)fs%(endtag)s\n" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " @@ -1875,6 +1902,13 @@ "%(cache_misses)d. úÁÇÒÕÚËÁ ÏÂßÅËÔÏ×: %(get_items)f ÓÅË. æÉÌØÔÒÁÃÉÑ: " "%(filtering)f ÓÅË.%(endtag)s\n" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1948,18 +1982,18 @@ # ../roundup/cgi/templating.py:673 :792 :1166 :1187 :1231 :1253 :1287 :1326 # :1377 :1394 :1470 :1490 :1503 :1520 :1530 :1580 :1755 #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[ÎÅÄÏÓÔÕÐÎÏ]" @@ -1985,64 +2019,70 @@ msgid "The linked class %(classname)s no longer exists" msgstr "ó×ÑÚÑÎÎÙÊ ËÌÁÓÓ %(classname)s ÕÖÅ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # :823 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>ó×ÑÚÁÎÎÙÊ ÏÂßÅËÔ ÕÖÅ ÎÅ ÓÕÝÅÓÔ×ÕÅÔ</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (ÎÅÔ ÚÎÁÞÅÎÉÑ)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" "strong>" msgstr "<strong><em>îÅÉÚ×ÅÓÔÎÙÊ ÔÉÐ ÓÏÂÙÔÉÑ!</em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>ðÒÉÍÅÞÁÎÉÅ:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "éÓÔÏÒÉÑ" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>äÁÔÁ</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "éÓÔÏÒÉÑ" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>äÁÔÁ</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>ðÏÌØÚÏ×ÁÔÅÌØ</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>äÅÊÓÔ×ÉÅ</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>ðÁÒÁÍÅÔÒÙ</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, python-format msgid "Copy of %(class)s %(id)s" msgstr "ëÏÐÉÑ: %(class)s %(id)s" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "îÅÔ" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "äÁ" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." @@ -2050,17 +2090,17 @@ "ÚÎÁÞÅÎÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ ÄÌÑ DateHTMLProperty ÄÏÌÖÎÏ ÂÙÔØ ÏÂßÅËÔÏÍ " "DateHTMLProperty ÉÌÉ ÓÔÒÏËÏ×ÙÍ ÐÒÅÄÓÔÁ×ÌÅÎÉÅÍ ÄÁÔÙ." -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "ðÏÐÙÔËÁ ÐÏÌÕÞÉÔØ ÁÔÒÉÂÕÔ \"%(attr)s\" ÎÅÓÕÝÅÓÔ×ÕÀÝÅÇÏ ÏÂßÅËÔÁ" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, fuzzy, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "ðÏÐÙÔËÁ ÐÏÌÕÞÉÔØ ÁÔÒÉÂÕÔ \"%(attr)s\" ÎÅÓÕÝÅÓÔ×ÕÀÝÅÇÏ ÏÂßÅËÔÁ" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- ÎÅ ÕËÁÚÁÎÏ -</option>" @@ -2078,11 +2118,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ" + #: ../roundup/date.py:395 #, fuzzy, python-format msgid "" @@ -2257,23 +2309,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -2287,44 +2339,44 @@ "÷îéíáîéå! ëÁÔÁÌÏÇ '%s'\n" "\tÓÏÄÅÒÖÉÔ ÛÁÂÌÏÎ ÓÔÁÒÏÇÏ ÏÂÒÁÚÃÁ - ÐÒÏÐÕÝÅÎ" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "îÏ×ÏÅ ÓÏÏÂÝÅÎÉÅ" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" @@ -2332,7 +2384,7 @@ "\n" "÷ ÐÉÓØÍÁÈ ÄÌÑ ÔÒÅËÅÒÁ Roundup ÄÏÌÖÎÁ ÂÙÔØ ÕËÁÚÁÎÁ ÔÅÍÁ ÓÏÏÂÝÅÎÉÑ (Subject).\n" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2361,7 +2413,7 @@ " 1234, ËÏÔÏÒÁÑ ÕÖÅ ÓÕÝÅÓÔ×ÕÅÔ × ÔÒÅËÅÒÅ.\n" "ôÅÍÁ ×ÁÛÅÇÏ ÐÉÓØÍÁ: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -2378,7 +2430,7 @@ "éÍÅÎÁ ÓÕÝÅÓÔ×ÕÀÝÉÈ ËÌÁÓÓÏ×: %(validname)s\n" "ôÅÍÁ ×ÁÛÅÇÏ ÐÉÓØÍÁ: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -2408,7 +2460,7 @@ "\n" "ôÅÍÁ ×ÁÛÅÇÏ ÐÉÓØÍÁ: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -2427,7 +2479,7 @@ "\n" "ôÅÍÁ ×ÁÛÅÇÏ ÐÉÓØÍÁ: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2442,7 +2494,7 @@ "\n" "ôÅÍÁ ×ÁÛÅÇÏ ÐÉÓØÍÁ: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -2456,21 +2508,21 @@ "\n" "îÅÉÚ×ÅÓÔÎÙÊ ÁÄÒÅÓ: %(from_address)s\n" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÎÁ ÄÏÓÔÕÐ Ë ÜÔÏÍÕ ÔÒÅËÅÒÕ." -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÒÅÄÁËÔÉÒÏ×ÁÔØ %(classname)s" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÓÏÚÄÁ×ÁÔØ ÏÂßÅËÔÙ %(classname)s" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2485,27 +2537,27 @@ "\n" "ôÅÍÁ ÐÉÓØÍÁ: \"%(subject)s\"\n" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÎÁ ÓÏÚÄÁÎÉÅ ÆÁÊÌÏ×." -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÄÏÂÁ×ÌÑÔØ ÆÁÊÌÙ ÄÌÑ ËÌÁÓÓÁ %(classname)s." -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" @@ -2515,11 +2567,11 @@ "óÏÏÂÝÅÎÉÑ ÄÌÑ Roundup ÄÏÌÖÎÙ ÂÙÔØ × ÔÅËÓÔÏ×ÏÍ ÆÏÒÍÁÔÅ.\n" "÷ ×ÁÛÅÍ ÓÏÏÂÝÅÎÉÉ ÎÅ ÎÁÊÄÅÎÁ ÞÁÓÔØ ÆÏÒÍÁÔÁ text/plain.\n" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÎÁ ÓÏÚÄÁÎÉÅ ÓÏÏÂÝÅÎÉÊ" -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2530,22 +2582,22 @@ "óÏÏÂÝÅÎÉÅ ÏÔÂÒÏÛÅÎÏ ÄÅÔÅËÔÏÒÏÍ.\n" "%(error)s\n" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÄÏÂÁ×ÌÑÔØ ÓÏÏÂÝÅÎÉÑ ÄÌÑ ËÌÁÓÓÁ %(classname)s." -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÉÚÍÅÎÑÔØ ÁÔÒÉÂÕÔ %(prop)s ËÌÁÓÓÁ %(classname)s" -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "õ ×ÁÓ ÎÅÔ ÒÁÚÒÅÛÅÎÉÑ ÉÚÍÅÎÑÔØ ÁÔÒÉÂÕÔ %(prop)s ËÌÁÓÓÁ %(classname)s" -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2556,7 +2608,7 @@ "ðÒÉ ÏÂÒÁÂÏÔËÅ ×ÁÛÅÇÏ ÓÏÏÂÝÅÎÉÑ ÐÒÏÉÚÏÛÌÁ ÏÛÉÂËÁ:\n" " %(message)s\n" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, fuzzy, python-format msgid "" "\n" @@ -2570,7 +2622,7 @@ "Ï ÎÅÐÒÁ×ÉÌØÎÏ ÏÐÉÓÁÎÎÏÍ ËÌÁÓÓÅ:\n" " %(current_class)s\n" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2584,24 +2636,41 @@ "Ï ÎÅÐÒÁ×ÉÌØÎÏ ÏÐÉÓÁÎÎÙÈ ÁÔÒÉÂÕÔÁÈ:\n" " %(errors)s\n" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "" "ÁÒÇÕÍÅÎÔÙ ÄÏÌÖÎÙ ÂÙÔØ × ÆÏÒÍÁÔÅ [ÉÍÑ=ÚÎÁÞÅÎÉÅ,ÚÎÁÞÅÎÉÅ,...;ÉÍÑ=ÚÎÁÞÅÎÉÅ," "ÚÎÁÞÅÎÉÅ,...]" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÏÌØ ÉÌÉ ÉÍÑ ÐÏÌØÚÏ×ÁÔÅÌÑ." + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2903,7 +2972,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "÷îéíáîéå: ÓÏÚÄÁÅÔÓÑ ×ÒÅÍÅÎÎÙÊ ÓÅÒÔÉÆÉËÁÔ ÄÌÑ SSL" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2911,56 +2980,56 @@ "<html><head><title>óÐÉÓÏË ÔÒÅËÅÒÏ× Roundup</title></head>\n" "<body><h1>óÐÉÓÏË ÔÒÅËÅÒÏ× Roundup</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s (ËÌÀÞÅ×ÏÊ ÁÔÒÉÂÕÔ)" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "" "÷îéíáîéå: ÐÁÒÁÍÅÔÒ \"-g\" ÎÅ ÉÓÐÏÌØÚÕÅÔÓÑ, ÏÎ ÒÁÚÒÅÛÅÎ ÔÏÌØËÏ ÄÌÑ " "ÐÏÌØÚÏ×ÁÔÅÌÑ root" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "ðÏÄÍÅÎÁ ÇÒÕÐÐÙ ÎÅ×ÏÚÍÏÖÎÁ - ÎÕÖÅÎ ÍÏÄÕÌØ grp" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "çÒÕÐÐÁ %(group)s ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "úÁÐÕÓË ÓÅÒ×ÅÒÁ Ó ÐÏÌÎÏÍÏÞÉÑÍÉ ÐÏÌØÚÏ×ÁÔÅÌÑ root ÚÁÐÒÅÝÅÎ!" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "" "÷îéíáîéå: ÐÁÒÁÍÅÔÒ \"-u\" ÎÅ ÉÓÐÏÌØÚÕÅÔÓÑ, ÏÎ ÒÁÚÒÅÛÅÎ ÔÏÌØËÏ ÄÌÑ " "ÐÏÌØÚÏ×ÁÔÅÌÑ root" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "ðÏÄÍÅÎÁ ÐÏÌØÚÏ×ÁÔÅÌÑ ÎÅ×ÏÚÍÏÖÎÁ - ÎÕÖÅÎ ÍÏÄÕÌØ pwd" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "ðÏÌØÚÏ×ÁÔÅÌØ %(user)s ÎÅ ÓÕÝÅÓÔ×ÕÅÔ" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "òÅÖÉÍ \"%s\" ÎÅÄÏÓÔÕÐÅÎ, ÐÅÒÅËÌÀÞÁÅÍÓÑ × ÏÄÎÏÚÁÄÁÞÎÙÊ ÒÅÖÉÍ" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "îÅ×ÏÚÍÏÖÎÏ ÕÓÔÁÎÏ×ÉÔØ ÓÅÒ×ÅÒ ÎÁ ÐÏÒÔÕ %s, ÐÏÒÔ ÕÖÅ ÚÁÎÑÔ." -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 msgid "" " -c <Command> Windows Service options.\n" " If you want to run the server as a Windows Service, you\n" @@ -2977,7 +3046,7 @@ " ÆÁÊÌ ÐÒÏÔÏËÏÌÁ. ëÏÍÁÎÄÁ 'roundup-server -c help'\n" " ×ÙÄÁÅÔ ÓÐÒÁ×ËÕ Ï ËÏÍÁÎÄÎÏÊ ÓÔÒÏËÅ ÓÅÒ×ÉÓÁ Windows." -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2991,9 +3060,10 @@ " É ÚÁÐÕÓÔÉÔØ ÓÅÒ×ÅÒ × ÆÏÎÏ×ÏÍ ÒÅÖÉÍÅ. åÓÌÉ ÕËÁÚÁÎÏ \"-d\",\n" " ÆÁÊÌ ÐÒÏÔÏËÏÌÁ *ÏÂÑÚÁÔÅÌØÎÏ* ÄÏÌÖÅÎ ÂÙÔØ ÚÁÄÁÎ ËÌÀÞÏÍ \"-l\"" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -3016,6 +3086,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -3110,21 +3183,21 @@ " ÎÅ ÍÏÇÕÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ × URL (ÐÒÏÂÅÌÙ, ÒÕÓÓËÉÅ ÂÕË×Ù É ÐÒÏÞ.),\n" " ÐÏÔÏÍÕ ÞÔÏ ÔÁËÉÅ ÉÍÅÎÁ ÓÂÉ×ÁÀÔ Ó ÔÏÌËÕ ÎÅËÏÔÏÒÙÅ ÂÒÁÕÚÅÒÙ ÔÉÐÁ IE.\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "óÐÉÓÏË ÔÒÅËÅÒÏ× ÄÏÌÖÅÎ ÂÙÔØ × ÆÏÒÍÁÔÅ ÉÍÑ=ËÁÔÁÌÏÇ" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "ëÏÎÆÉÇÕÒÁÃÉÑ ÚÁÐÉÓÁÎÁ × %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "" "éÚ×ÉÎÉÔÅ, × ÜÔÏÊ ÏÐÅÒÁÃÉÏÎÎÏÊ ÓÉÓÔÅÍÅ ÒÁÂÏÔÁ × ÆÏÎÏ×ÏÍ ÒÅÖÉÍÅ ÎÅ×ÏÚÍÏÖÎÁ" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "óÅÒ×ÅÒ Roundup ÇÏÔÏ× Ë ÒÁÂÏÔÅ ÐÏ ÁÄÒÅÓÕ %(HOST)s:%(PORT)s" @@ -3262,6 +3335,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3278,6 +3352,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3294,6 +3369,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -4125,6 +4201,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4673,7 +4750,7 @@ msgid "User listing" msgstr "óÐÉÓÏË ÐÏÌØÚÏ×ÁÔÅÌÅÊ" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4681,13 +4758,13 @@ msgid "Username" msgstr "ðÏÌØÚÏ×ÁÔÅÌØ" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "éÍÑ, ÆÁÍÉÌÉÑ" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4696,26 +4773,26 @@ msgid "Organisation" msgstr "ïÒÇÁÎÉÚÁÃÉÑ" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "áÄÒÅÓ email" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "ôÅÌÅÆÏÎ" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "õ×ÏÌÉÔØ" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4866,67 +4943,67 @@ "ÚÁËÏÎÞÉÔØ ÒÅÇÉÓÔÒÁÃÉÀ, ×ÙÚÏ×ÉÔÅ ÕËÁÚÁÎÎÕÀ × ÐÉÓØÍÅ ÓÓÙÌËÕ." #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "ËÒÉÔÉÞÅÓËÉÊ" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "ÓÒÏÞÎÙÊ" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "ÏÛÉÂËÁ" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "ÒÁÚ×ÉÔÉÅ" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "ÐÏÖÅÌÁÎÉÅ" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "ÎÏ×ÙÊ" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "ÏÔÌÏÖÅÎ" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "ÏÂÓÕÖÄÅÎÉÅ" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "ÎÕÖÅÎ ÐÒÉÍÅÒ" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "× ÒÁÂÏÔÅ" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "ÔÅÓÔÉÒÏ×ÁÎÉÅ" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "ÓÄÅÌÁÎÏ; ÍÏÖÎÏ ÕÌÕÞÛÉÔØ" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "ÓÄÅÌÁÎÏ"
--- a/locale/zh_CN.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/zh_CN.po Thu Apr 21 16:54:17 2022 -0400 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: 0.8.3\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:22+0100\n" "Last-Translator: Cheer Xiao <xiaqqaix@gmail.com>\n" "Language-Team: Chinese Simplified <limodou@gmail.com>\n" @@ -31,19 +31,19 @@ msgstr "ä½ ä¸èƒ½æ’¤é™¤ç®¡ç†å‘˜æˆ–匿å用户" # ../roundup/admin.py:84 :943 :992 :1014 -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "æ— æ¤ç±»åˆ« \"%(classname)s\"" # ../roundup/admin.py:94 :98 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "傿•° \"%(arg)s\" 䏿˜¯ propname=value 的形å¼" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -52,7 +52,7 @@ "问题: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -99,12 +99,12 @@ " roundup-admin help <command> -- 命令详解帮助\n" " roundup-admin help all -- 所有å¯ç”¨çš„帮助\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "命令:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -112,7 +112,7 @@ "命令å¯ä»¥è¢«ç¼©å†™ï¼Œåªè¦ç¼©å†™åªæœ‰ä¸€ä¸ªå‘½ä»¤å¯ä»¥åŒ¹é…上,\n" "如:l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -235,12 +235,12 @@ "\n" "使用帮助:\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "%s:" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -260,22 +260,22 @@ " all -- 所有å¯ç”¨çš„帮助\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "抱æ‰ï¼Œæ²¡æœ‰â€œ%(topic)sâ€çš„帮助信æ¯" # ../roundup/admin.py:337 :387 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "模æ¿:" # ../roundup/admin.py:340 :398 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "åŽç«¯:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 #, fuzzy msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" @@ -317,23 +317,23 @@ # ../roundup/admin.py:359 :494 :573 :623 :676 :697 :725 :796 :863 :934 :982 # :1004 :1031 :1093 :1159 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "未æä¾›è¶³å¤Ÿçš„傿•°" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "实例目录的父目录 \"%(parent)s\" ä¸å˜åœ¨" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -344,22 +344,22 @@ "å¦‚æžœä½ é‡æ–°å®‰è£…,所有的数æ®å°†ä¼šä¸¢å¤±ï¼\n" "åˆ é™¤å®ƒå—?Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "é€‰æ‹©æ¨¡æ¿ [classic]:" -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "选择åŽç«¯ [anydbm]:" -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, python-format msgid "Error in configuration settings: \"%s\"" msgstr "é…置设定有错: “%sâ€" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, fuzzy, python-format msgid "" "\n" @@ -371,11 +371,11 @@ " çŽ°åœ¨ä½ åº”è¯¥ä¿®æ”¹trackerçš„é…置文件:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... è‡³å°‘ï¼Œä½ å¿…é¡»è®¾ç½®ä»¥ä¸‹é€‰é¡¹ï¼š" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, fuzzy, python-format msgid "" "\n" @@ -399,7 +399,7 @@ " %(database_init_file)s\n" " ... 查看关于客户化的文档æ¥äº†è§£æ›´å¤šçš„ä¿¡æ¯ã€‚\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 msgid "" "Usage: genconfig <filename>\n" " Generate a new tracker config file (ini style) with default\n" @@ -407,7 +407,7 @@ " " msgstr "" -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 msgid "" "Usage: updateconfig <filename>\n" " Generate an updated tracker config file (ini style) in\n" @@ -417,7 +417,7 @@ msgstr "" #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -435,23 +435,23 @@ " 执行trackerçš„åˆå§‹åŒ–函数 dbinit.init()\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "管ç†å‘˜å¯†ç :" -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " 确认:" -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "实例目录ä¸å˜åœ¨" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "实例还没有安装" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -461,7 +461,7 @@ "å¦‚æžœä½ é‡æ–°åˆå§‹åŒ–它,所有的数æ®å°†ä¼šä¸¢å¤±ï¼\n" "åˆ é™¤å®ƒå—?Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -481,24 +481,24 @@ " " # ../roundup/admin.py:527 :542 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "属性 %s 䏿˜¯ Multilink 或 Link 类型,所以 -d æ ‡å¿—ä¸èƒ½åº”用。" # ../roundup/admin.py:550 :945 :994 :1016 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "æ²¡æœ‰è¿™æ ·çš„ %(classname)s 结点 \"%(nodeid)s\"" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "æ²¡æœ‰è¿™æ ·çš„ %(classname)s 属性 \"%(propname)s\"" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -531,7 +531,7 @@ " ä½ éœ€è¦ä¸ºå¤šé“¾æŽ¥æä¾›ç”¨é€—å·åˆ†éš”的数å—(例如 \"1,2,3\")。\n" " " -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -553,20 +553,20 @@ " " # ../roundup/admin.py:663 :816 :828 :882 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "%(classname)s 没有 \"%(propname)s\" 属性" # ../roundup/admin.py:663 :816 :828 :882 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "%(classname)s 没有 \"%(propname)s\" 属性" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -584,7 +584,7 @@ " 或者是结点的键值。\n" " " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -598,17 +598,17 @@ " 会列出给定类型的属性。\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (关键属性)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -628,12 +628,12 @@ " 将显示给出结点的属性和相应的值。\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -651,31 +651,31 @@ "name=value 傿•°ã€‚\n" " " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (密ç ):" -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (冿¬¡):" -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "抱æ‰ï¼Œå†è¯•一次..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "" -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "ä½ å¿…é¡»æä¾› \"%(propname)s\" 属性。" -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -701,16 +701,16 @@ " 定了属性,对æ¯ä¸ªç±»åž‹å®žä¾‹ä¼šæ‰“å°å‡ºè¿™ä¸ªå±žæ€§ã€‚\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "æä¾›äº†å¤ªå¤šçš„傿•°äº†" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "%(nodeid)4s: %(value)s" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -768,17 +768,17 @@ " 将生æˆ4个å—符宽的 \"Name\" 列。\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "\"%(spec)s\" 䏿˜¯ åå—:宽度" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -793,7 +793,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -814,7 +814,7 @@ " 在命令行ä¸çš„ One-off 命令如果æˆåŠŸä¼šè¢«è‡ªåŠ¨æäº¤ã€‚\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -833,7 +833,7 @@ " 产生å˜åŒ–。\n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -853,7 +853,7 @@ " 它的键值å¯ä»¥è¢«é‡ç”¨ã€‚\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -872,13 +872,13 @@ " " # ../roundup/admin.py:550 :945 :994 :1016 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "æ²¡æœ‰è¿™æ ·çš„ %(classname)s 结点 \"%(nodeid)s\"" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 #, fuzzy msgid "" "Usage: export [[-]class[,class]] export_dir\n" @@ -903,7 +903,7 @@ " æ”¾åœ¨æŒ‡å®šçš„ç›®æ ‡ç›®å½•ä¸ã€‚\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 #, fuzzy msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" @@ -929,7 +929,7 @@ " æ”¾åœ¨æŒ‡å®šçš„ç›®æ ‡ç›®å½•ä¸ã€‚\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -969,7 +969,7 @@ " æ—§æ•°æ®ã€‚)\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -977,7 +977,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1015,11 +1015,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "æ— æ•ˆçš„æ ¼å¼" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1034,12 +1034,12 @@ " 釿–°ç”Ÿæˆ tracker çš„æœç´¢ç´¢å¼•,它将自动进行。\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "æ²¡æœ‰è¿™æ ·çš„æ¡ç›® \"%(designator)s\"" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1051,47 +1051,47 @@ " 显示一个或多个角色的æƒé™ã€‚\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "æ²¡æœ‰è¿™æ ·çš„è§’è‰² \"%(role)s\"" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "æ–°Web用户得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "æ–°Web用户得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "新邮件用户得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "新邮件用户得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "角色 \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s 仅用于 \"%(klass)s\")" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr " %(description)s (%(name)s 仅用于 \"%(klass)s\")" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1099,17 +1099,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s 仅用于 \"%(klass)s\")" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s)" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -1133,42 +1133,42 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 msgid "Tracker updated" msgstr "Tracker å·²ç»æ›´æ–°" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "ä¸å¿…执行è¿ç§»" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "未知命令 \"%(command)s\" (\"help commands\" 查看命令列表)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "å¤šå‘½ä»¤åŒ¹é… \"%(command)s\": %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "输入tracker起始目录:" # ../roundup/admin.py:1279 :1285 :1305 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "错误:%(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "错误:ä¸èƒ½æ‰“å¼€tracker:%(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1177,41 +1177,41 @@ "Roundup %s 输入就绪。\n" "敲入 \"help\" 获得帮助。" -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "注æ„:命令历å²å’Œç¼–è¾‘æ— æ•ˆ" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "roundup>" -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "退出..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "å˜åœ¨æœªè¢«ä¿å˜çš„æ”¹åŠ¨ã€‚æäº¤å—(y/N)?" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1225,53 +1225,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "创建" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "解链" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "链接" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "修改" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "撤除" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "æ¢å¤" @@ -1505,22 +1527,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "æ— æ•ˆç™»å½•" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "ä½ æ²¡æœ‰ç™»å½•çš„æƒé™" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, python-format msgid "You do not have permission to view %(class)s" msgstr "ä½ æ²¡æœ‰æŸ¥çœ‹ %(class)s çš„æƒé™" @@ -1617,160 +1644,167 @@ "</body></html>" msgstr "" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "è¡¨æ ¼é”™è¯¯ï¼š" -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "æ— æ³•è¯†åˆ«çš„å—符集:%r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "匿å用户ä¸å…许使用 web 界é¢" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, fuzzy, python-format -msgid "Invalid Origin %s" -msgstr "æ— æ•ˆç™»å½•" - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 +#, python-format +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 #, fuzzy, python-format -msgid "Invalid HOST %s" -msgstr "æ— æ•ˆè¯·æ±‚" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +msgid "Invalid Origin %s" +msgstr "æ— æ•ˆç™»å½•" + +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, fuzzy, python-format +msgid "Invalid HOST %s" +msgstr "æ— æ•ˆè¯·æ±‚" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 msgid "You are not allowed to view this file." msgstr "ä½ æ²¡æœ‰æŸ¥çœ‹æ¤æ–‡ä»¶çš„æƒé™" -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " "items: %(get_items)f secs. Filtering: %(filtering)f secs.%(endtag)s\n" msgstr "" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, fuzzy, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1837,18 +1871,18 @@ msgstr "æäº¤" #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "[éšè—]" @@ -1874,80 +1908,86 @@ msgid "The linked class %(classname)s no longer exists" msgstr "链接的类 %(classname)s ä¸å†å˜åœ¨" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:872 :893 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>链接的结点ä¸å†å˜åœ¨</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (æ— å€¼)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" "strong>" msgstr "<strong><em>这个事件ä¸èƒ½è¢«åކ岿˜¾ç¤ºæ‰€å¤„ç†ï¼</em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>注æ„:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "历å²" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>日期</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "历å²" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>日期</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>用户</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>动作</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>傿•°</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, fuzzy, python-format msgid "Copy of %(class)s %(id)s" msgstr "%(class)s %(id)s 被创建" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "å¦" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "是" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." msgstr "DateHTMLProperty 的缺çœå€¼æˆ–者是 DateHTMLProperty 或å—符串的日期表示。" -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- 未选择 -</option>" @@ -1965,11 +2005,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "æ— æ•ˆè¯·æ±‚" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "æ— æ•ˆè¯·æ±‚" + #: ../roundup/date.py:395 #, python-format msgid "" @@ -2120,23 +2172,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, python-format msgid "Not a property name: %s" msgstr "䏿˜¯å±žæ€§å: %s" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -2148,50 +2200,50 @@ "\tcontains old-style template - ignored" msgstr "" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "新消æ¯" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" msgstr "" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2208,7 +2260,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -2219,7 +2271,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -2236,7 +2288,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -2247,7 +2299,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2257,7 +2309,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -2266,21 +2318,21 @@ "Unknown address: %(from_address)s\n" msgstr "" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 msgid "You are not permitted to access this tracker." msgstr "ä½ æ²¡æœ‰è®¿é—®æ¤ tracker çš„æƒé™ã€‚" -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, python-format msgid "You are not permitted to edit %(classname)s." msgstr "ä½ æ²¡æœ‰ç¼–è¾‘ %(classname)s çš„æƒé™ã€‚" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, python-format msgid "You are not permitted to create %(classname)s." msgstr "ä½ åˆ›å»º %(classname)s çš„æƒé™ã€‚" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2290,38 +2342,38 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 msgid "You are not permitted to create files." msgstr "ä½ æ²¡æœ‰åˆ›å»ºæ–‡ä»¶çš„æƒé™ã€‚" -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "ä½ æ²¡æœ‰å‘ %(classname)s æ·»åŠ æ–‡ä»¶çš„æƒé™ã€‚" -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" "not find a text/plain part to use.\n" msgstr "" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 msgid "You are not permitted to create messages." msgstr "ä½ æ²¡æœ‰åˆ›å»ºæ¶ˆæ¯çš„æƒé™ã€‚" -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2329,22 +2381,22 @@ "%(error)s\n" msgstr "" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "ä½ æ²¡æœ‰å‘ %(classname)s æ·»åŠ æ¶ˆæ¯çš„æƒé™ã€‚" -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "ä½ æ²¡æœ‰ç¼–è¾‘ %(classname)s 类的 %(prop)s 属性的æƒé™ã€‚" -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "ä½ æ²¡æœ‰ç¼–è¾‘ %(classname)s 类的 %(prop)s 属性的æƒé™ã€‚" -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2352,7 +2404,7 @@ " %(message)s\n" msgstr "" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, python-format msgid "" "\n" @@ -2361,7 +2413,7 @@ " %(clsname)s\n" msgstr "" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2370,22 +2422,39 @@ " %(errors)s\n" msgstr "" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "æ— æ•ˆç™»å½•" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2663,7 +2732,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2671,52 +2740,52 @@ "<html><head><title>Roundup tracker 索引</title></head>\n" "<body><h1>Roundup tracker 索引</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "è¦å‘Šï¼šå¿½ç•¥ \"-g\" 傿•°ï¼Œä¸æ˜¯ root" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "ä¸èƒ½ä¿®æ”¹ç»„ - æ— grp 模å—" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "组 %(group)s ä¸å˜åœ¨" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "ä¸èƒ½ä»¥ root è¿è¡Œï¼" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "è¦å‘Šï¼šå¿½ç•¥ \"-u\" 傿•°ï¼Œä¸æ˜¯ root" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "ä¸èƒ½ä¿®æ”¹ç”¨æˆ· - æ— pwd 模å—" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "用户 %(user)s ä¸å˜åœ¨" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "æ— æ³•ç»‘å®šåˆ°ç«¯å£ %s, 端å£å·²ç»è¢«å 用。" -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 #, fuzzy msgid "" " -c <Command> Windows Service options.\n" @@ -2733,7 +2802,7 @@ " å˜é‡ä¸Šé…置一个tracker。这个选项与其ç»é€‰é¡¹æ˜¯äº’斥的。打入\n" " \"roundup-server -c help\" æ¥äº†è§£WindowsæœåŠ¡çš„è§„èŒƒã€‚" -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2747,9 +2816,10 @@ "去。\n" " 如果使用了 -d 选项,则 -l 选项 *å¿…é¡»* è¦æŒ‡å®šã€‚" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2772,6 +2842,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -2839,20 +2912,20 @@ " æ„æ•°é‡çš„ name=home 对。è¦ç¡®ä¿ name 部分ä¸èƒ½åŒ…括任何éžurl安全的\n" " å—ç¬¦ï¼Œè±¡ç©ºæ ¼ï¼Œå› ä¸ºå®ƒä»¬ä¼šæŠŠIEæžä¹±ã€‚\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "实例必须是 实例å=实例路径" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "é…ç½®ä¿å˜åˆ° %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "抱æ‰ï¼Œåœ¨è¿™ä¸ªæ“作系统上ä¸èƒ½ä»¥å®ˆæŠ¤è¿›ç¨‹çš„æ–¹å¼æ¥è¿è¡ŒæœåŠ¡" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Roundup server å¯åŠ¨äºŽ %(HOST)s:%(PORT)s" @@ -2987,6 +3060,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3003,6 +3077,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3019,6 +3094,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -3843,6 +3919,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4381,7 +4458,7 @@ msgid "User listing" msgstr "用户列表" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4389,13 +4466,13 @@ msgid "Username" msgstr "用户å" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "真实姓å" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4404,26 +4481,26 @@ msgid "Organisation" msgstr "组织" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "邮件地å€" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "电è¯å·ç " -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "撤除" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4572,67 +4649,67 @@ msgstr "ä½ å°†å¾ˆå¿«æ”¶åˆ°ä¸€å°ç¡®è®¤ä¿¡ã€‚è®¿é—®é‚®ä»¶ä¸æŒ‡ç¤ºçš„链接,å³å¯å®Œæˆæ³¨å†Œã€‚" #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "关键" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "紧急" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "bug" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "特性" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "未读" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "延期" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "讨论ä¸" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "进行ä¸" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 msgid "testing" msgstr "测试ä¸" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "done-cbb" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 msgid "resolved" msgstr "已解决"
--- a/locale/zh_TW.po Fri Oct 08 00:37:16 2021 -0400 +++ b/locale/zh_TW.po Thu Apr 21 16:54:17 2022 -0400 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: 0.8.3\n" "Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2021-07-12 22:10-0400\n" +"POT-Creation-Date: 2022-03-05 18:51-0500\n" "PO-Revision-Date: 2013-10-31 12:23+0100\n" "Last-Translator: Fred Lin <gasolin@gmail>\n" "Language-Team: Chinese Traditional <gasolin@gmail.com>\n" @@ -30,19 +30,19 @@ msgstr "ä½ ä¸èƒ½åˆªé™¤ç®¡ç†å“¡æˆ–匿å用戶" # ../roundup/admin.py:84 :943 :992 :1014 -#: ../roundup/admin.py:95 ../roundup/admin.py:1173 ../roundup/admin.py:1228 -#: ../roundup/admin.py:1255 ../roundup/admin.py:95:1173 :1228:1255 +#: ../roundup/admin.py:99 ../roundup/admin.py:1199 ../roundup/admin.py:1254 +#: ../roundup/admin.py:1281 ../roundup/admin.py:99:1199 :1254:1281 #, python-format msgid "no such class \"%(classname)s\"" msgstr "ç„¡æ¤é¡žåˆ¥ \"%(classname)s\"" # ../roundup/admin.py:94 :98 -#: ../roundup/admin.py:107 +#: ../roundup/admin.py:111 #, python-format msgid "argument \"%(arg)s\" not propname=value" msgstr "åƒæ•¸ \"%(arg)s\" 䏿˜¯ propname=value 的形å¼" -#: ../roundup/admin.py:120 +#: ../roundup/admin.py:124 #, python-format msgid "" "Problem: %(message)s\n" @@ -51,7 +51,7 @@ "å•題: %(message)s\n" "\n" -#: ../roundup/admin.py:121 +#: ../roundup/admin.py:125 #, fuzzy, python-format msgid "" "%(message)sUsage: roundup-admin [options] [<command> <arguments>]\n" @@ -98,12 +98,12 @@ " roundup-admin help <command> -- 命令詳解說明\n" " roundup-admin help all -- 所有å¯ç”¨çš„說明\n" -#: ../roundup/admin.py:148 +#: ../roundup/admin.py:152 #, fuzzy msgid "Commands: " msgstr "命令:" -#: ../roundup/admin.py:155 +#: ../roundup/admin.py:159 msgid "" "Commands may be abbreviated as long as the abbreviation\n" "matches only one command, e.g. l == li == lis == list." @@ -111,7 +111,7 @@ "命令å¯ä»¥è¢«ç¸®å¯«ï¼Œåªè¦ç¸®å¯«åªæœ‰ä¸€å€‹å‘½ä»¤å¯ä»¥åŒ¹é…上,\n" "如:l == li == lis == list." -#: ../roundup/admin.py:182 +#: ../roundup/admin.py:186 msgid "" "\n" "All commands (except help) require a tracker specifier. This is just\n" @@ -233,12 +233,12 @@ "\n" "使用說明:\n" -#: ../roundup/admin.py:245 +#: ../roundup/admin.py:249 #, python-format msgid "%s:" msgstr "" -#: ../roundup/admin.py:250 +#: ../roundup/admin.py:254 msgid "" "Usage: help topic\n" " Give help about topic.\n" @@ -258,22 +258,22 @@ " all -- 所有å¯ç”¨çš„說明\n" " " -#: ../roundup/admin.py:272 +#: ../roundup/admin.py:276 #, python-format msgid "Sorry, no help for \"%(topic)s\"" msgstr "抱æ‰ï¼Œæ²’æœ‰å° \"%(topic)s\" 的說明信æ¯" # ../roundup/admin.py:337 :387 -#: ../roundup/admin.py:349 ../roundup/admin.py:405 ../roundup/admin.py:349:405 +#: ../roundup/admin.py:375 ../roundup/admin.py:431 ../roundup/admin.py:375:431 msgid "Templates:" msgstr "模æ¿ï¼š" # ../roundup/admin.py:340 :398 -#: ../roundup/admin.py:352 ../roundup/admin.py:415 ../roundup/admin.py:352:415 +#: ../roundup/admin.py:378 ../roundup/admin.py:441 ../roundup/admin.py:378:441 msgid "Back ends:" msgstr "後端:" -#: ../roundup/admin.py:355 +#: ../roundup/admin.py:381 #, fuzzy msgid "" "Usage: install [template [backend [key=val[,key=val]]]]\n" @@ -315,23 +315,23 @@ # ../roundup/admin.py:359 :494 :573 :623 :676 :697 :725 :796 :863 :934 :982 # :1004 :1031 :1093 :1159 -#: ../roundup/admin.py:378 ../roundup/admin.py:510 ../roundup/admin.py:583 -#: ../roundup/admin.py:674 ../roundup/admin.py:732 ../roundup/admin.py:816 -#: ../roundup/admin.py:875 ../roundup/admin.py:902 ../roundup/admin.py:929 -#: ../roundup/admin.py:1004 ../roundup/admin.py:1071 ../roundup/admin.py:1157 -#: ../roundup/admin.py:1218 ../roundup/admin.py:1245 ../roundup/admin.py:1281 -#: ../roundup/admin.py:1412 ../roundup/admin.py:1499 -#: ../roundup/admin.py:378:510 :1071 :1157:1218 :1245:1281 :1412:1499 :583:674 -#: :732:816 :875:902 :929:1004 +#: ../roundup/admin.py:404 ../roundup/admin.py:536 ../roundup/admin.py:609 +#: ../roundup/admin.py:700 ../roundup/admin.py:758 ../roundup/admin.py:842 +#: ../roundup/admin.py:901 ../roundup/admin.py:928 ../roundup/admin.py:955 +#: ../roundup/admin.py:1030 ../roundup/admin.py:1097 ../roundup/admin.py:1183 +#: ../roundup/admin.py:1244 ../roundup/admin.py:1271 ../roundup/admin.py:1307 +#: ../roundup/admin.py:1435 ../roundup/admin.py:1522 +#: ../roundup/admin.py:404:536 :1097 :1183:1244 :1271:1307 :1435:1522 :609:700 +#: :758:842 :901:928 :955:1030 msgid "Not enough arguments supplied" msgstr "未æä¾›è¶³å¤ çš„åƒæ•¸" -#: ../roundup/admin.py:384 +#: ../roundup/admin.py:410 #, python-format msgid "Instance home parent directory \"%(parent)s\" does not exist" msgstr "實例目錄的父目錄 \"%(parent)s\" ä¸å˜åœ¨" -#: ../roundup/admin.py:393 +#: ../roundup/admin.py:419 #, python-format msgid "" "WARNING: There appears to be a tracker in \"%(tracker_home)s\"!\n" @@ -342,22 +342,22 @@ "å¦‚æžœä½ æ‰“ç®—é‡æ–°å®‰è£å®ƒï¼Œæ‰€æœ‰çš„æ•¸æ“šå°‡æœƒä¸Ÿå¤±ï¼\n" "刪除它嗎?Y/N: " -#: ../roundup/admin.py:406 +#: ../roundup/admin.py:432 #, fuzzy msgid "Select template" msgstr "鏿“‡æ¨¡æ¿ [classic]:" -#: ../roundup/admin.py:416 +#: ../roundup/admin.py:442 #, fuzzy msgid "Select backend" msgstr "鏿“‡å¾Œç«¯ [anydbm]:" -#: ../roundup/admin.py:427 +#: ../roundup/admin.py:453 #, fuzzy, python-format msgid "Error in configuration settings: \"%s\"" msgstr "é…ç½®ä¿å˜åˆ° %s" -#: ../roundup/admin.py:458 +#: ../roundup/admin.py:484 #, fuzzy, python-format msgid "" "\n" @@ -369,11 +369,11 @@ " ç¾åœ¨ä½ 應該修改trackerçš„é…置文件:\n" " %(config_file)s" -#: ../roundup/admin.py:468 +#: ../roundup/admin.py:494 msgid " ... at a minimum, you must set following options:" msgstr " ... è‡³å°‘ï¼Œä½ å¿…é ˆè¨ç½®ä»¥ä¸‹é¸é …:" -#: ../roundup/admin.py:473 +#: ../roundup/admin.py:499 #, fuzzy, python-format msgid "" "\n" @@ -397,7 +397,7 @@ " %(database_init_file)s\n" " ... 查看關於客戶化的文檔來çžè§£æ›´å¤šçš„ä¿¡æ¯ã€‚\n" -#: ../roundup/admin.py:505 +#: ../roundup/admin.py:531 msgid "" "Usage: genconfig <filename>\n" " Generate a new tracker config file (ini style) with default\n" @@ -405,7 +405,7 @@ " " msgstr "" -#: ../roundup/admin.py:520 +#: ../roundup/admin.py:546 msgid "" "Usage: updateconfig <filename>\n" " Generate an updated tracker config file (ini style) in\n" @@ -415,7 +415,7 @@ msgstr "" #. password -#: ../roundup/admin.py:528 +#: ../roundup/admin.py:554 msgid "" "Usage: initialise [adminpw]\n" " Initialise a new Roundup tracker.\n" @@ -433,23 +433,23 @@ " 執行trackerçš„åˆå§‹åŒ–函數 dbinit.init()\n" " " -#: ../roundup/admin.py:542 +#: ../roundup/admin.py:568 msgid "Admin Password: " msgstr "管ç†å“¡å£ä»¤ï¼š" -#: ../roundup/admin.py:543 +#: ../roundup/admin.py:569 msgid " Confirm: " msgstr " 確èªï¼š" -#: ../roundup/admin.py:547 +#: ../roundup/admin.py:573 msgid "Instance home does not exist" msgstr "實例目錄ä¸å˜åœ¨" -#: ../roundup/admin.py:551 +#: ../roundup/admin.py:577 msgid "Instance has not been installed" msgstr "實例還沒有安è£" -#: ../roundup/admin.py:557 +#: ../roundup/admin.py:583 msgid "" "WARNING: The database is already initialised!\n" "If you re-initialise it, you will lose all the data!\n" @@ -459,7 +459,7 @@ "å¦‚æžœä½ é‡æ–°åˆå§‹åŒ–它,所有的數據將會丟失ï¼\n" "刪除它嗎?Y/N: " -#: ../roundup/admin.py:573 +#: ../roundup/admin.py:599 #, fuzzy msgid "" "Usage: get property designator[,designator]*\n" @@ -479,24 +479,24 @@ " " # ../roundup/admin.py:527 :542 -#: ../roundup/admin.py:616 ../roundup/admin.py:633 ../roundup/admin.py:616:633 +#: ../roundup/admin.py:642 ../roundup/admin.py:659 ../roundup/admin.py:642:659 #, python-format msgid "property %s is not of type Multilink or Link so -d flag does not apply." msgstr "屬性 %s 䏿˜¯ Multilink 或 Link 類型,所以 -d 標誌ä¸èƒ½æ‡‰ç”¨ã€‚" # ../roundup/admin.py:550 :945 :994 :1016 -#: ../roundup/admin.py:643 ../roundup/admin.py:1175 ../roundup/admin.py:1230 -#: ../roundup/admin.py:643:1175:1230 +#: ../roundup/admin.py:669 ../roundup/admin.py:1201 ../roundup/admin.py:1256 +#: ../roundup/admin.py:669:1201:1256 #, python-format msgid "no such %(classname)s node \"%(nodeid)s\"" msgstr "沒有這樣的 %(classname)s çµé»ž \"%(nodeid)s\"" -#: ../roundup/admin.py:646 +#: ../roundup/admin.py:672 #, python-format msgid "no such %(classname)s property \"%(propname)s\"" msgstr "沒有這樣的 %(classname)s 屬性 \"%(propname)s\"" -#: ../roundup/admin.py:654 +#: ../roundup/admin.py:680 #, fuzzy msgid "" "Usage: set items property=value property=value ...\n" @@ -529,7 +529,7 @@ " ä½ éœ€è¦ç‚ºå¤šéˆæŽ¥æä¾›ç”¨é€—號分隔的數å—(例如 \"1,2,3\")。\n" " " -#: ../roundup/admin.py:722 +#: ../roundup/admin.py:748 #, fuzzy msgid "" "Usage: filter classname propname=value ...\n" @@ -551,20 +551,20 @@ " " # ../roundup/admin.py:663 :816 :828 :882 -#: ../roundup/admin.py:764 +#: ../roundup/admin.py:790 #, fuzzy, python-format msgid "Class %(curclassname)s has no property %(pn)s in %(propname)s." msgstr "%(classname)s 沒有 \"%(propname)s\" 屬性" # ../roundup/admin.py:663 :816 :828 :882 -#: ../roundup/admin.py:801 ../roundup/admin.py:862 ../roundup/admin.py:1024 -#: ../roundup/admin.py:1036 ../roundup/admin.py:1091 -#: ../roundup/admin.py:801:862 :1024:1036:1091 +#: ../roundup/admin.py:827 ../roundup/admin.py:888 ../roundup/admin.py:1050 +#: ../roundup/admin.py:1062 ../roundup/admin.py:1117 +#: ../roundup/admin.py:827:888 :1050:1062:1117 #, python-format msgid "%(classname)s has no property \"%(propname)s\"" msgstr "%(classname)s 沒有 \"%(propname)s\" 屬性" -#: ../roundup/admin.py:808 +#: ../roundup/admin.py:834 msgid "" "Usage: find classname propname=value ...\n" " Find the nodes of the given class with a given link property value.\n" @@ -582,7 +582,7 @@ " 或者是çµé»žçš„éµå€¼ã€‚\n" " " -#: ../roundup/admin.py:869 +#: ../roundup/admin.py:895 msgid "" "Usage: specification classname\n" " Show the properties for a classname.\n" @@ -596,17 +596,17 @@ " 會列出給定類型的屬性。\n" " " -#: ../roundup/admin.py:885 +#: ../roundup/admin.py:911 #, fuzzy, python-format msgid "%(key)s: %(value)s (key property)\n" msgstr "%(key)s: %(value)s (é—œéµå±¬æ€§)" -#: ../roundup/admin.py:888 +#: ../roundup/admin.py:914 #, fuzzy, python-format msgid "%(key)s: %(value)s\n" msgstr "%(key)s: %(value)s (é—œéµå±¬æ€§)" -#: ../roundup/admin.py:891 +#: ../roundup/admin.py:917 #, fuzzy msgid "" "Usage: display designator[,designator]*\n" @@ -626,12 +626,12 @@ " 將顯示給出çµé»žçš„屬性和相應的值。\n" " " -#: ../roundup/admin.py:918 +#: ../roundup/admin.py:944 #, python-format msgid "%(key)s: %(value)s" msgstr "" -#: ../roundup/admin.py:921 +#: ../roundup/admin.py:947 msgid "" "Usage: create classname property=value ...\n" " Create a new entry of a given class.\n" @@ -649,31 +649,31 @@ "name=value åƒæ•¸ã€‚\n" " " -#: ../roundup/admin.py:949 +#: ../roundup/admin.py:975 #, python-format msgid "%(propname)s (Password): " msgstr "%(propname)s (å£ä»¤):" -#: ../roundup/admin.py:952 +#: ../roundup/admin.py:978 #, python-format msgid " %(propname)s (Again): " msgstr " %(propname)s (冿¬¡):" -#: ../roundup/admin.py:955 +#: ../roundup/admin.py:981 msgid "Sorry, try again..." msgstr "抱æ‰ï¼Œå†è©¦ä¸€æ¬¡..." -#: ../roundup/admin.py:959 +#: ../roundup/admin.py:985 #, python-format msgid "%(propname)s (%(proptype)s): " msgstr "" -#: ../roundup/admin.py:977 +#: ../roundup/admin.py:1003 #, python-format msgid "you must provide the \"%(propname)s\" property." msgstr "ä½ å¿…é ˆæä¾› \"%(propname)s\" 屬性。" -#: ../roundup/admin.py:989 +#: ../roundup/admin.py:1015 msgid "" "Usage: list classname [property]\n" " List the instances of a class.\n" @@ -699,16 +699,16 @@ " å®šäº†å±¬æ€§ï¼Œå°æ¯å€‹é¡žåž‹å¯¦ä¾‹æœƒåˆ—å°å‡ºé€™å€‹å±¬æ€§ã€‚\n" " " -#: ../roundup/admin.py:1002 +#: ../roundup/admin.py:1028 msgid "Too many arguments supplied" msgstr "æä¾›äº†å¤ªå¤šçš„åƒæ•¸äº†" -#: ../roundup/admin.py:1038 +#: ../roundup/admin.py:1064 #, python-format msgid "%(nodeid)4s: %(value)s" msgstr "" -#: ../roundup/admin.py:1042 +#: ../roundup/admin.py:1068 msgid "" "Usage: table classname [property[,property]*]\n" " List the instances of a class in tabular form.\n" @@ -766,17 +766,17 @@ " 將生æˆ4個å—符寬的 \"Name\" 列。\n" " " -#: ../roundup/admin.py:1086 +#: ../roundup/admin.py:1112 #, python-format msgid "\"%(spec)s\" not name:width" msgstr "\"%(spec)s\" 䏿˜¯ åå—:寬度" -#: ../roundup/admin.py:1108 +#: ../roundup/admin.py:1134 #, python-format msgid "\"%(spec)s\" does not have an integer width: \"%(width)s\"" msgstr "" -#: ../roundup/admin.py:1144 +#: ../roundup/admin.py:1170 msgid "" "Usage: history designator [skipquiet]\n" " Show the history entries of a designator.\n" @@ -791,7 +791,7 @@ " " msgstr "" -#: ../roundup/admin.py:1180 +#: ../roundup/admin.py:1206 msgid "" "Usage: commit\n" " Commit changes made to the database during an interactive session.\n" @@ -812,7 +812,7 @@ " 在命令行ä¸çš„ One-off 命令如果æˆåŠŸæœƒè¢«è‡ªå‹•æäº¤ã€‚\n" " " -#: ../roundup/admin.py:1195 +#: ../roundup/admin.py:1221 msgid "" "Usage: rollback\n" " Undo all changes that are pending commit to the database.\n" @@ -831,7 +831,7 @@ " 產生變化。\n" " " -#: ../roundup/admin.py:1208 +#: ../roundup/admin.py:1234 #, fuzzy msgid "" "Usage: retire designator[,designator]*\n" @@ -851,7 +851,7 @@ " 它的éµå€¼å¯ä»¥è¢«é‡ç”¨ã€‚\n" " " -#: ../roundup/admin.py:1236 +#: ../roundup/admin.py:1262 #, fuzzy msgid "" "Usage: restore designator[,designator]*\n" @@ -870,13 +870,13 @@ " " # ../roundup/admin.py:550 :945 :994 :1016 -#: ../roundup/admin.py:1261 +#: ../roundup/admin.py:1287 #, fuzzy msgid "no such %(classname)s node \" % (nodeid)s\"" msgstr "沒有這樣的 %(classname)s çµé»ž \"%(nodeid)s\"" #. grab the directory to export to -#: ../roundup/admin.py:1267 +#: ../roundup/admin.py:1293 #, fuzzy msgid "" "Usage: export [[-]class[,class]] export_dir\n" @@ -901,7 +901,7 @@ " 放在指定的目標目錄ä¸ã€‚\n" " " -#: ../roundup/admin.py:1377 +#: ../roundup/admin.py:1400 #, fuzzy msgid "" "Usage: exporttables [[-]class[,class]] export_dir\n" @@ -927,7 +927,7 @@ " 放在指定的目標目錄ä¸ã€‚\n" " " -#: ../roundup/admin.py:1392 +#: ../roundup/admin.py:1415 msgid "" "Usage: import import_dir\n" " Import a database from the directory containing CSV files,\n" @@ -967,7 +967,7 @@ " 舊數據。)\n" " " -#: ../roundup/admin.py:1474 +#: ../roundup/admin.py:1497 msgid "" "Usage: importtables export_dir\n" "\n" @@ -975,7 +975,7 @@ " " msgstr "" -#: ../roundup/admin.py:1481 +#: ../roundup/admin.py:1504 msgid "" "Usage: pack period | date\n" "\n" @@ -1013,11 +1013,11 @@ "\n" " " -#: ../roundup/admin.py:1509 +#: ../roundup/admin.py:1532 msgid "Invalid format" msgstr "ç„¡æ•ˆçš„æ ¼å¼" -#: ../roundup/admin.py:1520 +#: ../roundup/admin.py:1543 msgid "" "Usage: reindex [classname|designator]*\n" " Re-generate a tracker's search indexes.\n" @@ -1032,12 +1032,12 @@ " 釿–°ç”Ÿæˆ tracker çš„æœç´¢ç´¢å¼•,它將自動進行。\n" " " -#: ../roundup/admin.py:1534 +#: ../roundup/admin.py:1557 #, python-format msgid "no such item \"%(designator)s\"" msgstr "沒有這樣的æ¢ç›® \"%(designator)s\"" -#: ../roundup/admin.py:1544 +#: ../roundup/admin.py:1567 #, fuzzy msgid "" "Usage: security [Role name]\n" @@ -1049,47 +1049,47 @@ " 顯示一個或多個角色的權é™ã€‚\n" " " -#: ../roundup/admin.py:1553 +#: ../roundup/admin.py:1576 #, fuzzy, python-format msgid "No such Role \"%(role)s\"\n" msgstr "沒有這樣的角色 \"%(role)s\"" -#: ../roundup/admin.py:1559 +#: ../roundup/admin.py:1582 #, fuzzy, python-format msgid "New Web users get the Roles \"%(role)s\"\n" msgstr "æ–°Web用戶得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1562 +#: ../roundup/admin.py:1585 #, fuzzy, python-format msgid "New Web users get the Role \"%(role)s\"\n" msgstr "æ–°Web用戶得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1566 +#: ../roundup/admin.py:1589 #, fuzzy, python-format msgid "New Email users get the Roles \"%(role)s\"\n" msgstr "新郵件用戶得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1568 +#: ../roundup/admin.py:1591 #, fuzzy, python-format msgid "New Email users get the Role \"%(role)s\"\n" msgstr "新郵件用戶得到角色 \"%(role)s\"" -#: ../roundup/admin.py:1571 +#: ../roundup/admin.py:1594 #, fuzzy, python-format msgid "Role \"%(name)s\":\n" msgstr "角色 \"%(name)s\":" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy msgid " %(description)s (%(name)s for \"%(klass)s\"" msgstr " %(description)s (%(name)s 僅用於 \"%(klass)s\")" -#: ../roundup/admin.py:1576 +#: ../roundup/admin.py:1599 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\": %(properties)s only)\n" msgstr " %(description)s (%(name)s 僅用於 \"%(klass)s\")" -#: ../roundup/admin.py:1588 +#: ../roundup/admin.py:1611 #, python-format msgid "" "\n" @@ -1097,17 +1097,17 @@ "\n" msgstr "" -#: ../roundup/admin.py:1591 +#: ../roundup/admin.py:1614 #, fuzzy, python-format msgid " %(description)s (%(name)s for \"%(klass)s\" only)\n" msgstr " %(description)s (%(name)s 僅用於 \"%(klass)s\")" -#: ../roundup/admin.py:1594 +#: ../roundup/admin.py:1617 #, fuzzy, python-format msgid " %(description)s (%(name)s)\n" msgstr " %(description)s (%(name)s 僅用於 \"%(klass)s\")" -#: ../roundup/admin.py:1598 +#: ../roundup/admin.py:1621 msgid "" "Usage: migrate\n" "\n" @@ -1131,43 +1131,43 @@ " " msgstr "" -#: ../roundup/admin.py:1619 +#: ../roundup/admin.py:1642 #, fuzzy msgid "Tracker updated" msgstr "Trackeræ ¹ç›®éŒ„" -#: ../roundup/admin.py:1622 +#: ../roundup/admin.py:1645 msgid "No migration action required" msgstr "" -#: ../roundup/admin.py:1648 +#: ../roundup/admin.py:1671 #, python-format msgid "Unknown command \"%(command)s\" (\"help commands\" for a list)" msgstr "未知命令 \"%(command)s\" (\"help commands\" 查看命令列表)" -#: ../roundup/admin.py:1654 +#: ../roundup/admin.py:1677 #, python-format msgid "Multiple commands match \"%(command)s\": %(list)s" msgstr "å¤šå‘½ä»¤åŒ¹é… \"%(command)s\": %(list)s" -#: ../roundup/admin.py:1663 +#: ../roundup/admin.py:1686 msgid "Enter tracker home: " msgstr "輸入tracker起始目錄:" # ../roundup/admin.py:1279 :1285 :1305 -#: ../roundup/admin.py:1672 ../roundup/admin.py:1678 ../roundup/admin.py:1704 -#: ../roundup/admin.py:1672:1678:1704 +#: ../roundup/admin.py:1695 ../roundup/admin.py:1701 ../roundup/admin.py:1730 +#: ../roundup/admin.py:1695:1701:1730 #, python-format msgid "Error: %(message)s" msgstr "錯誤:%(message)s" -#: ../roundup/admin.py:1686 ../roundup/admin.py:1690 -#: ../roundup/admin.py:1686:1690 +#: ../roundup/admin.py:1709 ../roundup/admin.py:1713 +#: ../roundup/admin.py:1709:1713 #, python-format msgid "Error: Couldn't open tracker: %(message)s" msgstr "錯誤:ä¸èƒ½æ‰“é–‹tracker:%(message)s" -#: ../roundup/admin.py:1717 +#: ../roundup/admin.py:1743 #, python-format msgid "" "Roundup %s ready for input.\n" @@ -1176,41 +1176,41 @@ "Roundup %s 輸入就緒。\n" "敲入 \"help\" ç²å¾—說明。" -#: ../roundup/admin.py:1722 +#: ../roundup/admin.py:1748 msgid "Note: command history and editing not available" msgstr "注æ„:命令æ·å²å’Œç·¨è¼¯ç„¡æ•ˆ" -#: ../roundup/admin.py:1726 +#: ../roundup/admin.py:1752 msgid "roundup> " msgstr "" -#: ../roundup/admin.py:1728 +#: ../roundup/admin.py:1754 msgid "exit..." msgstr "退出..." -#: ../roundup/admin.py:1741 +#: ../roundup/admin.py:1767 msgid "There are unsaved changes. Commit them (y/N)? " msgstr "å˜åœ¨æœªè¢«ä¿å˜çš„æ”¹å‹•。æäº¤å—Ž(y/N)?" -#: ../roundup/backends/back_anydbm.py:173 -#: ../roundup/backends/rdbms_common.py:877 +#: ../roundup/backends/back_anydbm.py:173 ../roundup/backends/back_lmdb.py:251 +#: ../roundup/backends/rdbms_common.py:887 #, python-format msgid "Class \"%s\" already defined." msgstr "" -#: ../roundup/backends/back_anydbm.py:234 +#: ../roundup/backends/back_anydbm.py:234 ../roundup/backends/back_lmdb.py:312 #: ../roundup/backends/sessions_dbm.py:55 msgid "Couldn't identify database type" msgstr "" -#: ../roundup/backends/back_anydbm.py:268 +#: ../roundup/backends/back_anydbm.py:268 ../roundup/backends/back_lmdb.py:346 #, python-format msgid "" "Couldn't open database - the required module '%s' (as dbm.gnu) is not " "available" msgstr "" -#: ../roundup/backends/back_anydbm.py:271 +#: ../roundup/backends/back_anydbm.py:271 ../roundup/backends/back_lmdb.py:349 #, python-format msgid "Couldn't open database - the required module '%s' is not available" msgstr "" @@ -1224,53 +1224,75 @@ #: ../roundup/backends/back_anydbm.py:1438 #: ../roundup/backends/back_anydbm.py:2063 #: ../roundup/backends/back_anydbm.py:827:840 -#: ../roundup/backends/rdbms_common.py:1646 -#: ../roundup/backends/rdbms_common.py:1893 -#: ../roundup/backends/rdbms_common.py:2128 -#: ../roundup/backends/rdbms_common.py:2148 -#: ../roundup/backends/rdbms_common.py:2201 -#: ../roundup/backends/rdbms_common.py:3147 -#: ../roundup/backends/rdbms_common.py:1646:1893 :1113:1148 :1374:1392:1438 -#: :2063 :2128:2148 :2201:3147 +#: ../roundup/backends/back_lmdb.py:905 ../roundup/backends/back_lmdb.py:918 +#: ../roundup/backends/back_lmdb.py:1191 ../roundup/backends/back_lmdb.py:1226 +#: ../roundup/backends/back_lmdb.py:1452 ../roundup/backends/back_lmdb.py:1470 +#: ../roundup/backends/back_lmdb.py:1516 ../roundup/backends/back_lmdb.py:2138 +#: ../roundup/backends/back_lmdb.py:905:918 +#: ../roundup/backends/rdbms_common.py:1656 +#: ../roundup/backends/rdbms_common.py:1903 +#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2158 +#: ../roundup/backends/rdbms_common.py:2211 +#: ../roundup/backends/rdbms_common.py:3157 +#: ../roundup/backends/rdbms_common.py:1656:1903 :1113:1148 :1191:1226 +#: :1374:1392:1438 :1452:1470 :1516:2138:2063 :2138:2158:2211 :3157 msgid "Database open read-only" msgstr "" -#: ../roundup/backends/rdbms_common.py:580 +#: ../roundup/backends/indexer_postgresql_fts.py:108 +msgid "" +"You have non-word/operator characters \"<>!&|()*\" in your query. Did you " +"want to do a tsquery search and forgot to start it with \"ts:\"?" +msgstr "" + +#: ../roundup/backends/indexer_postgresql_fts.py:135 +#, python-format +msgid "" +"Check tracker config.ini for a bad indexer_language setting. Error is: %s" +msgstr "" + +#: ../roundup/backends/indexer_sqlite_fts.py:117 +msgid "" +"Search failed. Try quoting any terms that include a '-' and retry the search." +msgstr "" + +#: ../roundup/backends/rdbms_common.py:590 #, python-format msgid "ALTER operation disallowed: %(old)r -> %(new)r." msgstr "" -#: ../roundup/backends/rdbms_common.py:816 +#: ../roundup/backends/rdbms_common.py:826 #, python-format msgid "CREATE operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:833 +#: ../roundup/backends/rdbms_common.py:843 #, python-format msgid "DROP operation disallowed: \"%s\"." msgstr "" -#: ../roundup/backends/rdbms_common.py:1789 +#: ../roundup/backends/rdbms_common.py:1799 msgid "create" msgstr "建立" -#: ../roundup/backends/rdbms_common.py:1963 +#: ../roundup/backends/rdbms_common.py:1973 msgid "unlink" msgstr "解除" -#: ../roundup/backends/rdbms_common.py:1967 +#: ../roundup/backends/rdbms_common.py:1977 msgid "link" msgstr "éˆæŽ¥" -#: ../roundup/backends/rdbms_common.py:2109 +#: ../roundup/backends/rdbms_common.py:2119 msgid "set" msgstr "è¨ç½®" -#: ../roundup/backends/rdbms_common.py:2138 +#: ../roundup/backends/rdbms_common.py:2148 msgid "retired" msgstr "收回" -#: ../roundup/backends/rdbms_common.py:2168 +#: ../roundup/backends/rdbms_common.py:2178 msgid "restored" msgstr "æ¢å¾©" @@ -1507,22 +1529,27 @@ msgid "Logins occurring too fast. Please wait: %s seconds." msgstr "" -#: ../roundup/cgi/actions.py:1369 ../roundup/cgi/actions.py:1373 -#: ../roundup/cgi/actions.py:1369:1373 +#: ../roundup/cgi/actions.py:1357 +#, python-format +msgid "Welcome %(username)s!" +msgstr "" + +#: ../roundup/cgi/actions.py:1377 ../roundup/cgi/actions.py:1381 +#: ../roundup/cgi/actions.py:1377:1381 msgid "Invalid login" msgstr "無效登錄" -#: ../roundup/cgi/actions.py:1379 +#: ../roundup/cgi/actions.py:1387 msgid "You do not have permission to login" msgstr "ä½ æ²’æœ‰ç™»éŒ„çš„æ¬Šé™" -#: ../roundup/cgi/actions.py:1422 ../roundup/cgi/actions.py:1587 -#: ../roundup/cgi/actions.py:1422:1587 +#: ../roundup/cgi/actions.py:1430 ../roundup/cgi/actions.py:1609 +#: ../roundup/cgi/actions.py:1430:1609 #, python-format msgid "Column \"%(column)s\" not found in %(class)s" msgstr "" -#: ../roundup/cgi/actions.py:1643 +#: ../roundup/cgi/actions.py:1680 #, fuzzy, python-format msgid "You do not have permission to view %(class)s" msgstr "ä½ æ²’æœ‰æ¬Šé™ä¾†ç·¨è¼¯ %(class)s" @@ -1619,161 +1646,168 @@ "</body></html>" msgstr "" -#: ../roundup/cgi/client.py:795 +#: ../roundup/cgi/client.py:837 msgid "Form Error: " msgstr "è¡¨æ ¼éŒ¯èª¤ï¼š" -#: ../roundup/cgi/client.py:885 +#: ../roundup/cgi/client.py:927 #, python-format msgid "Unrecognized charset: %r" msgstr "無法è˜åˆ¥çš„å—符集:%r" -#: ../roundup/cgi/client.py:1141 +#: ../roundup/cgi/client.py:1183 msgid "Anonymous users are not allowed to use the web interface" msgstr "匿å用戶ä¸å…許使用web界é¢" -#: ../roundup/cgi/client.py:1214 +#: ../roundup/cgi/client.py:1256 msgid "Referer header not available." msgstr "" -#: ../roundup/cgi/client.py:1218 +#: ../roundup/cgi/client.py:1260 #, python-format msgid "csrf key used with wrong method from: %s" msgstr "" -#: ../roundup/cgi/client.py:1246 +#: ../roundup/cgi/client.py:1288 #, python-format msgid "csrf header %s required but missing for user%s." msgstr "" -#: ../roundup/cgi/client.py:1247 -#, python-format -msgid "Missing header: %s" -msgstr "" - -#: ../roundup/cgi/client.py:1257 ../roundup/cgi/client.py:1260 -#: ../roundup/cgi/client.py:1257:1260 -#, python-format -msgid "csrf Referer header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1258 -#, python-format -msgid "Invalid Referer %s, %s" -msgstr "" - -#: ../roundup/cgi/client.py:1273 ../roundup/cgi/client.py:1276 -#: ../roundup/cgi/client.py:1273:1276 -#, python-format -msgid "csrf Origin header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1274 -#, fuzzy, python-format -msgid "Invalid Origin %s" -msgstr "無效登錄" - -#: ../roundup/cgi/client.py:1288 ../roundup/cgi/client.py:1291 -#: ../roundup/cgi/client.py:1288:1291 -#, python-format -msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" -msgstr "" - #: ../roundup/cgi/client.py:1289 #, python-format -msgid "Invalid X-FORWARDED-HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1308 ../roundup/cgi/client.py:1311 -#: ../roundup/cgi/client.py:1308:1311 +msgid "Missing header: %s" +msgstr "" + +#: ../roundup/cgi/client.py:1299 ../roundup/cgi/client.py:1302 +#: ../roundup/cgi/client.py:1299:1302 +#, python-format +msgid "csrf Referer header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1300 #, python-format -msgid "csrf HOST header check failed for user%s. Value=%s" -msgstr "" - -#: ../roundup/cgi/client.py:1309 +msgid "Invalid Referer %s, %s" +msgstr "" + +#: ../roundup/cgi/client.py:1315 ../roundup/cgi/client.py:1318 +#: ../roundup/cgi/client.py:1315:1318 #, python-format -msgid "Invalid HOST %s" -msgstr "" - -#: ../roundup/cgi/client.py:1317 -msgid "Csrf: unable to verify sufficient headers" -msgstr "" - -#: ../roundup/cgi/client.py:1318 -msgid "Unable to verify sufficient headers" +msgid "csrf Origin header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1316 +#, fuzzy, python-format +msgid "Invalid Origin %s" +msgstr "無效登錄" + +#: ../roundup/cgi/client.py:1330 ../roundup/cgi/client.py:1333 +#: ../roundup/cgi/client.py:1330:1333 +#, python-format +msgid "csrf X-FORWARDED-HOST header check failed for user%s. Value=%s" msgstr "" #: ../roundup/cgi/client.py:1331 #, python-format -msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." -msgstr "" - -#: ../roundup/cgi/client.py:1332 -msgid "Required Header Missing" -msgstr "" - -#: ../roundup/cgi/client.py:1369 +msgid "Invalid X-FORWARDED-HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1350 ../roundup/cgi/client.py:1353 +#: ../roundup/cgi/client.py:1350:1353 #, python-format -msgid "Required csrf field missing for user%s" -msgstr "" - -#: ../roundup/cgi/client.py:1370 ../roundup/cgi/client.py:1422 -#: ../roundup/cgi/client.py:1432 ../roundup/cgi/client.py:1370:1422:1432 -msgid "" -"We can't validate your session (csrf failure). Re-enter any unsaved data and " -"try again." +msgid "csrf HOST header check failed for user%s. Value=%s" +msgstr "" + +#: ../roundup/cgi/client.py:1351 +#, python-format +msgid "Invalid HOST %s" +msgstr "" + +#: ../roundup/cgi/client.py:1359 +msgid "Csrf: unable to verify sufficient headers" +msgstr "" + +#: ../roundup/cgi/client.py:1360 +msgid "Unable to verify sufficient headers" msgstr "" #: ../roundup/cgi/client.py:1373 #, python-format +msgid "csrf X-REQUESTED-WITH xmlrpc required header check failed for user%s." +msgstr "" + +#: ../roundup/cgi/client.py:1374 +msgid "Required Header Missing" +msgstr "" + +#: ../roundup/cgi/client.py:1411 +#, python-format +msgid "Required csrf field missing for user%s" +msgstr "" + +#: ../roundup/cgi/client.py:1412 ../roundup/cgi/client.py:1464 +#: ../roundup/cgi/client.py:1474 ../roundup/cgi/client.py:1412:1464:1474 +msgid "" +"We can't validate your session (csrf failure). Re-enter any unsaved data and " +"try again." +msgstr "" + +#: ../roundup/cgi/client.py:1415 +#, python-format msgid "csrf field not supplied by user%s" msgstr "" -#: ../roundup/cgi/client.py:1420 +#: ../roundup/cgi/client.py:1462 #, python-format msgid "" "Csrf mismatch user: current user %s != stored user %s, current session, " "stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1425 +#: ../roundup/cgi/client.py:1467 #, python-format msgid "" "logged only: Csrf mismatch user: current user %s != stored user %s, current " "session, stored session: %s,%s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1430 +#: ../roundup/cgi/client.py:1472 #, python-format msgid "" "Csrf mismatch user: current session %s != stored session %s, current user/" "stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1435 +#: ../roundup/cgi/client.py:1477 #, python-format msgid "" "logged only: Csrf mismatch user: current session %s != stored session %s, " "current user/stored user is: %s for key %s." msgstr "" -#: ../roundup/cgi/client.py:1607 +#: ../roundup/cgi/client.py:1649 #, fuzzy msgid "You are not allowed to view this file." msgstr "ä½ ä¸å…許查看æ¤é " -#: ../roundup/cgi/client.py:1886 +#: ../roundup/cgi/client.py:1938 #, python-format msgid "%(starttag)sTime elapsed: %(seconds)fs%(endtag)s\n" msgstr "" -#: ../roundup/cgi/client.py:1890 +#: ../roundup/cgi/client.py:1942 #, python-format msgid "" "%(starttag)sCache hits: %(cache_hits)d, misses %(cache_misses)d. Loading " "items: %(get_items)f secs. Filtering: %(filtering)f secs.%(endtag)s\n" msgstr "" +#: ../roundup/cgi/client.py:2472 +#, python-format +msgid "" +"Cache failure: compressed file %(compressed)s is older than its source file " +"%(filename)s" +msgstr "" + #: ../roundup/cgi/form_parser.py:290 #, fuzzy, python-format msgid "link \"%(key)s\" value \"%(entry)s\" not a designator" @@ -1840,18 +1874,18 @@ msgstr "æäº¤æ–°çš„é …" #: ../roundup/cgi/templating.py:963 ../roundup/cgi/templating.py:1134 -#: ../roundup/cgi/templating.py:1747 ../roundup/cgi/templating.py:1776 -#: ../roundup/cgi/templating.py:1796 ../roundup/cgi/templating.py:1809 -#: ../roundup/cgi/templating.py:1846 ../roundup/cgi/templating.py:1899 -#: ../roundup/cgi/templating.py:1922 ../roundup/cgi/templating.py:1929 -#: ../roundup/cgi/templating.py:1965 ../roundup/cgi/templating.py:2002 -#: ../roundup/cgi/templating.py:2035 ../roundup/cgi/templating.py:2124 -#: ../roundup/cgi/templating.py:2145 ../roundup/cgi/templating.py:2235 -#: ../roundup/cgi/templating.py:2255 ../roundup/cgi/templating.py:2277 -#: ../roundup/cgi/templating.py:2316 ../roundup/cgi/templating.py:2326 -#: ../roundup/cgi/templating.py:2390 ../roundup/cgi/templating.py:2688 -#: ../roundup/cgi/templating.py:963:1134 :1747:1776 :1796:1809 :1846:1899 -#: :1922:1929 :1965:2002 :2035:2124 :2145:2235 :2255:2277 :2316:2326 :2390:2688 +#: ../roundup/cgi/templating.py:1753 ../roundup/cgi/templating.py:1782 +#: ../roundup/cgi/templating.py:1802 ../roundup/cgi/templating.py:1815 +#: ../roundup/cgi/templating.py:1852 ../roundup/cgi/templating.py:1905 +#: ../roundup/cgi/templating.py:1928 ../roundup/cgi/templating.py:1935 +#: ../roundup/cgi/templating.py:1971 ../roundup/cgi/templating.py:2008 +#: ../roundup/cgi/templating.py:2041 ../roundup/cgi/templating.py:2130 +#: ../roundup/cgi/templating.py:2151 ../roundup/cgi/templating.py:2241 +#: ../roundup/cgi/templating.py:2261 ../roundup/cgi/templating.py:2283 +#: ../roundup/cgi/templating.py:2322 ../roundup/cgi/templating.py:2332 +#: ../roundup/cgi/templating.py:2396 ../roundup/cgi/templating.py:2695 +#: ../roundup/cgi/templating.py:963:1134 :1753:1782 :1802:1815 :1852:1905 +#: :1928:1935 :1971:2008 :2041:2130 :2151:2241 :2261:2283 :2322:2332 :2396:2695 msgid "[hidden]" msgstr "" @@ -1877,80 +1911,86 @@ msgid "The linked class %(classname)s no longer exists" msgstr "éˆæŽ¥çš„é¡žåˆ¥ %(classname)s ä¸å†å˜åœ¨" +#: ../roundup/cgi/templating.py:1249 ../roundup/cgi/templating.py:1277 +#: ../roundup/cgi/templating.py:2405 ../roundup/cgi/templating.py:2704 +#: ../roundup/cgi/templating.py:1249:1277 :2405:2704 +msgid "[label is missing]" +msgstr "" + # ../roundup/cgi/templating.py:872 :893 -#: ../roundup/cgi/templating.py:1251 ../roundup/cgi/templating.py:1277 -#: ../roundup/cgi/templating.py:1251:1277 +#: ../roundup/cgi/templating.py:1253 ../roundup/cgi/templating.py:1280 +#: ../roundup/cgi/templating.py:1253:1280 msgid "<strike>The linked node no longer exists</strike>" msgstr "<strike>éˆæŽ¥çš„çµé»žä¸å†å˜åœ¨</strike>" -#: ../roundup/cgi/templating.py:1338 +#: ../roundup/cgi/templating.py:1341 #, python-format msgid "%s: (no value)" msgstr "%s: (無值)" -#: ../roundup/cgi/templating.py:1354 +#: ../roundup/cgi/templating.py:1357 #, fuzzy, python-format msgid "" "<strong><em>This event %s is not handled by the history display!</em></" "strong>" msgstr "<strong><em>這個事件ä¸èƒ½è¢«æ·å²é¡¯ç¤ºæ‰€è™•ç†ï¼</em></strong>" -#: ../roundup/cgi/templating.py:1367 +#: ../roundup/cgi/templating.py:1370 msgid "<tr><td colspan=4><strong>Note:</strong></td></tr>" msgstr "<tr><td colspan=4><strong>注æ„:</strong></td></tr>" -#: ../roundup/cgi/templating.py:1376 -msgid "History" -msgstr "æ·å²" - -#: ../roundup/cgi/templating.py:1378 -msgid "<th>Date</th>" -msgstr "<th>日期</th>" - #: ../roundup/cgi/templating.py:1379 +msgid "History" +msgstr "æ·å²" + +#: ../roundup/cgi/templating.py:1381 +msgid "<th>Date</th>" +msgstr "<th>日期</th>" + +#: ../roundup/cgi/templating.py:1382 msgid "<th>User</th>" msgstr "<th>用戶</th>" -#: ../roundup/cgi/templating.py:1380 +#: ../roundup/cgi/templating.py:1383 msgid "<th>Action</th>" msgstr "<th>動作</th>" -#: ../roundup/cgi/templating.py:1381 +#: ../roundup/cgi/templating.py:1384 msgid "<th>Args</th>" msgstr "<th>åƒæ•¸</th>" -#: ../roundup/cgi/templating.py:1432 +#: ../roundup/cgi/templating.py:1435 #, fuzzy, python-format msgid "Copy of %(class)s %(id)s" msgstr "%(class)s %(id)s 被建立" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2072 -#: ../roundup/cgi/templating.py:1320:2039:2072 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2078 +#: ../roundup/cgi/templating.py:1323:2045:2078 msgid "No" msgstr "å¦" -#: ../roundup/cgi/templating.py:2039 ../roundup/cgi/templating.py:2067 -#: ../roundup/cgi/templating.py:1320:2039:2067 +#: ../roundup/cgi/templating.py:2045 ../roundup/cgi/templating.py:2073 +#: ../roundup/cgi/templating.py:1323:2045:2073 msgid "Yes" msgstr "是" -#: ../roundup/cgi/templating.py:2193 +#: ../roundup/cgi/templating.py:2199 msgid "" "default value for DateHTMLProperty must be either DateHTMLProperty or string " "date representation." msgstr "DateHTMLProperty çš„é è¨å€¼æˆ–者是 DateHTMLProperty 或å—符串的日期表示。" -#: ../roundup/cgi/templating.py:2370 +#: ../roundup/cgi/templating.py:2376 #, python-format msgid "Attempt to look up %(attr)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2381 +#: ../roundup/cgi/templating.py:2387 #, python-format msgid "Attempt to look up %(item)s on a missing value" msgstr "" -#: ../roundup/cgi/templating.py:2484 +#: ../roundup/cgi/templating.py:2491 #, python-format msgid "<option %svalue=\"-1\">- no selection -</option>" msgstr "<option %svalue=\"-1\">- æœªé¸æ“‡ -</option>" @@ -1968,11 +2008,23 @@ msgid "Responding to form too quickly." msgstr "" -#: ../roundup/configuration.py:1887 +#: ../roundup/configuration.py:274 +#, python-format +msgid "" +"Error in %(filepath)s with section [%(section)s] at option %(option)s: " +"%(message)s" +msgstr "" + +#: ../roundup/configuration.py:494 #, fuzzy msgid "Valid languages: " msgstr "ç„¡æ•ˆçš„æ ¼å¼" +#: ../roundup/configuration.py:504 +#, fuzzy +msgid "Expected languages: " +msgstr "ç„¡æ•ˆçš„æ ¼å¼" + #: ../roundup/date.py:395 #, python-format msgid "" @@ -2123,23 +2175,23 @@ msgid "\"%s\" not a node designator" msgstr "" -#: ../roundup/hyperdb.py:1472 ../roundup/hyperdb.py:1480 -#: ../roundup/hyperdb.py:1472:1480 +#: ../roundup/hyperdb.py:1473 ../roundup/hyperdb.py:1481 +#: ../roundup/hyperdb.py:1473:1481 #, fuzzy, python-format msgid "Not a property name: %s" msgstr "䏿˜¯æ—¥æœŸæ ¼å¼ï¼š%s" -#: ../roundup/hyperdb.py:1939 +#: ../roundup/hyperdb.py:1940 #, python-format msgid "property %s: %r is not a %s." msgstr "" -#: ../roundup/hyperdb.py:1942 +#: ../roundup/hyperdb.py:1943 #, python-format msgid "you may only enter ID values for property %s" msgstr "" -#: ../roundup/hyperdb.py:1976 +#: ../roundup/hyperdb.py:1977 #, python-format msgid "%r is not a property of %s" msgstr "" @@ -2151,50 +2203,50 @@ "\tcontains old-style template - ignored" msgstr "" -#: ../roundup/mailgw.py:197 ../roundup/mailgw.py:210 -#: ../roundup/mailgw.py:197:210 +#: ../roundup/mailgw.py:198 ../roundup/mailgw.py:211 +#: ../roundup/mailgw.py:198:211 #, python-format msgid "Message signed with unknown key: %s" msgstr "" -#: ../roundup/mailgw.py:200 +#: ../roundup/mailgw.py:201 #, python-format msgid "Message signed with an expired key: %s" msgstr "" -#: ../roundup/mailgw.py:203 +#: ../roundup/mailgw.py:204 #, python-format msgid "Message signed with a revoked key: %s" msgstr "" -#: ../roundup/mailgw.py:206 +#: ../roundup/mailgw.py:207 msgid "Invalid PGP signature detected." msgstr "" -#: ../roundup/mailgw.py:213 +#: ../roundup/mailgw.py:214 #, fuzzy msgid "Unsigned Message" msgstr "æ–°ä¿¡æ¯" -#: ../roundup/mailgw.py:463 +#: ../roundup/mailgw.py:464 msgid "Unknown multipart/encrypted version." msgstr "" -#: ../roundup/mailgw.py:472 +#: ../roundup/mailgw.py:473 msgid "Unable to decrypt your message." msgstr "" -#: ../roundup/mailgw.py:499 +#: ../roundup/mailgw.py:500 msgid "No PGP signature found in message." msgstr "" -#: ../roundup/mailgw.py:580 +#: ../roundup/mailgw.py:581 msgid "" "\n" "Emails to Roundup trackers must include a Subject: line!\n" msgstr "" -#: ../roundup/mailgw.py:693 +#: ../roundup/mailgw.py:694 #, python-format msgid "" "\n" @@ -2211,7 +2263,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:731 +#: ../roundup/mailgw.py:732 #, python-format msgid "" "\n" @@ -2222,7 +2274,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:739 +#: ../roundup/mailgw.py:740 #, python-format msgid "" "\n" @@ -2239,7 +2291,7 @@ "Subject was: '%(subject)s'\n" msgstr "" -#: ../roundup/mailgw.py:775 +#: ../roundup/mailgw.py:776 #, python-format msgid "" "\n" @@ -2250,7 +2302,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:808 +#: ../roundup/mailgw.py:809 #, python-format msgid "" "\n" @@ -2260,7 +2312,7 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:853 +#: ../roundup/mailgw.py:854 #, python-format msgid "" "\n" @@ -2269,22 +2321,22 @@ "Unknown address: %(from_address)s\n" msgstr "" -#: ../roundup/mailgw.py:861 +#: ../roundup/mailgw.py:862 #, fuzzy msgid "You are not permitted to access this tracker." msgstr "ä½ ä¸å…許查看æ¤é " -#: ../roundup/mailgw.py:872 +#: ../roundup/mailgw.py:873 #, fuzzy, python-format msgid "You are not permitted to edit %(classname)s." msgstr "ä½ æ²’æœ‰æ¬Šé™ä¾†ç·¨è¼¯ %(class)s" -#: ../roundup/mailgw.py:878 +#: ../roundup/mailgw.py:879 #, fuzzy, python-format msgid "You are not permitted to create %(classname)s." msgstr "ä½ æ²’æœ‰æ¬Šé™ä¾†å»ºç«‹ %(class)s" -#: ../roundup/mailgw.py:960 +#: ../roundup/mailgw.py:961 #, python-format msgid "" "\n" @@ -2294,40 +2346,40 @@ "Subject was: \"%(subject)s\"\n" msgstr "" -#: ../roundup/mailgw.py:1012 +#: ../roundup/mailgw.py:1013 msgid "This tracker has been configured to require all email be PGP encrypted." msgstr "" -#: ../roundup/mailgw.py:1049 +#: ../roundup/mailgw.py:1050 msgid "" "\n" "This tracker has been configured to require all email be PGP signed or\n" "encrypted." msgstr "" -#: ../roundup/mailgw.py:1080 +#: ../roundup/mailgw.py:1081 #, fuzzy msgid "You are not permitted to create files." msgstr "ä¸å…許編輯查詢" -#: ../roundup/mailgw.py:1094 +#: ../roundup/mailgw.py:1095 #, fuzzy, python-format msgid "You are not permitted to add files to %(classname)s." msgstr "ä½ æ²’æœ‰æ¬Šé™ä¾† %(action)s %(classname)s 類型。" -#: ../roundup/mailgw.py:1124 +#: ../roundup/mailgw.py:1125 msgid "" "\n" "Roundup requires the submission to be plain text. The message parser could\n" "not find a text/plain part to use.\n" msgstr "" -#: ../roundup/mailgw.py:1137 +#: ../roundup/mailgw.py:1138 #, fuzzy msgid "You are not permitted to create messages." msgstr "ä¸å…許編輯查詢" -#: ../roundup/mailgw.py:1145 +#: ../roundup/mailgw.py:1146 #, python-format msgid "" "\n" @@ -2335,22 +2387,22 @@ "%(error)s\n" msgstr "" -#: ../roundup/mailgw.py:1153 +#: ../roundup/mailgw.py:1154 #, fuzzy, python-format msgid "You are not permitted to add messages to %(classname)s." msgstr "ä½ æ²’æœ‰æ¬Šé™ä¾† %(action)s %(classname)s 類型。" -#: ../roundup/mailgw.py:1175 +#: ../roundup/mailgw.py:1176 #, fuzzy, python-format msgid "You are not permitted to edit property %(prop)s of class %(classname)s." msgstr "ä½ ä¸å…許 %(action)s 類別 %(class)s çš„é …ç›®" -#: ../roundup/mailgw.py:1184 +#: ../roundup/mailgw.py:1185 #, fuzzy, python-format msgid "You are not permitted to set property %(prop)s of class %(classname)s." msgstr "ä½ ä¸å…許 %(action)s 類別 %(class)s çš„é …ç›®" -#: ../roundup/mailgw.py:1192 +#: ../roundup/mailgw.py:1193 #, python-format msgid "" "\n" @@ -2358,7 +2410,7 @@ " %(message)s\n" msgstr "" -#: ../roundup/mailgw.py:1658 +#: ../roundup/mailgw.py:1659 #, python-format msgid "" "\n" @@ -2367,7 +2419,7 @@ " %(clsname)s\n" msgstr "" -#: ../roundup/mailgw.py:1689 +#: ../roundup/mailgw.py:1690 #, python-format msgid "" "\n" @@ -2376,22 +2428,39 @@ " %(errors)s\n" msgstr "" -#: ../roundup/mailgw.py:1710 +#: ../roundup/mailgw.py:1711 msgid "not of form [arg=value,value,...;arg=value,value,...]" msgstr "" -#: ../roundup/rest.py:1883 +#: ../roundup/rest.py:406 +#, python-format +msgid "Method %(m)s not allowed. Allowed: %(a)s" +msgstr "" + +#: ../roundup/rest.py:1104 +#, fuzzy, python-format +msgid "Invalid attribute %s" +msgstr "無效登錄" + +#: ../roundup/rest.py:2065 #, python-format msgid "Api rate limits exceeded. Please wait: %s seconds." msgstr "" -#: ../roundup/rest.py:1918 +#: ../roundup/rest.py:2100 #, python-format msgid "" "Unable to parse Accept Header. %(error)s. Acceptable types: " "%(acceptable_types)s" msgstr "" +#: ../roundup/rest.py:2223 +#, python-format +msgid "" +"Unrecognized api version: %s. See /rest without specifying api version for " +"supported versions." +msgstr "" + #: ../roundup/roundupdb.py:135 #, python-format msgid "Username '%s' already exists." @@ -2670,7 +2739,7 @@ msgid "WARNING: generating temporary SSL certificate" msgstr "" -#: ../roundup/scripts/roundup_server.py:293 +#: ../roundup/scripts/roundup_server.py:296 msgid "" "<html><head><title>Roundup trackers index</title></head>\n" "<body><h1>Roundup trackers index</h1><ol>\n" @@ -2678,52 +2747,52 @@ "<html><head><title>Roundup tracker 索引</title></head>\n" "<body><h1>Roundup tracker 索引</h1><ol>\n" -#: ../roundup/scripts/roundup_server.py:508 +#: ../roundup/scripts/roundup_server.py:525 #, fuzzy, python-format msgid "Error: %(type)s: %(value)s" msgstr "%(key)s: %(value)s (é—œéµå±¬æ€§)" -#: ../roundup/scripts/roundup_server.py:520 +#: ../roundup/scripts/roundup_server.py:537 msgid "WARNING: ignoring \"-g\" argument, not root" msgstr "è¦å‘Šï¼šå¿½ç•¥ \"-g\" åƒæ•¸ï¼Œä¸æ˜¯ root" -#: ../roundup/scripts/roundup_server.py:526 +#: ../roundup/scripts/roundup_server.py:543 msgid "Can't change groups - no grp module" msgstr "ä¸èƒ½ä¿®æ”¹çµ„ - ç„¡ grp 模塊" -#: ../roundup/scripts/roundup_server.py:535 +#: ../roundup/scripts/roundup_server.py:552 #, python-format msgid "Group %(group)s doesn't exist" msgstr "組 %(group)s ä¸å˜åœ¨" -#: ../roundup/scripts/roundup_server.py:547 +#: ../roundup/scripts/roundup_server.py:564 msgid "Can't run as root!" msgstr "ä¸èƒ½ä»¥ root é‹è¡Œï¼" -#: ../roundup/scripts/roundup_server.py:550 +#: ../roundup/scripts/roundup_server.py:567 msgid "WARNING: ignoring \"-u\" argument, not root" msgstr "è¦å‘Šï¼šå¿½ç•¥ \"-u\" åƒæ•¸ï¼Œä¸æ˜¯ root" -#: ../roundup/scripts/roundup_server.py:556 +#: ../roundup/scripts/roundup_server.py:573 msgid "Can't change users - no pwd module" msgstr "ä¸èƒ½ä¿®æ”¹ç”¨æˆ¶ - ç„¡ pwd 模塊" -#: ../roundup/scripts/roundup_server.py:565 +#: ../roundup/scripts/roundup_server.py:582 #, python-format msgid "User %(user)s doesn't exist" msgstr "用戶 %(user)s ä¸å˜åœ¨" -#: ../roundup/scripts/roundup_server.py:755 +#: ../roundup/scripts/roundup_server.py:778 #, python-format msgid "Multiprocess mode \"%s\" is not available, switching to single-process" msgstr "" -#: ../roundup/scripts/roundup_server.py:782 +#: ../roundup/scripts/roundup_server.py:805 #, python-format msgid "Unable to bind to port %s, port already in use." msgstr "無法ç¶å®šåˆ°ç«¯å£ %s, 端å£å·²ç¶“被佔用。" -#: ../roundup/scripts/roundup_server.py:854 +#: ../roundup/scripts/roundup_server.py:877 #, fuzzy msgid "" " -c <Command> Windows Service options.\n" @@ -2740,7 +2809,7 @@ " 變é‡ä¸Šé…置一個tracker。這個é¸é …與其經é¸é …是互斥的。打入\n" " \"roundup-server -c help\" 來çžè§£Windowsæœå‹™çš„è¦ç¯„。" -#: ../roundup/scripts/roundup_server.py:861 +#: ../roundup/scripts/roundup_server.py:884 msgid "" " -u <UID> runs the Roundup web server as this UID\n" " -g <GID> runs the Roundup web server as this GID\n" @@ -2754,9 +2823,10 @@ "去。\n" " 如果使用了 -d é¸é …,則 -l é¸é … *å¿…é ˆ* è¦æŒ‡å®šã€‚" -#: ../roundup/scripts/roundup_server.py:868 +#: ../roundup/scripts/roundup_server.py:891 #, fuzzy, python-format msgid "" +"\n" "%(message)sUsage: roundup-server [options] [name=tracker home]*\n" "\n" "Options:\n" @@ -2779,6 +2849,9 @@ " -e <fname> PEM file containing SSL key and certificate\n" " -t <mode> multiprocess mode (default: %(mp_def)s).\n" " Allowed values: %(mp_types)s.\n" +" -V <version> set HTTP version (default: HTTP/1.1).\n" +" Allowed values: HTTP/1.0, HTTP/1.1.\n" +"\n" "%(os_part)s\n" "\n" "Long options:\n" @@ -2846,20 +2919,20 @@ " æ„æ•¸é‡çš„ name=home å°ã€‚è¦ç¢ºä¿ name 部分ä¸èƒ½åŒ…括任何éžurl安全的\n" " å—符,åƒç©ºæ ¼ï¼Œå› 為它們會把IEæžäº‚。\n" -#: ../roundup/scripts/roundup_server.py:1041 +#: ../roundup/scripts/roundup_server.py:1067 msgid "Instances must be name=home" msgstr "å¯¦ä¾‹å¿…é ˆæ˜¯ 實例å=實例路徑" -#: ../roundup/scripts/roundup_server.py:1055 +#: ../roundup/scripts/roundup_server.py:1081 #, python-format msgid "Configuration saved to %s" msgstr "é…ç½®ä¿å˜åˆ° %s" -#: ../roundup/scripts/roundup_server.py:1073 +#: ../roundup/scripts/roundup_server.py:1099 msgid "Sorry, you can't run the server as a daemon on this Operating System" msgstr "抱æ‰ï¼Œåœ¨é€™å€‹æ“作系統上ä¸èƒ½ä»¥å®ˆè·é€²ç¨‹çš„æ–¹å¼ä¾†é‹è¡Œæœå‹™" -#: ../roundup/scripts/roundup_server.py:1093 +#: ../roundup/scripts/roundup_server.py:1119 #, python-format msgid "Roundup server started on %(HOST)s:%(PORT)s" msgstr "Roundup server 啟動於 %(HOST)s:%(PORT)s" @@ -2994,6 +3067,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:41 #: ../share/roundup/templates/classic/html/help.html:21 #: ../share/roundup/templates/classic/html/issue.index.html:80 +#: ../share/roundup/templates/classic/html/user.index.html:82 #: ../share/roundup/templates/devel/html/_generic.help.html:42 #: ../share/roundup/templates/devel/html/bug.index.html:94 #: ../share/roundup/templates/devel/html/help.html:51 @@ -3010,6 +3084,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:53 #: ../share/roundup/templates/classic/html/help.html:28 #: ../share/roundup/templates/classic/html/issue.index.html:88 +#: ../share/roundup/templates/classic/html/user.index.html:90 #: ../share/roundup/templates/devel/html/_generic.help.html:54 #: ../share/roundup/templates/devel/html/bug.index.html:102 #: ../share/roundup/templates/devel/html/help.html:58 @@ -3026,6 +3101,7 @@ #: ../share/roundup/templates/classic/html/_generic.help.html:57 #: ../share/roundup/templates/classic/html/help.html:32 #: ../share/roundup/templates/classic/html/issue.index.html:91 +#: ../share/roundup/templates/classic/html/user.index.html:93 #: ../share/roundup/templates/devel/html/_generic.help.html:58 #: ../share/roundup/templates/devel/html/bug.index.html:105 #: ../share/roundup/templates/devel/html/help.html:62 @@ -3854,6 +3930,7 @@ #: ../share/roundup/templates/classic/html/page.html:40 #: ../share/roundup/templates/classic/html/page.html:92 #: ../share/roundup/templates/classic/html/user.help-search.html:69 +#: ../share/roundup/templates/classic/html/user.index.html:38 #: ../share/roundup/templates/devel/html/bug.search.html:292 #: ../share/roundup/templates/devel/html/page.html:79 #: ../share/roundup/templates/devel/html/page.html:126 @@ -4393,7 +4470,7 @@ msgid "User listing" msgstr "用戶列表" -#: ../share/roundup/templates/classic/html/user.index.html:19 +#: ../share/roundup/templates/classic/html/user.index.html:48 #: ../share/roundup/templates/devel/html/user.index.html:48 #: ../share/roundup/templates/minimal/html/user.index.html:19 #: ../share/roundup/templates/responsive/html/page.html:180 @@ -4401,13 +4478,13 @@ msgid "Username" msgstr "用戶å" -#: ../share/roundup/templates/classic/html/user.index.html:20 +#: ../share/roundup/templates/classic/html/user.index.html:49 #: ../share/roundup/templates/devel/html/user.index.html:49 #: ../share/roundup/templates/responsive/html/user.index.html:50 msgid "Real name" msgstr "真實姓å" -#: ../share/roundup/templates/classic/html/user.index.html:21 +#: ../share/roundup/templates/classic/html/user.index.html:50 #: ../share/roundup/templates/classic/html/user.register.html:47 #: ../share/roundup/templates/devel/html/user.index.html:50 #: ../share/roundup/templates/devel/html/user.register.html:54 @@ -4416,26 +4493,26 @@ msgid "Organisation" msgstr "組織" -#: ../share/roundup/templates/classic/html/user.index.html:22 +#: ../share/roundup/templates/classic/html/user.index.html:51 #: ../share/roundup/templates/devel/html/user.index.html:51 #: ../share/roundup/templates/minimal/html/user.index.html:20 #: ../share/roundup/templates/responsive/html/user.index.html:52 msgid "Email address" msgstr "郵件地å€" -#: ../share/roundup/templates/classic/html/user.index.html:23 +#: ../share/roundup/templates/classic/html/user.index.html:52 #: ../share/roundup/templates/devel/html/user.index.html:52 #: ../share/roundup/templates/responsive/html/user.index.html:53 msgid "Phone number" msgstr "電話號碼" -#: ../share/roundup/templates/classic/html/user.index.html:24 +#: ../share/roundup/templates/classic/html/user.index.html:53 #: ../share/roundup/templates/devel/html/user.index.html:53 #: ../share/roundup/templates/responsive/html/user.index.html:54 msgid "Retire" msgstr "收回" -#: ../share/roundup/templates/classic/html/user.index.html:43 +#: ../share/roundup/templates/classic/html/user.index.html:72 #: ../share/roundup/templates/devel/html/user.index.html:66 #: ../share/roundup/templates/responsive/html/user.index.html:67 msgid "retire" @@ -4584,68 +4661,68 @@ msgstr "ä½ å°‡å¾ˆå¿«æ”¶åˆ°ä¸€å°ç¢ºèªä¿¡ã€‚為了完æˆè¨»å†ŠéŽç¨‹ï¼Œè«‹è¨ªå•éƒµä»¶ä¸æŒ‡ç¤ºçš„éˆæŽ¥ã€‚" #: ../share/roundup/templates/classic/initial_data.py:5 -#: ../share/roundup/templates/jinja2/initial_data.py:6 +#: ../share/roundup/templates/jinja2/initial_data.py:4 msgid "critical" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:6 -#: ../share/roundup/templates/jinja2/initial_data.py:7 +#: ../share/roundup/templates/jinja2/initial_data.py:5 msgid "urgent" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:7 -#: ../share/roundup/templates/jinja2/initial_data.py:8 +#: ../share/roundup/templates/jinja2/initial_data.py:6 msgid "bug" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:8 -#: ../share/roundup/templates/jinja2/initial_data.py:9 +#: ../share/roundup/templates/jinja2/initial_data.py:7 msgid "feature" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:9 -#: ../share/roundup/templates/jinja2/initial_data.py:10 +#: ../share/roundup/templates/jinja2/initial_data.py:8 msgid "wish" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:12 -#: ../share/roundup/templates/jinja2/initial_data.py:13 +#: ../share/roundup/templates/jinja2/initial_data.py:11 msgid "unread" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:13 -#: ../share/roundup/templates/jinja2/initial_data.py:14 +#: ../share/roundup/templates/jinja2/initial_data.py:12 msgid "deferred" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:14 -#: ../share/roundup/templates/jinja2/initial_data.py:15 +#: ../share/roundup/templates/jinja2/initial_data.py:13 msgid "chatting" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:15 -#: ../share/roundup/templates/jinja2/initial_data.py:16 +#: ../share/roundup/templates/jinja2/initial_data.py:14 msgid "need-eg" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:16 -#: ../share/roundup/templates/jinja2/initial_data.py:17 +#: ../share/roundup/templates/jinja2/initial_data.py:15 msgid "in-progress" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:17 -#: ../share/roundup/templates/jinja2/initial_data.py:18 +#: ../share/roundup/templates/jinja2/initial_data.py:16 #, fuzzy msgid "testing" msgstr "用戶列表" #: ../share/roundup/templates/classic/initial_data.py:18 -#: ../share/roundup/templates/jinja2/initial_data.py:19 +#: ../share/roundup/templates/jinja2/initial_data.py:17 msgid "done-cbb" msgstr "" #: ../share/roundup/templates/classic/initial_data.py:19 -#: ../share/roundup/templates/jinja2/initial_data.py:20 +#: ../share/roundup/templates/jinja2/initial_data.py:18 #, fuzzy msgid "resolved" msgstr "未解決"
--- a/roundup/admin.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/admin.py Thu Apr 21 16:54:17 2022 -0400 @@ -23,12 +23,13 @@ __docformat__ = 'restructuredtext' -import csv, getopt, getpass, os, re, shutil, sys, operator +import csv, getopt, getpass, operator, os, re, shutil, sys from roundup import date, hyperdb, init, password, token from roundup import __version__ as roundup_version import roundup.instance -from roundup.configuration import CoreConfig, NoConfigError, UserConfig +from roundup.configuration import (CoreConfig, NoConfigError, + ParsingOptionError, UserConfig) from roundup.i18n import _ from roundup.exceptions import UsageError from roundup.anypy.my_input import my_input @@ -51,13 +52,16 @@ if key in self.data: return [(key, self.data[key])] keylist = sorted(self.data) - l = [] + matching_keys = [] for ki in keylist: if ki.startswith(key): - l.append((ki, self.data[ki])) - if not l and default is self._marker: + matching_keys.append((ki, self.data[ki])) + if not matching_keys and default is self._marker: raise KeyError(key) - return l + # FIXME: what happens if default is not self._marker but + # there are no matching keys? Should (default, self.data[default]) + # be returned??? + return matching_keys class AdminTool: @@ -101,12 +105,12 @@ """ props = {} for arg in args: - l = arg.split('=', 1) + key_val = arg.split('=', 1) # if = not in string, will return one element - if len(l) < 2: + if len(key_val) < 2: raise UsageError(_('argument "%(arg)s" not propname=value') % locals()) - key, value = l + key, value = key_val if value: props[key] = value else: @@ -117,7 +121,7 @@ """ Display a simple usage message. """ if message: - message = _('Problem: %(message)s\n\n')% locals() + message = _('Problem: %(message)s\n\n') % locals() sys.stdout.write(_("""%(message)sUsage: roundup-admin [options] [<command> <arguments>] Options: @@ -267,13 +271,13 @@ # try command docstrings try: - l = self.commands.get(topic) + cmd_docs = self.commands.get(topic) except KeyError: print(_('Sorry, no help for "%(topic)s"') % locals()) return 1 # display the help for each match, removing the docstring indent - for _name, help in l: + for _name, help in cmd_docs: lines = nl_re.split(_(help.__doc__)) print(lines[0]) indent = indent_re.match(lines[1]) @@ -295,12 +299,15 @@ 2. <prefix>/share/roundup/templates/* this should be the standard place to find them when Roundup is installed - 3. <roundup.admin.__file__>/../templates/* + 3. <roundup.admin.__file__>/../../<sys.prefix>/share/\ + roundup/templates/* which is where they will be found if + roundup is installed as a wheel using pip install + 4. <roundup.admin.__file__>/../templates/* this will be used if Roundup's run in the distro (aka. source) directory - 4. <current working dir>/* + 5. <current working dir>/* this is for when someone unpacks a 3rd-party template - 5. <current working dir> + 6. <current working dir> this is for someone who "cd"s to the 3rd-party template dir """ # OK, try <prefix>/share/roundup/templates @@ -324,6 +331,25 @@ templates = init.listTemplates(tdir) break + # search for data files parallel to the roundup + # install dir. E.G. a wheel install + # use roundup.__path__ and go up a level then use sys.prefix + # to create a base path for searching. + + import sys + # __file__ should be something like: + # /usr/local/lib/python3.10/site-packages/roundup/admin.py + # os.prefix should be /usr, /usr/local or root of virtualenv + # strip leading / to make os.path.join work right. + path = __file__ + for _N in 1, 2: + path = os.path.dirname(path) + # path is /usr/local/lib/python3.10/site-packages + tdir = os.path.join(path, sys.prefix[1:], 'share', + 'roundup', 'templates') + if os.path.isdir(tdir): + templates.update(init.listTemplates(tdir)) + # OK, now try as if we're in the roundup source distribution # directory, so this module will be in .../roundup-*/roundup/admin.py # and we're interested in the .../roundup-*/ part. @@ -435,7 +461,7 @@ # it sets parameters like template_engine that are # template specific. template_config = UserConfig(templates[template]['path'] + - "/config_ini.ini") + "/config_ini.ini") for k in template_config.keys(): if k == 'HOME': # ignore home. It is a default param. continue @@ -583,7 +609,7 @@ raise UsageError(_('Not enough arguments supplied')) propname = args[0] designators = args[1].split(',') - l = [] + linked_props = [] for designator in designators: # decode the node designator try: @@ -619,11 +645,11 @@ propclassname = self.db.getclass(property.classname).classname id = cl.get(nodeid, propname) for i in id: - l.append(propclassname + i) + linked_props.append(propclassname + i) else: id = cl.get(nodeid, propname) for i in id: - l.append(i) + linked_props.append(i) else: if self.print_designator: properties = cl.getprops() @@ -646,7 +672,7 @@ raise UsageError(_('no such %(classname)s property ' '"%(propname)s"') % locals()) if self.separator: - print(self.separator.join(l)) + print(self.separator.join(linked_props)) return 0 @@ -743,20 +769,20 @@ if ',' in value: values = value.split(',') else: - values = [ value ] + values = [value] props[propname] = [] # start handling transitive props # given filter issue assignedto.roles=Admin # start at issue curclass = cl - lastprop = propname # handle case 'issue assignedto=admin' + lastprop = propname # handle case 'issue assignedto=admin' if '.' in propname: # start splitting transitive prop into components # we end when we have no more links for pn in propname.split('.'): try: - lastprop=pn # get current component + lastprop = pn # get current component # get classname for this link try: curclassname = curclass.getprops()[pn].classname @@ -779,7 +805,7 @@ try: id = [] designator = [] - props = { "filterspec": props } + props = {"filterspec": props} if self.separator: if self.print_designator: @@ -967,7 +993,7 @@ for propname in props: try: props[propname] = hyperdb.rawToHyperdb(self.db, cl, None, - propname, props[propname]) + propname, props[propname]) except hyperdb.HyperdbValueError as message: raise UsageError(message) @@ -975,7 +1001,7 @@ propname = cl.getkey() if propname and propname not in props: raise UsageError(_('you must provide the "%(propname)s" ' - 'property.') % locals()) + 'property.') % locals()) # do the actual create try: @@ -1099,7 +1125,7 @@ if ':' in spec: name, width = spec.split(':') if width == '': - # spec includes trailing :, use label/name width + # spec includes trailing :, use label/name width props.append((name, len(name))) else: try: @@ -1123,7 +1149,7 @@ # and the table data for nodeid in cl.list(): - l = [] + table_columns = [] for name, width in props: if name != 'id': try: @@ -1136,8 +1162,8 @@ else: value = str(nodeid) f = '%%-%ds' % width - l.append(f % value[:width]) - print(' '.join(l)) + table_columns.append(f % value[:width]) + print(' '.join(table_columns)) return 0 def do_history(self, args): @@ -1259,7 +1285,7 @@ raise UsageError(e.args[0]) except IndexError: raise UsageError(_('no such %(classname)s node ' - '" % (nodeid)s"')%locals()) + '" % (nodeid)s"') % locals()) self.db_uncommitted = True return 0 @@ -1286,7 +1312,7 @@ if len(args) == 2: if args[0].startswith('-'): classes = [c for c in self.db.classes - if c not in args[0][1:].split(',')] + if c not in args[0][1:].split(',')] else: classes = args[0].split(',') else: @@ -1308,12 +1334,11 @@ if not export_files and hasattr(cl, 'export_files'): sys.stdout.write('Exporting %s WITHOUT the files\r\n' % - classname) + classname) with open(os.path.join(dir, classname+'.csv'), 'w') as f: writer = csv.writer(f, colon_separated) - properties = cl.getprops() propnames = cl.export_propnames() fields = propnames[:] fields.append('is retired') @@ -1329,7 +1354,7 @@ all_nodes = cl.getnodeids() classkey = cl.getkey() - if classkey: # False sorts before True, so negate is_retired + if classkey: # False sorts before True, so negate is_retired keysort = lambda i: (cl.get(i, classkey), not cl.is_retired(i)) all_nodes.sort(key=keysort) @@ -1337,12 +1362,13 @@ for nodeid in all_nodes: if self.verbose: - sys.stdout.write('\rExporting %s - %s' % + sys.stdout.write('\rExporting %s - %s' % (classname, nodeid)) sys.stdout.flush() node = cl.getnode(nodeid) exp = cl.export_list(propnames, nodeid) - lensum = sum([len(repr_export(node[p])) for p in propnames]) + lensum = sum([len(repr_export(node[p])) for + p in propnames]) # for a safe upper bound of field length we add # difference between CSV len and sum of all field lengths d = sum([len(x) for x in exp]) - lensum @@ -1359,7 +1385,8 @@ # export the journals with open(os.path.join(dir, classname+'-journals.csv'), 'w') as jf: if self.verbose: - sys.stdout.write("\nExporting Journal for %s\n" % classname) + sys.stdout.write("\nExporting Journal for %s\n" % + classname) sys.stdout.flush() journals = csv.writer(jf, colon_separated) for row in cl.export_journals(): @@ -1642,12 +1669,12 @@ except KeyError: # not a valid command print(_('Unknown command "%(command)s" ("help commands" for a ' - 'list)') % locals()) + 'list)') % locals()) return 1 # check for multiple matches if len(functions) > 1: - print(_('Multiple commands match "%(command)s": %(list)s') % \ + print(_('Multiple commands match "%(command)s": %(list)s') % {'command': command, 'list': ', '.join([i[0] for i in functions])}) return 1 @@ -1685,6 +1712,9 @@ self.tracker_home = '' print(_("Error: Couldn't open tracker: %(message)s") % locals()) return 1 + except ParsingOptionError as message: # message used via locals + print("%(message)s" % locals()) + return 1 # only open the database once! if not self.db: @@ -1751,10 +1781,10 @@ self.name = 'admin' self.password = '' # unused if 'ROUNDUP_LOGIN' in os.environ: - l = os.environ['ROUNDUP_LOGIN'].split(':') - self.name = l[0] - if len(l) > 1: - self.password = l[1] + login_env = os.environ['ROUNDUP_LOGIN'].split(':') + self.name = login_env[0] + if len(login_env) > 1: + self.password = login_env[1] self.separator = None self.print_designator = 0 self.verbose = 0 @@ -1788,10 +1818,10 @@ elif opt == '-d': self.print_designator = 1 elif opt == '-u': - l = arg.split(':') - self.name = l[0] - if len(l) > 1: - self.password = l[1] + login_opt = arg.split(':') + self.name = login_opt[0] + if len(login_opt) > 1: + self.password = login_opt[1] # if no command - go interactive # wrap in a try/finally so we always close off the db
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/roundup/anypy/ssl_.py Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,6 @@ +try: + # Python 3+ + from ssl import SSLError +except (ImportError, AttributeError): + # Python 2.5-2.7 + from socket import sslerror as SSLError
--- a/roundup/anypy/strings.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/anypy/strings.py Thu Apr 21 16:54:17 2022 -0400 @@ -142,7 +142,15 @@ def eval_import(s): """Evaluate a Python-2-style value imported from a CSV file.""" if _py3: - v = eval(s) + try: + v = eval(s) + except SyntaxError: + # handle case where link operation reports id a long int + # ('issue', 5002L, "status") rather than as a string. + # This was a bug that existed and was fixed before or with v1.2.0 + import re + v = eval(re.sub(r', ([0-9]+)L,',r', \1,', s)) + if isinstance(v, str): return v.encode('iso-8859-1').decode('utf-8') elif isinstance(v, dict):
--- a/roundup/backends/back_mysql.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/backends/back_mysql.py Thu Apr 21 16:54:17 2022 -0400 @@ -234,8 +234,10 @@ self.sql('''CREATE TABLE __textids (_class VARCHAR(255), _itemid VARCHAR(255), _prop VARCHAR(255), _textid INT) ENGINE=%s'''%self.mysql_backend) - self.sql('''CREATE TABLE __words (_word VARCHAR(30), - _textid INT) ENGINE=%s'''%self.mysql_backend) + self.sql('''CREATE TABLE __words (_word VARCHAR(%s), + _textid INT) ENGINE=%s''' % ((self.indexer.maxlength + 5), + self.mysql_backend) + ) self.sql('CREATE INDEX words_word_ids ON __words(_word)') self.sql('CREATE INDEX words_by_id ON __words (_textid)') self.sql('CREATE UNIQUE INDEX __textids_by_props ON ' @@ -410,6 +412,15 @@ else: self.log_info('No changes needed.') + def fix_version_6_tables(self): + # Modify length for __words._word column. + c = self.cursor + sql = "alter table __words change column _word _word varchar(%s)" % ( + self.arg) + # Why magic number 5? It was the original offset between + # column length and maxlength. + c.execute(sql, (self.indexer.maxlength + 5,)) + def __repr__(self): return '<myroundsql 0x%x>'%id(self)
--- a/roundup/backends/back_postgresql.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/backends/back_postgresql.py Thu Apr 21 16:54:17 2022 -0400 @@ -196,25 +196,40 @@ self.sql("CREATE TABLE dual (dummy integer)") self.sql("insert into dual values (1)") self.create_version_2_tables() + self.fix_version_3_tables() # Need to commit here, otherwise otk/session will not find # the necessary tables (in a parallel connection!) self.commit() - - def checkpoint_data(self): - """Commit the state of the database. Allows recovery/retry - of operation in exception handler because postgres - requires a rollback in case of error generating exception - """ - self.commit() + self._add_fts_table() + self.commit() - def restore_connection_on_error(self): - """Postgres leaves a cursor in an unusable state after - an error. Rollback the transaction to recover and - permit a retry of the failed statement. Used with - checkpoint_data to handle uniqueness conflict in - import_table() + def checkpoint_data(self, savepoint="importing"): + """Create a subtransaction savepoint. Allows recovery/retry + of operation in exception handler because + postgres requires a rollback in case of error + generating exception. Used with + restore_connecion_on_error to handle uniqueness + conflict in import_table(). """ - self.rollback() + # Savepoints take resources. Postgres keeps all + # savepoints (rather than overwriting) until a + # commit(). If an import fails because of a resource + # issue with savepoints, uncomment this line. I + # expect it will slow down the import but it should + # eliminate any issue with stored savepoints and + # resource use. + # + # self.sql('RELEASE SAVEPOINT %s' % savepoint) + self.sql('SAVEPOINT %s' % savepoint) + + def restore_connection_on_error(self, savepoint="importing"): + """Postgres leaves a connection/cursor in an unusable state + after an error. Rollback the transaction to a + previous savepoint and permit a retry of the + failed statement. Used with checkpoint_data to + handle uniqueness conflict in import_table(). + """ + self.sql('ROLLBACK TO %s' % savepoint) def create_version_2_tables(self): # OTK store @@ -234,8 +249,8 @@ self.sql('''CREATE TABLE __textids ( _textid integer primary key, _class VARCHAR(255), _itemid VARCHAR(255), _prop VARCHAR(255))''') - self.sql('''CREATE TABLE __words (_word VARCHAR(30), - _textid integer)''') + self.sql('''CREATE TABLE __words (_word VARCHAR(%s), + _textid integer)''' % (self.indexer.maxlength + 5)) self.sql('CREATE INDEX words_word_idx ON __words(_word)') self.sql('CREATE INDEX words_by_id ON __words (_textid)') self.sql('CREATE UNIQUE INDEX __textids_by_props ON ' @@ -263,6 +278,24 @@ self.sql('''CREATE INDEX words_both_idx ON public.__words USING btree (_word, _textid)''') + def _add_fts_table(self): + self.sql('CREATE TABLE __fts (_class VARCHAR(255), ' + '_itemid VARCHAR(255), _prop VARCHAR(255), _tsv tsvector)' + ) + + self.sql('CREATE INDEX __fts_idx ON __fts USING GIN (_tsv)') + + def fix_version_6_tables(self): + # Modify length for __words._word column. + c = self.cursor + sql = 'alter table __words alter column _word type varchar(%s)' % ( + self.arg) + # Why magic number 5? It was the original offset between + # column length and maxlength. + c.execute(sql, (self.indexer.maxlength + 5,)) + + self._add_fts_table() + def add_actor_column(self): # update existing tables to have the new actor column tables = self.database_schema['tables']
--- a/roundup/backends/back_sqlite.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/backends/back_sqlite.py Thu Apr 21 16:54:17 2022 -0400 @@ -174,6 +174,7 @@ self.sql('create table ids (name varchar, num integer)') self.sql('create index ids_name_idx on ids(name)') self.create_version_2_tables() + self._add_fts5_table() def create_version_2_tables(self): self.sql('create table otks (otk_key varchar, ' @@ -212,6 +213,17 @@ # NOOP - no restriction on column length here pass + def _add_fts5_table(self): + self.sql('CREATE virtual TABLE __fts USING fts5(_class, ' + '_itemid, _prop, _textblob)' + ) + + def fix_version_6_tables(self): + # note sqlite has no limit on column size so v6 fixes + # to __words._word length are not needed. + # Add native full-text indexing table + self._add_fts5_table() + def update_class(self, spec, old_spec, force=0, adding_v2=0): """ Determine the differences between the current spec and the database version of the spec, and update where necessary.
--- a/roundup/backends/indexer_common.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/backends/indexer_common.py Thu Apr 21 16:54:17 2022 -0400 @@ -19,11 +19,15 @@ self.stopwords = set(STOPWORDS) for word in db.config[('main', 'indexer_stopwords')]: self.stopwords.add(word) - # Do not index anything longer than 25 characters since that'll be - # gibberish (encoded text or somesuch) or shorter than 2 characters + # Do not index anything longer than maxlength characters since + # that'll be gibberish (encoded text or somesuch) or shorter + # than 2 characters self.minlength = 2 - self.maxlength = 25 + self.maxlength = 50 self.language = db.config[('main','indexer_language')] + # Some indexers have a query language. If that is the case, + # we don't parse the user supplied query into a wordlist. + self.query_language = False def is_stopword(self, word): return word in self.stopwords @@ -134,6 +138,19 @@ from .indexer_whoosh import Indexer return Indexer(db) + if indexer_name == "native-fts": + if db.dbtype not in ("sqlite", "postgres"): + raise AssertionError("Indexer native-fts is configured, but only sqlite and postgres support it. Database is: %r" % db.dbtype) + + if db.dbtype == "sqlite": + from roundup.backends.indexer_sqlite_fts import Indexer + return Indexer(db) + + if db.dbtype == "postgres": + raise NotImplementedError("Postgres FTS not available") + from roundup.backends.indexer_postgres_fts import Indexer + return Indexer(db) + if indexer_name == "native": # load proper native indexing based on database type if db.dbtype == "anydbm":
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/roundup/backends/indexer_postgresql_fts.py Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,141 @@ +""" This implements the PostgreSQL full-text indexer. +The table consists of (Class, propname, itemid) instances as columns +along with an _tsv tsvector column. The _tsv column is searched using +@@ and the instances returned. +""" + +import re + +from roundup.backends.indexer_common import Indexer as IndexerBase +from roundup.i18n import _ +from roundup.cgi.exceptions import IndexerQueryError + +from psycopg2.errors import InFailedSqlTransaction, SyntaxError, \ + UndefinedObject + + +class Indexer(IndexerBase): + def __init__(self, db): + IndexerBase.__init__(self, db) + self.db = db + if db.conn.server_version < 110000: + db.sql("select version()") + server_descr = db.cursor.fetchone() + raise ValueError("Postgres native_fts indexing requires postgres " + "11.0 or newer. Server is version: %s" % + server_descr) + self.reindex = 0 + self.query_language = True + + def close(self): + """close the indexing database""" + # just nuke the circular reference + self.db = None + + def save_index(self): + """Save the changes to the index.""" + # not necessary - the RDBMS connection will handle this for us + pass + + def force_reindex(self): + """Force a reindexing of the database. This essentially + empties the __fts table and sets a flag so + that the databases are reindexed""" + self.reindex = 1 + + def should_reindex(self): + """returns True if the indexes need to be rebuilt""" + return self.reindex + + def add_text(self, identifier, text, mime_type='text/plain'): + """ "identifier" is (classname, itemid, property) """ + if mime_type != 'text/plain': + return + + # Ensure all elements of the identifier are strings 'cos the itemid + # column is varchar even if item ids may be numbers elsewhere in the + # code. ugh. + identifier = tuple(map(str, identifier)) + + # removed pre-processing of text that incudes only words with: + # self.minlength <= len(word) <= self.maxlength + # Not sure if that is correct. + + # first, find the rowid of the (classname, itemid, property) + a = self.db.arg # arg is the token for positional parameters + sql = 'select ctid from __fts where _class=%s and '\ + '_itemid=%s and _prop=%s' % (a, a, a) + self.db.cursor.execute(sql, identifier) + r = self.db.cursor.fetchone() + if not r: + # not previously indexed + sql = 'insert into __fts (_class, _itemid, _prop, _tsv)'\ + ' values (%s, %s, %s, to_tsvector(%s, %s))' % (a, a, a, a, a) + self.db.cursor.execute(sql, identifier + + (self.db.config['INDEXER_LANGUAGE'], text)) + else: + id = r[0] + sql = 'update __fts set _tsv=to_tsvector(%s, %s) where ctid=%s' % \ + (a, a, a) + self.db.cursor.execute(sql, (self.db.config['INDEXER_LANGUAGE'], + text, id)) + + def find(self, wordlist): + """look up all the words in the wordlist. + For testing wordlist is actually a list. + In production, wordlist is a list of a single string + that is a postgresql websearch_to_tsquery() query. + + https://www.postgresql.org/docs/14/textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES + """ + + if not wordlist: + return [] + + a = self.db.arg # arg is the token for positional parameters + + # removed filtering of word in wordlist to include only + # words with: self.minlength <= len(word) <= self.maxlength + if wordlist[0].startswith("ts:"): + wordlist[0] = wordlist[0][3:] + sql = ('select _class, _itemid, _prop from __fts ' + 'where _tsv @@ to_tsquery(%s, %s)' % (a, a)) + + else: + if re.search(r'[<>!&|()*]', " ".join(wordlist)): + # assume this is a ts query processed by websearch_to_tsquery. + # since it has operator characters in it. + raise IndexerQueryError(_('You have non-word/operator ' + 'characters "<>!&|()*" in your query. Did you want to ' + 'do a tsquery search and forgot to start it with "ts:"?')) + else: + sql = 'select _class, _itemid, _prop from __fts '\ + 'where _tsv @@ websearch_to_tsquery(%s, %s)' % (a, a) + + try: + # tests supply a multi element word list. Join them. + self.db.cursor.execute(sql, (self.db.config['INDEXER_LANGUAGE'], + " ".join(wordlist),)) + except SyntaxError as e: + # reset the cursor as it's invalid currently + # reuse causes an InFailedSqlTransaction + self.db.rollback() + + raise IndexerQueryError(e.args[0]) + except InFailedSqlTransaction: + # reset the cursor as it's invalid currently + self.db.rollback() + raise + except UndefinedObject as e: + # try for a nicer user error + self.db.rollback() + lookfor = ('text search configuration "%s" does ' + 'not exist' % self.db.config['INDEXER_LANGUAGE']) + if lookfor in e.args[0]: + raise ValueError(_("Check tracker config.ini for a bad " + "indexer_language setting. Error is: %s") % + e) + else: + raise + + return self.db.cursor.fetchall()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/roundup/backends/indexer_sqlite_fts.py Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,123 @@ +""" This implements the full-text indexer using fts5 in sqlite. +The table consists of (Class, propname, itemid) instances as columns +along with a textblob column. The textblob column is searched using +MATCH and the instances returned. + +sqlite test commands to manage schema version change required by +this update. + +-- check length before and after +select length(schema) from schema; + +-- reset from version 7 (with fts index) to version 6 + update schema set schema = (select replace(schema, + '''version'': 7','''version'': 6') as new_schema from schema); + +-- check version. Good thing it's at the front of the schema + select substr(schema,0,15) from schema; + {'version': 6, +""" + +from roundup.backends.indexer_common import Indexer as IndexerBase +from roundup.i18n import _ +from roundup.cgi.exceptions import IndexerQueryError + +try: + import sqlite3 as sqlite + if sqlite.sqlite_version_info < (3, 9, 0): + raise ValueError('sqlite minimum version for FTS5 is 3.9.0+ ' + '- %s found' % sqlite.sqlite_version) +except ImportError: + raise ValueError('Unable to import sqlite3 to support FTS.') + + +class Indexer(IndexerBase): + def __init__(self, db): + IndexerBase.__init__(self, db) + self.db = db + self.reindex = 0 + self.query_language = True + + def close(self): + """close the indexing database""" + # just nuke the circular reference + self.db = None + + def save_index(self): + """Save the changes to the index.""" + # not necessary - the RDBMS connection will handle this for us + pass + + def force_reindex(self): + """Force a reindexing of the database. This essentially + empties the __fts table and sets a flag so + that the databases are reindexed""" + self.reindex = 1 + + def should_reindex(self): + """returns True if the indexes need to be rebuilt""" + return self.reindex + + def add_text(self, identifier, text, mime_type='text/plain'): + """ "identifier" is (classname, itemid, property) """ + if mime_type != 'text/plain': + return + + # Ensure all elements of the identifier are strings 'cos the itemid + # column is varchar even if item ids may be numbers elsewhere in the + # code. ugh. + identifier = tuple(map(str, identifier)) + + # removed pre-processing of text that incudes only words with: + # self.minlength <= len(word) <= self.maxlength + # Not sure if that is correct. + + # first, find the rowid of the (classname, itemid, property) + a = self.db.arg # arg is the token for positional parameters + sql = 'select rowid from __fts where _class=%s and '\ + '_itemid=%s and _prop=%s' % (a, a, a) + self.db.cursor.execute(sql, identifier) + r = self.db.cursor.fetchone() + if not r: + # not previously indexed + sql = 'insert into __fts (_class, _itemid, _prop, _textblob)'\ + ' values (%s, %s, %s, %s)' % (a, a, a, a) + self.db.cursor.execute(sql, identifier + (text,)) + else: + id = int(r[0]) + sql = 'update __fts set _textblob=%s where rowid=%s' % \ + (a, a) + self.db.cursor.execute(sql, (text, id)) + + def find(self, wordlist): + """look up all the words in the wordlist. + For testing wordlist is actually a list. + In production, wordlist is a list of a single string + that is a sqlite MATCH query. + + https://www.sqlite.org/fts5.html#full_text_query_syntax + """ + if not wordlist: + return [] + + a = self.db.arg # arg is the token for positional parameters + + # removed filtering of word in wordlist to include only + # words with: self.minlength <= len(word) <= self.maxlength + + sql = 'select _class, _itemid, _prop from __fts '\ + 'where _textblob MATCH %s' % a + + try: + # tests supply a multi element word list. Join them. + self.db.cursor.execute(sql, (" ".join(wordlist),)) + except sqlite.OperationalError as e: + if 'no such column' in e.args[0]: + raise IndexerQueryError( + _("Search failed. Try quoting any terms that " + "include a '-' and retry the search.")) + else: + raise IndexerQueryError(e.args[0].replace("fts5:", + "Query error:")) + + return self.db.cursor.fetchall()
--- a/roundup/backends/rdbms_common.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/backends/rdbms_common.py Thu Apr 21 16:54:17 2022 -0400 @@ -329,8 +329,8 @@ self.sql_commit() # update this number when we need to make changes to the SQL structure - # of the backen database - current_db_version = 6 + # of the backend database + current_db_version = 7 db_version_updated = False def upgrade_db(self): @@ -376,10 +376,18 @@ self.log_info('upgrade to version 6') self.fix_version_5_tables() + if version < 7: + self.log_info('upgrade to version 7') + self.fix_version_6_tables() + self.database_schema['version'] = self.current_db_version self.db_version_updated = True return 1 + def fix_version_2_tables(self): + # Default (used by sqlite): NOOP + pass + def fix_version_3_tables(self): # drop the shorter VARCHAR OTK column and add a new TEXT one for name in ('otk', 'session'): @@ -387,10 +395,6 @@ self.sql('ALTER TABLE %ss DROP %s_value' % (name, name)) self.sql('ALTER TABLE %ss ADD %s_value TEXT' % (name, name)) - def fix_version_2_tables(self): - # Default (used by sqlite): NOOP - pass - def fix_version_4_tables(self): # note this is an explicit call now c = self.cursor @@ -411,6 +415,12 @@ # as version 5. pass + def fix_version_6_tables(self): + # Default (used by nobody): NOOP + # Each backend mysql, postgres, sqlite overrides this + # You would think ALTER commands would be the same but nooo. + pass + def _convert_journal_tables(self): """Get current journal table contents, drop the table and re-create""" c = self.cursor
--- a/roundup/backends/sessions_dbm.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/backends/sessions_dbm.py Thu Apr 21 16:54:17 2022 -0400 @@ -6,7 +6,7 @@ """ __docformat__ = 'restructuredtext' -import os, marshal, time +import os, marshal, time, logging, random from roundup.anypy.html import html_escape as escape @@ -132,21 +132,24 @@ dbm = __import__(db_type) retries_left = 15 + logger = logging.getLogger('roundup.hyperdb.backend.sessions') while True: try: handle = dbm.open(path, mode) break - except OSError: + except OSError as e: # Primarily we want to catch and retry: # [Errno 11] Resource temporarily unavailable retry # FIXME: make this more specific + if retries_left < 10: + logger.warning('dbm.open failed, retrying %s left: %s'%(retries_left,e)) if retries_left < 0: # We have used up the retries. Reraise the exception # that got us here. raise else: - # delay retry a bit - time.sleep(0.01) + # stagger retry to try to get around thundering herd issue. + time.sleep(random.randint(0,25)*.005) retries_left = retries_left - 1 continue # the while loop return handle
--- a/roundup/cgi/actions.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/cgi/actions.py Thu Apr 21 16:54:17 2022 -0400 @@ -464,7 +464,7 @@ different from 'index' """ template = self.getFromForm('template') - if template and template != 'index': + if template and template not in ['index', 'index|search']: return req.indexargs_url('', {'@template': template})[1:] return req.indexargs_url('', {})[1:] @@ -1433,8 +1433,22 @@ # full-text search if request.search_text: - matches = self.db.indexer.search( - re.findall(r'\b\w{2,25}\b', request.search_text), klass) + indexer = self.db.indexer + if self.db.indexer.query_language: + try: + matches = indexer.search( + [request.search_text], klass) + except Exception as e: + error = " ".join(e.args) + self.client.add_error_message(error) + self.client.response_code = 400 + # trigger error reporting. NotFound isn't right but... + raise exceptions.NotFound(error) + else: + matches = indexer.search( + re.findall(r'\b\w{%s,%s}\b' % (indexer.minlength, + indexer.maxlength), + request.search_text), klass) else: matches = None @@ -1598,8 +1612,23 @@ # full-text search if request.search_text: - matches = self.db.indexer.search( - re.findall(r'\b\w{2,25}\b', request.search_text), klass) + indexer = self.db.indexer + if indexer.query_language: + try: + matches = indexer.search( + [request.search_text], klass) + except Exception as e: + error = " ".join(e.args) + self.client.add_error_message(error) + self.client.response_code = 400 + # trigger error reporting. NotFound isn't right but... + raise exceptions.NotFound(error) + else: + matches = indexer.search( + re.findall(r'\b\w{%s,%s}\b' % (indexer.minlength, + indexer.maxlength), + request.search_text), + klass) else: matches = None
--- a/roundup/cgi/client.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/cgi/client.py Thu Apr 21 16:54:17 2022 -0400 @@ -31,8 +31,8 @@ from roundup.exceptions import LoginError, Reject, RejectRaw, \ Unauthorised, UsageError from roundup.cgi.exceptions import ( - FormError, NotFound, NotModified, Redirect, SendFile, SendStaticFile, - DetectorError, SeriousError) + FormError, IndexerQueryError, NotFound, NotModified, Redirect, + SendFile, SendStaticFile, DetectorError, SeriousError) from roundup.cgi.form_parser import FormParser from roundup.mailer import Mailer, MessageSendError from roundup.cgi import accept_language @@ -340,7 +340,10 @@ # Key can be explicitly file basename - value applied to just that file # takes precedence over mime type. # Key can be mime type - all files of that mimetype will get the value - Cache_Control = {} + Cache_Control = { + 'application/javascript': "public, max-age=1209600", # 2 weeks + 'text/css': "public, max-age=4838400", # 8 weeks/2 months + } # list of valid http compression (Content-Encoding) algorithms # we have available @@ -645,8 +648,11 @@ # type header set by rest handler # self.setHeader("Content-Type", "text/xml") - self.setHeader("Content-Length", str(len(output))) - self.write(output) + if self.response_code == 204: # no body with 204 + self.write("") + else: + self.setHeader("Content-Length", str(len(output))) + self.write(output) def add_ok_message(self, msg, escape=True): add_message(self._ok_message, msg, escape) @@ -848,7 +854,7 @@ else: # in debug mode, only write error to screen. self.write_html(e.html) - except: + except Exception as e: # Something has gone badly wrong. Therefore, we should # make sure that the response code indicates failure. if self.response_code == http_.client.OK: @@ -1775,7 +1781,6 @@ """ # spit out headers - self.additional_headers['Content-Type'] = mime_type self.additional_headers['Last-Modified'] = email.utils.formatdate(lmt) ims = None @@ -1796,6 +1801,9 @@ self.setVary("Accept-Encoding") raise NotModified + # don't set until we are sure we are sending a response body. + self.additional_headers['Content-Type'] = mime_type + if filename: self.write_file(filename) else: @@ -1915,7 +1923,11 @@ } pt = self.instance.templates.load(tplname) # let the template render figure stuff out - result = pt.render(self, None, None, **args) + try: + result = pt.render(self, None, None, **args) + except IndexerQueryError as e: + result = self.renderError(e.args[0]) + self.additional_headers['Content-Type'] = pt.content_type if self.env.get('CGI_SHOW_TIMING', ''): if self.env['CGI_SHOW_TIMING'].upper() == 'COMMENT': @@ -1962,6 +1974,46 @@ else: exec('raise exc_info[0], exc_info[1], exc_info[2]') # nosec + def renderError(self, error, response_code=400, use_template=True): + self.response_code = response_code + + # see if error message already logged add if not + if error not in self._error_message: + self.add_error_message(error, escape=True) + + # allow use of template for a specific code + trial_templates = [] + if use_template: + if response_code == 400: + trial_templates = [ "400" ] + else: + trial_templates = [ str(response_code), "400" ] + + tplname = None + for rcode in trial_templates: + try: + tplname = self.selectTemplate(self.classname, rcode) + break + except templating.NoTemplate: + pass + + if not tplname: + # call string of serious error to get basic html + # response. + return str(SeriousError(error)) + + args = { + 'ok_message': self._ok_message, + 'error_message': self._error_message + } + + try: + pt = self.instance.templates.load(tplname) + return pt.render(self, None, None, **args) + except Exception: + # report original error + return str(SeriousError(error)) + # these are the actions that are available actions = ( ('edit', actions.EditItemAction), @@ -2163,6 +2215,14 @@ self.additional_headers['Content-Length'] = str(len(new_content)) self.additional_headers['Content-Encoding'] = encoder self.setVary('Accept-Encoding') + try: + current_etag = self.additional_headers['ETag'] + except KeyError: + pass # etag not set for non-rest endpoints + else: + etag_end = current_etag.rindex('"') + self.additional_headers['ETag'] = ( current_etag[:etag_end] + + '-' + encoder + current_etag[etag_end:]) return new_content @@ -2196,6 +2256,8 @@ if 'Content-Type' not in self.additional_headers: self.additional_headers['Content-Type'] = \ 'text/html; charset=%s' % self.charset + if 'Content-Length' not in self.additional_headers: + self.additional_headers['Content-Length'] = str(len(content)) self.header() if self.env['REQUEST_METHOD'] == 'HEAD': @@ -2479,9 +2541,15 @@ self.write(content) def setHeader(self, header, value): - """Override a header to be returned to the user's browser. + """Override or delete a header to be returned to the user's browser. """ - self.additional_headers[header] = value + if value is None: + try: + del(self.additional_headers[header]) + except KeyError: + pass + else: + self.additional_headers[header] = value def header(self, headers=None, response=None): """Put up the appropriate header. @@ -2497,6 +2565,9 @@ if headers.get('Content-Type', 'text/html') == 'text/html': headers['Content-Type'] = 'text/html; charset=utf-8' + if response in [ 204, 304]: # has no body so no content-type + del(headers['Content-Type']) + headers = list(headers.items()) for ((path, name), (value, expire)) in self._cookies.items():
--- a/roundup/cgi/exceptions.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/cgi/exceptions.py Thu Apr 21 16:54:17 2022 -0400 @@ -54,6 +54,11 @@ """ pass +class IndexerQueryError(RoundupException): + """Raised to handle errors from FTS searches due to query + syntax errors. + """ + pass class SendFile(RoundupException): """Send a file from the database."""
--- a/roundup/cgi/templating.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/cgi/templating.py Thu Apr 21 16:54:17 2022 -0400 @@ -1244,7 +1244,9 @@ try: if labelprop is not None and \ labelprop != 'id': - label = linkcl.get(linkid, labelprop) + label = linkcl.get(linkid, labelprop, + default=self._( + "[label is missing]")) label = html_escape(label) except IndexError: comments['no_link'] = self._( @@ -1271,7 +1273,8 @@ if labelprop is not None and labelprop != 'id': try: label = html_escape(linkcl.get(args[k], - labelprop)) + labelprop, default=self._( + "[label is missing]"))) except IndexError: comments['no_link'] = self._( "<strike>The linked node" @@ -1281,7 +1284,7 @@ label = None if label is not None: if hrefable: - old = '<a ref="nofollow noopener" href="%s%s">%s</a>'%(classname, + old = '<a rel="nofollow noopener" href="%s%s">%s</a>'%(classname, args[k], label) else: old = label; @@ -1612,7 +1615,7 @@ (/[\w\-$.+!*(),;:@&=?/~\\#%]*)? # path etc. )| (?P<email>[-+=%/\w\.]+@[\w\.\-]+)| - (?P<item>(?P<class>[A-Za-z_]+)(\s*)(?P<id>\d+)) + (?P<item>(?P<class>[A-Za-z_]+)(\s*)(?P<id>\d+)(?P<fragment>\#[^][\#%^{}"<>\s]+)?) )''', re.X | re.I) protocol_re = re.compile('^(ht|f)tp(s?)://', re.I) @@ -1630,7 +1633,7 @@ return self._hyper_repl_email(match, '<a href="mailto:%s">%s</a>') elif len(match.group('id')) < 10: return self._hyper_repl_item(match, - '<a href="%(cls)s%(id)s">%(item)s</a>') + '<a href="%(cls)s%(id)s%(fragment)s">%(item)s</a>') else: # just return the matched text return match.group(0) @@ -1664,6 +1667,9 @@ item = match.group('item') cls = match.group('class').lower() id = match.group('id') + fragment = match.group('fragment') + if fragment is None: + fragment="" try: # make sure cls is a valid tracker classname cl = self._db.getclass(cls) @@ -2422,7 +2428,8 @@ k = linkcl.labelprop(1) if num_re.match(self._value): try: - value = str(linkcl.get(self._value, k)) + value = str(linkcl.get(self._value, k, + default=self._("[label is missing]"))) except IndexError: value = self._value else : @@ -2720,7 +2727,8 @@ for v in self._value: if num_re.match(v): try: - label = linkcl.get(v, k) + label = linkcl.get(v, k, + default=self._("[label is missing]")) except IndexError: label = None # fall back to designator if label is None @@ -3343,11 +3351,21 @@ # get the list of ids we're batching over klass = self.client.db.getclass(self.classname) if self.search_text: - matches = self.client.db.indexer.search( - [u2s(w.upper()) for w in re.findall( - r'(?u)\b\w{2,25}\b', - s2u(self.search_text, "replace") - )], klass) + indexer = self.client.db.indexer + if indexer.query_language: + try: + matches = indexer.search( + [self.search_text], klass) + except Exception as e: + self.client.add_error_message(" ".join(e.args)) + raise + else: + matches = indexer.search( + [u2s(w.upper()) for w in re.findall( + r'(?u)\b\w{%s,%s}\b' % (indexer.minlength, + indexer.maxlength), + s2u(self.search_text, "replace") + )], klass) else: matches = None
--- a/roundup/configuration.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/configuration.py Thu Apr 21 16:54:17 2022 -0400 @@ -9,7 +9,9 @@ # used here instead of try/except. import sys import getopt -import logging, logging.config +import errno +import logging +import logging.config import os import re import time @@ -31,8 +33,6 @@ from roundup.exceptions import RoundupException -# XXX i don't think this module needs string translation, does it? - ### Exceptions @@ -40,6 +40,11 @@ pass +class ParsingOptionError(ConfigurationError): + def __str__(self): + return self.args[0] + + class NoConfigError(ConfigurationError): """Raised when configuration loading fails @@ -261,8 +266,17 @@ def load_ini(self, config): """Load value from ConfigParser object""" - if config.has_option(self.section, self.setting): - self.set(config.get(self.section, self.setting)) + try: + if config.has_option(self.section, self.setting): + self.set(config.get(self.section, self.setting)) + except configparser.InterpolationSyntaxError as e: + raise ParsingOptionError( + _("Error in %(filepath)s with section [%(section)s] at " + "option %(option)s: %(message)s") % { + "filepath": self.config.filepath, + "section": e.section, + "option": e.option, + "message": str(e)}) class BooleanOption(Option): @@ -408,19 +422,91 @@ return _val raise OptionValueError(self, value, self.class_description) + class IndexerOption(Option): """Valid options for indexer""" - allowed = ['', 'xapian', 'whoosh', 'native'] + allowed = ['', 'xapian', 'whoosh', 'native', 'native-fts'] class_description = "Allowed values: %s" % ', '.join("'%s'" % a for a in allowed) + # FIXME this is the result of running: + # SELECT cfgname FROM pg_ts_config; + # on a postgresql 14.1 server. + # So the best we can do is hardcode this. + valid_langs = [ "simple", + "custom1", + "custom2", + "custom3", + "custom4", + "custom5", + "arabic", + "armenian", + "basque", + "catalan", + "danish", + "dutch", + "english", + "finnish", + "french", + "german", + "greek", + "hindi", + "hungarian", + "indonesian", + "irish", + "italian", + "lithuanian", + "nepali", + "norwegian", + "portuguese", + "romanian", + "russian", + "serbian", + "spanish", + "swedish", + "tamil", + "turkish", + "yiddish" ] + def str2value(self, value): _val = value.lower() if _val in self.allowed: return _val raise OptionValueError(self, value, self.class_description) + def validate(self, options): + + if self._value in ("", "xapian"): + try: + import xapian + except ImportError: + # indexer is probably '' and xapian isn't present + # so just return at end of method + pass + else: + try: + lang = options["INDEXER_LANGUAGE"]._value + xapian.Stem(lang) + except xapian.InvalidArgumentError: + import textwrap + lang_avail = b2s(xapian.Stem.get_available_languages()) + languages = textwrap.fill(_("Valid languages: ") + + lang_avail, 75, + subsequent_indent=" ") + raise OptionValueError(options["INDEXER_LANGUAGE"], + lang, languages) + + if self._value == "native-fts": + lang = options["INDEXER_LANGUAGE"]._value + if lang not in self.valid_langs: + import textwrap + languages = textwrap.fill(_("Expected languages: ") + + " ".join(self.valid_langs), 75, + subsequent_indent=" ") + raise OptionValueError(options["INDEXER_LANGUAGE"], + lang, languages) + class MailAddressOption(Option): """Email address @@ -552,6 +638,62 @@ return value +class SecretOption(Option): + """A string not beginning with file:// or a file starting with file:// + + Paths may be either absolute or relative to the HOME. + Value for option is the first line in the file. + It is mean to store secret information in the config file but + allow the config file to be stored in version control without + storing the secret there. + + """ + + class_description = \ + "A string that starts with 'file://' is interpreted as a file path \n" \ + "relative to the tracker home. Using 'file:///' defines an absolute \n" \ + "path. The first line of the file will be used as the value. Any \n" \ + "string that does not start with 'file://' is used as is. It \n" \ + "removes any whitespace at the end of the line, so a newline can \n" \ + "be put in the file.\n" + + def get(self): + _val = Option.get(self) + if isinstance(_val, str) and _val.startswith('file://'): + filepath = _val[7:] + if filepath and not os.path.isabs(filepath): + filepath = os.path.join(self.config["HOME"], filepath.strip()) + try: + with open(filepath) as f: + _val = f.readline().rstrip() + # except FileNotFoundError: py2/py3 + # compatible version + except EnvironmentError as e: + if e.errno != errno.ENOENT: + raise + else: + raise OptionValueError(self, _val, + "Unable to read value for %s. Error opening " + "%s: %s." % (self.name, e.filename, e.args[1])) + return self.str2value(_val) + + def validate(self, options): + if self.name == 'MAIL_PASSWORD': + if options['MAIL_USERNAME']._value: + # MAIL_PASSWORD is an exception. It is mandatory only + # if MAIL_USERNAME is set. So check only if username + # is set. + try: + self.get() + except OptionUnsetError: + # provide error message with link to MAIL_USERNAME + raise OptionValueError(options["MAIL_PASSWORD"], + "not defined", + "Mail username is set, so this must be defined.") + else: + self.get() + + class WebUrlOption(Option): """URL MUST start with http/https scheme and end with '/'""" @@ -614,6 +756,18 @@ # everything else taken from NullableOption (inheritance order) +class SecretMandatoryOption(MandatoryOption, SecretOption): + # use get from SecretOption and rest from MandatoryOption + get = SecretOption.get + class_description = SecretOption.class_description + + +class SecretNullableOption(NullableOption, SecretOption): + # use get from SecretOption and rest from NullableOption + get = SecretOption.get + class_description = SecretOption.class_description + + class TimezoneOption(Option): class_description = \ @@ -639,6 +793,17 @@ return value +class HttpVersionOption(Option): + """Used by roundup-server to verify http version is set to valid + string.""" + + def str2value(self, value): + if value not in ["HTTP/1.0", "HTTP/1.1"]: + raise OptionValueError(self, value, + "Valid vaues for -V or --http_version are: HTTP/1.0, HTTP/1.1") + return value + + class RegExpOption(Option): """Regular Expression option (value is Regular Expression Object)""" @@ -758,17 +923,20 @@ "Force Roundup to use a particular text indexer.\n" "If no indexer is supplied, the first available indexer\n" "will be used in the following order:\n" - "Possible values: xapian, whoosh, native (internal)."), + "Possible values: xapian, whoosh, native (internal), " + "native-fts.\nNote 'native-fts' will only be used if set."), (Option, "indexer_language", "english", "Used to determine what language should be used by the\n" - "indexer above. Currently only affects Xapian indexer. It\n" - "sets the language for the stemmer.\n" + "indexer above. Applies to Xapian and PostgreSQL native-fts\n" + "indexer. It sets the language for the stemmer, and PostgreSQL\n" + "native-fts stopwords and other dictionaries.\n" "Possible values: must be a valid language for the indexer,\n" "see indexer documentation for details."), (WordListOption, "indexer_stopwords", "", "Additional stop-words for the full-text indexer specific to\n" "your tracker. See the indexer source for the default list of\n" - "stop-words (eg. A,AND,ARE,AS,AT,BE,BUT,BY, ...)"), + "stop-words (eg. A,AND,ARE,AS,AT,BE,BUT,BY, ...). This is\n" + "not used by the native-fts indexer."), (OctalNumberOption, "umask", "0o002", "Defines the file creation mode mask."), (IntegerNumberGeqZeroOption, 'csv_field_size', '131072', @@ -1038,7 +1206,7 @@ "Setting this option makes Roundup migrate passwords with\n" "an insecure password-scheme to a more secure scheme\n" "when the user logs in via the web-interface."), - (MandatoryOption, "secret_key", create_token(), + (SecretMandatoryOption, "secret_key", create_token(), "A per tracker secret used in etag calculations for\n" "an object. It must not be empty.\n" "It prevents reverse engineering hidden data in an object\n" @@ -1050,7 +1218,7 @@ "(Note the default value changes every time\n" " roundup-admin updateconfig\n" "is run, so it must be explicitly set to a non-empty string.\n"), - (MandatoryOption, "jwt_secret", "disabled", + (SecretNullableOption, "jwt_secret", "disabled", "This is used to generate/validate json web tokens (jwt).\n" "Even if you don't use jwts it must not be empty.\n" "If less than 256 bits (32 characters) in length it will\n" @@ -1076,7 +1244,7 @@ (NullableOption, 'user', 'roundup', "Database user name that Roundup should use.", ['MYSQL_DBUSER']), - (NullableOption, 'password', 'roundup', + (SecretNullableOption, 'password', 'roundup', "Database user password.", ['MYSQL_DBPASSWORD']), (NullableOption, 'read_default_file', '~/.my.cnf', @@ -1157,7 +1325,7 @@ (Option, "username", "", "SMTP login name.\n" "Set this if your mail host requires authenticated access.\n" "If username is not empty, password (below) MUST be set!"), - (Option, "password", NODEFAULT, "SMTP login password.\n" + (SecretMandatoryOption, "password", NODEFAULT, "SMTP login password.\n" "Set this if your mail host requires authenticated access."), (IntegerNumberGeqZeroOption, "port", smtplib.SMTP_PORT, "Default port to send SMTP on.\n" @@ -1400,7 +1568,11 @@ # actual name of the config file. set on load. filepath = os.path.join(HOME, INI_FILE) - def __init__(self, config_path=None, layout=None, settings={}): + # List of option names that need additional validation after + # all options are loaded. + option_validators = [] + + def __init__(self, config_path=None, layout=None, settings=None): """Initialize confing instance Parameters: @@ -1417,6 +1589,8 @@ The overrides are applied after loading config file. """ + if settings is None: + settings = {} # initialize option containers: self.sections = [] self.section_descriptions = {} @@ -1471,6 +1645,9 @@ for _name in option.aliases: self.options[_name] = option + if hasattr(option, 'validate'): + self.option_validators.append(option.name) + def update_option(self, name, klass, default=NODEFAULT, description=None): """Override behaviour of early created option. @@ -1815,7 +1992,9 @@ ext = None detectors = None - def __init__(self, home_dir=None, settings={}): + def __init__(self, home_dir=None, settings=None): + if settings is None: + settings = {} Config.__init__(self, home_dir, layout=SETTINGS, settings=settings) # load the config if home_dir given if home_dir is None: @@ -1882,25 +2061,10 @@ on each other. E.G. indexer_language can only be validated if xapian indexer is used. """ - if options['INDEXER']._value in ("", "xapian"): - try: - import xapian - except ImportError: - # indexer is probably '' and xapian isn't present - # so just return at end of method - pass - else: - try: - lang = options["INDEXER_LANGUAGE"]._value - xapian.Stem(lang) - except xapian.InvalidArgumentError: - import textwrap - lang_avail = b2s(xapian.Stem.get_available_languages()) - languages = textwrap.fill(_("Valid languages: ") + - lang_avail, 75, - subsequent_indent=" ") - raise OptionValueError( options["INDEXER_LANGUAGE"], - lang, languages) + + for option in self.option_validators: + # validate() should throw an exception if there is an issue. + options[option].validate(options) def load(self, home_dir): """Load configuration from path designated by home_dir argument"""
--- a/roundup/demo.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/demo.py Thu Apr 21 16:54:17 2022 -0400 @@ -39,7 +39,13 @@ from roundup import init, instance, password # set up the config for this tracker - config = configuration.CoreConfig() + template_dir = os.path.join('share', 'roundup', 'templates', template) + + # Load optional override ini file. Missing ini file is ignored. + template_cfg = configuration.UserConfig(template_dir + "/config_ini.ini") + config = configuration.CoreConfig(settings={ + i.name: i.get() for i in template_cfg.items() + }) config['TRACKER_HOME'] = home config['MAIL_DOMAIN'] = 'localhost' config['DATABASE'] = 'db' @@ -64,8 +70,18 @@ print(" %s" % home) sys.exit(1) - template_dir = os.path.join('share', 'roundup', 'templates', template) init.install(home, template_dir) + # Remove config_ini.ini file from tracker_home (not template dir). + # Ignore file not found - not all templates have + # config_ini.ini files. + try: + os.remove(home + "/config_ini.ini") + except OSError as e: # FileNotFound exception under py3 + if e.errno == 2: + pass + else: + raise + # don't have email flying around nosyreaction = os.path.join(home, 'detectors', 'nosyreaction.py') if os.path.exists(nosyreaction): @@ -97,12 +113,6 @@ # write the config config['INSTANT_REGISTRATION'] = 1 - # FIXME: Move template-specific demo initialization into the templates. - if template == 'responsive': - config['STATIC_FILES'] = "static" - if template == 'jinja2': - config['TEMPLATE_ENGINE'] = 'jinja2' - config['STATIC_FILES'] = "static" config.save(os.path.join(home, config.INI_FILE)) # open the tracker and initialise @@ -113,7 +123,7 @@ db = tracker.open('admin') # FIXME: Move tracker-specific demo initialization into the tracker # templates. - if template == 'minimal': + if os.path.basename(template) == 'minimal': db.user.create(username='demo', password=password.Password('demo'), roles='User') else:
--- a/roundup/hyperdb.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/hyperdb.py Thu Apr 21 16:54:17 2022 -0400 @@ -1019,8 +1019,9 @@ for cn in self.getclasses(): cl = self.getclass(cn) # This will change properties if a back-multilink happens to - # have the same class, so we need to iterate over .keys() - for p in cl.properties.keys(): + # have the same class, so we need to iterate over a list made + # from .keys() + for p in list(cl.properties.keys()): prop = cl.properties[p] if not isinstance (prop, (Link, Multilink)): continue @@ -1167,7 +1168,7 @@ This method must be called at the end of processing. """ - + raise NotImplementedError def iter_roles(roles): ''' handle the text processing of turning the roles list
--- a/roundup/i18n.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/i18n.py Thu Apr 21 16:54:17 2022 -0400 @@ -58,6 +58,20 @@ LOCALE_DIRS.append(_mo_path) del _mo_path +import sys +# __file__ should be something like: +# /usr/local/lib/python3.10/site-packages/roundup/i18n.py +# os.prefix should be /usr, /usr/local or root of virtualenv +# strip leading / to make os.path.join work right. +path = __file__ +for N in 1, 2: + path = os.path.dirname(path) + # path is /usr/local/lib/python3.10/site-packages +_ldir = os.path.join(path, sys.prefix[1:], 'share', 'locale') +if os.path.isdir(_ldir): + LOCALE_DIRS.append(_ldir) +del _ldir + # Roundup text domain DOMAIN = "roundup"
--- a/roundup/instance.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/instance.py Thu Apr 21 16:54:17 2022 -0400 @@ -134,6 +134,8 @@ extension(self) detectors = self.get_extensions('detectors') db = env['db'] + # *Must* call post_init! It is not an error if called multiple times. + db.post_init () db.tx_Source = None # apply the detectors
--- a/roundup/mailgw.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/mailgw.py Thu Apr 21 16:54:17 2022 -0400 @@ -112,6 +112,7 @@ from roundup.hyperdb import iter_roles from roundup.anypy.strings import StringIO, b2s, u2s import roundup.anypy.random_ as random_ +import roundup.anypy.ssl_ as ssl_ try: import gpg, gpg.core, gpg.constants, gpg.constants.sigsum @@ -1373,7 +1374,7 @@ else: self.logger.debug('Trying server %r without ssl' % server) server = imaplib.IMAP4(server) - except (imaplib.IMAP4.error, socket.error, socket.sslerror): + except (imaplib.IMAP4.error, socket.error, ssl_.SSLError): self.logger.exception('IMAP server error') return 1 @@ -1415,7 +1416,7 @@ finally: try: server.expunge() - except (imaplib.IMAP4.error, socket.error, socket.sslerror): + except (imaplib.IMAP4.error, socket.error, ssl_.SSLError): pass server.logout() @@ -1461,7 +1462,7 @@ else: klass = poplib.POP3 server = klass(server) - except socket.error: + except (socket.error, ssl_.SSLError): self.logger.exception('POP server error') return 1 if apop:
--- a/roundup/password.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/password.py Thu Apr 21 16:54:17 2022 -0400 @@ -201,7 +201,10 @@ s = sha1(s2b(plaintext)).hexdigest() # nosec elif scheme == 'MD5': s = md5(s2b(plaintext)).hexdigest() # nosec - elif scheme == 'crypt' and crypt is not None: + elif scheme == 'crypt': + if crypt is None: + raise PasswordValueError( + 'Unsupported encryption scheme %r' % scheme) if other is not None: salt = other else: @@ -355,6 +358,8 @@ raise ValueError('Password not set') return '{%s}%s' % (self.scheme, self.password) +def test_missing_crypt(): + p = encodePassword('sekrit', 'crypt') def test(): # SHA @@ -415,5 +420,6 @@ if __name__ == '__main__': test() + test_missing_crypt() # vim: set filetype=python sts=4 sw=4 et si :
--- a/roundup/rest.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/rest.py Thu Apr 21 16:54:17 2022 -0400 @@ -123,8 +123,51 @@ 'data': data } return result + + format_object.wrapped_func = func return format_object +def openapi_doc(d): + """Annotate rest routes with openapi data. Takes a dict + for the openapi spec. It can be used standalone + as the openapi spec paths.<path>.<method> = + + { + "summary": "this path gets a value", + "description": "a longer description", + "responses": { + "200": { + "description": "normal response", + "content": { + "application/json": {}, + "application/xml": {} + } + }, + "406": { + "description": "Unable to provide requested content type", + "content": { + "application/json": {} + } + } + }, + "parameters": [ + { + "$ref": "#components/parameters/generic_.stats" + }, + { + "$ref": "#components/parameters/generic_.apiver" + }, + { + "$ref": "#components/parameters/generic_.verbose" + } + ] + } + """ + + def wrapper(f): + f.openapi_doc = d + return f + return wrapper def calculate_etag(node, key, classname="Missing", id="0", repr_format="json"): @@ -175,8 +218,20 @@ repr_format=repr_format) for etag in etags: - if etag is not None: - if etag != node_etag: + # etag includes doublequotes around tag: + # '"a46a5572190e4fad63958c135f3746fa"' + # but can include content-encoding suffix like: + # '"a46a5572190e4fad63958c135f3746fa-gzip"' + # turn the latter into the former as we don't care what + # encoding was used to send the body with the etag. + try: + suffix_start = etag.rindex('-') + clean_etag = etag[:suffix_start] + '"' + except (ValueError, AttributeError): + # - not in etag or etag is None + clean_etag = etag + if clean_etag is not None: + if clean_etag != node_etag: return False have_etag_match = True @@ -347,7 +402,13 @@ try: func_obj = funcs[method] except KeyError: - raise Reject('Method %s not allowed' % method) + valid_methods = ', '.join(sorted(funcs.keys())) + raise Reject(_('Method %(m)s not allowed. ' + 'Allowed: %(a)s')% { + 'm': method, + 'a': valid_methods + }, + valid_methods) # retrieve the vars list and the function caller list_vars = func_obj['vars'] @@ -502,13 +563,13 @@ for pn in p.split('.'): # Tried to dereference a non-Link property if cn is None: - raise AttributeError("Unknown: %s" % p) + raise UsageError("Property %(base)s can not be dereferenced in %(p)s." % { "base": p[:-(len(pn)+1)], "p": p}) cls = self.db.getclass(cn) # This raises a KeyError for unknown prop: try: prop = cls.getprops(protected=True)[pn] except KeyError: - raise AttributeError("Unknown: %s" % p) + raise KeyError("Unknown property: %s" % p) if isinstance(prop, hyperdb.Multilink): raise UsageError( 'Multilink Traversal not allowed: %s' % p) @@ -521,6 +582,13 @@ cn = prop.classname except AttributeError: cn = None + else: + cls = self.db.getclass(cn) + # This raises a KeyError for unknown prop: + try: + prop = cls.getprops(protected=True)[pn] + except KeyError: + raise KeyError("Unknown property: %s" % pn) checked_props.append (p) return checked_props @@ -741,11 +809,9 @@ f = value.split(",") if len(f) == 1: f = value.split(":") - allprops = class_obj.getprops(protected=True) display_props.update(self.transitive_props(class_name, f)) elif key == "@sort": f = value.split(",") - allprops = class_obj.getprops(protected=True) for p in f: if not p: raise UsageError("Empty property " @@ -784,6 +850,10 @@ except KeyError: raise UsageError("Field %s is not valid for %s class." % (p, class_name)) + # Call this for the side effect of validating the key + # use _discard as _ is apparently a global for the translation + # service. + _discard = self.transitive_props(class_name, [ key ]) # We drop properties without search permission silently # This reflects the current behavior of other roundup # interfaces @@ -891,6 +961,7 @@ result['@total_size'] = result_len self.client.setHeader("X-Count-Total", str(result_len)) + self.client.setHeader("Allow", "OPTIONS, GET, POST") return 200, result @Routing.route("/data/<:class_name>/<:item_id>", 'GET') @@ -962,7 +1033,6 @@ f = value.split(",") if len(f) == 1: f = value.split(":") - allprops = class_obj.getprops(protected=True) props.update(self.transitive_props(class_name, f)) elif key == "@protected": # allow client to request read only @@ -1028,7 +1098,10 @@ node = class_obj.getnode(item_id) etag = calculate_etag(node, self.db.config.WEB_SECRET_KEY, class_name, item_id, repr_format="json") - data = node.__getattr__(attr_name) + try: + data = node.__getattr__(attr_name) + except AttributeError as e: + raise UsageError(_("Invalid attribute %s"%attr_name)) result = { 'id': item_id, 'type': str(type(data)), @@ -1189,6 +1262,15 @@ link = '%s/%s/%s' % (self.data_path, class_name, item_id) self.client.setHeader("Location", link) + self.client.setHeader( + "Allow", + None + ) + self.client.setHeader( + "Access-Control-Allow-Methods", + None + ) + # set the response body result = { 'id': item_id, @@ -1643,6 +1725,11 @@ "Allow", "OPTIONS, GET, POST" ) + + self.client.setHeader( + "Access-Control-Allow-Methods", + "OPTIONS, GET, POST" + ) return 204, "" @Routing.route("/data/<:class_name>/<:item_id>", 'OPTIONS') @@ -1698,19 +1785,114 @@ attr_name, class_name)) return 204, "" + @openapi_doc({"summary": "Describe Roundup rest endpoint.", + "description": ("Report all supported api versions " + "and default api version. " + "Also report next level of link " + "endpoints below /rest endpoint"), + "responses": { + "200": { + "description": "Successful response.", + "content": { + "application/json": { + "examples": { + "success": { + "summary": "Normal json data.", + "value": """{ + "data": { + "default_version": 1, + "supported_versions": [ + 1 + ], + "links": [ + { + "uri": "https://tracker.example.com/demo/rest", + "rel": "self" + }, + { + "uri": "https://tracker.example.com/demo/rest/data", + "rel": "data" + }, + { + "uri": "https://tracker.example.com/demo/rest/summary", + "rel": "summary" + } + ] + } +}""" + } + } + }, + "application/xml": { + "examples": { + "success": { + "summary": "Normal xml data", + "value": """<dataf type="dict"> + <default_version type="int">1</default_version> + <supported_versions type="list"> + <item type="int">1</item> + </supported_versions> + <links type="list"> + <item type="dict"> + <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest</uri> + <rel type="str">self</rel> + </item> + <item type="dict"> + <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest/data</uri> + <rel type="str">data</rel> + </item> + <item type="dict"> + <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest/summary</uri> + <rel type="str">summary</rel> + </item> + <item type="dict"> + <uri type="str">https://rouilj.dynamic-dns.net/sysadmin/rest/summary2</uri> + <rel type="str">summary2</rel> + </item> + </links> +</dataf>""" + } + } + } + } + } + } + } + ) @Routing.route("/") @_data_decorator def describe(self, input): - """Describe the rest endpoint""" + """Describe the rest endpoint. Return direct children in + links list. + """ + + # paths looks like ['^rest/$', '^rest/summary$', + # '^rest/data/<:class>$', ...] + paths = Routing._Routing__route_map.keys() + + links = [] + # p[1:-1] removes ^ and $ from regexp + # if p has only 1 /, it's a child of rest/ root. + child_paths = sorted([ p[1:-1] for p in paths if + p.count('/') == 1 ]) + for p in child_paths: + # p.split('/')[1] is the residual path after + # removing rest/. child_paths look like: + # ['rest/', 'rest/summary'] etc. + rel = p.split('/')[1] + if rel: + rel_path = "/" + rel + else: + rel_path = rel + rel = "self" + links.append( {"uri": self.base_path + rel_path, + "rel": rel + }) + result = { "default_version": self.__default_api_version, "supported_versions": self.__supported_api_versions, - "links": [{"uri": self.base_path + "/summary", - "rel": "summary"}, - {"uri": self.base_path, - "rel": "self"}, - {"uri": self.base_path + "/data", - "rel": "data"}] + "links": links } return 200, result @@ -1949,8 +2131,8 @@ self.api_version = None except (ValueError, TypeError): # TypeError if int(None) - msg = ("Unrecognized version: %s. " - "See /rest without specifying version " + msg = ("Unrecognized api version: %s. " + "See /rest without specifying api version " "for supported versions." % ( part[1]['version'])) output = self.error_obj(400, msg) @@ -1961,22 +2143,29 @@ # default (application/json) ext_type = os.path.splitext(urlparse(uri).path)[1][1:] + # Check to see if the length of the extension is less than 6. + # this allows use of .vcard for a future use in downloading + # user info. It also allows passing through larger items like + # JWT that has a final component > 6 items. This method also + # allow detection of mistyped types like jon for json. + if ext_type and (len(ext_type) < 6): + # strip extension so uri make sense + # .../issue.json -> .../issue + uri = uri[:-(len(ext_type) + 1)] + else: + ext_type = None + # headers.get('Accept') is never empty if called here. # accept_type will be set to json if there is no Accept header # accept_type wil be empty only if there is an Accept header # with invalid values. data_type = ext_type or accept_type or headers.get('Accept') or "invalid" - if (ext_type): - # strip extension so uri make sense - # .../issue.json -> .../issue - uri = uri[:-(len(ext_type) + 1)] - # add access-control-allow-* to support CORS self.client.setHeader("Access-Control-Allow-Origin", "*") self.client.setHeader( "Access-Control-Allow-Headers", - "Content-Type, Authorization, X-HTTP-Method-Override" + "Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override" ) self.client.setHeader( "Allow", @@ -1984,7 +2173,7 @@ ) self.client.setHeader( "Access-Control-Allow-Methods", - "HEAD, OPTIONS, GET, PUT, DELETE, PATCH" + "HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH" ) # Is there an input.value with format json data? # If so turn it into an object that emulates enough @@ -2023,15 +2212,16 @@ # check for runtime statistics try: + # self.report_stats initialized to False self.report_stats = input['@stats'].value.lower() == "true" # Can also return a TypeError ("not indexable") # In case the FieldStorage could not parse the result except (KeyError, TypeError): - report_stats = False + pass # check for @apiver in query string - msg = ("Unrecognized version: %s. " - "See /rest without specifying version " + msg = _("Unrecognized api version: %s. " + "See /rest without specifying api version " "for supported versions.") try: if not self.api_version: @@ -2052,7 +2242,7 @@ # Use default if not specified for now. self.api_version = self.__default_api_version elif self.api_version not in self.__supported_api_versions: - raise UsageError(msg % self.api_version) + output = self.error_obj(400, msg % self.api_version) # sadly del doesn't work on FieldStorage which can be the type of # input. So we have to ignore keys starting with @ at other @@ -2069,7 +2259,8 @@ except NotFound as msg: output = self.error_obj(404, msg) except Reject as msg: - output = self.error_obj(405, msg) + output = self.error_obj(405, msg.args[0]) + self.client.setHeader("Allow", msg.args[1]) # Format the content type if data_type.lower() == "json":
--- a/roundup/scripts/roundup_server.py Fri Oct 08 00:37:16 2021 -0400 +++ b/roundup/scripts/roundup_server.py Thu Apr 21 16:54:17 2022 -0400 @@ -321,6 +321,8 @@ self.send_response(200) self.send_header('Content-Type', 'image/x-icon') + self.send_header('Content-Length', len(favico)) + self.send_header('Cache-Control', "public, max-age=86400") self.end_headers() # this bufsize is completely arbitrary, I picked 4K because @@ -635,9 +637,12 @@ (configuration.WordListOption, "include_headers", "", "Comma separated list of extra headers that should\n" "be copied into the CGI environment.\n" - "E.G. if you want to acces the REMOTE_USER and\n" + "E.G. if you want to access the REMOTE_USER and\n" "X-Proxy-User headers in the back end,\n" "set to the value REMOTE_USER,X-Proxy-User."), + (configuration.HttpVersionOption, "http_version", "HTTP/1.1", + "Change to HTTP/1.0 if needed. This disables keepalive."), + )), ("trackers", (), "Roundup trackers to serve.\n" "Each option in this section defines single Roundup tracker.\n" @@ -663,6 +668,7 @@ "ssl": "s", "pem": "e:", "include_headers": "I:", + "http_version": 'V:', } def __init__(self, config_file=None): @@ -732,6 +738,8 @@ # internal state correctly so that later closing SSL # socket works (with SSL end-handshake started) self.request.do_handshake() + RoundupRequestHandler.protocol_version = \ + self.CONFIG["HTTP_VERSION"] RoundupRequestHandler.setup(self) def finish(self): @@ -864,8 +872,8 @@ to the file indicated by PIDfile. The -l option *must* be specified if -d is used.''' if message: - message += '\n' - print(_('''%(message)sUsage: roundup-server [options] [name=tracker home]* + message += '\n\n' + print(_('''\n%(message)sUsage: roundup-server [options] [name=tracker home]* Options: -v print the Roundup version number and exit @@ -886,6 +894,9 @@ -e <fname> PEM file containing SSL key and certificate -t <mode> multiprocess mode (default: %(mp_def)s). Allowed values: %(mp_types)s. + -V <version> set HTTP version (default: HTTP/1.1). + Allowed values: HTTP/1.0, HTTP/1.1. + %(os_part)s Long options:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/Docker/Dockerfile Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,152 @@ +# build in root dir using: +# +# docker build -t roundup-app --rm -f scripts/Dockerfile . +# +# run using: +# +# docker run --rm -v /.../issue.tracker:/usr/src/app/tracker \ +# -p 9017:8080 roundup-app:latest + + +# Global vars for all build stages + +# application directory +ARG appdir=/usr/src/app + +# support roundup install from 'local' directory, +# 'local_pip' local directory using pip to install or +# latest release from 'pypi' +ARG source=local + +FROM python:3-alpine as build + +# Inherit global values https://github.com/moby/moby/issues/37345 +ARG appdir + +WORKDIR $appdir + +# Add packages needed to compile mysql, pgsql and other python modules. +# Can't use apk to add them as that installs a 3.9 python version. +# g++ installs cc1plus needed by pip install +RUN apk add \ + g++ \ + gcc \ + gpgme-dev \ + libxapian \ + linux-headers \ + make \ + musl-dev \ + mysql-dev \ + postgresql-dev \ + swig \ + xapian-core-dev + +# build xapian bindings: +# file with sphinx build dependencies to remove after build +# they are over 70MB of space. +COPY scripts/Docker/sphinxdeps.txt . + +RUN set -xv && CWD=$PWD && \ + VER=$(apk list -I 'xapian-core-dev' | \ + sed 's/^xapian-core-dev-\([0-9.]*\)-.*/\1/') && \ + cd /tmp && \ + wget https://oligarchy.co.uk/xapian/$VER/xapian-bindings-$VER.tar.xz && \ + tar -Jxvf xapian-bindings-$VER.tar.xz && \ + cd xapian-bindings-$VER/ && \ + pip --no-cache-dir install sphinx==1.8.5 && \ + ./configure --prefix=/usr/local --with-python3 --disable-documentation && \ + make && make install && \ + pip uninstall --no-cache-dir -y -r $CWD/sphinxdeps.txt + +# add requirements for pip here, e.g. Whoosh, gpg, zstd or other +# modules not installed in the base library. +# ignore warnings from pip to use virtualenv +COPY scripts/Docker/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# copy the elements of the release directory to the docker image +COPY setup.py install/ +COPY doc install/doc/ +COPY frontends install/frontends/ +COPY locale install/locale/ +COPY roundup install/roundup/ +COPY share install/share/ + +# verify source has one of two valid values then +# install in python3 standard directories from local copy +# or install in python3 standard directories from pypi using pip +# import from global/command line +ARG source +RUN set -xv && if [ "$source" = "local" ] || \ + [ "$source" = "pypi" ] || \ + [ "$source" = "local_pip" ]; then :; \ + else echo "invalid value for source: $source"; \ + echo "must be local or pypi"; exit 1; fi; \ + if [ "$source" = "local" ]; then cd install && ./setup.py install; fi; \ + if [ "$source" = "local_pip" ]; then cd install && pip install \ + --use-feature=in-tree-build . ; fi; \ + if [ "$source" = "pypi" ]; then pip install roundup; \ + cp -ril /usr/local/lib/python3.10/site-packages/usr/local/share/* \ + /usr/local/share; fi + +# build a new smaller docker image for execution. Build image above +# is 1G in size. +FROM python:3-alpine + +# import from global +ARG appdir + +WORKDIR $appdir + +# add libraries needed to run gpg/mysql/pgsql/brotli +RUN apk add \ + gpgme \ + mariadb-connector-c \ + libpq \ + libstdc++ \ + libxapian + +ARG source +LABEL "org.roundup-tracker.vendor"="Roundup Issue Tracker Team" \ + "org.roundup-tracker.description"="Roundup Issue Tracker using sqlite" \ + "version"="2.1.0 $source" \ + "org.opencontainers.image.authors"="roundup-devel@lists.sourceforge.net" + + +# pull over built assets +COPY --from=build /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages/ +COPY --from=build /usr/local/bin/roundup* /usr/local/bin/ +COPY --from=build /usr/local/share /usr/local/share/ +COPY scripts/Docker/roundup_start . + +# map port 8080 to your local port +EXPOSE 8080/tcp + +# mount a trackerdir on tracker location +RUN mkdir tracker +VOLUME $appdir/tracker + +HEALTHCHECK --start-period=1m \ + CMD wget -q -O /dev/null --no-verbose http://localhost:8080/issues/ + +# do not run roundup as root +RUN adduser -D -h /usr/src/app roundup +USER roundup + +# run the server, disable output buffering so we can see logs. +ENV PYTHONUNBUFFERED=1 +#ENTRYPOINT [ "roundup-server", "-n", "0.0.0.0" ] +ENTRYPOINT [ "./roundup_start" ] + +# allow the invoker to override cmd with multiple trackers +# in each subdirectory under $appdir/tracker. E.G. +# docker run .... \ +# issues=tracker/issues foo=tracker/foo +# +# note using "issue=$appdir/tracker" results in error: +# +# No valid configuration files found in directory /usr/src/app/$appdir/tracker +# +# so $appdir not expanded and $PWD prefixed onto the (relative path) +# $appdir/tracker. Hence use relative path for spec. +CMD [ "issues=tracker" ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/Docker/docker-compose.yml Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,81 @@ +# docker-roundup +# roundup issue tracker application with mariadb running as docker container +# +# docker-compose.yml +# +# Build components: +# docker-compose -f scripts/Docker/docker-compose.yml build +# +# Install tracker template: +# $ docker-compose -f scripts/Docker/docker-compose.yml run \ +# --rm --entrypoint roundup-admin --no-deps roundup-app \ +# -i tracker install +# +# Edit scripts/Docker/tracker/config.ini configure database settings +# and any NO DEFAULT settings. +# +# Initialize the database, wait 1 minute so +# +# $ docker-compose -f scripts/Docker/docker-compose.yml run \ +# --rm --entrypoint roundup-admin roundup-app \ +# -i tracker +# +# wait 1 minute for mariadb to initialize +# init tracker at roundup prompt +# +# roundup> init +# roundup> exit +# +# may need ^\ to get roundup-admin to exit. +# +# run +# docker-compose -f scripts/Docker/docker-compose.yml up +# +# tracker should be running at port 9017. + +# Note: mysql volume and tracker directories will be put in the +# scripts/Docker subdir. +# Paths for volumes are relative to docker-compose.yml location not +# docker-compose cwd or build context directory. + +version: '3' +services: + mariadb: + image: lscr.io/linuxserver/mariadb + container_name: mariadb + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/New_York + - MYSQL_ROOT_PASSWORD=myPassword + - MYSQL_DATABASE=roundup + - MYSQL_USER=roundup_user + - MYSQL_PASSWORD=roundup_pass +# ports: +# - 3306:3306 + volumes: + - ./dbData:/config + + roundup-app: + container_name: roundup-app + build: + context: ../.. + dockerfile: scripts/Docker/Dockerfile + args: + source: local_pip + #source: local + #source: pypi + command: "issues=tracker" + restart: unless-stopped + environment: + - TZ=America/New_York + ports: + - 9017:8080 + links: + - mariadb + depends_on: + - mariadb + volumes: + # will be placed in Docker subdir next to this file + - ./tracker:/usr/src/app/tracker
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/Docker/requirements.txt Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,14 @@ +# human timezones +pytz +# indexer +Whoosh +# extra database support +psycopg2 +mysqlclient +# encryption +gpg +# java web tokens +PyJWT +# extra HTTP compression methods +Brotli +zstd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/Docker/roundup_start Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,61 @@ +#! /bin/sh + +# When container starts verify that the trackers are configured. +# If they are, start the server otherwise run roundup-admin +# for installation and initialization. + +# "$@" should be a set of tracker=directory pairs. + +if ! [ -z "$SHELL_DEBUG" ]; then + set -xv +fi + +trap exit INT + +do_exit=0 + +for tracker_spec in "$@"; do + # IFS== set a=b doesn't assign $1 and $2 in busybox ash + # it also clobbers '$@'. 'echo mumble | read' starts read in a + # subshell so vars are not available in parent. + IFS="=" read tracker directory <<- EOE + $tracker_spec + EOE + # ^ is a tab for use with <<- + + # was $tracker_spec in the form of a=b, if not ignore it. + # allows setting CMD to -i index_template issue=tracker for example. + if [ -z "$directory" ]; then continue; fi + + # something is specified or built wrong. Don't start. + if [ ! -d "$directory" ]; then + printf "Unable to find directory %s. Exiting\n" "$directory" + exit 1 + fi + + # user must define web in config.ini. + if ! grep '^\s*web\s\s*=\s\s*' "$directory/config.ini" > /dev/null; then + roundup-admin -i "$directory" install + do_exit=1 + fi + + # we have a valid config.ini so init database if not done + if [ $do_exit == 0 -a ! -e "$directory/.init_done" ]; then + if roundup-admin -i "$directory" init; then + cat > "$directory/.init_done" <<- EOD + Don't delete this file. The docker startup needs it so it won't + re-initialze the database destroying all the data. + EOD + else + do_exit=1 + fi + fi +done + +# if any config.ini needs editing don't start up. +if [ $do_exit == 0 ]; then + # make roundup-server process 1 with exec + exec roundup-server -n 0.0.0.0 "$@" +fi + +exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/Docker/sphinxdeps.txt Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,19 @@ +Babel +Jinja2 +MarkupSafe +Pygments +alabaster +certifi +charset-normalizer +docutils +idna +imagesize +packaging +pyparsing +requests +six +snowballstemmer +sphinxcontrib-serializinghtml +sphinxcontrib-websupport +urllib3 +
--- a/scripts/README.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/scripts/README.txt Thu Apr 21 16:54:17 2022 -0400 @@ -7,6 +7,10 @@ copy-user.py Copy one or more Roundup users from one tracker instance to another. +dump_dbm_sessions_db.py + Simple script to dump a session style dbm database e.g. db/otks or + db/sessions in readable form. + imapServer.py This IMAP server script that runs in the background and checks for new email from a variety of mailboxes. @@ -31,6 +35,10 @@ Remove file attachment spam from a tracker. (Warning destructive, read script well.) +stats.xmlrpc.py + Script using the xmlrpc interface to retrieve info. Generates report + on what values are used by the various issues on bugs.python.org. + weekly-report Generate a simple report outlining the activity in one tracker for the most recent week. @@ -56,3 +64,18 @@ contributors.py Analyzes Mercurial log, filters and compiles list of committers with years of contribution. Can be useful for updating COPYING.txt + +---- + +Docker + Directory for docker setup. More info on how to use it is in + doc/installation.txt. + +Docker/Dockerfile - Create roundup docker. + +Docker/requirements.txt - Python requirements built into docker. + +Docker/roundup-start - Startup script for roundup in docker. + +Docker/docker-compose.yml - Manage two docker containers for roundup + and mysql.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/dump_dbm_sessions_db.py Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,35 @@ +#! /usr/bin/env python3 +"""Usage: dump_dbm_sessions_db.py [filename] + +Simple script to dump the otks and sessions dbm databases. Dumps +sessions db in current directory if no argument is given. + +Dump format: + + key: <timestamp> data + +where <timestamp> is the human readable __timestamp decoded from the +data object. + +""" + +import dbm, marshal, sys +from datetime import datetime + +try: + file = sys.argv[1] +except IndexError: + file="sessions" + +try: + db = dbm.open(file) +except Exception: + print("Unable to open database: %s"%file) + exit(1) + +k = db.firstkey() +while k is not None: + d = marshal.loads(db[k]) + t = datetime.fromtimestamp(d['__timestamp']) + print("%s: %s %s"%(k, t, d)) + k = db.nextkey(k)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/stats.xmlrpc.py Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,95 @@ +"""Count how many issues use each bpo field and print a report.""" +""" sample output: https://github.com/psf/gh-migration/issues/5#issuecomment-935697646""" + +import xmlrpc.client + +from collections import defaultdict + +class SpecialTransport(xmlrpc.client.SafeTransport): + def send_content(self, connection, request_body): + connection.putheader("Referer", "https://bugs.python.org/") + connection.putheader("Origin", "https://bugs.python.org") + connection.putheader("X-Requested-With", "XMLHttpRequest") + xmlrpc.client.SafeTransport.send_content(self, connection, request_body) + +# connect to bpo +roundup = xmlrpc.client.ServerProxy('https://bugs.python.org/xmlrpc', + transport=SpecialTransport(), + allow_none=True) + +# map bpo classes -> propname +# the class is the name of the class (e.g. issue_type, keyword -- +# also used in e.g. in https://bugs.python.org/keyword) +# the propname is the name used as attribute on the issue class +# (e.g. issue.type, issue.keywords) +classes = { + # 'status': 'status', # skip this + 'issue_type': 'type', + 'stage': 'stage', + 'component': 'components', + 'version': 'versions', + 'resolution': 'resolution', + 'priority': 'priority', + 'keyword': 'keywords', +} + +# find the id for the 'open' status +open_id = roundup.lookup('status', 'open') + +print(f'* Counting total issues...') +total_issues_num = len(roundup.filter('issue', None, {})) + +print(f'* Counting open issues...') +# use this list to filter only the open issues +open_issues = roundup.filter('issue', None, {'status': open_id}) +open_issues_num = len(open_issues) + +# save the totals in a dict with this structure: +# totals[propname][open/all][num/perc][name] +# where propname is e.g. 'keyword' and name is e.g. 'easy' +totals = defaultdict(lambda: {'all': {'perc': {}, 'num': {}}, + 'open': {'perc': {}, 'num': {}}}) +for cls, propname in classes.items(): + print(f'* Counting <{cls}>...') + # get the list of ids/names for the given class (e.g. 'easy' is 6) + ids = roundup.list(cls, 'id') + names = roundup.list(cls, 'name') + for id, name in zip(ids, names): + # filter and count on *all* issues with the given propname + tot_all = len(roundup.filter('issue', None, {propname: id})) + totals[propname]['all']['num'][name] = tot_all + totals[propname]['all']['perc'][name] = tot_all / total_issues_num + # filter and count on *open* issues with the given propname + tot_open = len(roundup.filter('issue', open_issues, {propname: id})) + totals[propname]['open']['num'][name] = tot_open + totals[propname]['open']['perc'][name] = tot_open / open_issues_num + + +print(f'Issues (open/all): {open_issues_num}/{total_issues_num}') + +# print a list of markdown tables for each bpo class name +for propname in classes.values(): + print(f'### {propname}') + print('| bpo field | open | all |') + print('| :--- | ---: | ---: |') + # pick the dict for the given propname (e.g. keywords) + proptots = totals[propname] + names = proptots['open']['num'] + # sort the names (e.g. 'easy') in reverse order + # based on the number of open issues + for name in sorted(names, key=names.get, reverse=True): + # get and print num/perc for all/open issues + issues_all = proptots['all']['num'][name] + issues_open = proptots['open']['num'][name] + perc_all = proptots['all']['perc'][name] + perc_open = proptots['open']['perc'][name] + print(f'| {name:20} | {issues_open:>5} ({perc_open:5.1%}) |' + f' {issues_all:>5} ({perc_all:5.1%}) |') + # calc and print num/perc for all/open issues + tot_issues_all = sum(proptots['all']['num'].values()) + tot_issues_open = sum(proptots['open']['num'].values()) + tot_perc_all = sum(proptots['all']['perc'].values()) + tot_perc_open = sum(proptots['open']['perc'].values()) + print(f'| **Total** | {tot_issues_open:>5} ({tot_perc_open:5.1%}) |' + f' {tot_issues_all:>5} ({tot_perc_all:5.1%}) |') +
--- a/setup.py Fri Oct 08 00:37:16 2021 -0400 +++ b/setup.py Thu Apr 21 16:54:17 2022 -0400 @@ -87,13 +87,13 @@ if prefix: return prefix else: - # get the platform lib path. + # get the platform lib path. Must start with / else infinite loop. plp = get_path('platlib') # nuke suffix that matches lib/* and return prefix head, tail = os.path.split(plp) - while tail != 'lib' and head != '': + while tail not in ['lib', 'lib64' ] and head != '/': head, tail = os.path.split(head) - if not head: + if head == '/': head = sys.prefix return head @@ -143,6 +143,19 @@ data_files = make_data_files_absolute(data_files, get_prefix()) + # when running under python2, even if called from setup, it tries + # and fails to perform an egg easy install even though it shouldn't: + # https://issues.roundup-tracker.org/issue2551185 + # Add this argument if we are an install to prevent this. + # This works right under python3. + # FIXME there has to be a better way than this + # https://issues.roundup-tracker.org/issue2551185 + + if sys.version_info[0] < 3: + for arg in sys.argv: + if arg == 'install': + sys.argv.append('--old-and-unmanageable') + # perform the setup action from roundup import __version__ @@ -216,6 +229,16 @@ data_files=data_files) if __name__ == '__main__': + + # Prevent `pip install roundup` from building bdist_wheel. + # Man pages, templates, locales installed under site-packages not + # in normal system locations. + # https://stackoverflow.com/questions/36846260/can-python-setuptools-install-files-outside-dist-packages + ''' + if 'bdist_wheel' in sys.argv: + raise RuntimeError("This setup.py does not support wheels") + ''' + os.chdir(os.path.dirname(__file__) or '.') main()
--- a/share/man/man1/roundup-server.1 Fri Oct 08 00:37:16 2021 -0400 +++ b/share/man/man1/roundup-server.1 Thu Apr 21 16:54:17 2022 -0400 @@ -35,8 +35,15 @@ The variable "trackers" is available to the template and is a dict of all configured trackers. .TP +\fB-I\fP \fIheader1[,header2,...]\fP +Pass the header(s) and their values to the backend. This allow-list +of header variables can be used by custom code in the tracker or with +a tracker's \fBhttp_auth_header\fP configuration option to allows a +front end server to authenticate a user and pass the user identity to +roundup. +.TP \fB-s\fP -Enables to use of SSL. +Enables use of SSL. .TP \fB-e\fP \fIfile\fP Sets a filename containing the PEM file to use for SSL. If left blank, a @@ -45,6 +52,10 @@ \fB-N\fP Log client machine names instead of IP addresses (much slower). .TP +\fB-V\fP \fIHTTPVER\fP +By default roundup-server uses HTTP/1.1 to enable keepalives for faster +response. HTTPVER can be set to \fBHTTP/1.0\fP to disable keepalives. +.TP \fB-u\fP \fIUID\fP Runs the Roundup web server as this UID. .TP
--- a/share/roundup/templates/jinja2/initial_data.py Fri Oct 08 00:37:16 2021 -0400 +++ b/share/roundup/templates/jinja2/initial_data.py Thu Apr 21 16:54:17 2022 -0400 @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - from roundup import password, date pri = db.getclass('priority')
--- a/test/db_test_base.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/db_test_base.py Thu Apr 21 16:54:17 2022 -0400 @@ -252,9 +252,21 @@ self.db.issue.create(title="flebble frooz") self.db.commit() - self.assertEqual(self.db.database_schema['version'], 6, - "This test only runs for database version 6") - self.db.database_schema['version'] = 5 + if self.db.database_schema['version'] > 6: + # make testUpgrades run the downgrade code only. + if hasattr(self, "downgrade_only"): + # we are being called by an earlier test + self.testUpgrade_6_to_7() + self.assertEqual(self.db.database_schema['version'], 6) + else: + # we are being called directly + self.downgrade_only = True + self.testUpgrade_6_to_7() + self.assertEqual(self.db.database_schema['version'], 6) + del(self.downgrade_only) + elif self.db.database_schema['version'] != 6: + self.skipTest("This test only runs for database version 6") + if self.db.dbtype == 'mysql': # version 6 has 5 indexes self.db.sql('show indexes from _user;') @@ -268,6 +280,11 @@ self.db.sql('show indexes from _user;') self.assertEqual(3,len(self.db.cursor.fetchall())) + self.db.database_schema['version'] = 5 + + if hasattr(self, "downgrade_only"): + return + # test upgrade adding index self.db.post_init() @@ -284,10 +301,16 @@ self.db.sql('show indexes from _user;') self.assertEqual(5,len(self.db.cursor.fetchall())) else: + if hasattr(self, "downgrade_only"): + return # this should be a no-op # test upgrade self.db.post_init() + # we should be at the current db version + self.assertEqual(self.db.database_schema['version'], + self.db.current_db_version) + def drop_key_retired_idx(self): c = self.db.cursor for cn, klass in self.db.classes.items():
--- a/test/rest_common.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/rest_common.py Thu Apr 21 16:54:17 2022 -0400 @@ -391,6 +391,68 @@ results = self.server.get_collection('issue', form) self.assertDictEqual(expected, results) + def testGetBadTransitive(self): + """ + Mess up the names of various properties and make sure we get a 400 + and a somewhat useful error message. + """ + base_path = self.db.config['TRACKER_WEB'] + 'rest/data/' + #self.maxDiff=None + self.create_sampledata() + self.db.issue.set('2', status=self.db.status.lookup('closed')) + self.db.issue.set('3', status=self.db.status.lookup('chatting')) + expected = [ + {'error': {'msg': KeyError('Unknown property: assignedto.isse',), + 'status': 400}}, + {'error': {'msg': KeyError('Unknown property: stat',), + 'status': 400}}, + {'error': {'msg': KeyError('Unknown property: status.nam',), + 'status': 400}}, + ] + + ## test invalid transitive property in @fields + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('status.name', 'o'), + cgi.MiniFieldStorage('@fields', 'status,assignedto.isse'), + cgi.MiniFieldStorage('@sort', 'status.name'), + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 400) + self.assertEqual(repr(expected[0]['error']['msg']), + repr(results['error']['msg'])) + self.assertEqual(expected[0]['error']['status'], + results['error']['status']) + + ## test invalid property in @fields + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('status.name', 'o'), + cgi.MiniFieldStorage('@fields', 'stat,assignedto.isuse'), + cgi.MiniFieldStorage('@sort', 'status.name'), + ] + results = self.server.get_collection('issue', form) + self.assertEqual(self.dummy_client.response_code, 400) + self.assertEqual(repr(expected[1]['error']['msg']), + repr(results['error']['msg'])) + self.assertEqual(expected[1]['error']['status'], + results['error']['status']) + + ## test invalid transitive property in filter TODO + form = cgi.FieldStorage() + form.list = [ + cgi.MiniFieldStorage('status.nam', 'o'), + cgi.MiniFieldStorage('@fields', 'status,assignedto.isuse'), + cgi.MiniFieldStorage('@sort', 'status.name'), + ] + results = self.server.get_collection('issue', form) + # is currently 403 not 400 + self.assertEqual(self.dummy_client.response_code, 400) + self.assertEqual(repr(expected[2]['error']['msg']), + repr(results['error']['msg'])) + self.assertEqual(expected[2]['error']['status'], + results['error']['status']) + def testGetExactMatch(self): """ Retrieve all issues with an exact title """ @@ -1180,8 +1242,8 @@ each one broke and no etag. Use the put command to trigger the etag checking code. ''' - for mode in ('header', 'etag', 'both', - 'brokenheader', 'brokenetag', 'none'): + for mode in ('header', 'header-gzip', 'etag', 'etag-br', + 'both', 'brokenheader', 'brokenetag', 'none'): try: # clean up any old header del(self.headers) @@ -1198,9 +1260,17 @@ if mode == 'header': print("Mode = %s"%mode) self.headers = {'if-match': etag} + elif mode == 'header-gzip': + print("Mode = %s"%mode) + gzip_etag = etag[:-1] + "-gzip" + etag[-1:] + self.headers = {'if-match': gzip_etag} elif mode == 'etag': print("Mode = %s"%mode) form.list.append(cgi.MiniFieldStorage('@etag', etag)) + elif mode == 'etag-br': + print("Mode = %s"%mode) + br_etag = etag[:-1] + "-br" + etag[-1:] + form.list.append(cgi.MiniFieldStorage('@etag', br_etag)) elif mode == 'both': print("Mode = %s"%mode) self.headers = {'etag': etag} @@ -1216,7 +1286,7 @@ elif mode == 'none': print( "Mode = %s"%mode) else: - self.fail("unknown mode found") + self.fail("unknown mode '%s' found"%mode) results = self.server.put_attribute( 'user', self.joeid, 'realname', form @@ -2010,8 +2080,8 @@ json_dict = json.loads(b2s(results)) self.assertEqual(json_dict['error']['status'], 400) self.assertEqual(json_dict['error']['msg'], - "Unrecognized version: L. See /rest without " - "specifying version for supported versions.") + "Unrecognized api version: L. See /rest without " + "specifying api version for supported versions.") headers={"accept": "application/json; version=z" } self.headers=headers @@ -2022,8 +2092,8 @@ json_dict = json.loads(b2s(results)) self.assertEqual(json_dict['error']['status'], 400) self.assertEqual(json_dict['error']['msg'], - "Unrecognized version: z. See /rest without " - "specifying version for supported versions.") + "Unrecognized api version: z. See /rest without " + "specifying api version for supported versions.") headers={"accept": "application/vnd.roundup.test-vz+json" } self.headers=headers @@ -2035,8 +2105,8 @@ json_dict = json.loads(b2s(results)) self.assertEqual(json_dict['error']['status'], 400) self.assertEqual(json_dict['error']['msg'], - "Unrecognized version: z. See /rest without " - "specifying version for supported versions.") + "Unrecognized api version: z. See /rest without " + "specifying api version for supported versions.") # verify that version priority is correct; should be version=... headers={"accept": "application/vnd.roundup.test-vz+json; version=a" @@ -2050,8 +2120,8 @@ json_dict = json.loads(b2s(results)) self.assertEqual(json_dict['error']['status'], 400) self.assertEqual(json_dict['error']['msg'], - "Unrecognized version: a. See /rest without " - "specifying version for supported versions.") + "Unrecognized api version: a. See /rest without " + "specifying api version for supported versions.") # TEST #10 # check /rest and /rest/summary and /rest/notthere @@ -2063,16 +2133,16 @@ "default_version": 1, "links": [ { - "rel": "summary", - "uri": "http://tracker.example/cgi-bin/roundup.cgi/bugs/rest/summary" - }, - { "rel": "self", "uri": "http://tracker.example/cgi-bin/roundup.cgi/bugs/rest" }, { "rel": "data", "uri": "http://tracker.example/cgi-bin/roundup.cgi/bugs/rest/data" + }, + { + "rel": "summary", + "uri": "http://tracker.example/cgi-bin/roundup.cgi/bugs/rest/summary" } ] } @@ -2272,15 +2342,18 @@ headers={"accept": "application/json; version=99" } self.headers=headers - with self.assertRaises(UsageError) as ctx: - results = self.server.dispatch('GET', - "/rest/data/status/1", - self.empty_form) + results = self.server.dispatch('GET', + "/rest/data/status/1", + self.empty_form) print(results) - self.assertEqual(self.server.client.response_code, 200) - self.assertEqual(ctx.exception.args[0], - "Unrecognized version: 99. See /rest without " - "specifying version for supported versions.") + json_dict = json.loads(b2s(results)) + self.assertEqual(self.server.client.response_code, 400) + self.assertEqual(self.server.client.additional_headers['Content-Type'], + "application/json") + self.assertEqual(json_dict['error']['msg'], + "Unrecognized api version: 99. See /rest " + "without specifying api version for " + "supported versions.") def testMethodOverride(self): # TEST #1
--- a/test/test_actions.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_actions.py Thu Apr 21 16:54:17 2022 -0400 @@ -82,6 +82,16 @@ self.assertRaisesMessage(ValueError, action.handle, 'No type specified') + def testShowActionBadNumber(self): + action = ShowAction(self.client) + self.assertRaises(ValueError, action.handle) + self.form.value.append(MiniFieldStorage('@number', 'A')) + self.form.value.append(MiniFieldStorage('@type', 'issue')) + with self.assertRaises(SeriousError) as ctx: + action.handle() + self.assertEqual('"A" is not an ID (issue ID required)', + ctx.exception.args[0]) + class RetireActionTestCase(ActionTestCase): def testRetireAction(self): self.client.db.security.hasPermission = true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/test_anypy.py Thu Apr 21 16:54:17 2022 -0400 @@ -0,0 +1,43 @@ +"""Random tests for anypy modules""" + + +import unittest +from roundup.anypy.strings import repr_export, eval_import + +import sys +_py3 = sys.version_info[0] > 2 + +class StringsTest(unittest.TestCase): + + def test_import_params(self): + """ issue2551170 - handle long int in history/journal + params tuple + """ + # python2 export with id as number + val = eval_import("('issue', 2345L, 'status')") + self.assertSequenceEqual(val, ('issue', 2345, 'status')) + + # python3 export with id as number + val = eval_import("('issue', 2345, 'status')") + self.assertSequenceEqual(val, ('issue', 2345, 'status')) + + # python2 or python3 export with id as string + val = eval_import("('issue', '2345', 'status')") + self.assertSequenceEqual(val, ('issue', '2345', 'status')) + + def test_export_params(self): + """ issue2551170 - handle long int in history/journal + params tuple + """ + # python2 export with id as number + if _py3: + val = repr_export(('issue', 2345, 'status')) + self.assertEqual(val, "('issue', 2345, 'status')") + else: + val = repr_export(('issue', long(2345), 'status')) + self.assertEqual(val, "('issue', 2345L, 'status')") + + # python2 or python3 export with id as string + val = repr_export(('issue', '2345', 'status')) + self.assertEqual(val, "('issue', '2345', 'status')") +
--- a/test/test_cgi.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_cgi.py Thu Apr 21 16:54:17 2022 -0400 @@ -33,6 +33,9 @@ from . import db_test_base from .db_test_base import FormTestParent, setupTracker, FileUpload from .cmp_helper import StringFragmentCmpHelper +from .test_postgresql import skip_postgresql +from .test_mysql import skip_mysql + class FileList: def __init__(self, name, *files): @@ -42,6 +45,24 @@ for f in self.files: yield (self.name, f) +class testFtsQuery(object): + + def testRenderContextFtsQuery(self): + self.db.issue.create(title='i1 is found', status="chatting") + + self.client.form=db_test_base.makeForm( + { "@ok_message": "ok message", "@template": "index", + "@search_text": "found"}) + self.client.path = 'issue' + self.client.determine_context() + + result = self.client.renderContext() + + expected = '">i1 is found</a>' + + self.assertIn(expected, result) + self.assertEqual(self.client.response_code, 200) + cm = client.add_message class MessageTestCase(unittest.TestCase): # Note: Escaping is now handled on a message-by-message basis at a @@ -79,7 +100,86 @@ self.assertEqual(cm([],'<i>x</i>\n<b>x</b>',False), ['<i>x</i><br />\n<b>x</b>']) -class FormTestCase(FormTestParent, StringFragmentCmpHelper, unittest.TestCase): +class testCsvExport(object): + + def testCSVExportBase(self): + cl = self._make_client( + {'@columns': 'id,title,status,keyword,assignedto,nosy,creation'}, + nodeid=None, userid='1') + cl.classname = 'issue' + + demo_id=self.db.user.create(username='demo', address='demo@test.test', + roles='User', realname='demo') + key_id1=self.db.keyword.create(name='keyword1') + key_id2=self.db.keyword.create(name='keyword2') + + originalDate = date.Date + dummy=date.Date('2000-06-26.00:34:02.0') + # is a closure the best way to return a static Date object?? + def dummyDate(adate=None): + def dummyClosure(adate=None, translator=None): + return dummy + return dummyClosure + date.Date = dummyDate() + + self.db.issue.create(title='foo1', status='2', assignedto='4', nosy=['3',demo_id]) + self.db.issue.create(title='bar2', status='1', assignedto='3', keyword=[key_id1,key_id2]) + self.db.issue.create(title='baz32', status='4') + output = io.BytesIO() + cl.request = MockNull() + cl.request.wfile = output + # call export version that outputs names + actions.ExportCSVAction(cl).handle() + should_be=(s2b('"id","title","status","keyword","assignedto","nosy","creation"\r\n' + '"1","foo1","deferred","","Contrary, Mary","Bork, Chef;Contrary, Mary;demo","2000-06-26 00:34"\r\n' + '"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef","2000-06-26 00:34"\r\n' + '"3","baz32","need-eg","","","","2000-06-26 00:34"\r\n')) + + + #print(should_be) + #print(output.getvalue()) + self.assertEqual(output.getvalue(), should_be) + output = io.BytesIO() + cl.request = MockNull() + cl.request.wfile = output + # call export version that outputs id numbers + actions.ExportCSVWithIdAction(cl).handle() + should_be = s2b('"id","title","status","keyword","assignedto","nosy","creation"\r\n' + '''"1","foo1","2","[]","4","['3', '4', '5']","2000-06-26.00:34:02"\r\n''' + '''"2","bar2","1","['1', '2']","3","['3']","2000-06-26.00:34:02"\r\n''' + '''"3","baz32","4","[]","None","[]","2000-06-26.00:34:02"\r\n''') + #print(should_be) + #print(output.getvalue()) + self.assertEqual(output.getvalue(), should_be) + + # reset the real date command + date.Date = originalDate + + # test full text search + # call export version that outputs names + cl = self._make_client( + {'@columns': 'id,title,status,keyword,assignedto,nosy', + "@search_text": "bar2"}, nodeid=None, userid='1') + cl.classname = 'issue' + output = io.BytesIO() + cl.request = MockNull() + cl.request.wfile = output + actions.ExportCSVAction(cl).handle() + should_be=(s2b('"id","title","status","keyword","assignedto","nosy"\r\n' + '"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef"\r\n')) + + self.assertEqual(output.getvalue(), should_be) + + # call export version that outputs id numbers + output = io.BytesIO() + cl.request = MockNull() + cl.request.wfile = output + actions.ExportCSVWithIdAction(cl).handle() + should_be = s2b('"id","title","status","keyword","assignedto","nosy"\r\n' + "\"2\",\"bar2\",\"1\",\"['1', '2']\",\"3\",\"['3']\"\r\n") + self.assertEqual(output.getvalue(), should_be) + +class FormTestCase(FormTestParent, StringFragmentCmpHelper, testCsvExport, unittest.TestCase): def setUp(self): FormTestParent.setUp(self) @@ -1789,44 +1889,6 @@ self.db.user.set('1', roles='') self.assertTrue(not item.hasRole('')) - def testCSVExport(self): - cl = self._make_client( - {'@columns': 'id,title,status,keyword,assignedto,nosy'}, - nodeid=None, userid='1') - cl.classname = 'issue' - - demo_id=self.db.user.create(username='demo', address='demo@test.test', - roles='User', realname='demo') - key_id1=self.db.keyword.create(name='keyword1') - key_id2=self.db.keyword.create(name='keyword2') - self.db.issue.create(title='foo1', status='2', assignedto='4', nosy=['3',demo_id]) - self.db.issue.create(title='bar2', status='1', assignedto='3', keyword=[key_id1,key_id2]) - self.db.issue.create(title='baz32', status='4') - output = io.BytesIO() - cl.request = MockNull() - cl.request.wfile = output - # call export version that outputs names - actions.ExportCSVAction(cl).handle() - should_be=(s2b('"id","title","status","keyword","assignedto","nosy"\r\n' - '"1","foo1","deferred","","Contrary, Mary","Bork, Chef;Contrary, Mary;demo"\r\n' - '"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef"\r\n' - '"3","baz32","need-eg","","",""\r\n')) - #print(should_be) - print(output.getvalue()) - self.assertEqual(output.getvalue(), should_be) - output = io.BytesIO() - cl.request = MockNull() - cl.request.wfile = output - # call export version that outputs id numbers - actions.ExportCSVWithIdAction(cl).handle() - should_be = s2b('"id","title","status","keyword","assignedto","nosy"\r\n' - "\"1\",\"foo1\",\"2\",\"[]\",\"4\",\"['3', '4', '5']\"\r\n" - "\"2\",\"bar2\",\"1\",\"['1', '2']\",\"3\",\"['3']\"\r\n" - '\"3\","baz32",\"4\","[]","None","[]"\r\n') - #print(should_be) - print(output.getvalue()) - self.assertEqual(output.getvalue(), should_be) - def testCSVExportCharset(self): cl = self._make_client( {'@columns': 'id,title,status,keyword,assignedto,nosy'}, @@ -1976,7 +2038,7 @@ self.assertRaises(exceptions.Unauthorised, actions.ExportCSVWithIdAction(cl).handle) -class TemplateHtmlRendering(unittest.TestCase): +class TemplateHtmlRendering(unittest.TestCase, testFtsQuery): ''' try to test the rendering code for tal ''' def setUp(self): self.dirname = '_test_template' @@ -2036,6 +2098,61 @@ self.assertNotEqual(-1, self.output[0].index('<!-- SHA: c87a4e18d59a527331f1d367c0c6cc67ee123e63 -->')) + def testRenderError(self): + # set up the client; + # run determine_context to set the required client attributes + # run renderError(); check result for proper page + + self.client.form=db_test_base.makeForm({}) + self.client.path = '' + self.client.determine_context() + + error = "Houston, we have a problem" + + + # template rendering will fail and return fallback html + out = self.client.renderError(error, 404) + + expected_fallback = ( + '\n<html><head><title>Roundup issue tracker: ' + 'An error has occurred</title>\n' + ' <link rel="stylesheet" type="text/css" href="@@file/style.css">\n' + '</head>\n' + '<body class="body" marginwidth="0" marginheight="0">\n' + ' <p class="error-message">Houston, we have a problem</p>\n' + '</body></html>\n') + + self.assertEqual(out, expected_fallback) + self.assertIn(error, self.client._error_message) + self.assertEqual(self.client.response_code, 404) + + ### next test + # Set this so template rendering works. + self.client.classname = 'issue' + + out = self.client.renderError("Houston, we have a problem", 404) + # match hard coded line in 404 template + expected = ('There is no <span>issue</span> with id') + + self.assertIn(expected, out) + self.assertEqual(self.client.response_code, 404) + + + ### next test + # disable template use get fallback + out = self.client.renderError("Houston, we have a problem", 404, + use_template=False) + + self.assertEqual(out, expected_fallback) + self.assertEqual(self.client.response_code, 404) + + ### next test + # no 400 template (default 2nd param) so we get fallback + out = self.client.renderError("Houston, we have a problem") + self.assertEqual(out, expected_fallback) + self.assertIn(error, self.client._error_message) + self.assertEqual(self.client.response_code, 400) + def testrenderContext(self): # set up the client; # run determine_context to set the required client attributes @@ -2288,4 +2405,252 @@ r = t.selectTemplate("user", "subdir/item") self.assertEqual("subdir/user.item", r) +class SqliteNativeFtsCgiTest(unittest.TestCase, testFtsQuery, testCsvExport): + """All of the rest of the tests use anydbm as the backend. + In addtion to normal fts test, this class tests renderError + when renderContext fails. + Triggering this error requires the native-fts backend for + the sqlite db. + """ + + def setUp(self): + self.dirname = '_test_template' + # set up and open a tracker + self.instance = setupTracker(self.dirname, backend="sqlite") + + self.instance.config.INDEXER = "native-fts" + + # open the database + self.db = self.instance.open('admin') + self.db.tx_Source = "web" + self.db.user.create(username='Chef', address='chef@bork.bork.bork', + realname='Bork, Chef', roles='User') + self.db.user.create(username='mary', address='mary@test.test', + roles='User', realname='Contrary, Mary') + self.db.post_init() + + # create a client instance and hijack write_html + self.client = client.Client(self.instance, "user", + {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, + form=db_test_base.makeForm({"@template": "item"})) + + self.client._error_message = [] + self.client._ok_message = [] + self.client.db = self.db + self.client.userid = '1' + self.client.language = ('en',) + self.client.session_api = MockNull(_sid="1234567890") + + self.output = [] + # ugly hack to get html_write to return data here. + def html_write(s): + self.output.append(s) + + # hijack html_write + self.client.write_html = html_write + + def tearDown(self): + self.db.close() + try: + shutil.rmtree(self.dirname) + except OSError as error: + if error.errno not in (errno.ENOENT, errno.ESRCH): raise + + def testRenderContextBadFtsQuery(self): + # only test for sqlite + if self.db.dbtype not in [ "sqlite" ]: + pytest.skip("Not tested for backends without native FTS") + + # generate a bad fts query + self.client.form=db_test_base.makeForm( + { "@ok_message": "ok message", "@template": "index", + "@search_text": "foo-bar"}) + self.client.path = 'issue' + self.client.determine_context() + + result = self.client.renderContext() + + expected = '\n<html><head><title>Roundup issue tracker: An error has occurred</title>\n <link rel="stylesheet" type="text/css" href="@@file/style.css">\n</head>\n<body class="body" marginwidth="0" marginheight="0">\n <p class="error-message">Search failed. Try quoting any terms that include a \'-\' and retry the search.</p>\n</body></html>\n' + + self.assertEqual(result, expected) + self.assertEqual(self.client.response_code, 400) + + # + # SECURITY + # + # XXX test all default permissions + def _make_client(self, form, classname='user', nodeid='1', + userid='2', template='item'): + cl = client.Client(self.instance, None, {'PATH_INFO':'/', + 'REQUEST_METHOD':'POST'}, db_test_base.makeForm(form)) + cl.classname = classname + if nodeid is not None: + cl.nodeid = nodeid + cl.db = self.db + #cl.db.Otk = MockNull() + #cl.db.Otk.data = {} + #cl.db.Otk.getall = self.data_get + #cl.db.Otk.set = self.data_set + cl.userid = userid + cl.language = ('en',) + cl._error_message = [] + cl._ok_message = [] + cl.template = template + return cl + + def testCSVExportSearchError(self): + # test full text search + cl = self._make_client( + {'@columns': 'id,title,status,keyword,assignedto,nosy', + "@search_text": "foo + ^bar2"}, nodeid=None, userid='1') + cl.classname = 'issue' + output = io.BytesIO() + cl.request = MockNull() + cl.request.wfile = output + + # note NotFound isn't quite right. however this exception + # passes up the stack to where it is handled with a suitable + # display of the error. + # call export version that outputs names + with self.assertRaises(NotFound) as cm: + actions.ExportCSVAction(cl).handle() + + # call export version that outputs id numbers + with self.assertRaises(NotFound) as cm: + actions.ExportCSVWithIdAction(cl).handle() + +class SqliteNativeCgiTest(unittest.TestCase, testFtsQuery): + """All of the rest of the tests use anydbm as the backend. + This class tests renderContext for fulltext search. + Run with sqlite and native indexer. + """ + + def setUp(self): + self.dirname = '_test_template' + # set up and open a tracker + self.instance = setupTracker(self.dirname, backend="sqlite") + + self.instance.config.INDEXER = "native" + + # open the database + self.db = self.instance.open('admin') + self.db.tx_Source = "web" + + # create a client instance and hijack write_html + self.client = client.Client(self.instance, "user", + {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, + form=db_test_base.makeForm({"@template": "item"})) + + self.client._error_message = [] + self.client._ok_message = [] + self.client.db = self.db + self.client.userid = '1' + self.client.language = ('en',) + self.client.session_api = MockNull(_sid="1234567890") + + self.output = [] + # ugly hack to get html_write to return data here. + def html_write(s): + self.output.append(s) + + # hijack html_write + self.client.write_html = html_write + + def tearDown(self): + self.db.close() + try: + shutil.rmtree(self.dirname) + except OSError as error: + if error.errno not in (errno.ENOENT, errno.ESRCH): raise + +@skip_postgresql +class PostgresqlNativeCgiTest(unittest.TestCase, testFtsQuery): + """All of the rest of the tests use anydbm as the backend. + This class tests renderContext for fulltext search. + Run with postgresql and native indexer. + """ + + def setUp(self): + self.dirname = '_test_template' + # set up and open a tracker + self.instance = setupTracker(self.dirname, backend="postgresql") + + self.instance.config.INDEXER = "native" + + # open the database + self.db = self.instance.open('admin') + self.db.tx_Source = "web" + + # create a client instance and hijack write_html + self.client = client.Client(self.instance, "user", + {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, + form=db_test_base.makeForm({"@template": "item"})) + + self.client._error_message = [] + self.client._ok_message = [] + self.client.db = self.db + self.client.userid = '1' + self.client.language = ('en',) + self.client.session_api = MockNull(_sid="1234567890") + + self.output = [] + # ugly hack to get html_write to return data here. + def html_write(s): + self.output.append(s) + + # hijack html_write + self.client.write_html = html_write + + def tearDown(self): + self.db.close() + try: + shutil.rmtree(self.dirname) + except OSError as error: + if error.errno not in (errno.ENOENT, errno.ESRCH): raise + +@skip_mysql +class MysqlNativeCgiTest(unittest.TestCase, testFtsQuery): + """All of the rest of the tests use anydbm as the backend. + This class tests renderContext for fulltext search. + Run with mysql and native indexer. + """ + + def setUp(self): + self.dirname = '_test_template' + # set up and open a tracker + self.instance = setupTracker(self.dirname, backend="mysql") + + self.instance.config.INDEXER = "native" + + # open the database + self.db = self.instance.open('admin') + self.db.tx_Source = "web" + + # create a client instance and hijack write_html + self.client = client.Client(self.instance, "user", + {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, + form=db_test_base.makeForm({"@template": "item"})) + + self.client._error_message = [] + self.client._ok_message = [] + self.client.db = self.db + self.client.userid = '1' + self.client.language = ('en',) + self.client.session_api = MockNull(_sid="1234567890") + + self.output = [] + # ugly hack to get html_write to return data here. + def html_write(s): + self.output.append(s) + + # hijack html_write + self.client.write_html = html_write + + def tearDown(self): + self.db.close() + try: + shutil.rmtree(self.dirname) + except OSError as error: + if error.errno not in (errno.ENOENT, errno.ESRCH): raise + # vim: set filetype=python sts=4 sw=4 et si :
--- a/test/test_config.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_config.py Thu Apr 21 16:54:17 2022 -0400 @@ -19,7 +19,7 @@ import logging import fileinput -import os, shutil, errno +import os, shutil, errno, sys import pytest from roundup import configuration @@ -37,7 +37,17 @@ skip_xapian = mark_class(pytest.mark.skip( "Skipping Xapian indexer tests: 'xapian' not installed")) include_no_xapian = lambda func, *args, **kwargs: func - + +_py3 = sys.version_info[0] > 2 +if _py3: + skip_py2 = lambda func, *args, **kwargs: func +else: + # FIX: workaround for a bug in pytest.mark.skip(): + # https://github.com/pytest-dev/pytest/issues/568 + from .pytest_patcher import mark_class + skip_py2 = mark_class(pytest.mark.skip( + reason='Skipping test under python2.')) + config = configuration.CoreConfig() config.DATABASE = "db" @@ -339,34 +349,59 @@ except OSError as error: if error.errno not in (errno.ENOENT, errno.ESRCH): raise - def munge_configini(self, mods = None): + def munge_configini(self, mods = None, section=None): """ modify config.ini to meet testing requirements mods is a list of tuples: - [ ( "a = ", "b" ), ("c = ", None) ] + [ ( "a = ", "b" ), ("c = ", None), ("d = ", "b", "z = ") ] Match line with first tuple element e.g. "a = ". Note specify trailing "=" and space to delimit keyword and properly format - replacement line. If first tuple element matches, the line is + replacement line. If there are two elements in the tuple, + and the first element matches, the line is replaced with the concatenation of the first and second elements. If second element is None ("" doesn't work), the line will be - deleted. + deleted. If there are three elements in the tuple, the line + is replaced with the contcatentation of the third and second + elements (used to replace commented out parameters). - Note the key/first element of tuple must be unique in config.ini. - It is possible to have duplicates in different sections. This - method doesn't handle that. TBD option third element of tuple - defining section if needed. + Note if the key/first element of tuple is not unique in + config.ini, you must set the section to match the bracketed + section name. """ if mods is None: return + # if section is defined, the tests in the loop will turn + # it off on [main] if section != '[main]'. + in_section = True + for line in fileinput.input(os.path.join(self.dirname, "config.ini"), inplace=True): - for match, value in mods: - if line.startswith(match): - if value is not None: - print(match + value) - break + if section: + if line.startswith('['): + in_section = False + + if line.startswith(section): + in_section = True + + if in_section: + for rule in mods: + if len(rule) == 3: + match, value, repl = rule + else: + match, value = rule + repl = None + + if line.startswith(match): + if value is not None: + if repl: + print(repl + value) + else: + print(match + value) + break + else: + print(line[:-1]) # remove trailing \n else: print(line[:-1]) # remove trailing \n @@ -387,6 +422,183 @@ self.assertEqual("RDBMS_BACKEND is not set" " and has no default", cm.exception.__str__()) + def testUnsetMailPassword_with_set_username(self): + """ Set [mail] username but don't set the + [mail] password. Should get an OptionValueError. + """ + # SETUP: set mail username + self.munge_configini(mods=[ ("username = ", "foo"), ], + section="[mail]") + + config = configuration.CoreConfig() + + with self.assertRaises(configuration.OptionValueError) as cm: + config.load(self.dirname) + + print(cm.exception) + # test repr. The type is right since it passed assertRaises. + self.assertIn("OptionValueError", repr(cm.exception)) + # look for 'not defined' + self.assertEqual("not defined", cm.exception.args[1]) + + + def testUnsetMailPassword_with_unset_username(self): + """ Set [mail] username but don't set the + [mail] password. Should get an OptionValueError. + """ + config = configuration.CoreConfig() + + config.load(self.dirname) + + self.assertEqual(config['MAIL_USERNAME'], '') + + with self.assertRaises(configuration.OptionUnsetError) as cm: + self.assertEqual(config['MAIL_PASSWORD'], 'NO DEFAULT') + + def testSecretMandatory_missing_file(self): + + # SETUP: + self.munge_configini(mods=[ ("secret_key = ", "file://secret_key"), ]) + + config = configuration.CoreConfig() + + with self.assertRaises(configuration.OptionValueError) as cm: + config.load(self.dirname) + + print(cm.exception) + self.assertEqual(cm.exception.args[0].setting, "secret_key") + + def testSecretMandatory_load_from_file(self): + + # SETUP: + self.munge_configini(mods=[ ("secret_key = ", "file://secret_key"), ]) + + secret = "ASDQWEZXCRFVBGTYHNMJU" + with open(self.dirname + "/secret_key", "w") as f: + f.write(secret + "\n") + + config = configuration.CoreConfig() + + config.load(self.dirname) + + self.assertEqual(config['WEB_SECRET_KEY'], secret) + + + def testSecretMandatory_load_from_abs_file(self): + + abs_file = "/tmp/secret_key.%s"%os.getpid() + + # SETUP: + self.munge_configini(mods=[ ("secret_key = ", "file://%s"%abs_file), ]) + + secret = "ASDQWEZXCRFVBGTYHNMJU" + with open(abs_file, "w") as f: + f.write(secret + "\n") + + config = configuration.CoreConfig() + + config.load(self.dirname) + + self.assertEqual(config['WEB_SECRET_KEY'], secret) + + os.remove(abs_file) + + def testSecretMandatory_empty_file(self): + + self.munge_configini(mods=[ ("secret_key = ", "file:// secret_key"), ]) + + # file with no value just newline. + with open(self.dirname + "/secret_key", "w") as f: + f.write("\n") + + config = configuration.CoreConfig() + + with self.assertRaises(configuration.OptionValueError) as cm: + config.load(self.dirname) + + print(cm.exception.args) + self.assertEqual(cm.exception.args[2],"Value must not be empty.") + + def testNullableSecret_empty_file(self): + + self.munge_configini(mods=[ ("password = ", "file://db_password"), ]) + + # file with no value just newline. + with open(self.dirname + "/db_password", "w") as f: + f.write("\n") + + config = configuration.CoreConfig() + + config.load(self.dirname) + + v = config['RDBMS_PASSWORD'] + + self.assertEqual(v, None) + + def testNullableSecret_with_file_value(self): + + self.munge_configini(mods=[ ("password = ", "file://db_password"), ]) + + # file with no value just newline. + with open(self.dirname + "/db_password", "w") as f: + f.write("test\n") + + config = configuration.CoreConfig() + + config.load(self.dirname) + + v = config['RDBMS_PASSWORD'] + + self.assertEqual(v, "test") + + def testNullableSecret_with_value(self): + + self.munge_configini(mods=[ ("password = ", "test"), ]) + + config = configuration.CoreConfig() + + config.load(self.dirname) + + v = config['RDBMS_PASSWORD'] + + self.assertEqual(v, "test") + + def testSetMailPassword_with_set_username(self): + """ Set [mail] username and set the password. + Should have both values set. + """ + # SETUP: set mail username + self.munge_configini(mods=[ ("username = ", "foo"), + ("#password = ", "passwordfoo", + "password = ") ], + section="[mail]") + + config = configuration.CoreConfig() + + config.load(self.dirname) + + self.assertEqual(config['MAIL_USERNAME'], 'foo') + self.assertEqual(config['MAIL_PASSWORD'], 'passwordfoo') + + def testSetMailPassword_from_file(self): + """ Set [mail] username and set the password. + Should have both values set. + """ + # SETUP: set mail username + self.munge_configini(mods=[ ("username = ", "foo"), + ("#password = ", "file://password", + "password = ") ], + section="[mail]") + with open(self.dirname + "/password", "w") as f: + f.write("passwordfoo\n") + + config = configuration.CoreConfig() + + config.load(self.dirname) + + self.assertEqual(config['MAIL_USERNAME'], 'foo') + self.assertEqual(config['MAIL_PASSWORD'], 'passwordfoo') + @skip_xapian def testInvalidIndexerLanguage_w_empty(self): """ make sure we have a reasonable error message if @@ -492,6 +704,24 @@ # if exception not generated assertRaises # will generate failure. + def testInvalidIndexerLanguage_w_native_fts(self): + """ Use explicit native-fts indexer. Verify exception is + generated. + """ + + self.munge_configini(mods=[ ("indexer = ", "native-fts"), + ("indexer_language = ", "NO_LANG") ]) + + with self.assertRaises(configuration.OptionValueError) as cm: + config.load(self.dirname) + + # test repr. The type is right since it passed assertRaises. + self.assertIn("OptionValueError", repr(cm.exception)) + # look for failing language + self.assertIn("NO_LANG", cm.exception.args[1]) + # look for supported language + self.assertIn("basque", cm.exception.args[2]) + def testLoadConfig(self): """ run load to validate config """ @@ -553,6 +783,43 @@ # this should work self.assertEqual(config_copy['HTML_VERSION'], 'xhtml') + @skip_py2 + def testConfigValueInterpolateError(self): + ''' error is not raised using ConfigParser under Python 2. + Unknown cause, so skip it if running python 2. + ''' + + self.munge_configini(mods=[ ("admin_email = ", "a bare % is invalid") ]) + + config = configuration.CoreConfig() + + # load config generates: + ''' +E roundup.configuration.ParsingOptionError: Error in _test_instance/config.ini with section [main] at option admin_email: '%' must be followed by '%' or '(', found: '% is invalid' + ''' + + with self.assertRaises(configuration.ParsingOptionError) as cm: + config.load(self.dirname) + + print(cm.exception) + self.assertIn("'%' must be followed by '%' or '(', found: '% is invalid'", cm.exception.args[0]) + self.assertIn("_test_instance/config.ini with section [main] at option admin_email", cm.exception.args[0]) + + + from roundup.admin import AdminTool + from .test_admin import captured_output + + admin=AdminTool() + with captured_output() as (out, err): + sys.argv=['main', '-i', self.dirname, 'get', 'tile', 'issue1'] + ret = admin.main() + + expected_err = "Error in _test_instance/config.ini with section [main] at option admin_email: '%' must be followed by '%' or '(', found: '% is invalid'" + + self.assertEqual(ret, 1) + out = out.getvalue().strip() + self.assertEqual(out, expected_err) + def testInvalidIndexerValue(self): """ Mistype native indexer. Verify exception is generated. @@ -576,5 +843,3 @@ print(string_rep) self.assertIn("nati", string_rep) self.assertIn("'whoosh'", string_rep) - -
--- a/test/test_demo.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_demo.py Thu Apr 21 16:54:17 2022 -0400 @@ -33,7 +33,7 @@ except FileNotFoundError: pass - def testDemo(self): + def testDemoClassic(self): with captured_output() as (out, err): install_demo(self.home, 'anydbm', 'classic') output = out.getvalue().strip() @@ -61,4 +61,71 @@ # last line in the output. self.assertIn("Keyboard Interrupt: exiting", output.split('\n')) + def testDemoMinimal(self): + with captured_output() as (out, err): + # use a modified path that resolves when + install_demo(self.home, 'sqlite', '../templates/minimal') + output = out.getvalue().strip() + print(output) + # verify that db was set properly by reading config + with open(self.home + "/config.ini", "r") as f: + config_lines = f.readlines() + + self.assertIn("backend = sqlite\n", config_lines) + + # dummy up the return of get_server so the serve_forever method + # raises keyboard interrupt exiting the server so the test exits. + gs = roundup.scripts.roundup_server.ServerConfig.get_server + def raise_KeyboardInterrupt(): + raise KeyboardInterrupt + + def test_get_server(self): + httpd = gs(self) + httpd.serve_forever = raise_KeyboardInterrupt + return httpd + + roundup.scripts.roundup_server.ServerConfig.get_server = test_get_server + + # Run under context manager to capture output of startup text. + with captured_output() as (out, err): + run_demo(self.home) + output = out.getvalue().strip() + print(output) + # if the server installed and started this will be the + # last line in the output. + self.assertIn("Keyboard Interrupt: exiting", output.split('\n')) + + def testDemoJinja(self): + with captured_output() as (out, err): + install_demo(self.home, 'anydbm', 'jinja2') + output = out.getvalue().strip() + print(output) + + # verify that template was set to jinja2 by reading config + with open(self.home + "/config.ini", "r") as f: + config_lines = f.readlines() + + self.assertIn("template_engine = jinja2\n", config_lines) + + # dummy up the return of get_server so the serve_forever method + # raises keyboard interrupt exiting the server so the test exits. + gs = roundup.scripts.roundup_server.ServerConfig.get_server + def raise_KeyboardInterrupt(): + raise KeyboardInterrupt + + def test_get_server(self): + httpd = gs(self) + httpd.serve_forever = raise_KeyboardInterrupt + return httpd + + roundup.scripts.roundup_server.ServerConfig.get_server = test_get_server + + # Run under context manager to capture output of startup text. + with captured_output() as (out, err): + run_demo(self.home) + output = out.getvalue().strip() + print(output) + # if the server installed and started this will be the + # last line in the output. + self.assertIn("Keyboard Interrupt: exiting", output.split('\n'))
--- a/test/test_indexer.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_indexer.py Thu Apr 21 16:54:17 2022 -0400 @@ -24,6 +24,8 @@ from roundup.backends import get_backend, have_backend from roundup.backends.indexer_rdbms import Indexer +from roundup.cgi.exceptions import IndexerQueryError + # borrow from other tests from .db_test_base import setupSchema, config from .test_postgresql import postgresqlOpener, skip_postgresql @@ -115,8 +117,14 @@ ('test', '2', 'bar')]) def test_extremewords(self): """Testing too short or too long words.""" + + # skip this for FTS test + if ( isinstance(self,sqliteFtsIndexerTest) or + isinstance(self,postgresqlFtsIndexerTest)): + pytest.skip("extremewords not tested for native FTS backends") + short = "b" - long = "abcdefghijklmnopqrstuvwxyz" + long = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" self.dex.add_text(('test', '1', 'a'), '%s hello world' % short) self.dex.add_text(('test', '2', 'a'), 'blah a %s world' % short) self.dex.add_text(('test', '3', 'a'), 'blah Blub river') @@ -133,7 +141,7 @@ % (short, long)) self.assertSeqEqual(self.dex.find(["py"]), [('test', '5', 'a')]) - def test_casesensitity(self): + def test_casesensitivity(self): """Test if searches are case-in-sensitive.""" self.dex.add_text(('test', '1', 'a'), 'aaaa bbbb') self.dex.add_text(('test', '2', 'a'), 'aAaa BBBB') @@ -220,6 +228,214 @@ postgresqlOpener.tearDown(self) +@skip_postgresql +class postgresqlFtsIndexerTest(postgresqlOpener, RDBMSIndexerTest, IndexerTest): + def setUp(self): + postgresqlOpener.setUp(self) + RDBMSIndexerTest.setUp(self) + from roundup.backends.indexer_postgresql_fts import Indexer + self.dex = Indexer(self.db) + self.dex.db = self.db + + def tearDown(self): + RDBMSIndexerTest.tearDown(self) + postgresqlOpener.tearDown(self) + + def test_websearch_syntax(self): + """Test searches using websearch_to_tsquery. These never throw + errors regardless of how wacky the input. + """ + + self.dex.add_text(('test', '1', 'foo'), 'a the hello world') + self.dex.add_text(('test', '2', 'foo'), 'helh blah blah the world') + self.dex.add_text(('test', '3', 'foo'), 'blah hello the world') + self.dex.add_text(('test', '4', 'foo'), 'hello blah blech the world') + self.dex.add_text(('test', '5', 'foo'), 'a car drove') + self.dex.add_text(('test', '6', 'foo'), 'a car driving itself') + self.dex.add_text(('test', '7', 'foo'), "let's drive in the car") + self.dex.add_text(('test', '8', 'foo'), 'a drive-in movie') + + # test two separate words for sanity + self.assertSeqEqual(self.dex.find(['"hello" "world"']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo') + ]) + # now check the phrase + self.assertSeqEqual(self.dex.find(['"hello world"']), + [('test', '1', 'foo'), + ]) + + # test negation + self.assertSeqEqual(self.dex.find(['hello world -blech']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ]) + + # phrase negation + self.assertSeqEqual(self.dex.find(['hello world -"blah hello"']), + [('test', '1', 'foo'), + ('test', '4', 'foo'), + ]) + + # test without or + self.assertSeqEqual(self.dex.find(['blah blech']), + [('test', '4', 'foo'), + ]) + + # test with or + self.assertSeqEqual(self.dex.find(['blah or blech']), + [ ('test', '2', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo'), + ]) + + # stemmer test for english + self.assertSeqEqual(self.dex.find(['ts:drive']), + [('test', '6', 'foo'), + ('test', '7', 'foo'), + ('test', '8', 'foo') + ]) + + # stemmer is not disabled by quotes 8-( + self.assertSeqEqual(self.dex.find(['ts:"drive"']), + [('test', '6', 'foo'), + ('test', '7', 'foo'), + ('test', '8', 'foo') + ]) + + + # this is missing ts: at the start, so uses the websearch + # parser. We search for operator characters and wanr the user + # Otherwise "hello <-> world" is the same as "hello world" + # and is not a phrase search. + with self.assertRaises(IndexerQueryError) as ctx: + self.dex.find(['hello <-> world']) + + self.assertIn('do a tsquery search', ctx.exception.args[0]) + + def test_tsquery_syntax(self): + """Because websearch_to_tsquery doesn't allow prefix searches, + near searches with any value except 1 (phrase search), allow + use of to_tsquery by prefixing the search term wih ts:. + + However, unlike websearch_to_tsquery, this will throw a + psycopg2.errors.SyntaxError on bad input. SyntaxError is + re-raised as IndexerQueryError. But it makes a bunch of + useful expert functionality available. + + """ + + self.dex.add_text(('test', '1', 'foo'), 'a the hello world') + self.dex.add_text(('test', '2', 'foo'), 'helh blah blah the world') + self.dex.add_text(('test', '3', 'foo'), 'blah hello the world') + self.dex.add_text(('test', '4', 'foo'), 'hello blah blech the world') + self.dex.add_text(('test', '5', 'foo'), 'a car drove') + self.dex.add_text(('test', '6', 'foo'), 'a car driving itself') + self.dex.add_text(('test', '7', 'foo'), "let's drive in the car") + self.dex.add_text(('test', '8', 'foo'), 'a drive-in movie') + self.dex.db.commit() + + # test two separate words for sanity + self.assertSeqEqual(self.dex.find(['ts:hello & world']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo') + ]) + # now check the phrase + self.assertSeqEqual(self.dex.find(['ts:hello <-> world']), + [('test', '1', 'foo'), + ]) + + # test negation + self.assertSeqEqual(self.dex.find(['ts:hello & world & !blech']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ]) + + self.assertSeqEqual(self.dex.find( + ['ts:hello & world & !(blah <-> hello)']), + [('test', '1', 'foo'), + ('test', '4', 'foo'), + ]) + + # test without or + self.assertSeqEqual(self.dex.find(['ts:blah & blech']), + [('test', '4', 'foo'), + ]) + + # test with or + self.assertSeqEqual(self.dex.find(['ts:blah | blech']), + [ ('test', '2', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo'), + ]) + # stemmer test for english + self.assertSeqEqual(self.dex.find(['ts:drive']), + [('test', '6', 'foo'), + ('test', '7', 'foo'), + ('test', '8', 'foo') + ]) + + # stemmer is not disabled by quotes 8-( + self.assertSeqEqual(self.dex.find(['ts:"drive"']), + [('test', '6', 'foo'), + ('test', '7', 'foo'), + ('test', '8', 'foo') + ]) + + + # test with syntax error + with self.assertRaises(IndexerQueryError) as ctx: + self.dex.find(['ts:blah blech']) + + self.assertEqual(ctx.exception.args[0], + 'syntax error in tsquery: "blah blech"\n') + + # now check the phrase Note unlike sqlite, order matters, + # hello must come first. + self.assertSeqEqual(self.dex.find(['ts:hello <-> world']), + [('test', '1', 'foo'), + ]) + + # now check the phrase with explicitly 1 intervening item + self.assertSeqEqual(self.dex.find(['ts:hello <2> world']), + [('test', '3', 'foo'), + ]) + # now check the phrase with near explicitly 1 or 3 intervening items + self.assertSeqEqual(self.dex.find([ + 'ts:(hello <4> world) | (hello<2>world)']), + [('test', '3', 'foo'), + ('test', '4', 'foo'), + ]) + + # now check the phrase with near explicitly 3 intervening item + # with prefix for world. + self.assertSeqEqual(self.dex.find(['ts:hello <4> wor:*']), + [('test', '4', 'foo'), + ]) + + def test_invalid_language(self): + import psycopg2 + + from roundup.configuration import IndexerOption + IndexerOption.valid_langs.append("foo") + self.db.config["INDEXER_LANGUAGE"] = "foo" + + with self.assertRaises(psycopg2.errors.UndefinedObject) as ctx: + # psycopg2.errors.UndefinedObject: text search configuration + # "foo" does not exist + self.dex.add_text(('test', '1', 'foo'), 'a the hello world') + self.assertIn('search configuration "foo" does', ctx.exception.args[0]) + self.db.rollback() + + with self.assertRaises(ValueError) as ctx: + self.dex.find(['"hello" "world"']) + self.assertIn('search configuration "foo" does', ctx.exception.args[0]) + self.db.rollback() + + self.db.config["INDEXER_LANGUAGE"] = "english" + @skip_mysql class mysqlIndexerTest(mysqlOpener, RDBMSIndexerTest, IndexerTest): def setUp(self): @@ -233,4 +449,129 @@ class sqliteIndexerTest(sqliteOpener, RDBMSIndexerTest, IndexerTest): pass +class sqliteFtsIndexerTest(sqliteOpener, RDBMSIndexerTest, IndexerTest): + def setUp(self): + RDBMSIndexerTest.setUp(self) + from roundup.backends.indexer_sqlite_fts import Indexer + self.dex = Indexer(self.db) + self.dex.db = self.db + + def test_phrase_and_near(self): + self.dex.add_text(('test', '1', 'foo'), 'a the hello world') + self.dex.add_text(('test', '2', 'foo'), 'helh blah blah the world') + self.dex.add_text(('test', '3', 'foo'), 'blah hello the world') + self.dex.add_text(('test', '4', 'foo'), 'hello blah blech the world') + + # test two separate words for sanity + self.assertSeqEqual(self.dex.find(['"hello" "world"']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo') + ]) + # now check the phrase + self.assertSeqEqual(self.dex.find(['"hello world"']), + [('test', '1', 'foo'), + ]) + + # now check the phrase with near explicitly 0 intervening items + self.assertSeqEqual(self.dex.find(['NEAR(hello world, 0)']), + [('test', '1', 'foo'), + ]) + + # now check the phrase with near explicitly 1 intervening item + self.assertSeqEqual(self.dex.find(['NEAR(hello world, 1)']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ]) + # now check the phrase with near explicitly 3 intervening item + self.assertSeqEqual(self.dex.find(['NEAR(hello world, 3)']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo'), + ]) + + def test_prefix(self): + self.dex.add_text(('test', '1', 'foo'), 'a the hello world') + self.dex.add_text(('test', '2', 'foo'), 'helh blah blah the world') + self.dex.add_text(('test', '3', 'foo'), 'blah hello the world') + self.dex.add_text(('test', '4', 'foo'), 'hello blah blech the world') + + self.assertSeqEqual(self.dex.find(['hel*']), + [('test', '1', 'foo'), + ('test', '2', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo') + ]) + + + def test_bool_start(self): + self.dex.add_text(('test', '1', 'foo'), 'a the hello world') + self.dex.add_text(('test', '2', 'foo'), 'helh blah blah the world') + self.dex.add_text(('test', '3', 'foo'), 'blah hello the world') + self.dex.add_text(('test', '4', 'foo'), 'hello blah blech the world') + + self.assertSeqEqual(self.dex.find(['hel* NOT helh NOT blech']), + [('test', '1', 'foo'), + ('test', '3', 'foo'), + ]) + + self.assertSeqEqual(self.dex.find(['hel* NOT helh NOT blech OR the']), + [('test', '1', 'foo'), + ('test', '2', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo'), + ]) + + self.assertSeqEqual(self.dex.find(['helh OR hello']), + [('test', '1', 'foo'), + ('test', '2', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo'), + ]) + + + self.assertSeqEqual(self.dex.find(['helh AND hello']), + []) + # matches if line starts with hello + self.assertSeqEqual(self.dex.find(['^hello']), + [ + ('test', '4', 'foo'), + ]) + + self.assertSeqEqual(self.dex.find(['hello']), + [ + ('test', '1', 'foo'), + ('test', '3', 'foo'), + ('test', '4', 'foo'), + ]) + + def test_query_errors(self): + """test query phrases that generate an error. Also test the + correction""" + + self.dex.add_text(('test', '1', 'foo'), 'a the hello-world') + self.dex.add_text(('test', '2', 'foo'), 'helh blah blah the world') + self.dex.add_text(('test', '3', 'foo'), 'blah hello the world') + self.dex.add_text(('test', '4', 'foo'), 'hello blah blech the world') + + # handle known error that roundup recognizes and tries to diagnose + with self.assertRaises(IndexerQueryError) as ctx: + self.dex.find(['the hello-world']) + + error = ( "Search failed. Try quoting any terms that include a '-' " + "and retry the search.") + self.assertEqual(str(ctx.exception), error) + + + self.assertSeqEqual(self.dex.find(['the "hello-world"']), + [('test', '1', 'foo'), + ]) + + # handle known error that roundup recognizes and tries to diagnose + with self.assertRaises(IndexerQueryError) as ctx: + self.dex.find(['hello world + ^the']) + + error = 'Query error: syntax error near "^"' + self.assertEqual(str(ctx.exception), error) + # vim: set filetype=python ts=4 sw=4 et si
--- a/test/test_liveserver.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_liveserver.py Thu Apr 21 16:54:17 2022 -0400 @@ -1,10 +1,12 @@ -import shutil, errno, pytest, json, gzip, os +import shutil, errno, pytest, json, gzip, os, re from roundup.anypy.strings import b2s from roundup.cgi.wsgi_handler import RequestDispatcher from .wsgi_liveserver import LiveServerTestCase from . import db_test_base +from wsgiref.validate import validator + try: import requests skip_requests = lambda func, *args, **kwargs: func @@ -30,6 +32,10 @@ skip_zstd = mark_class(pytest.mark.skip( reason='Skipping zstd tests: zstd library not available')) +import sys + +_py3 = sys.version_info[0] > 2 + @skip_requests class SimpleTest(LiveServerTestCase): # have chicken and egg issue here. Need to encode the base_url @@ -60,7 +66,7 @@ # set up mailhost so errors get reported to debuging capture file cls.db.config.MAILHOST = "localhost" cls.db.config.MAIL_HOST = "localhost" - cls.db.config.MAIL_DEBUG = "../mail.log.t" + cls.db.config.MAIL_DEBUG = "../_test_tracker_mail.log" # enable static precompressed files cls.db.config.WEB_USE_PRECOMPRESSED_FILES = 1 @@ -84,7 +90,13 @@ def create_app(self): '''The wsgi app to start''' - return RequestDispatcher(self.dirname) + if _py3: + return validator(RequestDispatcher(self.dirname)) + else: + # wsgiref/validator.py InputWrapper::readline is broke and + # doesn't support the max bytes to read argument. + return RequestDispatcher(self.dirname) + def test_start_page(self): """ simple test that verifies that the server can serve a start page. @@ -95,6 +107,33 @@ self.assertTrue(b'Creator' in f.content) + def test_rest_invalid_method_collection(self): + # use basic auth for rest endpoint + f = requests.put(self.url_base() + '/rest/data/user', + auth=('admin', 'sekrit'), + headers = {'content-type': "", + 'x-requested-with': "rest"}) + print(f.status_code) + print(f.headers) + print(f.content) + + self.assertEqual(f.status_code, 405) + expected = { 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', + 'Allow': 'DELETE, GET, OPTIONS, POST', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', + } + + print(f.headers) + # use dict comprehension to remove fields like date, + # content-length etc. from f.headers. + self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected) + + content = json.loads(f.content) + + exp_content = "Method PUT not allowed. Allowed: DELETE, GET, OPTIONS, POST" + self.assertEqual(exp_content, content['error']['msg']) + def test_http_options(self): """ options returns an unimplemented error for this case.""" @@ -113,11 +152,10 @@ print(f.headers) self.assertEqual(f.status_code, 204) - expected = { 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + expected = { 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', } # use dict comprehension to remove fields like date, @@ -134,11 +172,10 @@ print(f.headers) self.assertEqual(f.status_code, 204) - expected = { 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + expected = { 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', } # use dict comprehension to remove fields like date, @@ -154,11 +191,10 @@ print(f.headers) self.assertEqual(f.status_code, 204) - expected = { 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + expected = { 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, POST', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'OPTIONS, GET, POST', } # use dict comprehension to remove fields like date, @@ -175,11 +211,10 @@ print(f.headers) self.assertEqual(f.status_code, 204) - expected = { 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + expected = { 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', } # use dict comprehension to remove fields like date, @@ -195,11 +230,10 @@ print(f.headers) self.assertEqual(f.status_code, 204) - expected = { 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + expected = { 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', } # use dict comprehension to remove fields like date, @@ -264,8 +298,7 @@ print(f.headers) self.assertEqual(f.status_code, 304) - expected = { 'Content-Type': 'application/javascript', - 'Vary': 'Accept-Encoding', + expected = { 'Vary': 'Accept-Encoding', 'Content-Length': '0', } @@ -374,6 +407,57 @@ # cleanup os.remove(gzfile) + def test_compression_none_etag(self): + # use basic auth for rest endpoint + f = requests.get(self.url_base() + '/rest/data/user/1/username', + auth=('admin', 'sekrit'), + headers = {'content-type': "", + 'Accept-Encoding': "", + 'Accept': '*/*'}) + print(f.status_code) + print(f.headers) + + self.assertEqual(f.status_code, 200) + expected = { 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', + 'Allow': 'OPTIONS, GET, POST, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH' + } + + content_str = '''{ "data": { + "id": "1", + "link": "http://localhost:9001/rest/data/user/1/username", + "data": "admin" + } + }''' + content = json.loads(content_str) + + + if (type("") == type(f.content)): + json_dict = json.loads(f.content) + else: + json_dict = json.loads(b2s(f.content)) + + # etag wil not match, creation date different + del(json_dict['data']['@etag']) + + # type is "class 'str'" under py3, "type 'str'" py2 + # just skip comparing it. + del(json_dict['data']['type']) + + self.assertDictEqual(json_dict, content) + + # verify that ETag header has no - delimiter + print(f.headers['ETag']) + with self.assertRaises(ValueError): + f.headers['ETag'].index('-') + + # use dict comprehension to remove fields like date, + # content-length etc. from f.headers. + self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected) + + def test_compression_gzip(self): # use basic auth for rest endpoint f = requests.get(self.url_base() + '/rest/data/user/1/username', @@ -387,9 +471,9 @@ self.assertEqual(f.status_code, 200) expected = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, POST, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', 'Content-Encoding': 'gzip', 'Vary': 'Accept-Encoding', } @@ -417,6 +501,13 @@ self.assertDictEqual(json_dict, content) + # verify that ETag header ends with -gzip + try: + self.assertRegex(f.headers['ETag'], r'^"[0-9a-f]{32}-gzip"$') + except AttributeError: + # python2 no assertRegex so try substring match + self.assertEqual(33, f.headers['ETag'].rindex('-gzip"')) + # use dict comprehension to remove fields like date, # content-length etc. from f.headers. self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected) @@ -432,20 +523,19 @@ print(f.status_code) print(f.headers) - # ERROR: attribute error turns into 405, not sure that's right. # NOTE: not compressed payload too small - self.assertEqual(f.status_code, 405) + self.assertEqual(f.status_code, 400) expected = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, POST, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', } content = { "error": { - "status": 405, - "msg": "'foo'" + "status": 400, + "msg": "Invalid attribute foo" } } @@ -514,9 +604,9 @@ self.assertEqual(f.status_code, 200) expected = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, POST, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', 'Content-Encoding': 'br', 'Vary': 'Accept-Encoding', } @@ -547,6 +637,13 @@ self.assertDictEqual(json_dict, content) + # verify that ETag header ends with -br + try: + self.assertRegex(f.headers['ETag'], r'^"[0-9a-f]{32}-br"$') + except AttributeError: + # python2 no assertRegex so try substring match + self.assertEqual(33, f.headers['ETag'].rindex('-br"')) + # use dict comprehension to remove fields like date, # content-length etc. from f.headers. self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected) @@ -560,20 +657,20 @@ 'Accept': '*/*'}) print(f.status_code) print(f.headers) - # ERROR: attribute error turns into 405, not sure that's right. + # Note: not compressed payload too small - self.assertEqual(f.status_code, 405) + self.assertEqual(f.status_code, 400) expected = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, POST, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', } content = { "error": { - "status": 405, - "msg": "'foo'" + "status": 400, + "msg": "Invalid attribute foo" } } json_dict = json.loads(b2s(f.content)) @@ -660,9 +757,9 @@ self.assertEqual(f.status_code, 200) expected = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, POST, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', 'Content-Encoding': 'zstd', 'Vary': 'Accept-Encoding', } @@ -693,6 +790,13 @@ self.assertDictEqual(json_dict, content) + # verify that ETag header ends with -zstd + try: + self.assertRegex(f.headers['ETag'], r'^"[0-9a-f]{32}-zstd"$') + except AttributeError: + # python2 no assertRegex so try substring match + self.assertEqual(33, f.headers['ETag'].rindex('-zstd"')) + # use dict comprehension to remove fields like date, # content-length etc. from f.headers. self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected) @@ -708,20 +812,19 @@ print(f.status_code) print(f.headers) - # ERROR: attribute error turns into 405, not sure that's right. # Note: not compressed, payload too small - self.assertEqual(f.status_code, 405) + self.assertEqual(f.status_code, 400) expected = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-HTTP-Method-Override', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, X-HTTP-Method-Override', 'Allow': 'OPTIONS, GET, POST, PUT, DELETE, PATCH', - 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, PUT, DELETE, PATCH', + 'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, PUT, DELETE, PATCH', } content = { "error": { - "status": 405, - "msg": "'foo'" + "status": 400, + "msg": "Invalid attribute foo" } } @@ -776,3 +879,111 @@ self.assertDictEqual({ key: value for (key, value) in f.headers.items() if key in expected }, expected) + + @pytest.mark.xfail(reason="Fails with 3600 age on circle ci not sure why") + def test_cache_control_css(self): + f = requests.get(self.url_base() + '/@@file/style.css', + headers = {'content-type': "", + 'Accept': '*/*'}) + print(f.status_code) + print(f.headers) + + self.assertEqual(f.status_code, 200) + self.assertEqual(f.headers['Cache-Control'], 'public, max-age=4838400') + + def test_cache_control_js(self): + f = requests.get(self.url_base() + '/@@file/help_controls.js', + headers = {'content-type': "", + 'Accept': '*/*'}) + print(f.status_code) + print(f.headers) + + self.assertEqual(f.status_code, 200) + self.assertEqual(f.headers['Cache-Control'], 'public, max-age=1209600') + + def test_new_issue_with_file_upload(self): + # Set up session to manage cookies <insert blue monster here> + session = requests.Session() + + # login using form + login = {"__login_name": 'admin', '__login_password': 'sekrit', + "@action": "login"} + f = session.post(self.url_base()+'/', data=login) + # look for change in text in sidebar post login + self.assertIn('Hello, admin', f.text) + + # create a new issue and upload a file + file_content = 'this is a test file\n' + file = {"@file": ('test1.txt', file_content, "text/plain") } + issue = {"title": "my title", "priority": "1", "@action": "new"} + f = session.post(self.url_base()+'/issue?@template=item', data=issue, files=file) + + # use redirected url to determine which issue and file were created. + m = re.search(r'[0-9]/issue(?P<issue>[0-9]+)\?@ok_message.*file%20(?P<file>[0-9]+)%20', f.url) + + # verify message in redirected url: file 1 created\nissue 1 created + # warning may fail if another test loads tracker with files. + # Escape % signs in string by doubling them. This verifies the + # search is working correctly. + # use groupdict for python2. + self.assertEqual('http://localhost:9001/issue%(issue)s?@ok_message=file%%20%(file)s%%20created%%0Aissue%%20%(issue)s%%20created&@template=item'%m.groupdict(), f.url) + + # we have an issue display, verify filename is listed there + # seach for unique filename given to it. + self.assertIn("test1.txt", f.text) + + # download file and verify content + f = session.get(self.url_base()+'/file%(file)s/text1.txt'%m.groupdict()) + self.assertEqual(f.text, file_content) + print(f.text) + + def test_new_file_via_rest(self): + + session = requests.Session() + session.auth = ('admin', 'sekrit') + + url = self.url_base() + '/rest/data/' + fname = 'a-bigger-testfile' + d = dict(name = fname, type='application/octet-stream') + c = dict (content = r'xyzzy') + r = session.post(url + 'file', files = c, data = d, + headers = {'x-requested-with': "rest"} + ) + + # was a 500 before fix for issue2551178 + self.assertEqual(r.status_code, 201) + # just compare the path leave off the number + self.assertIn('http://localhost:9001/rest/data/file/', + r.headers["location"]) + json_dict = json.loads(r.text) + self.assertEqual(json_dict["data"]["link"], r.headers["location"]) + + # download file and verify content + r = session.get(r.headers["location"] +'/content') + json_dict = json.loads(r.text) + self.assertEqual(json_dict['data']['data'], c["content"]) + print(r.text) + + # Upload a file via rest interface - no auth + session.auth = None + r = session.post(url + 'file', files = c, data = d, + headers = {'x-requested-with': "rest"} + ) + self.assertEqual(r.status_code, 403) + + # get session variable from web form login + # and use it to upload file + # login using form + login = {"__login_name": 'admin', '__login_password': 'sekrit', + "@action": "login"} + f = session.post(self.url_base()+'/', data=login) + # look for change in text in sidebar post login + self.assertIn('Hello, admin', f.text) + + r = session.post(url + 'file', files = c, data = d, + headers = {'x-requested-with': "rest"} + ) + self.assertEqual(r.status_code, 201) + print(r.status_code) + +
--- a/test/test_mysql.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_mysql.py Thu Apr 21 16:54:17 2022 -0400 @@ -65,6 +65,51 @@ mysqlOpener.setUp(self) DBTest.setUp(self) + def testUpgrade_6_to_7(self): + + # load the database + self.db.issue.create(title="flebble frooz") + self.db.commit() + + if self.db.database_schema['version'] != 7: + self.skipTest("This test only runs for database version 7") + + + # test by shrinking _words and trying to insert a long value + # it should fail. + # run post-init + # same test should succeed. + + self.db.sql("alter table __words change column " + "_word _word varchar(10)") + + long_string = "a" * (self.db.indexer.maxlength + 5) + + with self.assertRaises(MySQLdb.DataError) as ctx: + # DataError : Data too long for column '_word' at row 1 + self.db.sql("insert into __words VALUES('%s',1)" % long_string) + + self.assertIn("Data too long for column '_word'", + ctx.exception.args[1]) + + self.db.database_schema['version'] = 6 + + if hasattr(self,"downgrade_only"): + return + + # test upgrade altering row + self.db.post_init() + + # This insert with text of expected column size should succeed + self.db.sql("insert into __words VALUES('%s',1)" % long_string) + + # Verify it fails at one more than the expected column size + too_long_string = "a" * (self.db.indexer.maxlength + 6) + with self.assertRaises(MySQLdb.DataError) as ctx: + self.db.sql("insert into __words VALUES('%s',1)" % too_long_string) + + self.assertEqual(self.db.database_schema['version'], + self.db.current_db_version) @skip_mysql class mysqlROTest(mysqlOpener, ROTest, unittest.TestCase):
--- a/test/test_postgresql.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_postgresql.py Thu Apr 21 16:54:17 2022 -0400 @@ -47,6 +47,16 @@ if have_backend('postgresql'): module = get_backend('postgresql') + def setup_class(cls): + # nuke the db once for the class. Handles the case + # where an aborted test run (^C during setUp for example) + # leaves the database in an unusable, partly configured state. + try: + cls.nuke_database(cls) + except: + # ignore failure to nuke the database. + pass + def setUp(self): pass @@ -68,6 +78,67 @@ DBTest.tearDown(self) postgresqlOpener.tearDown(self) + def testUpgrade_6_to_7(self): + + # load the database + self.db.issue.create(title="flebble frooz") + self.db.commit() + + if self.db.database_schema['version'] != 7: + # consider calling next testUpgrade script to roll back + # schema to version 7. + self.skipTest("This test only runs for database version 7") + + # remove __fts table/index; shrink length of __words._words + # trying to insert a long word in __words._words should fail. + # trying to select from __fts should fail + # looking for the index should fail + # run post-init + # tests should succeed. + + self.db.sql("drop table __fts") # also drops __fts_idx + self.db.sql("alter table __words ALTER column _word type varchar(10)") + self.db.commit() + + self.db.database_schema['version'] = 6 + + long_string = "a" * (self.db.indexer.maxlength + 5) + with self.assertRaises(psycopg2.DataError) as ctx: + # DataError : value too long for type character varying(10) + self.db.sql("insert into __words VALUES('%s',1)" % long_string) + + self.assertIn("varying(10)", ctx.exception.args[0]) + self.db.rollback() # clear cursor error so db.sql can be used again + + with self.assertRaises(psycopg2.errors.UndefinedTable) as ctx: + self.db.sql("select * from _fts") + self.db.rollback() + + self.assertFalse(self.db.sql_index_exists('__fts', '__fts_idx')) + + if hasattr(self, "downgrade_only"): + return + + # test upgrade path + self.db.post_init() + + # This insert with text of expected column size should succeed + self.db.sql("insert into __words VALUES('%s',1)" % long_string) + + # verify it fails at one more than the expected column size + too_long_string = "a" * (self.db.indexer.maxlength + 6) + with self.assertRaises(psycopg2.DataError) as ctx: + self.db.sql("insert into __words VALUES('%s',1)" % too_long_string) + + # clean db handle + self.db.rollback() + + self.assertTrue(self.db.sql_index_exists('__fts', '__fts_idx')) + + self.db.sql("select * from __fts") + + self.assertEqual(self.db.database_schema['version'], + self.db.current_db_version) @skip_postgresql class postgresqlROTest(postgresqlOpener, ROTest, unittest.TestCase):
--- a/test/test_security.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_security.py Thu Apr 21 16:54:17 2022 -0400 @@ -411,8 +411,15 @@ self.assertEqual(has(uimu, 'issue', 'messages.recipients'), 1) self.assertEqual(has(uimu, 'issue', 'messages.recipients.username'), 1) - # roundup.password has its own built-in test, call it. + # roundup.password has its own built-in tests, call them. def test_password(self): roundup.password.test() + # pretend import of crypt failed + orig_crypt = roundup.password.crypt + roundup.password.crypt = None + with self.assertRaises(roundup.password.PasswordValueError) as ctx: + roundup.password.test_missing_crypt() + roundup.password.crypt = orig_crypt + # vim: set filetype=python sts=4 sw=4 et si :
--- a/test/test_sqlite.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_sqlite.py Thu Apr 21 16:54:17 2022 -0400 @@ -16,6 +16,8 @@ # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. import unittest, os, shutil, time +import sqlite3 as sqlite + from roundup.backends import get_backend, have_backend from .db_test_base import DBTest, ROTest, SchemaTest, ClassicInitTest, config @@ -32,8 +34,43 @@ class sqliteDBTest(sqliteOpener, DBTest, unittest.TestCase): - pass + + def testUpgrade_6_to_7(self): + + # load the database + self.db.issue.create(title="flebble frooz") + self.db.commit() + + if self.db.database_schema['version'] != 7: + self.skipTest("This test only runs for database version 7") + + self.db.database_schema['version'] = 6 + + # dropping _fts + # select * from _fts + # it should fail. + # run post-init + # same select should succeed (with no rows returned) + self.db.sql("drop table __fts") + + with self.assertRaises(sqlite.OperationalError) as ctx: + self.db.sql("select * from __fts") + + self.assertIn("no such table: __fts", ctx.exception.args[0]) + + if hasattr(self, "downgrade_only"): + return + + # test upgrade adding __fts table + self.db.post_init() + + # select should now work. + self.db.sql("select * from __fts") + + # we should be at the current db version + self.assertEqual(self.db.database_schema['version'], + self.db.current_db_version) class sqliteROTest(sqliteOpener, ROTest, unittest.TestCase): pass
--- a/test/test_templating.py Fri Oct 08 00:37:16 2021 -0400 +++ b/test/test_templating.py Thu Apr 21 16:54:17 2022 -0400 @@ -422,6 +422,7 @@ groups[g], s)) #t('123.321.123.321', 'url') + t('https://example.com/demo/issue8#24MRV9BZYx:V:1B~sssssssssssssss~4~4', url="https://example.com/demo/issue8#24MRV9BZYx:V:1B~sssssssssssssss~4~4") t('http://localhost/', url='http://localhost/') t('http://roundup.net/', url='http://roundup.net/') t('http://richard@localhost/', url='http://richard@localhost/') @@ -439,6 +440,7 @@ t('r@a.com', email='r@a.com') t('i1', **{'class':'i', 'id':'1'}) t('item123', **{'class':'item', 'id':'123'}) + t('item 123', **{'class':'item', 'id':'123'}) t('www.user:pass@host.net', email='pass@host.net') t('user:pass@www.host.net', url='user:pass@www.host.net') t('123.35', nothing=True) @@ -448,6 +450,12 @@ p = StringHTMLProperty(self.client, 'test', '1', None, 'test', '') def t(s): return p.hyper_re.sub(p._hyper_repl, s) ae = self.assertEqual + ae(t('issue5#msg10'), '<a href="issue5#msg10">issue5#msg10</a>') + ae(t('issue5'), '<a href="issue5">issue5</a>') + ae(t('issue2255'), 'issue2255') + ae(t('foo https://example.com/demo/issue8#24MRV9BZYx:V:1B~sssssssssssssss~4~4 bar'), + 'foo <a href="https://example.com/demo/issue8#24MRV9BZYx:V:1B~sssssssssssssss~4~4" rel="nofollow noopener">' + 'https://example.com/demo/issue8#24MRV9BZYx:V:1B~sssssssssssssss~4~4</a> bar') ae(t('item123123123123'), 'item123123123123') ae(t('http://roundup.net/'), '<a href="http://roundup.net/" rel="nofollow noopener">http://roundup.net/</a>') @@ -478,9 +486,19 @@ # trailing punctuation is not included ae(t('http://roundup.net/%c ' % c), '<a href="http://roundup.net/" rel="nofollow noopener">http://roundup.net/</a>%c ' % c) + # trailing punctuation is not included without trailing space + ae(t('http://roundup.net/%c' % c), + '<a href="http://roundup.net/" rel="nofollow noopener">http://roundup.net/</a>%c' % c) # but it's included if it's part of the URL ae(t('http://roundup.net/%c/' % c), '<a href="http://roundup.net/%c/" rel="nofollow noopener">http://roundup.net/%c/</a>' % (c, c)) + # including with a non / terminated path + ae(t('http://roundup.net/test%c ' % c), + '<a href="http://roundup.net/test" rel="nofollow noopener">http://roundup.net/test</a>%c ' % c) + # but it's included if it's part of the URL path + ae(t('http://roundup.net/%ctest' % c), + '<a href="http://roundup.net/%ctest" rel="nofollow noopener">http://roundup.net/%ctest</a>' % (c, c)) + def test_input_html4(self): # boolean attributes are just the attribute name
--- a/website/issues/extensions/templating.py Fri Oct 08 00:37:16 2021 -0400 +++ b/website/issues/extensions/templating.py Thu Apr 21 16:54:17 2022 -0400 @@ -17,12 +17,18 @@ if module == 'pyme': from pyme import version version="version %s"%version.versionstr + elif module == 'MySQLdb': + from MySQLdb import version_info + version="version %s"%".".join([str(v) for v in version_info]) elif module == 'pychart': from pychart import version version="version %s"%version.version elif module == 'sqlite3': from sqlite3 import version version="version %s"%version + elif module == "whoosh": + from whoosh import versionstring + version="version %s"%versionstring() elif module == 'xapian': from xapian import version_string version="version %s"%version_string()
--- a/website/www/index.txt Fri Oct 08 00:37:16 2021 -0400 +++ b/website/www/index.txt Thu Apr 21 16:54:17 2022 -0400 @@ -1,15 +1,32 @@ Roundup Issue Tracker ===================== +.. raw:: foo + + meta:: + :title: Roundup Issue Tracker + :description: A simple-to-use and -install issue-tracking system + with command-line, web, REST, XML-RPC and e-mail interfaces. + Adaptable to many uses cases. Allows you to customise the look + and feel and implement different workflows. + :og:type: website + :og:url: https://www.roundup-tracker.org/ + :og:title: Roundup Issue Tracker + :og:description: A simple-to-use and -install issue-tracking system + with command-line, web, REST, XML-RPC and e-mail interfaces. + Adaptable to many uses cases. Allows you to customise the look + and feel and implement different workflows. + :og:image: https://www.roundup-tracker.org/_images/index_logged_out.png + .. raw:: html <div class="release_info note">Download: <a href="https://pypi.org/project/roundup/">latest</a></div> Roundup is a simple-to-use and -install issue-tracking system with -command-line, web and e-mail interfaces. It is based on the winning -design from Ka-Ping Yee in the Software Carpentry "Track" design -competition. +command-line, web, REST, XML-RPC and e-mail interfaces. It is based +on the winning design from Ka-Ping Yee in the Software Carpentry +"Track" design competition. The current stable version of Roundup is 2.1.0. It is a bug fix and minor feature release for the major 2.0.0 release which
