annotate roundup/cgi/form_parser.py @ 5522:c5c33e62da39

Fix absent file uploads with Python 3. If a form has a file upload input control for a Link to a FileClass class, but no file is uploaded, browsers submit this as an upload with empty filename and file contents. This then goes through the Roundup code: # value might be a single file upload if not getattr(value, 'filename', None): value = value.value.strip() which results in value holding those empty file contents. With Python 2, the code elif value == '': # other types should be None'd if there's no value value = None then results in value being set to None, meaning no file node gets created. With Python 3, however, value is b'' at this point and so the code ends up creating a file node with empty content. Thus, this patch fixes this by also checking for b'' there.
author Joseph Myers <jsm@polyomino.org.uk>
date Sat, 01 Sep 2018 18:29:16 +0000
parents 3fa026621f69
children 936275dfe1fa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
1 import re, mimetypes
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
2
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
3 from roundup import hyperdb, date, password
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
4 from roundup.cgi import templating
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
5 from roundup.cgi.exceptions import FormError
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
6
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
7 class FormParser:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
8 # edit form variable handling (see unit tests)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
9 FV_LABELS = r'''
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
10 ^(
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
11 (?P<note>[@:]note)|
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
12 (?P<file>[@:]file)|
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
13 (
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
14 ((?P<classname>%s)(?P<id>[-\d]+))? # optional leading designator
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
15 ((?P<required>[@:]required$)| # :required
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
16 (
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
17 (
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
18 (?P<add>[@:]add[@:])| # :add:<prop>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
19 (?P<remove>[@:]remove[@:])| # :remove:<prop>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
20 (?P<confirm>[@:]confirm[@:])| # :confirm:<prop>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
21 (?P<link>[@:]link[@:])| # :link:<prop>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
22 ([@:]) # just a separator
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
23 )?
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
24 (?P<propname>[^@:]+) # <prop>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
25 )
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
26 )
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
27 )
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
28 )$'''
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
29
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
30 def __init__(self, client):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
31 self.client = client
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
32 self.db = client.db
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
33 self.form = client.form
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
34 self.classname = client.classname
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
35 self.nodeid = client.nodeid
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
36 try:
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
37 self._ = self.gettext = client.gettext
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
38 self.ngettext = client.ngettext
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
39 except AttributeError:
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
40 _translator = templating.translationService
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
41 self._ = self.gettext = _translator.gettext
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
42 self.ngettext = _translator.ngettext
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
43
2107
b7404a96b58a minor pre-release / test fixes
Richard Jones <richard@users.sourceforge.net>
parents: 2010
diff changeset
44 def parse(self, create=0, num_re=re.compile('^\d+$')):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
45 """ Item properties and their values are edited with html FORM
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
46 variables and their values. You can:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
47
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
48 - Change the value of some property of the current item.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
49 - Create a new item of any class, and edit the new item's
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
50 properties,
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
51 - Attach newly created items to a multilink property of the
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
52 current item.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
53 - Remove items from a multilink property of the current item.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
54 - Specify that some properties are required for the edit
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
55 operation to be successful.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
56
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
57 In the following, <bracketed> values are variable, "@" may be
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
58 either ":" or "@", and other text "required" is fixed.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
59
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
60 Most properties are specified as form variables:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
61
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
62 <propname>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
63 - property on the current context item
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
64
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
65 <designator>"@"<propname>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
66 - property on the indicated item (for editing related
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
67 information)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
68
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
69 Designators name a specific item of a class.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
70
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
71 <classname><N>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
72
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
73 Name an existing item of class <classname>.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
74
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
75 <classname>"-"<N>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
76
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
77 Name the <N>th new item of class <classname>. If the form
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
78 submission is successful, a new item of <classname> is
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
79 created. Within the submitted form, a particular
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
80 designator of this form always refers to the same new
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
81 item.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
82
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
83 Once we have determined the "propname", we look at it to see
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
84 if it's special:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
85
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
86 @required
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
87 The associated form value is a comma-separated list of
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
88 property names that must be specified when the form is
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
89 submitted for the edit operation to succeed.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
90
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
91 When the <designator> is missing, the properties are
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
92 for the current context item. When <designator> is
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
93 present, they are for the item specified by
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
94 <designator>.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
95
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
96 The "@required" specifier must come before any of the
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
97 properties it refers to are assigned in the form.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
98
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
99 @remove@<propname>=id(s) or @add@<propname>=id(s)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
100 The "@add@" and "@remove@" edit actions apply only to
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
101 Multilink properties. The form value must be a
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
102 comma-separate list of keys for the class specified by
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
103 the simple form variable. The listed items are added
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
104 to (respectively, removed from) the specified
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
105 property.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
106
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
107 @link@<propname>=<designator>
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
108 If the edit action is "@link@", the simple form
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
109 variable must specify a Link or Multilink property.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
110 The form value is a comma-separated list of
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
111 designators. The item corresponding to each
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
112 designator is linked to the property given by simple
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
113 form variable. These are collected up and returned in
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
114 all_links.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
115
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
116 None of the above (ie. just a simple form value)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
117 The value of the form variable is converted
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
118 appropriately, depending on the type of the property.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
119
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
120 For a Link('klass') property, the form value is a
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
121 single key for 'klass', where the key field is
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
122 specified in dbinit.py.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
123
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
124 For a Multilink('klass') property, the form value is a
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
125 comma-separated list of keys for 'klass', where the
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
126 key field is specified in dbinit.py.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
127
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
128 Note that for simple-form-variables specifiying Link
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
129 and Multilink properties, the linked-to class must
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
130 have a key field.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
131
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
132 For a String() property specifying a filename, the
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
133 file named by the form value is uploaded. This means we
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
134 try to set additional properties "filename" and "type" (if
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
135 they are valid for the class). Otherwise, the property
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
136 is set to the form value.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
137
5067
e424987d294a Add support for an integer type to join the existing number type.
John Rouillard <rouilj@ieee.org>
parents: 5066
diff changeset
138 For Date(), Interval(), Boolean(), and Number(), Integer()
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
139 properties, the form value is converted to the
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
140 appropriate
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
141
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
142 Any of the form variables may be prefixed with a classname or
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
143 designator.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
144
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
145 Two special form values are supported for backwards
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
146 compatibility:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
147
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
148 @note
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
149 This is equivalent to::
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
150
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
151 @link@messages=msg-1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
152 msg-1@content=value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
153
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
154 except that in addition, the "author" and "date"
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
155 properties of "msg-1" are set to the userid of the
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
156 submitter, and the current time, respectively.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
157
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
158 @file
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
159 This is equivalent to::
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
160
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
161 @link@files=file-1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
162 file-1@content=value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
163
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
164 The String content value is handled as described above for
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
165 file uploads.
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
166 If "multiple" is turned on for file uploads in the html
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
167 template, multiple links are generated::
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
168
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
169 @link@files=file-2
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
170 file-2@content=value
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
171 ...
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
172
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
173 depending on how many files the user has attached.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
174
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
175 If both the "@note" and "@file" form variables are
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
176 specified, the action::
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
177
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
178 @link@msg-1@files=file-1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
179
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
180 is also performed. If "multiple" is specified this is
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
181 carried out for each of the attached files.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
182
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
183 We also check that FileClass items have a "content" property with
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
184 actual content, otherwise we remove them from all_props before
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
185 returning.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
186
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
187 The return from this method is a dict of
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
188 (classname, id): properties
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
189 ... this dict _always_ has an entry for the current context,
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
190 even if it's empty (ie. a submission for an existing issue that
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
191 doesn't result in any changes would return {('issue','123'): {}})
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
192 The id may be None, which indicates that an item should be
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
193 created.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
194 """
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
195 # some very useful variables
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
196 db = self.db
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
197 form = self.form
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
198
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
199 if not hasattr(self, 'FV_SPECIAL'):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
200 # generate the regexp for handling special form values
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
201 classes = '|'.join(db.classes.keys())
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
202 # specials for parsePropsFromForm
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
203 # handle the various forms (see unit tests)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
204 self.FV_SPECIAL = re.compile(self.FV_LABELS%classes, re.VERBOSE)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
205 self.FV_DESIGNATOR = re.compile(r'(%s)([-\d]+)'%classes)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
206
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
207 # these indicate the default class / item
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
208 default_cn = self.classname
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
209 default_cl = self.db.classes[default_cn]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
210 default_nodeid = self.nodeid
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
211
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
212 # we'll store info about the individual class/item edit in these
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
213 all_required = {} # required props per class/item
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
214 all_props = {} # props to set per class/item
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
215 got_props = {} # props received per class/item
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
216 all_propdef = {} # note - only one entry per class
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
217 all_links = [] # as many as are required
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
218
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
219 # we should always return something, even empty, for the context
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
220 all_props[(default_cn, default_nodeid)] = {}
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
221
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
222 keys = form.keys()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
223 timezone = db.getUserTimezone()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
224
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
225 # sentinels for the :note and :file props
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
226 have_note = have_file = 0
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
227
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
228 # extract the usable form labels from the form
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
229 matches = []
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
230 for key in keys:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
231 m = self.FV_SPECIAL.match(key)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
232 if m:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
233 matches.append((key, m.groupdict()))
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
234
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
235 # now handle the matches
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
236 for key, d in matches:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
237 if d['classname']:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
238 # we got a designator
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
239 cn = d['classname']
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
240 cl = self.db.classes[cn]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
241 nodeid = d['id']
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
242 propname = d['propname']
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
243 elif d['note']:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
244 # the special note field
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
245 cn = 'msg'
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
246 cl = self.db.classes[cn]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
247 nodeid = '-1'
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
248 propname = 'content'
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
249 all_links.append((default_cn, default_nodeid, 'messages',
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
250 [('msg', '-1')]))
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
251 have_note = 1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
252 elif d['file']:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
253 # the special file field
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
254 cn = default_cn
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
255 cl = default_cl
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
256 nodeid = default_nodeid
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
257 propname = 'files'
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
258 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
259 # default
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
260 cn = default_cn
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
261 cl = default_cl
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
262 nodeid = default_nodeid
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
263 propname = d['propname']
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
264
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
265 # the thing this value relates to is...
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
266 this = (cn, nodeid)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
267
2010
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
268 # skip implicit create if this isn't a create action
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
269 if not create and nodeid is None:
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
270 continue
1b11ffd8015e forward-porting of fixed edit action / parsePropsFromForm...
Richard Jones <richard@users.sourceforge.net>
parents: 2004
diff changeset
271
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
272 # get more info about the class, and the current set of
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
273 # form props for it
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
274 if cn not in all_propdef:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
275 all_propdef[cn] = cl.getprops()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
276 propdef = all_propdef[cn]
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
277 if this not in all_props:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
278 all_props[this] = {}
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
279 props = all_props[this]
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
280 if this not in got_props:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
281 got_props[this] = {}
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
282
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
283 # is this a link command?
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
284 if d['link']:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
285 value = []
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
286 for entry in self.extractFormList(form[key]):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
287 m = self.FV_DESIGNATOR.match(entry)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
288 if not m:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
289 raise FormError (self._('link "%(key)s" '
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
290 'value "%(entry)s" not a designator') % locals())
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
291 value.append((m.group(1), m.group(2)))
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
292
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
293 # get details of linked class
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
294 lcn = m.group(1)
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
295 lcl = self.db.classes[lcn]
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
296 lnodeid = m.group(2)
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
297 if lcn not in all_propdef:
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
298 all_propdef[lcn] = lcl.getprops()
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
299 if (lcn, lnodeid) not in all_props:
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
300 all_props[(lcn, lnodeid)] = {}
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
301 if (lcn, lnodeid) not in got_props:
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
302 got_props[(lcn, lnodeid)] = {}
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
303
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
304 # make sure the link property is valid
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
305 if (not isinstance(propdef[propname], hyperdb.Multilink) and
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
306 not isinstance(propdef[propname], hyperdb.Link)):
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
307 raise FormError (self._('%(class)s %(property)s '
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
308 'is not a link or multilink property') % {
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
309 'class':cn, 'property':propname})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
310
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
311 all_links.append((cn, nodeid, propname, value))
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
312 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
313
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
314 # detect the special ":required" variable
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
315 if d['required']:
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
316 for entry in self.extractFormList(form[key]):
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
317 m = self.FV_SPECIAL.match(entry)
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
318 if not m:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
319 raise FormError (self._('The form action claims to '
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
320 'require property "%(property)s" '
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
321 'which doesn\'t exist') % {
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
322 'property':propname})
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
323 if m.group('classname'):
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
324 this = (m.group('classname'), m.group('id'))
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
325 entry = m.group('propname')
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
326 if this not in all_required:
3656
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
327 all_required[this] = []
0119e04886d8 @required in forms may now specify properties of linked items
Richard Jones <richard@users.sourceforge.net>
parents: 3651
diff changeset
328 all_required[this].append(entry)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
329 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
330
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
331 # see if we're performing a special multilink action
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
332 mlaction = 'set'
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
333 if d['remove']:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
334 mlaction = 'remove'
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
335 elif d['add']:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
336 mlaction = 'add'
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
337
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
338 # does the property exist?
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
339 if propname not in propdef:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
340 if mlaction != 'set':
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
341 raise FormError (self._('You have submitted a %(action)s '
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
342 'action for the property "%(property)s" '
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
343 'which doesn\'t exist') % {
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
344 'action': mlaction, 'property':propname})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
345 # the form element is probably just something we don't care
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
346 # about - ignore it
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
347 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
348 proptype = propdef[propname]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
349
3559
4b80c330f02b translate class name in "required property not supplied" message [SF#1429669]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3491
diff changeset
350 # Get the form value. This value may be a MiniFieldStorage
4b80c330f02b translate class name in "required property not supplied" message [SF#1429669]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3491
diff changeset
351 # or a list of MiniFieldStorages.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
352 value = form[key]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
353
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
354 # handle unpacking of the MiniFieldStorage / list form value
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
355 if d['file']:
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
356 assert isinstance(proptype, hyperdb.Multilink)
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
357 # value is a file upload... we *always* handle multiple
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
358 # files here (html5)
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
359 if not isinstance(value, type([])):
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
360 value = [value]
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
361 elif isinstance(proptype, hyperdb.Multilink):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
362 value = self.extractFormList(value)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
363 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
364 # multiple values are not OK
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
365 if isinstance(value, type([])):
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
366 raise FormError (self._('You have submitted more than one '
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
367 'value for the %s property') % propname)
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
368 # value might be a single file upload
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
369 if not getattr(value, 'filename', None):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
370 value = value.value.strip()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
371
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
372 # now that we have the props field, we need a teensy little
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
373 # extra bit of help for the old :note field...
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
374 if d['note'] and value:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
375 props['author'] = self.db.getuid()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
376 props['date'] = date.Date()
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
377
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
378 # handle by type now
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
379 if isinstance(proptype, hyperdb.Password):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
380 if not value:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
381 # ignore empty password values
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
382 continue
4559
86a270b5b993 - Ignore confirm set() fields by themselves in the absence of non-"confirm"
Richard Jones <richard@mechanicalcat.net>
parents: 4486
diff changeset
383 if d['confirm']:
86a270b5b993 - Ignore confirm set() fields by themselves in the absence of non-"confirm"
Richard Jones <richard@mechanicalcat.net>
parents: 4486
diff changeset
384 # ignore the "confirm" password value by itself
86a270b5b993 - Ignore confirm set() fields by themselves in the absence of non-"confirm"
Richard Jones <richard@mechanicalcat.net>
parents: 4486
diff changeset
385 continue
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
386 for key, d in matches:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
387 if d['confirm'] and d['propname'] == propname:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
388 confirm = form[key]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
389 break
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
390 else:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
391 raise FormError (self._('Password and confirmation text '
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
392 'do not match'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
393 if isinstance(confirm, type([])):
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
394 raise FormError (self._('You have submitted more than one '
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
395 'value for the %s property') % propname)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
396 if value != confirm.value:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
397 raise FormError (self._('Password and confirmation text '
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
398 'do not match'))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
399 try:
5053
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4559
diff changeset
400 value = password.Password(value, scheme = proptype.scheme,
9792b18e0b19 issue 2550880: Ability to choose password store scheme and SSHA support.
John Rouillard <rouilj@ieee.org>
parents: 4559
diff changeset
401 config=self.db.config)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5195
diff changeset
402 except hyperdb.HyperdbValueError as msg:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
403 raise FormError (msg)
5066
d2256fcfd81f Fix regression in password parsing
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5065
diff changeset
404 elif d['file']:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
405 # This needs to be a Multilink and is checked above
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
406 fcn = 'file'
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
407 fcl = self.db.classes[fcn]
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
408 fpropname = 'content'
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
409 if fcn not in all_propdef:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
410 all_propdef[fcn] = fcl.getprops()
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
411 fpropdef = all_propdef[fcn]
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
412 have_file = []
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
413 for n, v in enumerate(value):
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
414 if not hasattr(v, 'filename'):
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
415 raise FormError (self._('Not a file attachment'))
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
416 # skip if the upload is empty
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
417 if not v.filename:
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
418 continue
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
419 fnodeid = str (-(n+1))
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
420 have_file.append(fnodeid)
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
421 fthis = (fcn, fnodeid)
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
422 if fthis not in all_props:
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
423 all_props[fthis] = {}
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
424 fprops = all_props[fthis]
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
425 all_links.append((cn, nodeid, 'files', [('file', fnodeid)]))
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
426
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
427 fprops['content'] = self.parse_file(fpropdef, fprops, v)
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
428 value = None
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
429 nodeid = None
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
430 elif isinstance(proptype, hyperdb.Multilink):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
431 # convert input to list of ids
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
432 try:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
433 l = hyperdb.rawToHyperdb(self.db, cl, nodeid,
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
434 propname, value)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5195
diff changeset
435 except hyperdb.HyperdbValueError as msg:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
436 raise FormError (msg)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
437
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
438 # now use that list of ids to modify the multilink
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
439 if mlaction == 'set':
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
440 value = l
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
441 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
442 # we're modifying the list - get the current list of ids
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
443 if propname in props:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
444 existing = props[propname]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
445 elif nodeid and not nodeid.startswith('-'):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
446 existing = cl.get(nodeid, propname, [])
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
447 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
448 existing = []
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
449
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
450 # now either remove or add
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
451 if mlaction == 'remove':
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
452 # remove - handle situation where the id isn't in
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
453 # the list
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
454 for entry in l:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
455 try:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
456 existing.remove(entry)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
457 except ValueError:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
458 raise FormError (self._('property '
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
459 '"%(propname)s": "%(value)s" '
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
460 'not currently in list') % {
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
461 'propname': propname, 'value': entry})
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
462 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
463 # add - easy, just don't dupe
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
464 for entry in l:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
465 if entry not in existing:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
466 existing.append(entry)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
467 value = existing
4050
a412ce8ccf6f Use canonical sort order for multilinks.
Stefan Seefeld <stefan@seefeld.name>
parents: 4049
diff changeset
468 # Sort the value in the same order used by
a412ce8ccf6f Use canonical sort order for multilinks.
Stefan Seefeld <stefan@seefeld.name>
parents: 4049
diff changeset
469 # Multilink.from_raw.
5414
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5398
diff changeset
470 value.sort(key=int)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
471
5522
c5c33e62da39 Fix absent file uploads with Python 3.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5414
diff changeset
472 elif value == '' or value == b'':
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
473 # other types should be None'd if there's no value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
474 value = None
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
475 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
476 # handle all other types
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
477 try:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
478 # Try handling file upload
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
479 if (isinstance(proptype, hyperdb.String) and
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
480 hasattr(value, 'filename') and
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
481 value.filename is not None):
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
482 value = self.parse_file(propdef, props, value)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
483 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
484 value = hyperdb.rawToHyperdb(self.db, cl, nodeid,
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
485 propname, value)
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5195
diff changeset
486 except hyperdb.HyperdbValueError as msg:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
487 raise FormError (msg)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
488
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
489 # register that we got this property
3777
74aebbbea305 Sorry for the mega-patch - was all done on the train:
Richard Jones <richard@users.sourceforge.net>
parents: 3767
diff changeset
490 if isinstance(proptype, hyperdb.Multilink):
74aebbbea305 Sorry for the mega-patch - was all done on the train:
Richard Jones <richard@users.sourceforge.net>
parents: 3767
diff changeset
491 if value != []:
74aebbbea305 Sorry for the mega-patch - was all done on the train:
Richard Jones <richard@users.sourceforge.net>
parents: 3767
diff changeset
492 got_props[this][propname] = 1
74aebbbea305 Sorry for the mega-patch - was all done on the train:
Richard Jones <richard@users.sourceforge.net>
parents: 3767
diff changeset
493 elif value is not None:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
494 got_props[this][propname] = 1
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
495
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
496 # get the old value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
497 if nodeid and not nodeid.startswith('-'):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
498 try:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
499 existing = cl.get(nodeid, propname)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
500 except KeyError:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
501 # this might be a new property for which there is
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
502 # no existing value
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
503 if propname not in propdef:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
504 raise
5248
198b6e810c67 Use Python-3-compatible 'as' syntax for except statements
Eric S. Raymond <esr@thyrsus.com>
parents: 5195
diff changeset
505 except IndexError as message:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
506 raise FormError(str(message))
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
507
4050
a412ce8ccf6f Use canonical sort order for multilinks.
Stefan Seefeld <stefan@seefeld.name>
parents: 4049
diff changeset
508 # make sure the existing multilink is sorted. We must
a412ce8ccf6f Use canonical sort order for multilinks.
Stefan Seefeld <stefan@seefeld.name>
parents: 4049
diff changeset
509 # be sure to use the same sort order in all places,
a412ce8ccf6f Use canonical sort order for multilinks.
Stefan Seefeld <stefan@seefeld.name>
parents: 4049
diff changeset
510 # since we want to compare values with "=" or "!=".
a412ce8ccf6f Use canonical sort order for multilinks.
Stefan Seefeld <stefan@seefeld.name>
parents: 4049
diff changeset
511 # The canonical order (given in Multilink.from_raw) is
a412ce8ccf6f Use canonical sort order for multilinks.
Stefan Seefeld <stefan@seefeld.name>
parents: 4049
diff changeset
512 # by the numeric value of the IDs.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
513 if isinstance(proptype, hyperdb.Multilink):
5414
3fa026621f69 Python 3 preparation: comparisons.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5398
diff changeset
514 existing.sort(key=int)
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
515
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
516 # "missing" existing values may not be None
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
517 if not existing:
3491
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
518 if isinstance(proptype, hyperdb.String):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
519 # some backends store "missing" Strings as empty strings
3491
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
520 if existing == self.db.BACKEND_MISSING_STRING:
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
521 existing = None
5067
e424987d294a Add support for an integer type to join the existing number type.
John Rouillard <rouilj@ieee.org>
parents: 5066
diff changeset
522 elif isinstance(proptype, hyperdb.Number) or isinstance(proptype, hyperdb.Integer):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
523 # some backends store "missing" Numbers as 0 :(
3491
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
524 if existing == self.db.BACKEND_MISSING_NUMBER:
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
525 existing = None
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
526 elif isinstance(proptype, hyperdb.Boolean):
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
527 # likewise Booleans
3491
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
528 if existing == self.db.BACKEND_MISSING_BOOLEAN:
0e5f15520e70 fix detection of "missing" existing values in CGI form parser [SF#1414149]
Richard Jones <richard@users.sourceforge.net>
parents: 3267
diff changeset
529 existing = None
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
530
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
531 # if changed, set it
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
532 if value != existing:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
533 props[propname] = value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
534 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
535 # don't bother setting empty/unset values
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
536 if value is None:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
537 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
538 elif isinstance(proptype, hyperdb.Multilink) and value == []:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
539 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
540 elif isinstance(proptype, hyperdb.String) and value == '':
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
541 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
542
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
543 props[propname] = value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
544
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
545 # check to see if we need to specially link files to the note
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
546 if have_note and have_file:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
547 for fid in have_file:
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
548 all_links.append(('msg', '-1', 'files', [('file', fid)]))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
549
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
550 # see if all the required properties have been supplied
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
551 s = []
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
552 for thing, required in all_required.items():
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
553 # register the values we got
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
554 got = got_props.get(thing, {})
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
555 for entry in required[:]:
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
556 if entry in got:
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
557 required.remove(entry)
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
558
3765
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
559 # If a user doesn't have edit permission for a given property,
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
560 # but the property is already set in the database, we don't
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
561 # require a value.
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
562 if not (create or nodeid is None):
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
563 for entry in required[:]:
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
564 if not self.db.security.hasPermission('Edit',
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
565 self.client.userid,
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
566 self.classname,
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
567 entry):
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
568 cl = self.db.classes[self.classname]
3767
9d93653f8dcb fix typo.
Stefan Seefeld <stefan@seefeld.name>
parents: 3765
diff changeset
569 if cl.get(nodeid, entry) is not None:
3765
9a00da0f1da9 Fix [SF#1599740]
Stefan Seefeld <stefan@seefeld.name>
parents: 3656
diff changeset
570 required.remove(entry)
3936
63d58cc1394a make LinkHTMLProperty handle non-existing keys (patch [SF#1815895])
Richard Jones <richard@users.sourceforge.net>
parents: 3777
diff changeset
571
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
572 # any required values not present?
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
573 if not required:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
574 continue
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
575
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
576 # tell the user to entry the values required
2468
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
577 s.append(self.ngettext(
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
578 'Required %(class)s property %(property)s not supplied',
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
579 'Required %(class)s properties %(property)s not supplied',
7d5bf9cbd75d use self.client to translate messages; if that fails...
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2107
diff changeset
580 len(required)
2517
9260152ad143 translate property names in 'Required property not supplied' message
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2468
diff changeset
581 ) % {
3559
4b80c330f02b translate class name in "required property not supplied" message [SF#1429669]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3491
diff changeset
582 'class': self._(thing[0]),
2517
9260152ad143 translate property names in 'Required property not supplied' message
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2468
diff changeset
583 'property': ', '.join(map(self.gettext, required))
9260152ad143 translate property names in 'Required property not supplied' message
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2468
diff changeset
584 })
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
585 if s:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
586 raise FormError ('\n'.join(s))
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
587
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
588 # When creating a FileClass node, it should have a non-empty content
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
589 # property to be created. When editing a FileClass node, it should
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
590 # either have a non-empty content property or no property at all. In
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
591 # the latter case, nothing will change.
5395
23b8e6067f7c Python 3 preparation: update calls to dict methods.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5381
diff changeset
592 for (cn, id), props in list(all_props.items()):
4049
c9a8a47c4666 Do not try to create empty nodes with a negative ID.
Stefan Seefeld <stefan@seefeld.name>
parents: 3980
diff changeset
593 if id is not None and id.startswith('-') and not props:
3267
9ffea8719af1 disable node creation if no properties are set
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2517
diff changeset
594 # new item (any class) with no content - ignore
9ffea8719af1 disable node creation if no properties are set
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2517
diff changeset
595 del all_props[(cn, id)]
9ffea8719af1 disable node creation if no properties are set
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 2517
diff changeset
596 elif isinstance(self.db.classes[cn], hyperdb.FileClass):
5171
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
597 # three cases:
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
598 # id references existng file. If content is empty,
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
599 # remove content from form so we don't wipe
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
600 # existing file contents.
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
601 # id is -1, -2 ... I.E. a new file.
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
602 # if content is not defined remove all fields that
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
603 # reference that file.
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
604 # if content is defined, let it pass through even if
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
605 # content is empty. Yes people can upload/create
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
606 # empty files.
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
607 if 'content' in props:
5171
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
608 if id is not None and \
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
609 not id.startswith('-') and \
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
610 not props['content']:
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
611 # This is an existing file with emtpy content
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
612 # value in the form.
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
613 del props ['content']
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
614 else:
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
615 # this is a new file without any content property.
5170
2ae3954e972f Hopefully fix issue2550929
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5149
diff changeset
616 if id is not None and id.startswith('-'):
2ae3954e972f Hopefully fix issue2550929
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5149
diff changeset
617 del all_props[(cn, id)]
5171
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
618 # if this is a new file with content (even 0 length content)
5b63cfc95255 issue2550929 fix for my use case, need Ralf to check for his.
John Rouillard <rouilj@ieee.org>
parents: 5170
diff changeset
619 # allow it through and create the zero length file.
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
620 return all_props, all_links
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
621
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
622 def parse_file(self, fpropdef, fprops, v):
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
623 # try to determine the file content-type
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
624 fn = v.filename.split('\\')[-1]
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
625 if 'name' in fpropdef:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
626 fprops['name'] = fn
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
627 # use this info as the type/filename properties
5381
0942fe89e82e Python 3 preparation: change "x.has_key(y)" to "y in x".
Joseph Myers <jsm@polyomino.org.uk>
parents: 5248
diff changeset
628 if 'type' in fpropdef:
5065
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
629 if hasattr(v, 'type') and v.type:
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
630 fprops['type'] = v.type
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
631 elif mimetypes.guess_type(fn)[0]:
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
632 fprops['type'] = mimetypes.guess_type(fn)[0]
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
633 else:
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
634 fprops['type'] = "application/octet-stream"
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
635 # finally, read the content RAW
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
636 return v.value
47ab150b7325 Allow multiple file uploads
Ralf Schlatterbeck <rsc@runtux.com>
parents: 5053
diff changeset
637
2004
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
638 def extractFormList(self, value):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
639 ''' Extract a list of values from the form value.
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
640
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
641 It may be one of:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
642 [MiniFieldStorage('value'), MiniFieldStorage('value','value',...), ...]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
643 MiniFieldStorage('value,value,...')
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
644 MiniFieldStorage('value')
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
645 '''
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
646 # multiple values are OK
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
647 if isinstance(value, type([])):
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
648 # it's a list of MiniFieldStorages - join then into
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
649 values = ','.join([i.value.strip() for i in value])
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
650 else:
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
651 # it's a MiniFieldStorage, but may be a comma-separated list
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
652 # of values
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
653 values = value.value
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
654
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
655 value = [i.strip() for i in values.split(',')]
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
656
1782fe36e7b8 Move out parts of client.py to new modules:
Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
parents:
diff changeset
657 # filter out the empty bits
5398
99667a0cbd2d Python 3 preparation: use list() around filter() as needed.
Joseph Myers <jsm@polyomino.org.uk>
parents: 5395
diff changeset
658 return list(filter(None, value))
3559
4b80c330f02b translate class name in "required property not supplied" message [SF#1429669]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3491
diff changeset
659
4b80c330f02b translate class name in "required property not supplied" message [SF#1429669]
Alexander Smishlajev <a1s@users.sourceforge.net>
parents: 3491
diff changeset
660 # vim: set et sts=4 sw=4 :

Roundup Issue Tracker: http://roundup-tracker.org/