changeset 0e1a26853f2e in bugs.tryton.org:default
details: https://hg.tryton.org/bugs.tryton.org?cmd=changeset;node=0e1a26853f2e
description:
        Update to 1.6.0
diffstat:

 config.ini                       |  370 +++++++++++++++++++++++++++++++++++---
 html/_generic.404.html           |   22 +-
 html/_generic.calendar.html      |    1 -
 html/_generic.collision.html     |    1 -
 html/_generic.help-empty.html    |    1 -
 html/_generic.help-list.html     |    5 +-
 html/_generic.help-search.html   |    1 -
 html/_generic.help-submit.html   |    4 +-
 html/_generic.help.html          |    1 -
 html/_generic.index.html         |    3 +-
 html/_generic.item.html          |    1 -
 html/_generic.keywords_expr.html |   11 +
 html/file.index.html             |    1 -
 html/file.item.html              |    1 -
 html/help.html                   |    1 -
 html/help_controls.js            |   18 +
 html/home.classlist.html         |    1 -
 html/home.html                   |    1 -
 html/issue.index.html            |    9 -
 html/issue.item.html             |    7 +-
 html/issue.search.html           |   25 +-
 html/keyword.item.html           |   15 +-
 html/msg.index.html              |    1 -
 html/msg.item.html               |    1 -
 html/page.html                   |   47 +++-
 html/query.edit.html             |  127 ++++++++++---
 html/query.item.html             |   17 +-
 html/style.css                   |    9 +-
 html/user.forgotten.html         |    3 +-
 html/user.help-search.html       |    1 -
 html/user.help.html              |    1 -
 html/user.index.html             |    3 +-
 html/user.item.html              |    3 +-
 html/user.register.html          |    6 +-
 html/user.rego_progress.html     |    1 -
 35 files changed, 571 insertions(+), 149 deletions(-)

diffs (1458 lines):

diff -r 63c5e35df4b4 -r 0e1a26853f2e config.ini
--- a/config.ini        Sun Nov 18 14:03:18 2018 +0100
+++ b/config.ini        Sat Feb 16 19:38:54 2019 +0100
@@ -1,36 +1,40 @@
-# Roundup issue tracker configuration file
-# Autogenerated at Fri Feb  1 00:05:58 2008
-
-# WARNING! Following options need adjustments:
-#  [mail]: domain, host
-#  [tracker]: web
+# Tryton issue tracker configuration file
+# Autogenerated at Sat Feb 16 18:57:38 2019
 
 [main]
 
 # Database directory path.
 # The path may be either absolute or relative
-# to the directory containig this config file.
+# to the directory containing this config file.
 # Default: db
 database = db
 
+# Templating engine to use.
+# Possible values are 'zopetal' for the old TAL engine
+# ported from Zope, or 'chameleon' for Chameleon.
+# Default: zopetal
+template_engine = zopetal
+
 # Path to the HTML templates directory.
 # The path may be either absolute or relative
-# to the directory containig this config file.
+# to the directory containing this config file.
 # Default: html
 templates = html
 
-# Path to directory holding additional static files
-# available via Web UI.  This directory may contain
-# sitewide images, CSS stylesheets etc. and is searched
-# for these files prior to the TEMPLATES directory
-# specified above.  If this option is not set, all static
-# files are taken from the TEMPLATES directory
-# The path may be either absolute or relative
-# to the directory containig this config file.
+# A list of space separated directory paths (or a single
+# directory).  These directories hold additional static
+# files available via Web UI.  These directories may
+# contain sitewide images, CSS stylesheets etc. If a '-'
+# is included, the list processing ends and the TEMPLATES
+# directory is not searched after the specified
+# directories.  If this option is not set, all static
+# files are taken from the TEMPLATES directory.
+# The space separated paths may be either absolute or
+# relative to the directory containing this config file.
 # Default: 
 static_files = 
 
-# Email address that roundup will complain to if it runs into trouble.
+# Email address that roundup will complain to if it runs
 # into trouble.
 # If no domain is specified then the config item
 # mail -> domain is added.
@@ -64,6 +68,16 @@
 # Default: User
 new_email_user_roles = User
 
+# On schema changes, properties or classes in the history may
+# become obsolete.  Since normal access permissions do not apply
+# (we don't know if a user should see such a property or class)
+# a list of roles is specified here that are allowed to see
+# these obsolete properties in the history. By default only the
+# admin role may see these history entries, you can make them
+# visible to all users by adding, e.g., the 'User' role here.
+# Default: Admin
+obsolete_history_roles = Admin
+
 # Send error message emails to the dispatcher, user, or both?
 # The dispatcher is configured using the DISPATCHER_EMAIL setting.
 # Default: user
@@ -95,6 +109,13 @@
 # Default: yes
 email_registration_confirmation = yes
 
+# Force Roundup to use a particular text indexer.
+# If no indexer is supplied, the first available indexer
+# will be used in the following order:
+# Possible values: xapian, whoosh, native (internal).
+# Default: 
+indexer = 
+
 # Additional stop-words for the full-text indexer specific to
 # your tracker. See the indexer source for the default list of
 # stop-words (eg. A,AND,ARE,AS,AT,BE,BUT,BY, ...)
@@ -115,6 +136,24 @@
 # Default: 131072
 csv_field_size = 131072
 
+# Sets the default number of rounds used when encoding passwords
+# using the PBKDF2 scheme. Set this to a higher value on faster
+# systems which want more security.
+# PBKDF2 (Password-Based Key Derivation Function) is a
+# password hashing mechanism that derives hash from the
+# password and a random salt. For authentication this process
+# is repeated with the same salt as in the stored hash.
+# If both hashes match, the authentication succeeds.
+# PBKDF2 supports a variable 'rounds' parameter which varies
+# the time-cost of calculating the hash - doubling the number
+# of rounds doubles the cpu time required to calculate it. The
+# purpose of this is to periodically adjust the rounds as CPUs
+# become faster. The currently enforced minimum number of
+# rounds is 1000.
+# See: http://en.wikipedia.org/wiki/PBKDF2 and RFC2898
+# Default: 10000
+password_pbkdf2_default_rounds = 10000
+
 [tracker]
 
 # A descriptive name for your roundup instance.
@@ -127,12 +166,29 @@
 # that is required to get to the home page of the tracker.
 # You MUST include a trailing '/' in the URL.
 # Default: NO DEFAULT
-web = https://bugs.tryton.org/
+web = http://bugs.tryton.org/
 
 # Email address that mail to roundup should go to.
+# If no domain is specified then mail_domain is added.
 # Default: issue_tracker
 email = bugs
 
+# Controls the reply-to header address used when sending
+# nosy messages.
+# If the value is unset (default) the roundup tracker's
+# email address (above) is used.
+# If set to "AUTHOR" then the primary email address of the
+# author of the change will be used as the reply-to
+# address. This allows email exchanges to occur outside of
+# the view of roundup and exposes the address of the person
+# who updated the issue, but it could be useful in some
+# unusual circumstances.
+# If set to some other value, the value is used as the reply-to
+# address. It must be a valid RFC2822 address or people will not be
+# able to reply.
+# Default: 
+replyto_address = 
+
 # Default locale name for this tracker.
 # If this option is not set, the language is determined
 # by OS environment variable LANGUAGE, LC_ALL, LC_MESSAGES,
@@ -141,6 +197,7 @@
 language = en
 
 [web]
+
 # Setting this option enables Roundup to serve uploaded HTML
 # file content *as HTML*. This is a potential security risk
 # and is therefore disabled by default. Set to 'yes' if you
@@ -158,6 +215,120 @@
 # Default: yes
 http_auth = yes
 
+# Set the mode of the SameSite cookie option for
+# the session cookie. Choices are 'Lax' or
+# 'Strict'. 'None' can be used to suppress the
+# option. Strict mode provides additional security
+# against CSRF attacks, but may confuse users who
+# are logged into roundup and open a roundup link
+# from a source other than roundup (e.g. link in
+# email).
+# Allowed values: Strict, Lax, None
+# Default: Lax
+samesite_cookie_setting = Lax
+
+# How do we deal with @csrf fields in posted forms.
+# Set this to 'required' to block the post and notify
+#     the user if the field is missing or invalid.
+# Set this to 'yes' to block the post and notify the user
+#     if the token is invalid, but accept the form if
+#     the field is missing.
+# Set this to 'logfailure' to log a notice to the roundup
+#     log if the field is invalid or missing, but accept
+#     the post.
+# Set this to 'no' to ignore the field and accept the post.
+#             
+# Allowed values: required, yes, logfailure, no
+# Default: yes
+csrf_enforce_token = yes
+
+# csrf_tokens have a limited lifetime. If they are not
+# used they are purged from the database after this
+# number of minutes. Default (20160) is 2 weeks.
+# Default: 20160
+csrf_token_lifetime = 20160
+
+# This is only used for xmlrpc requests. This test is
+# done after Origin and Referer headers are checked. It only
+# verifies that the X-Requested-With header exists. The value
+# is ignored.
+# Set this to 'required' to block the post and notify
+#     the user if the header is missing or invalid.
+# Set this to 'yes' is the same as required.
+# Set this to 'logfailure' is the same as 'no'.
+# Set this to 'no' to ignore the header and accept the post.
+# Allowed values: required, yes, logfailure, no
+# Default: yes
+csrf_enforce_header_x-requested-with = yes
+
+# Verify that the Referer http header matches the
+# tracker.web setting in config.ini.
+# Set this to 'required' to block the post and notify
+#     the user if the header is missing or invalid.
+# Set this to 'yes' to block the post and notify the user
+#     if the header is invalid, but accept the form if
+#     the field is missing.
+# Set this to 'logfailure' to log a notice to the roundup
+#     log if the header is invalid or missing, but accept
+#     the post.
+# Set this to 'no' to ignore the header and accept the post.
+# Allowed values: required, yes, logfailure, no
+# Default: yes
+csrf_enforce_header_referer = yes
+
+# Verify that the Origin http header matches the
+# tracker.web setting in config.ini.
+# Set this to 'required' to block the post and notify
+#     the user if the header is missing or invalid.
+# Set this to 'yes' to block the post and notify the user
+#     if the header is invalid, but accept the form if
+#     the field is missing.
+# Set this to 'logfailure' to log a notice to the roundup
+#     log if the header is invalid or missing, but accept
+#     the post.
+# Set this to 'no' to ignore the header and accept the post.
+# Allowed values: required, yes, logfailure, no
+# Default: yes
+csrf_enforce_header_origin = yes
+
+# Verify that the X-Forwarded-Host http header matches
+# the host part of the tracker.web setting in config.ini.
+# Set this to 'required' to block the post and notify
+#     the user if the header is missing or invalid.
+# Set this to 'yes' to block the post and notify the user
+#     if the header is invalid, but accept the form if
+#     the field is missing.
+# Set this to 'logfailure' to log a notice to the roundup
+#     log if the header is invalid or missing, but accept
+#     the post.
+# Set this to 'no' to ignore the header and accept the post.
+# Allowed values: required, yes, logfailure, no
+# Default: yes
+csrf_enforce_header_x-forwarded-host = yes
+
+# "If there is no X-Forward-Host header, verify that
+# the Host http header matches the host part of the
+# tracker.web setting in config.ini.
+# Set this to 'required' to block the post and notify
+#     the user if the header is missing or invalid.
+# Set this to 'yes' to block the post and notify the user
+#     if the header is invalid, but accept the form if
+#     the field is missing.
+# Set this to 'logfailure' to log a notice to the roundup
+#     log if the header is invalid or missing, but accept
+#     the post.
+# Set this to 'no' to ignore the header and accept the post.
+# Allowed values: required, yes, logfailure, no
+# Default: yes
+csrf_enforce_header_host = yes
+
+# Minimum number of header checks that must pass
+# to accept the request. Set to 0 to accept post
+# even if no header checks pass. Usually the Host header check
+# always passes, so setting it less than 1 is not recommended.
+# Default: 1
+csrf_header_min_count = 1
+
 # Whether to use HTTP Accept-Language, if present.
 # Browsers send a language-region preference list.
 # It's usually set in the client's browser or in their
@@ -174,13 +345,24 @@
 # Default: no
 debug = no
 
-# Settings in this section are used by Postgresql and MySQL backends only
+# Setting this option makes Roundup migrate passwords with
+# an insecure password-scheme to a more secure scheme
+# when the user logs in via the web-interface.
+# Allowed values: yes, no
+# Default: yes
+migrate_passwords = yes
+
+# Settings in this section are used by RDBMS backends only
 [rdbms]
 
 # Name of the database to use.
 # Default: roundup
 name = roundup
 
+# Database backend.
+# Default: 
+backend = postgresql
+
 # Database server host.
 # Default: localhost
 host = localhost
@@ -210,10 +392,52 @@
 # Default: roundup
 read_default_group = roundup
 
+# Number of seconds to wait when the SQLite database is locked
+# Default: use a 30 second timeout (extraordinarily generous)
+# Only used in SQLite connections.
+# Default: 30
+sqlite_timeout = 30
+
 # Size of the node cache (in elements)
 # Default: 100
 cache_size = 100
 
+# Setting this option to 'no' protects the database against table creations.
+# Allowed values: yes, no
+# Default: yes
+allow_create = yes
+
+# Setting this option to 'no' protects the database against table alterations.
+# Allowed values: yes, no
+# Default: yes
+allow_alter = yes
+
+# Setting this option to 'no' protects the database against table drops.
+# Allowed values: yes, no
+# Default: yes
+allow_drop = yes
+
+# Name of the PostgreSQL template for database creation.
+# For database creation the template used has to match
+# the character encoding used (UTF8), there are different
+# PostgreSQL installations using different templates with
+# different encodings. If you get an error:
+#   new encoding (UTF8) is incompatible with the encoding of
+#   the template database (SQL_ASCII)
+#   HINT:  Use the same encoding as in the template database,
+#   or use template0 as template.
+# then set this option to the template name given in the
+# error message.
+# Default: 
+template = 
+
+# Database isolation level, currently supported for
+# PostgreSQL and mysql. See, e.g.,
+# http://www.postgresql.org/docs/9.1/static/transaction-iso.html
+# Allowed values: 'read uncommitted', 'read committed', 'repeatable read', 
'serializable'
+# Default: read committed
+isolation_level = read committed
+
 [logging]
 
 # Path to configuration file for standard Python logging module.
@@ -221,7 +445,7 @@
 # from specified file; options 'filename' and 'level'
 # in this section are ignored.
 # The path may be either absolute or relative
-# to the directory containig this config file.
+# to the directory containing this config file.
 # Default: 
 config = logging.ini
 
@@ -229,7 +453,7 @@
 # If no file name specified, log messages are written on stderr.
 # If above 'config' option is set, this option has no effect.
 # The path may be either absolute or relative
-# to the directory containig this config file.
+# to the directory containing this config file.
 # Default: 
 filename = 
 
@@ -240,10 +464,14 @@
 level = ERROR
 
 # Outgoing email options.
-# Used for nozy messages and approval requests
+# Used for nosy messages and approval requests
 [mail]
 
-# Domain name used for email addresses.
+# The email domain that admin_email, issue_tracker and
+# dispatcher_email belong to.
+# This domain is added to those config items if they don't
+# explicitly include a domain.
+# Do not include the '@' symbol.
 # Default: NO DEFAULT
 domain = tryton.org
 
@@ -281,14 +509,14 @@
 # If TLS is used, you may set this option to the name
 # of a PEM formatted file that contains your private key.
 # The path may be either absolute or relative
-# to the directory containig this config file.
+# to the directory containing this config file.
 # Default: 
 tls_keyfile = 
 
 # If TLS is used, you may set this option to the name
 # of a PEM formatted certificate chain file.
 # The path may be either absolute or relative
-# to the directory containig this config file.
+# to the directory containing this config file.
 # Default: 
 tls_certfile = 
 
@@ -300,12 +528,12 @@
 # Default: utf-8
 charset = utf-8
 
-# Setting this option makes Roundup to write all outgoing email
+# Setting this option makes Roundup write all outgoing email
 # messages to this file *instead* of sending them.
 # This option has the same effect as environment variable SENDMAILDEBUG.
 # Environment variable takes precedence.
 # The path may be either absolute or relative
-# to the directory containig this config file.
+# to the directory containing this config file.
 # Default: 
 debug = 
 
@@ -328,15 +556,19 @@
 [mailgw]
 
 # Keep email citations when accepting messages.
-# Setting this to "no" strips out "quoted" text from the message.
+# Setting this to "no" strips out "quoted" text
+# from the message. Setting this to "new" keeps quoted
+# text only if a new issue is being created.
 # Signatures are also stripped.
-# Allowed values: yes, no
+# Allowed values: yes, no, new
 # Default: yes
 keep_quoted_text = yes
 
-# Preserve the email body as is - that is,
-# keep the citations _and_ signatures.
-# Allowed values: yes, no
+# Setting this to "yes" preserves the email body
+# as is - that is, keep the citations _and_ signatures.
+# Setting this to "new" keeps the body only if we are
+# creating a new issue.
+# Allowed values: yes, no, new
 # Default: no
 leave_body_unchanged = no
 
@@ -389,6 +621,14 @@
 # Default: always
 subject_content_match = always
 
+# Update issue title if incoming subject of email is different.
+# Setting this to "no" will ignore the title part of the subject
+# of incoming email messages.
+# 
+# Allowed values: yes, no
+# Default: yes
+subject_updates_title = yes
+
 # Regular expression matching a single reply or forward
 # prefix prepended by the mailer. This is explicitly
 # stripped from the subject during parsing.
@@ -418,6 +658,13 @@
 # Default: [\r\n]+\s*[\r\n]+
 blankline_re = [\r\n]+\s*[\r\n]+
 
+# Unpack attached messages (encoded as message/rfc822 in MIME)
+# as multiple parts attached as files to the issue, if not
+# set we handle message/rfc822 attachments as a single file.
+# Allowed values: yes, no
+# Default: no
+unpack_rfc822 = no
+
 # When parsing incoming mails, roundup uses the first
 # text/plain part it finds. If this part is inside a
 # multipart/alternative, and this option is set, all other
@@ -425,19 +672,45 @@
 # is to keep all parts and attach them to the issue.
 # Allowed values: yes, no
 # Default: no
-ignore_alternatives = no
+ignore_alternatives = yes
+
+# If an email has only text/html parts, use this module
+# to convert the html to text. Choose from beautifulsoup 4,
+# dehtml - (internal code), or none to disable conversion.
+# If 'none' is selected, email without a text/plain part
+# will be returned to the user with a message. If
+# beautifulsoup is selected but not installed dehtml will
+# be used instead.
+# Allowed values: beautifulsoup, dehtml, none
+# Default: none
+convert_htmltotext = none
+
+# When handling emails ignore the Resent-From:-header
+# and use the original senders From:-header instead.
+# (This might be desirable in some situations where a moderator
+# reads incoming messages first before bouncing them to Roundup)
+# Allowed values: yes, no
+# Default: no
+keep_real_from = no
 
 # OpenPGP mail processing options
 [pgp]
 
-# Enable PGP processing. Requires pyme.
+# Enable PGP processing. Requires pyme. If you're planning
+# to send encrypted PGP mail to the tracker, you should also
+# enable the encrypt-option below, otherwise mail received
+# encrypted might be sent unencrypted to another user.
 # Allowed values: yes, no
 # Default: no
 enable = no
 
 # If specified, a comma-separated list of roles to perform
 # PGP processing on. If not specified, it happens for all
-# users.
+# users. Note that received PGP messages (signed and/or
+# encrypted) will be processed with PGP even if the user
+# doesn't have one of the PGP roles, you can use this to make
+# PGP processing completely optional by defining a role here
+# and not assigning any users to that role.
 # Default: 
 roles = 
 
@@ -446,11 +719,34 @@
 # Default: 
 homedir = 
 
+# Enable PGP encryption. All outgoing mails are encrypted.
+# This requires that keys for all users (with one of the gpg
+# roles above or all users if empty) are available. Note that
+# it makes sense to educate users to also send mails encrypted
+# to the tracker, to enforce this, set 'require_incoming'
+# option below (but see the note).
+# Allowed values: yes, no
+# Default: no
+encrypt = no
+
+# Require that pgp messages received by roundup are either
+# 'signed', 'encrypted' or 'both'. If encryption is required
+# we do not return the message (in clear) to the user but just
+# send an informational message that the message was rejected.
+# Note that this still presents known-plaintext to an attacker
+# when the users sends the mail a second time with encryption
+# turned on.
+# Default: signed
+require_incoming = signed
+
 # Nosy messages sending
 [nosy]
 
 # Send nosy messages to the author of the message.
-# Allowed values: yes, no, new
+# Allowed values: yes, no, new, nosy -- if yes, messages
+# are sent to the author even if not on the nosy list, same
+# for new (but only for new messages). When set to nosy,
+# the nosy list controls sending messages to the author.
 # Default: no
 messages_to_author = no
 
@@ -489,5 +785,5 @@
 # Attachments larger than the given number of bytes
 # won't be attached to nosy mails. They will be replaced by
 # a link to the tracker's download page for the file.
-# Default: 2147483647
+# Default: 9223372036854775807
 max_attachment_size = 2147483647
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.404.html
--- a/html/_generic.404.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.404.html    Sat Feb 16 19:38:54 2019 +0100
@@ -1,10 +1,14 @@
-<html>
-<head>
-<title>Item Not Found</title>
-</head>
+<!-- dollarId: issue.item,v 1.4 2001/08/03 01:19:43 richard Exp dollar-->
+<tal:block metal:use-macro="templates/page/macros/icing">
+  <title metal:fill-slot="head_title">
+  Item Not Found
+  </title>
+  <tal:block metal:fill-slot="body_title">
+  Item Not Found
+  </tal:block>
 
-<body>
-There is no <span tal:content="context/_classname" /> with id <span 
tal:content="context/id"/>
-</body>
-</html>
-<!-- SHA: 7c74a39904a98fd7aacba48daf5c6820da253ed2 -->
+<td class="content" metal:fill-slot="content">
+    There is no <span tal:content="context/_classname" /> with id
+    <span tal:content="context/id"/>
+</td>
+</tal:block>
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.calendar.html
--- a/html/_generic.calendar.html       Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.calendar.html       Sat Feb 16 19:38:54 2019 +0100
@@ -17,4 +17,3 @@
        tal:content="structure python:utils.html_calendar(request)">
  </body>
 </html>
-<!-- SHA: 3c1535fe01902cf3fa7115c982c45f7b0674b590 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.collision.html
--- a/html/_generic.collision.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.collision.html      Sat Feb 16 19:38:54 2019 +0100
@@ -14,4 +14,3 @@
 "><span tal:replace="context/designator" i18n:name="context" />
 </td>
 </tal:block>
-<!-- SHA: db15fb6c88215d4baf223910a6c9cd81c63dc994 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.help-empty.html
--- a/html/_generic.help-empty.html     Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.help-empty.html     Sat Feb 16 19:38:54 2019 +0100
@@ -6,4 +6,3 @@
     <p i18n:translate="">Please specify your search parameters!</p>
   </body>
 </html>
-<!-- SHA: 9a118377b03172347d95097ff75fca26a6dd3738 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.help-list.html
--- a/html/_generic.help-list.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.help-list.html      Sat Feb 16 19:38:54 2019 +0100
@@ -1,5 +1,5 @@
-<!-- $Id: _generic.help-list.html,v 1.2 2008-03-01 08:18:07 richard Exp $ vim: 
sw=2 ts=8 et
---><html tal:define="vok context/is_view_ok">
+<!-- vim: set sw=2 ts=8 et: -->
+<html tal:define="vok context/is_view_ok">
   <head>
     <title>Search result for user helper</title>
     <link rel="stylesheet" type="text/css" href="@@file/style.css" />
@@ -81,4 +81,3 @@
      //--></script>
   </body>
 </html>
-<!-- SHA: 9b8c6aade0245ba2f29505606f427948e3448d22 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.help-search.html
--- a/html/_generic.help-search.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.help-search.html    Sat Feb 16 19:38:54 2019 +0100
@@ -11,4 +11,3 @@
   </body>
 </html>
 
-<!-- SHA: b95a7bda7189c0747d2f4112d1d3d02808fd1753 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.help-submit.html
--- a/html/_generic.help-submit.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.help-submit.html    Sat Feb 16 19:38:54 2019 +0100
@@ -61,7 +61,8 @@
      onclick="text_field.value=original_field;f=getListForm();if (f) 
{reviseList_framed(f, this)};return false"
             />
      <input type="submit" id="btn_apply" class="apply"
-            value=" Apply " 
onclick="callingform[field].value=text_field.value; parent.close();"
+            value=" Apply " 
onclick="callingform[field].value=text_field.value;   if ('createEvent' in 
document) { var evt = document.createEvent('HTMLEvents');  
evt.initEvent('change', true, true); callingform[field].dispatchEvent(evt); } 
else
+{ callingform[field].fireEvent('onchange'); } parent.close();"
             i18n:attributes="value" />
  </form>
  <script type="text/javascript"><!--
@@ -71,4 +72,3 @@
 //--></script>
  </body>
 </html>
-<!-- SHA: 1de39ac0d15dc59c64187b6c691d58ba20931372 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.help.html
--- a/html/_generic.help.html   Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.help.html   Sat Feb 16 19:38:54 2019 +0100
@@ -96,4 +96,3 @@
  </form>
  </body>
 </html>
-<!-- SHA: 992685537210e03230c9cfc3d5a4060edb1f1536 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.index.html
--- a/html/_generic.index.html  Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.index.html  Sat Feb 16 19:38:54 2019 +0100
@@ -47,6 +47,8 @@
       tal:attributes="action context/designator">
 <textarea rows="15" style="width:90%" name="rows" 
tal:content="context/csv"></textarea>
 <br>
+<input name="@csrf" type="hidden"
+       tal:attributes="value python:utils.anti_csrf_nonce()">
 <input type="hidden" name="@action" value="editCSV">
 <input type="submit" value="Edit Items" i18n:attributes="value">
 </form>
@@ -69,4 +71,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: 0e2e831b8d3ec903798d21a7d1f96b3e07f740a1 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.item.html
--- a/html/_generic.item.html   Sun Nov 18 14:03:18 2018 +0100
+++ b/html/_generic.item.html   Sat Feb 16 19:38:54 2019 +0100
@@ -56,4 +56,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: 78108e49cad0014d9861f955e51d19ecb02c6b64 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/_generic.keywords_expr.html
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/html/_generic.keywords_expr.html  Sat Feb 16 19:38:54 2019 +0100
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+<html>
+ <head>
+  <link rel="stylesheet" type="text/css" href="@@file/style.css" />
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8;" />
+  <title tal:content="string:Roundup Keywords Expression Editor"></title>
+ </head>
+ <body class="body"
+       tal:content="structure python:utils.keywords_expressions(request)">
+ </body>
+</html>
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/file.index.html
--- a/html/file.index.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/file.index.html      Sat Feb 16 19:38:54 2019 +0100
@@ -29,4 +29,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: f3a343f0682801cb8c47bd793d2d436fc7258d73 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/file.item.html
--- a/html/file.item.html       Sun Nov 18 14:03:18 2018 +0100
+++ b/html/file.item.html       Sat Feb 16 19:38:54 2019 +0100
@@ -56,4 +56,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: 9b0955c553e1df1d791dfc24530aeb945896cf46 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/help.html
--- a/html/help.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/help.html    Sat Feb 16 19:38:54 2019 +0100
@@ -36,4 +36,3 @@
    </th>
   </tr>
  </table>
-<!-- SHA: 5bb5e9db92d4dea06f6bd0224f34dce86020d4c2 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/help_controls.js
--- a/html/help_controls.js     Sun Nov 18 14:03:18 2018 +0100
+++ b/html/help_controls.js     Sat Feb 16 19:38:54 2019 +0100
@@ -52,12 +52,30 @@
   // write back to opener window
   if (document.frm_help.check==undefined) { return; }
   form[field].value = text_field.value;
+
+  /* trigger change event on the field we changed */
+  if ("createEvent" in document) {
+    var evt = document.createEvent("HTMLEvents");
+    evt.initEvent("change", true, true);
+    form[field].dispatchEvent(evt);
+  }
+    else
+       form[field].fireEvent("onchange");
 }
 
 function updateList() {
   // write back to opener window
   if (document.frm_help.check==undefined) { return; }
   form[field].value = determineList();
+
+  /* trigger change event on the field we changed */
+  if ("createEvent" in document) {
+    var evt = document.createEvent("HTMLEvents");
+    evt.initEvent("change", true, true);
+    form[field].dispatchEvent(evt);
+  }
+    else
+       form[field].fireEvent("onchange");
 }
 
 function updatePreview() {
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/home.classlist.html
--- a/html/home.classlist.html  Sun Nov 18 14:03:18 2018 +0100
+++ b/html/home.classlist.html  Sat Feb 16 19:38:54 2019 +0100
@@ -23,4 +23,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: e82456270ae1048cefdead99afda95578fff7b74 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/home.html
--- a/html/home.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/home.html    Sat Feb 16 19:38:54 2019 +0100
@@ -8,4 +8,3 @@
     sort=[('-', 'activity')], group=[('+', 'priority')], filter=['status'],
     columns=['id','activity','component','title','assignedto', 'status'],
     filterspec={'status':['-1','1','2','3','4','5','6','7']})" />
-<!-- SHA: c87a4e18d59a527331f1d367c0c6cc67ee123e63 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/issue.index.html
--- a/html/issue.index.html     Sun Nov 18 14:03:18 2018 +0100
+++ b/html/issue.index.html     Sat Feb 16 19:38:54 2019 +0100
@@ -1,4 +1,3 @@
-<!-- $Id: issue.index.html,v 1.29 2007-09-18 17:44:26 jpend Exp $ -->
 <tal:block metal:use-macro="templates/page/macros/icing">
 <title metal:fill-slot="head_title" >
   <span tal:omit-tag="true" i18n:translate="" >List of issues</span>
@@ -30,12 +29,10 @@
    <th tal:condition="request/show/activity" i18n:translate="">Activity</th>
    <th tal:condition="request/show/actor" i18n:translate="">Actor</th>
    <th tal:condition="request/show/keyword" i18n:translate="">Keyword</th>
-   <th tal:condition="request/show/component" i18n:translate="">Components</th>
    <th tal:condition="request/show/title" i18n:translate="">Title</th>
    <th tal:condition="request/show/status" i18n:translate="">Status</th>
    <th tal:condition="request/show/creator" i18n:translate="">Creator</th>
    <th tal:condition="request/show/assignedto" 
i18n:translate="">Assigned&nbsp;To</th>
-   <th tal:condition="request/show/reviews" i18n:translate="">Reviews</th>
   </tr>
  <tal:block tal:repeat="i batch" condition=true>
   <tr tal:define="group python:[r[1] for r in request.group]"
@@ -59,9 +56,6 @@
        tal:content="python:i.actor.plain() or default">&nbsp;</td>
    <td tal:condition="request/show/keyword"
        tal:content="python:i.keyword.plain() or default">&nbsp;</td>
-   <td tal:condition="request/show/component"
-       i18n:translate=""
-       tal:content="python:i.component.plain() or default">&nbsp;</td>
    <td tal:condition="request/show/title">
     <a tal:attributes="href string:issue${i/id}"
                tal:content="python:str(i.title.plain(hyperlink=0)) or '[no 
title]'">title</a>
@@ -73,8 +67,6 @@
        tal:content="python:i.creator.plain() or default">&nbsp;</td>
    <td tal:condition="request/show/assignedto"
        tal:content="python:i.assignedto.plain() or default">&nbsp;</td>
-   <td tal:condition="request/show/reviews"
-       tal:content="python:i.reviews.plain() or default">&nbsp;</td>
   </tr>
 
  </tal:block>
@@ -171,4 +163,3 @@
 </td>
 </tal:block><tal:comment condition=false> vim: sw=1 ts=8 et si
 </tal:comment>
-<!-- SHA: 4600774f11f5947ff1f565e2fb8023125cf51fc2 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/issue.item.html
--- a/html/issue.item.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/issue.item.html      Sat Feb 16 19:38:54 2019 +0100
@@ -96,7 +96,7 @@
  <th i18n:translate="">Change Note</th>
  <td colspan=3>
   <textarea tal:content="request/form/@note/value | default"
-            name="@note" rows="5" cols="80"></textarea>
+            name="@note" wrap="soft" rows="5" cols="80"></textarea>
  </td>
 </tr>
 
@@ -177,6 +177,8 @@
    <form style="padding:0" method="POST" tal:condition="file/is_edit_ok"
          tal:attributes="action string:issue${context/id}">
     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
+    <input name="@csrf" type="hidden"
+           tal:attributes="value python:utils.anti_csrf_nonce()">
     <input type="hidden" name="@action" value="edit">
     <input type="submit" value="remove" i18n:attributes="value">
    </form>
@@ -203,6 +205,8 @@
     <form style="padding:0" method="POST" tal:condition="msg/is_edit_ok"
           tal:attributes="action string:issue${context/id}">
      <input type="hidden" name="@remove@messages" tal:attributes="value 
msg/id">
+     <input name="@csrf" type="hidden"
+            tal:attributes="value python:utils.anti_csrf_nonce()">
      <input type="hidden" name="@action" value="edit">
      <input type="submit" value="remove" i18n:attributes="value">
     </form>
@@ -229,4 +233,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: a242ab3ed5c6969916f3c42f80d487710f165fb8 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/issue.search.html
--- a/html/issue.search.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/issue.search.html    Sat Feb 16 19:38:54 2019 +0100
@@ -12,10 +12,10 @@
    cols python:request.columns or 'id activity title status 
assignedto'.split();
    sort_on python:request.sort and request.sort[0] or nothing;
    sort_desc python:sort_on and sort_on[0] == '-';
-   sort_on python:(sort_on and sort_on[1]) or 'activity';
+   sort_on python:(sort_on and sort_on[1]) or (not request.nodeid and 
'activity') or '';
    group_on python:request.group and request.group[0] or nothing;
    group_desc python:group_on and group_on[0] == '-';
-   group_on python:(group_on and group_on[1]) or 'priority';
+   group_on python:(group_on and group_on[1]) or (not request.nodeid and 
'priority') or '';
 
    search_input templates/page/macros/search_input;
    search_date templates/page/macros/search_date;
@@ -23,6 +23,7 @@
    sort_input templates/page/macros/sort_input;
    group_input templates/page/macros/group_input;
    search_select templates/page/macros/search_select;
+   search_select_keywords templates/page/macros/search_select_keywords;
    search_select_translated templates/page/macros/search_select_translated;
    search_multiselect templates/page/macros/search_multiselect;">
 
@@ -54,7 +55,7 @@
                 db_klass string:keyword;
                 db_content string:name;">
   <th i18n:translate="">Keyword:</th>
-  <td metal:use-macro="search_select">
+  <td metal:use-macro="search_select_keywords">
     <option metal:fill-slot="extra_options" value="-1" i18n:translate=""
             tal:attributes="selected python:value == '-1'">not 
selected</option>
   </td>
@@ -178,12 +179,12 @@
 </tr>
 
 <tr tal:define="name string:type;
-               db_klass string:type;
-               db_content string:name;">
+    db_klass string:type;
+    db_content string:name;">
   <th i18n:translate="">Type:</th>
   <td metal:use-macro="search_select">
     <option metal:fill-slot="extra_options" values="-1" i18n:translate=""
-           tal:attributes="selected python:value == '-1'">not selected</option>
+            tal:attributes="selected python:value == '-1'">not 
selected</option>
   </td>
   <td metal:use-macro="column_input"></td>
   <td metal:use-macro="sort_input"></td>
@@ -191,12 +192,12 @@
 </tr>
 
 <tr tal:define="name string:component;
-               db_klass string:component;
-               db_content string:name;">
+    db_klass string:component;
+    db_content string:name;">
   <th i18n:translate="">Component:</th>
   <td metal:use-macro="search_select">
     <option metal:fill-slot="extra_options" values="-1" i18n:translate=""
-           tal:attributes="selected python:value == '-1'">not selected</option>
+            tal:attributes="selected python:value == '-1'">not 
selected</option>
   </td>
   <td metal:use-macro="column_input"></td>
   <td metal:use-macro="sort_input"></td>
@@ -215,8 +216,8 @@
  <th i18n:translate="">No Sort or group:</th>
  <td>&nbsp;</td>
  <td>&nbsp;</td>
- <td><input type="radio" name="@sort" value=""></td>
- <td><input type="radio" name="@group" value=""></td>
+ <td><input type="radio" name="@sort" value="" tal:attributes="checked 
python:sort_on == ''"></td>
+ <td><input type="radio" name="@group" value="" tal:attributes="checked 
python:group_on == ''"></td>
 </tr>
 
 <tr>
@@ -250,6 +251,7 @@
  <td tal:define="value request/form/@queryname/value | nothing">
   <input name="@queryname" tal:attributes="value value">
   <input type="hidden" name="@old-queryname" tal:attributes="value value">
+  <input type="hidden" name="@template" value="index|search">
  </td>
 </tr>
 
@@ -280,4 +282,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: fa3cf334a00d3f923b4b6c2489205c6c9b0dbd99 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/keyword.item.html
--- a/html/keyword.item.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/keyword.item.html    Sat Feb 16 19:38:54 2019 +0100
@@ -36,6 +36,20 @@
   <tr>
    <th i18n:translate="">Keyword</th>
    <td tal:content="structure context/name/field">name</td>
+   <td tal:condition="not:context/id">
+     <tal:comment tal:replace="nothing">
+       If we get here and do not have an id, we are creating a new
+       keyword. It would be nice to provide some mechanism to
+       determine the preferred state of the "Continue adding keywords"
+       checkbox. By default I have it enabled.
+     </tal:comment>
+     <input type="checkbox" id="continue_new_keyword"
+           name="__redirect_to"
+           tal:attributes="value
+                           
string:${request/base}${request/env/PATH_INFO}?@template=item;
+                           checked python:True" />
+     <label for="continue_new_keyword" i18n:translate="">Continue adding 
keywords.</label>
+   </td>
   </tr>
 
   <tr>
@@ -53,4 +67,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: 69377db97f924d320fdd672dd8363256ef6f2fbb -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/msg.index.html
--- a/html/msg.index.html       Sun Nov 18 14:03:18 2018 +0100
+++ b/html/msg.index.html       Sat Feb 16 19:38:54 2019 +0100
@@ -23,4 +23,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: 474d801a8005811ea3f2600ff719af95c6b798ce -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/msg.item.html
--- a/html/msg.item.html        Sun Nov 18 14:03:18 2018 +0100
+++ b/html/msg.item.html        Sat Feb 16 19:38:54 2019 +0100
@@ -86,4 +86,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: e4a1c71477429a3750a6013098faa17f75d38f5d -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/page.html
--- a/html/page.html    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/page.html    Sat Feb 16 19:38:54 2019 +0100
@@ -35,8 +35,8 @@
    <div id="searchbox">
      <form method="GET" action="issue">
        <input type="hidden" name="@columns"
-             tal:attributes="value columns_showall"
-             value="id,activity,title,creator,assignedto,status"/>
+              tal:attributes="value columns_showall"
+              value="id,activity,title,creator,assignedto,status"/>
        <input type="hidden" name="@sort" value="activity"/>
        <input type="hidden" name="@group" value="priority"/>
        <input type="hidden" name="@filter" value="status"/>
@@ -66,7 +66,7 @@
    <span i18n:translate=""
     ><b>Your Queries</b> (<a href="query?@template=edit">edit</a>)</span><br>
    <tal:block tal:repeat="qs request/user/queries">
-    <a href="#" tal:attributes="href 
string:${qs/klass}?${qs/url}&@dispname=${qs/name}"
+    <a href="#" tal:attributes="href 
string:${qs/klass}?${qs/url}&@dispname=${qs/name/url_quote}"
        tal:content="qs/name">link</a><br>
    </tal:block>
   </p>
@@ -118,6 +118,8 @@
      i18n:attributes="value"><input class="form-small" size="4"
      type="text" name="@number">
     <input type="hidden" name="@type" value="issue">
+    <input name="@csrf" type="hidden"
+           tal:attributes="value python:utils.anti_csrf_nonce()">
     <input type="hidden" name="@action" value="show">
    </p>
   </form>
@@ -156,8 +158,15 @@
     <input type="hidden" name="@action" value="Login">
     <input type="checkbox" name="remember" id="remember">
     <label for="remember" i18n:translate="">Remember me?</label><br>
+    <input name="@csrf" type="hidden"
+           tal:attributes="value python:utils.anti_csrf_nonce()">
     <input type="submit" value="Login" i18n:attributes="value"><br>
-    <input type="hidden" name="__came_from" tal:attributes="value 
string:${request/base}${request/env/PATH_INFO}">
+    <input type="hidden" name="__came_from"
+           tal:condition="exists:request/env/QUERY_STRING"
+           tal:attributes="value 
string:${request/base}${request/env/PATH_INFO}?${request/env/QUERY_STRING}">
+    <input type="hidden" name="__came_from"
+           tal:condition="not:exists:request/env/QUERY_STRING"
+           tal:attributes="value 
string:${request/base}${request/env/PATH_INFO}">
     <span tal:replace="structure request/indexargs_form" />
     <a href="user?@template=register"
        tal:condition="python:request.user.hasPermission('Register', 'user')"
@@ -194,7 +203,8 @@
  </td>
  <td>
   <p tal:condition="options/error_message | nothing" class="error-message"
-     tal:repeat="m options/error_message" tal:content="structure m" />
+     tal:repeat="m options/error_message"
+     tal:content="structure string:$m <br/ > " />
   <p tal:condition="options/ok_message | nothing" class="ok-message">
     <span tal:repeat="m options/ok_message"
        tal:content="structure string:$m <br/ > " />
@@ -230,7 +240,7 @@
     tal:define="required required | python:[]"
     tal:attributes="class python:(name in required) and 'required' or nothing">
   <label tal:attributes="for name" tal:content="label" 
i18n:translate="">text</label>
-       <metal:x define-slot="behind_the_label" />
+  <metal:x define-slot="behind_the_label" />
 </th>
 
 <td metal:define-macro="search_input">
@@ -244,7 +254,7 @@
                          name name;
                          id name">
   <a class="classhelp"
-        tal:attributes="href 
python:'''javascript:help_window('issue?@template=calendar&property=%s&form=itemSynopsis',
 300, 200)'''%name">(cal)</a>
+     tal:attributes="href 
python:'''javascript:help_window('issue?@template=calendar&property=%s&form=itemSynopsis',
 300, 200)'''%name">(cal)</a>
 </td>
 
 <td metal:define-macro="search_popup">
@@ -271,6 +281,22 @@
   </select>
 </td>
 
+<td metal:define-macro="search_select_keywords">
+  <div tal:attributes="id python:'''keywords_%s'''%name">
+    <select tal:attributes="name name; id name"
+            tal:define="value python:request.form.getvalue(name)">
+      <option value="" i18n:translate="">don't care</option>
+      <metal:slot define-slot="extra_options" />
+      <option value="" i18n:translate="" 
disabled="disabled">------------</option>
+      <option tal:repeat="s python:db[db_klass].list()"
+              tal:attributes="value s/id; selected python:value == s.id"
+              tal:content="python:s[db_content]"></option>
+    </select>
+    <a class="classhelp"
+       tal:attributes="href 
python:'''javascript:help_window('issue?@template=keywords_expr&property=%s&form=itemSynopsis',
 350, 200)'''%name">(expr)</a>
+  </div>
+</td>
+
 <!-- like search_select, but translates the further values.
 Could extend it (METAL 1.1 attribute "extend-macro")
 -->
@@ -282,14 +308,14 @@
     <option value="" i18n:translate="" 
disabled="disabled">------------</option>
     <option tal:repeat="s python:db[db_klass].list()"
             tal:attributes="value s/id; selected python:value == s.id"
-                                               
tal:content="python:s[db_content]"
-                                               i18n:translate=""></option>
+            tal:content="python:s[db_content]"
+            i18n:translate=""></option>
   </select>
 </td>
 
 <!-- currently, there is no convenient API to get a list of all roles -->
 <td metal:define-macro="search_select_roles"
-         tal:define="onchange onchange | nothing">
+    tal:define="onchange onchange | nothing">
   <select name=roles id=roles tal:attributes="onchange onchange">
     <option value="" i18n:translate="">don't care</option>
     <option value="" i18n:translate="" 
disabled="disabled">------------</option>
@@ -369,4 +395,3 @@
     <input metal:define-macro="user_confirm_input" type="password"
     tal:attributes="id name; name string:@confirm@$name; readonly not:edit_ok" 
value="">
 
-<!-- SHA: 8fe4590b302310cbf69112649cc2d118ad1ff187 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/query.edit.html
--- a/html/query.edit.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/query.edit.html      Sat Feb 16 19:38:54 2019 +0100
@@ -6,16 +6,46 @@
 <span metal:fill-slot="body_title" tal:omit-tag="python:1"
  i18n:translate="">"Your Queries" Editing</span>
 
-<td class="content" metal:fill-slot="content">
+<td class="content" metal:fill-slot="content"
+    tal:define="anti_csrf_this_page python:utils.anti_csrf_nonce()" >
 
 <span tal:condition="not:context/is_edit_ok"
  i18n:translate="">You are not allowed to edit queries.</span>
 
-<script language="javascript">
-// This exists solely because I can't figure how to get the & into an
-// attributes TALES expression, and so it keeps getting quoted.
-function retire(qid) {
-    window.location = 'query'+qid+'?@action=retire&@template=edit';
+<script tal:attributes="nonce request/client/client_nonce"
+       language="javascript">
+// This allows us to make the delete button an immediate action.
+// The post_to_url function comes from:
+//    
http://stackoverflow.com/questions/133925/javascript-post-request-like-a-form-submit
+function retire(qid, csrf) {
+    post_to_url('query'+qid, {'@action': 'retire', '@template':'edit',
+                '@csrf': csrf});
+}
+
+function restore(qid, csrf) {
+    post_to_url('query'+qid, {'@action': 'restore', '@template': 'edit',
+                '@csrf': csrf});
+}
+function post_to_url(path, params, method) {
+    method = method || "post"; // Set method to post by default if not 
specified.
+
+    var form = document.createElement("form");
+    form.setAttribute("method", method);
+    form.setAttribute("action", path);
+
+    for(var key in params) {
+        if(params.hasOwnProperty(key)) {
+            var hiddenField = document.createElement("input");
+            hiddenField.setAttribute("type", "hidden");
+            hiddenField.setAttribute("name", key);
+            hiddenField.setAttribute("value", params[key]);
+
+            form.appendChild(hiddenField);
+         }
+    }
+
+    document.body.appendChild(form);
+    form.submit();
 }
 </script>
 
@@ -29,12 +59,15 @@
     <th i18n:translate="">Include in "Your Queries"</th>
     <th i18n:translate="">Edit</th>
     <th i18n:translate="">Private to you?</th>
-    <th>&nbsp;</th>
+    <th i18n:translate="">delete/restore<br> (javascript<br>required)</th>
+</tr>
+<tr>
+ <td colspan="5"><b i18n:translate="">Queries I created</b></td>
 </tr>
 
-<tr tal:repeat="query mine">
- <tal:block condition="query/is_retired">
-
+<tr tal:define="queries python:db.query.filter(filterspec={'creator': uid})"
+    tal:repeat="query queries">
+ <tal:block>
  <td><a tal:attributes="href string:${query/klass}?${query/url}"
         tal:content="query/name">query</a></td>
 
@@ -51,56 +84,87 @@
   </select>
  </td>
 
- <td colspan="3" i18n:translate="">[query is retired]</td>
-
- <!-- <td> maybe offer "restore" some day </td> -->
- </tal:block>
-</tr>
-
-<tr tal:repeat="query mine">
- <tal:block condition="not:query/is_retired">
- <td><a tal:attributes="href string:${query/klass}?${query/url}"
-        tal:content="query/name">query</a></td>
-
- <td metal:use-macro="template/macros/include" />
-
  <td><a tal:attributes="href string:query${query/id}" 
i18n:translate="">edit</a></td>
 
  <td>
   <select tal:attributes="name string:query${query/id}@private_for">
    <option tal:attributes="selected python:query.private_for == uid;
            value uid" i18n:translate="">yes</option>
-   <option tal:attributes="selected python:query.private_for == None"
+   <option tal:attributes="selected python:not query.private_for"
            value="-1" i18n:translate="">no</option>
   </select>
  </td>
 
  <td>
   <input type="button" value="Delete" i18n:attributes="value"
-  tal:attributes="onClick python:'''retire('%s')'''%query.id">
+  tal:attributes="onClick 
python:'''retire('%s','%s')'''%(query.id,anti_csrf_this_page)">
   </td>
   </tal:block>
 </tr>
+<tr>
+ <td colspan="4"><b i18n:translate="">Queries others created</b></td>
+ <td colspan="4"><b i18n:translate="">Owner</b></td>
+</tr>
 
-<tr tal:define="queries 
python:db.query.filter(filterspec={'private_for':None})"
+<tr tal:define="queries
+               python:db.query.filter(filterspec={'private_for': None})"
      tal:repeat="query queries">
- <tal:block condition="python: query.creator != uid">
+ <tal:block tal:condition="python:not query.creator == uid">
  <td><a tal:attributes="href string:${query/klass}?${query/url}"
         tal:content="query/name">query</a></td>
 
  <td metal:use-macro="template/macros/include" />
 
- <td colspan="3" tal:condition="query/is_edit_ok">
-  <a tal:attributes="href string:query${query/id}" i18n:translate="">edit</a>
- </td>
- <td tal:condition="not:query/is_edit_ok" colspan="3"
+ <td colspan="2" tal:condition="not:query/is_edit_ok"
     i18n:translate="">[not yours to edit]</td>
+ <td colspan="2" tal:condition="query/is_edit_ok"
+    i18n:translate=""><a tal:attributes="href string:query${query/id}" 
i18n:translate="">edit</a></td>
+ <td colspan="2"
+    tal:content="query/creator" i18n:translate="">put query owner here</td>
  </tal:block>
 </tr>
 
+<tr>
+ <td colspan="5"><b i18n:translate="">Active retired/private queries</b></td>
+</tr>
+<tal:block tal:repeat="query request/user/queries">
+<tr>
+ <tal:block condition="python:path('query/is_retired')">
+ <td><a tal:attributes="href string:${query/klass}?${query/url}"
+        tal:content="query/name">query</a></td>
+ <tal:block tal:condition="python: not query.creator == uid">
+    <td metal:use-macro="template/macros/include"> </td>
+ </tal:block>
+ <td colspan="2" tal:condition="python: not query.creator == uid" 
i18n:translate="">[query is retired]</td>
+ <td colspan="3" tal:condition="python:  query.creator == uid" 
i18n:translate="">[query is retired]</td>
+ <td tal:condition="python:query.creator == uid">
+  <input type="button" value="Restore" i18n:attributes="value"
+  tal:attributes="onClick 
python:'''restore('%s','%s')'''%(query.id,anti_csrf_this_page)">
+  </td>
+ <td colspan="1" tal:condition="python:not query.creator == uid" 
tal:content="query/creator" i18n:translate="">put query owner here</td>
+ </tal:block>
+</tr>
+<tr>
+ <tal:block condition="python:path('query/private_for') and (not query.creator 
== uid)">
+ <td><a tal:attributes="href string:${query/klass}?${query/url}"
+        tal:content="query/name">query</a></td>
+ <tal:block tal:condition="python: not query.creator == uid">
+    <td metal:use-macro="template/macros/include"> </td>
+ </tal:block>
+ <td colspan="2" i18n:translate="">[query is private]</td>
+ <td tal:condition="python:query.creator == uid">
+  <input type="button" value="Restore" i18n:attributes="value"
+  tal:attributes="onClick 
python:'''restore('%s','%s')'''%(query.id,anti_csrf_this_page)">
+   </td>
+ <td colspan="1" tal:content="query/creator" i18n:translate="">put query owner 
here</td>
+ </tal:block>
+</tr>
+</tal:block>
 <tr><td colspan="5">
    <input type="hidden" name="@action" value="edit">
    <input type="hidden" name="@template" value="edit">
+   <input name="@csrf" type="hidden"
+          tal:attributes="value anti_csrf_this_page">
    <input type="submit" value="Save Selection" i18n:attributes="value">
 </td></tr>
 
@@ -109,4 +173,3 @@
 </form>
 </td>
 </tal:block>
-<!-- SHA: 381522a1ff6675e1da99ccc7c2b012e5e1e5f7b8 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/query.item.html
--- a/html/query.item.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/query.item.html      Sat Feb 16 19:38:54 2019 +0100
@@ -1,4 +1,15 @@
 <!-- query.item -->
-<span tal:replace="structure context/renderQueryForm" />
-
-<!-- SHA: 027820442d9341987bbb8b732cd6233aa1e56bed -->
+<span tal:condition="context/is_view_ok" tal:replace="structure
+      context/renderQueryForm" />
+<tal:block tal:condition="not:context/is_view_ok">
+  <tal:block metal:use-macro="templates/page/macros/icing">
+    <title metal:fill-slot="head_title">You can not view query</title>
+    <tal:block metal:fill-slot="body_title">
+      You can not view query.
+    </tal:block>
+    <td class="content" metal:fill-slot="content">
+      You are not allowed to view <span tal:content="context/_classname"/>
+      with id <span tal:content="context/id"/>
+    </td>
+  </tal:block>
+</tal:block>
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/style.css
--- a/html/style.css    Sun Nov 18 14:03:18 2018 +0100
+++ b/html/style.css    Sat Feb 16 19:38:54 2019 +0100
@@ -14,6 +14,10 @@
   text-decoration: none;
 }
 
+pre {
+  white-space: pre-wrap;
+}
+
 table.body {
   border: 0;
   padding: 0;
@@ -267,10 +271,6 @@
   border-right: 1px solid #afafaf;
 }
 
-table.messages td pre {
-  white-space: pre-wrap;
-}
-
 .resolved, .closed, .invalid {
   text-decoration: line-through !important;
 }
@@ -457,4 +457,3 @@
 
 /* vim: sts=2 sw=2 et
 */
-/* SHA: a04232a326156d381a782cccb31d6d3948546227 */
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/user.forgotten.html
--- a/html/user.forgotten.html  Sun Nov 18 14:03:18 2018 +0100
+++ b/html/user.forgotten.html  Sat Feb 16 19:38:54 2019 +0100
@@ -19,6 +19,8 @@
       <tr>
         <td>&nbsp;</td>
         <td>
+          <input name="@csrf" type="hidden"
+                 tal:attributes="value python:utils.anti_csrf_nonce()">
           <input type="hidden" name="@action" value="passrst">
           <input type="hidden" name="@template" value="forgotten">
           <input type="submit" value="Request password reset"
@@ -41,4 +43,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: 6fdb58c55fd854904ae98906d5935549a221fabf -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/user.help-search.html
--- a/html/user.help-search.html        Sun Nov 18 14:03:18 2018 +0100
+++ b/html/user.help-search.html        Sat Feb 16 19:38:54 2019 +0100
@@ -83,4 +83,3 @@
 //--></script>
   </body>
 </html>
-<!-- SHA: df15cb20b84032f72d0530d0717382786668f6a0 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/user.help.html
--- a/html/user.help.html       Sun Nov 18 14:03:18 2018 +0100
+++ b/html/user.help.html       Sat Feb 16 19:38:54 2019 +0100
@@ -47,4 +47,3 @@
 </noframes>
 
 </html>
-<!-- SHA: d59dff4cb24ac0eee209b10c121299a203170227 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/user.index.html
--- a/html/user.index.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/user.index.html      Sat Feb 16 19:38:54 2019 +0100
@@ -37,6 +37,8 @@
     <form style="padding:0" method="POST"
           tal:attributes="action string:user${user/id}">
      <input type="hidden" name="@template" value="index">
+     <input name="@csrf" type="hidden"
+            tal:attributes="value python:utils.anti_csrf_nonce()">
      <input type="hidden" name="@action" value="retire">
      <input type="submit" value="retire" i18n:attributes="value">
     </form>
@@ -47,4 +49,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: 6d282dc45e45caf1d19d8ded6c5c57554be9c1af -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/user.item.html
--- a/html/user.item.html       Sun Nov 18 14:03:18 2018 +0100
+++ b/html/user.item.html       Sat Feb 16 19:38:54 2019 +0100
@@ -105,7 +105,7 @@
      tal:define="name string:timezone; label string:Timezone; value 
context/timezone">
   <th metal:use-macro="th_label">Timezone</th>
   <td><input name="timezone" metal:use-macro="normal_input">
-   <tal:block tal:condition="edit_ok" i18n:translate="">(this is a numeric 
hour offset, the default is
+   <tal:block tal:condition="edit_ok" i18n:translate="">(the default is
     <span tal:replace="db/config/DEFAULT_TIMEZONE" i18n:name="zone"
     />)</tal:block>
   </td>
@@ -196,4 +196,3 @@
 </td>
 
 </tal:doc>
-<!-- SHA: bfc3a0fd9a3a54b3b1d1d7bfeb43191237af5184 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/user.register.html
--- a/html/user.register.html   Sun Nov 18 14:03:18 2018 +0100
+++ b/html/user.register.html   Sat Feb 16 19:38:54 2019 +0100
@@ -58,7 +58,10 @@
   <td>&nbsp;</td>
   <td>
    <input type="hidden" name="@template" value="register">
-   <input type="hidden" name="@required" value="username,password,address">
+   <input type="hidden" name="@required"
+          value="username,password,address">
+   <input name="@csrf" type="hidden"
+          tal:attributes="value python:utils.anti_csrf_nonce()">
    <input type="hidden" name="@action" value="register">
    <input type="submit" name="submit" value="Register" i18n:attributes="value">
   </td>
@@ -79,4 +82,3 @@
 </td>
 
 </tal:block>
-<!-- SHA: ed7a2465033194eb71fa79431b028150c23be650 -->
diff -r 63c5e35df4b4 -r 0e1a26853f2e html/user.rego_progress.html
--- a/html/user.rego_progress.html      Sun Nov 18 14:03:18 2018 +0100
+++ b/html/user.rego_progress.html      Sat Feb 16 19:38:54 2019 +0100
@@ -14,4 +14,3 @@
 
 </td>
 </tal:block>
-<!-- SHA: c2f389db861a4e0d20b41e5ff88120270862f609 -->

Reply via email to