Mercurial > p > roundup > code
diff roundup/cgi/templating.py @ 7018:379a5e501dab
flake8: fix whitespace around : and operator and add blank lines
E203 whitespace before ':'
E221 multiple spaces before operator
E302 expected 2 blank lines, found 1
E301 expected 1 blank line, found 0
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 09 Oct 2022 17:22:32 -0400 |
| parents | 96be63649c92 |
| children | e1528860e591 |
line wrap: on
line diff
--- a/roundup/cgi/templating.py Sun Oct 09 17:13:56 2022 -0400 +++ b/roundup/cgi/templating.py Sun Oct 09 17:22:32 2022 -0400 @@ -63,6 +63,7 @@ from roundup.exceptions import RoundupException + def _import_markdown2(): try: import markdown2, re @@ -71,7 +72,7 @@ _safe_protocols = re.compile('(?!' + ':|'.join([re.escape(s) for s in _disable_url_schemes]) + ':)', re.IGNORECASE) def _extras(config): - extras = {'fenced-code-blocks' : {}, 'nofollow': None} + extras = {'fenced-code-blocks': {}, 'nofollow': None} if config['MARKDOWN_BREAK_ON_NEWLINE']: extras['break-on-newline'] = True return extras @@ -82,6 +83,7 @@ return markdown + def _import_markdown(): try: from markdown import markdown as markdown_impl @@ -144,6 +146,7 @@ return markdown + def _import_mistune(): try: import mistune @@ -201,6 +204,7 @@ # bring in the templating support from roundup.cgi import ZTUtils + def anti_csrf_nonce(client, lifetime=None): ''' Create a nonce for defending against CSRF attack. @@ -224,9 +228,11 @@ ### templating + class NoTemplate(RoundupException): pass + class Unauthorised(RoundupException): def __init__(self, action, klass, translator=None): self.action = action @@ -235,6 +241,7 @@ self._ = translator.gettext else: self._ = TranslationService.get_translation().gettext + def __str__(self): return self._('You are not allowed to %(action)s ' 'items of class %(class)s') % { @@ -270,6 +277,7 @@ """ raise NotImplementedError + class TALLoaderBase(LoaderBase): """ Common methods for the legacy TAL loaders.""" @@ -317,6 +325,7 @@ except NoTemplate as message: raise KeyError(message) + class MultiLoader(LoaderBase): def __init__(self): self.loaders = [] @@ -462,6 +471,7 @@ c['context'] = HTMLClass(client, classname, anonymous=1) return c + class HTMLDatabase: """ Return HTMLClasses for valid class fetches """ @@ -499,6 +509,7 @@ num_re = re.compile(r'^-?\d+$') + def lookupIds(db, prop, ids, fail_ok=0, num_re=num_re, do_lookup=True): """ "fail_ok" should be specified if we wish to pass through bad values (most likely form values that we wish to represent back to the user) @@ -526,6 +537,7 @@ l.append(entry) return l + def lookupKeys(linkcl, key, ids, num_re=num_re): """ Look up the "key" values for "ids" list - though some may already be key values, not ids. @@ -545,6 +557,7 @@ l.append(entry) return l + def _set_input_default_args(dic): # 'text' is the default value anyway -- # but for CSS usage it should be present @@ -559,6 +572,7 @@ except KeyError: pass + def html4_cgi_escape_attrs(**attrs): ''' Boolean attributes like 'disabled', 'required' are represented without a value. E.G. @@ -571,6 +585,7 @@ if v != None else '%s'%(k) for k,v in sorted(attrs.items())]) + def xhtml_cgi_escape_attrs(**attrs): ''' Boolean attributes like 'disabled', 'required' are represented with a value that is the same as @@ -584,16 +599,19 @@ if v != None else '%s="%s"'%(k,k) for k,v in sorted(attrs.items())]) + def input_html4(**attrs): """Generate an 'input' (html4) element with given attributes""" _set_input_default_args(attrs) return '<input %s>'%html4_cgi_escape_attrs(**attrs) + def input_xhtml(**attrs): """Generate an 'input' (xhtml) element with given attributes""" _set_input_default_args(attrs) return '<input %s/>'%xhtml_cgi_escape_attrs(**attrs) + class HTMLInputMixin(object): """ requires a _client property """ def __init__(self): @@ -619,6 +637,7 @@ _ = gettext + class HTMLPermissions(object): def view_check(self): @@ -892,7 +911,7 @@ else: sort = self._klass.orderprop() sort = '&@sort=' + sort - if group : + if group: group = '&@group=' + group if property: property = '&property=%s'%property @@ -967,6 +986,7 @@ } return pt.render(self._client, self.classname, req, **args) + class _HTMLItem(HTMLInputMixin, HTMLPermissions): """ Accesses through an *item* """ @@ -1219,7 +1239,7 @@ for linkid in linkids: # We're seeing things like # {'nosy':['38', '113', None, '82']} in the wild - if linkid is None : + if linkid is None: continue label = classname + linkid # if we have a label property, try to use it @@ -1431,10 +1451,12 @@ ["%s=%s" % (key, urllib_.quote(value)) for key, value in query.items()]) + class _HTMLUser(_HTMLItem): """Add ability to check for permissions on users. """ _marker = [] + def hasPermission(self, permission, classname=_marker, property=None, itemid=None): """Determine if the user has the Permission. @@ -1451,12 +1473,14 @@ """Determine whether the user has any role in rolenames.""" return self._db.user.has_role(self._nodeid, *rolenames) + def HTMLItem(client, classname, nodeid, anonymous=0): if classname == 'user': return _HTMLUser(client, classname, nodeid, anonymous) else: return _HTMLItem(client, classname, nodeid, anonymous) + class HTMLProperty(HTMLInputMixin, HTMLPermissions): """ String, Integer, Number, Date, Interval HTMLProperty @@ -1521,28 +1545,35 @@ classname = self.__class__.__name__ return '<%s(0x%x) %s %r %r>'%(classname, id(self), self._formname, self._prop, self._value) + def __str__(self): return self.plain() + def __lt__(self, other): if isinstance(other, HTMLProperty): return self._value < other._value return self._value < other + def __le__(self, other): if isinstance(other, HTMLProperty): return self._value <= other._value return self._value <= other + def __eq__(self, other): if isinstance(other, HTMLProperty): return self._value == other._value return self._value == other + def __ne__(self, other): if isinstance(other, HTMLProperty): return self._value != other._value return self._value != other + def __gt__(self, other): if isinstance(other, HTMLProperty): return self._value > other._value return self._value > other + def __ge__(self, other): if isinstance(other, HTMLProperty): return self._value >= other._value @@ -1581,6 +1612,7 @@ return 1 return self.is_edit_ok() + class StringHTMLProperty(HTMLProperty): hyper_re = re.compile(r'''( (?P<url> @@ -1904,6 +1936,7 @@ value = html_escape(value) return value + class PasswordHTMLProperty(HTMLProperty): def plain(self, escape=0): """ Render a "plain" representation of the property @@ -1947,6 +1980,7 @@ id="%s-confirm"%self._formname, size=size) + class NumberHTMLProperty(HTMLProperty): def plain(self, escape=0): """ Render a "plain" representation of the property @@ -1999,6 +2033,7 @@ """ return float(self._value) + class IntegerHTMLProperty(HTMLProperty): def plain(self, escape=0): """ Render a "plain" representation of the property @@ -2108,6 +2143,7 @@ return s + class DateHTMLProperty(HTMLProperty): _marker = [] @@ -2119,7 +2155,7 @@ if self._value and not is_us(self._value): self._value.setTranslator(self._client.translator) self._offset = offset - if self._offset is None : + if self._offset is None: self._offset = self._prop.offset (self._db) def plain(self, escape=0): @@ -2217,9 +2253,9 @@ else: value = date.Date(raw_value).pretty(format) else: - if self._offset is None : + if self._offset is None: offset = self._db.getUserTimezone() - else : + else: offset = self._offset value = raw_value.local(offset) if format is not self._marker: @@ -2292,7 +2328,7 @@ """ if self.isset(): date = "&date=%s"%self._value - else : + else: date = "" data_attr = { @@ -2306,6 +2342,7 @@ '">%s</a>'%(self.cgi_escape_attrs(**data_attr),self._classname, self._name, form, date, width, height, label)) + class IntervalHTMLProperty(HTMLProperty): def __init__(self, client, classname, nodeid, prop, name, value, anonymous=0): @@ -2347,6 +2384,7 @@ return self.input(name=self._formname, value=value, size=size, **kwargs) + class LinkHTMLProperty(HTMLProperty): """ Link HTMLProperty Include the above as well as being able to access the class @@ -2404,7 +2442,7 @@ default=self._("[label is missing]"))) except IndexError: value = self._value - else : + else: value = self._value if escape: value = html_escape(value) @@ -2426,10 +2464,10 @@ k = linkcl.getkey() idparse = self._prop.try_id_parsing if k and num_re.match(self._value): - try : + try: value = linkcl.get(self._value, k) - except IndexError : - if idparse : + except IndexError: + if idparse: raise value = '' else: @@ -2867,6 +2905,7 @@ (hyperdb.Multilink, MultilinkHTMLProperty), ] + def register_propclass(prop, cls): for index,propclass in enumerate(propclasses): p, c = propclass @@ -2889,11 +2928,12 @@ if num_re.match(a): a = linkcl.get(a, sort_on) # In Python3 we may not compare strings and None - if a is None : + if a is None: return '' return a return keyfunc + def handleListCGIValue(value): """ Value is either a single item or a list of items. Each item has a .value that we're actually interested in. @@ -2906,6 +2946,7 @@ return [] return [v.strip() for v in value.split(',')] + class HTMLRequest(HTMLInputMixin): """The *request*, holding the CGI form and environment. @@ -3351,6 +3392,7 @@ return Batch(self.client, l, self.pagesize, self.startwith, classname=self.classname) + # extend the standard ZTUtils Batch object to remove dependency on # Acquisition and add a couple of useful methods class Batch(ZTUtils.Batch): @@ -3445,11 +3487,13 @@ return Batch(self.client, self._sequence, self.size, self.end - self.overlap, 0, self.orphan, self.overlap) + class TemplatingUtils: """ Utilities for templating """ def __init__(self, client): self.client = client + def Batch(self, sequence, size, start, end=0, orphan=0, overlap=0): return Batch(self.client, sequence, size, start, end, orphan, overlap) @@ -3495,11 +3539,11 @@ """ tz = request.client.db.getUserTimezone() current_date = date.Date(".").local(tz) - date_str = request.form.getfirst("date", current_date) - display = request.form.getfirst("display", date_str) - template = request.form.getfirst("@template", "calendar") - form = request.form.getfirst("form") - property = request.form.getfirst("property") + date_str = request.form.getfirst("date", current_date) + display = request.form.getfirst("display", date_str) + template = request.form.getfirst("@template", "calendar") + form = request.form.getfirst("form") + property = request.form.getfirst("property") curr_date = "" try: # date_str and display can be set to an invalid value @@ -3507,13 +3551,13 @@ # If either or both invalid just ignore that we can't parse it # and assign them to today. curr_date = date.Date(date_str) # to highlight - display = date.Date(display) # to show + display = date.Date(display) # to show except ValueError: # we couldn't parse the date # just let the calendar display curr_date = current_date display = current_date - day = display.day + day = display.day # for navigation try: @@ -3587,17 +3631,18 @@ and display.year == curr_date.year): # highlight style = "today" - else : + else: style = "" if day: res.append(' <td class="%s"><a href="%s">%s</a></td>'%( style, link, day)) - else : + else: res.append(' <td></td>') res.append(' </tr>') res.append('</table></td></tr></table>') return "\n".join(res) + class MissingValue(object): def __init__(self, description, **kwargs): self.__description = description @@ -3605,6 +3650,7 @@ self.__dict__[key] = value def __call__(self, *args, **kwargs): return MissingValue(self.__description) + def __getattr__(self, name): # This allows assignments which assume all intermediate steps are Null # objects if they don't exist yet. @@ -3625,6 +3671,7 @@ def __str__(self): return '[%s]'%self.__description def __repr__(self): return '<MissingValue 0x%x "%s">'%(id(self), self.__description) + def gettext(self, str): return str _ = gettext
