comparison roundup/cgi/templating.py @ 7026:d7f0eab25305

flake8 E231 missing whitespace after ',' or ':'
author John Rouillard <rouilj@ieee.org>
date Sun, 09 Oct 2022 17:51:42 -0400
parents 66149a18f09e
children ab5e1fd920a1
comparison
equal deleted inserted replaced
7025:66149a18f09e 7026:d7f0eab25305
582 <input required ..> not <input required="required" ...> 582 <input required ..> not <input required="required" ...>
583 The latter is xhtml. Recognize booleans by: 583 The latter is xhtml. Recognize booleans by:
584 value is None 584 value is None
585 Code can use None to indicate a pure boolean. 585 Code can use None to indicate a pure boolean.
586 ''' 586 '''
587 return ' '.join(['%s="%s"'%(k,html_escape(str(v), True)) 587 return ' '.join(['%s="%s"'%(k, html_escape(str(v), True))
588 if v is not None else '%s'%(k) 588 if v is not None else '%s'%(k)
589 for k,v in sorted(attrs.items())]) 589 for k, v in sorted(attrs.items())])
590 590
591 591
592 def xhtml_cgi_escape_attrs(**attrs): 592 def xhtml_cgi_escape_attrs(**attrs):
593 ''' Boolean attributes like 'disabled', 'required' 593 ''' Boolean attributes like 'disabled', 'required'
594 are represented with a value that is the same as 594 are represented with a value that is the same as
596 <input required="required" ...> not <input required ..> 596 <input required="required" ...> not <input required ..>
597 The latter is html4 or 5. Recognize booleans by: 597 The latter is html4 or 5. Recognize booleans by:
598 value is None 598 value is None
599 Code can use None to indicate a pure boolean. 599 Code can use None to indicate a pure boolean.
600 ''' 600 '''
601 return ' '.join(['%s="%s"'%(k,html_escape(str(v), True)) 601 return ' '.join(['%s="%s"'%(k, html_escape(str(v), True))
602 if v is not None else '%s="%s"'%(k,k) 602 if v is not None else '%s="%s"'%(k, k)
603 for k,v in sorted(attrs.items())]) 603 for k, v in sorted(attrs.items())])
604 604
605 605
606 def input_html4(**attrs): 606 def input_html4(**attrs):
607 """Generate an 'input' (html4) element with given attributes""" 607 """Generate an 'input' (html4) element with given attributes"""
608 _set_input_default_args(attrs) 608 _set_input_default_args(attrs)
783 if isinstance(prop, klass): 783 if isinstance(prop, klass):
784 value = prop.get_default_value() 784 value = prop.get_default_value()
785 l.append(htmlklass(self._client, self._classname, '', 785 l.append(htmlklass(self._client, self._classname, '',
786 prop, name, value, self._anonymous)) 786 prop, name, value, self._anonymous))
787 if sort: 787 if sort:
788 l.sort(key=lambda a:a._name) 788 l.sort(key=lambda a: a._name)
789 return l 789 return l
790 790
791 def list(self, sort_on=None): 791 def list(self, sort_on=None):
792 """ List all items in this class. 792 """ List all items in this class.
793 """ 793 """
1158 timezone = self._db.getUserTimezone() 1158 timezone = self._db.getUserTimezone()
1159 l = [] 1159 l = []
1160 current = {} 1160 current = {}
1161 comments = {} 1161 comments = {}
1162 for id, evt_date, user, action, args in history: 1162 for id, evt_date, user, action, args in history:
1163 date_s = str(evt_date.local(timezone)).replace("."," ") 1163 date_s = str(evt_date.local(timezone)).replace(".", " ")
1164 arg_s = '' 1164 arg_s = ''
1165 if action in ['link', 'unlink'] and isinstance(args, tuple): 1165 if action in ['link', 'unlink'] and isinstance(args, tuple):
1166 if len(args) == 3: 1166 if len(args) == 3:
1167 linkcl, linkid, key = args 1167 linkcl, linkid, key = args
1168 arg_s += '<a rel="nofollow noopener" href="%s%s">%s%s %s</a>'%(linkcl, linkid, 1168 arg_s += '<a rel="nofollow noopener" href="%s%s">%s%s %s</a>'%(linkcl, linkid,
1704 return '`%s <%s>`_'%(s, s) 1704 return '`%s <%s>`_'%(s, s)
1705 elif match.group('email'): 1705 elif match.group('email'):
1706 s = match.group('email') 1706 s = match.group('email')
1707 return '`%s <mailto:%s>`_'%(s, s) 1707 return '`%s <mailto:%s>`_'%(s, s)
1708 elif len(match.group('id')) < 10: 1708 elif len(match.group('id')) < 10:
1709 return self._hyper_repl_item(match,'`%(item)s <%(cls)s%(id)s>`_') 1709 return self._hyper_repl_item(match, '`%(item)s <%(cls)s%(id)s>`_')
1710 else: 1710 else:
1711 # just return the matched text 1711 # just return the matched text
1712 return match.group(0) 1712 return match.group(0)
1713 1713
1714 def _hyper_repl_markdown(self, match): 1714 def _hyper_repl_markdown(self, match):
1742 if end < len(match.string): 1742 if end < len(match.string):
1743 suffix = match.string[end] 1743 suffix = match.string[end]
1744 if (prefix, suffix) in {('[', ']')}: 1744 if (prefix, suffix) in {('[', ']')}:
1745 if match.string[end+1] == '(': # find following ( 1745 if match.string[end+1] == '(': # find following (
1746 return match.group(0) 1746 return match.group(0)
1747 if (prefix, suffix) in {('(',')')}: 1747 if (prefix, suffix) in {('(', ')')}:
1748 if match.string[start-1] == ']': 1748 if match.string[start-1] == ']':
1749 return match.group(0) 1749 return match.group(0)
1750 return self._hyper_repl_item(match,'[%(item)s](%(cls)s%(id)s)') 1750 return self._hyper_repl_item(match, '[%(item)s](%(cls)s%(id)s)')
1751 else: 1751 else:
1752 # just return the matched text 1752 # just return the matched text
1753 return match.group(0) 1753 return match.group(0)
1754 1754
1755 def url_quote(self): 1755 def url_quote(self):
1820 return self._('[hidden]') 1820 return self._('[hidden]')
1821 1821
1822 s = self.plain(escape=escape, hyperlink=hyperlink) 1822 s = self.plain(escape=escape, hyperlink=hyperlink)
1823 if not StructuredText: 1823 if not StructuredText:
1824 return s 1824 return s
1825 return StructuredText(s,level=1,header=0) 1825 return StructuredText(s, level=1, header=0)
1826 1826
1827 def rst(self, hyperlink=1): 1827 def rst(self, hyperlink=1):
1828 """ Render the value of the property as ReStructuredText. 1828 """ Render the value of the property as ReStructuredText.
1829 1829
1830 This requires docutils to be installed separately. 1830 This requires docutils to be installed separately.
2339 "data-height": height 2339 "data-height": height
2340 } 2340 }
2341 2341
2342 return ('<a class="classhelp" %s href="javascript:help_window(' 2342 return ('<a class="classhelp" %s href="javascript:help_window('
2343 "'%s?@template=calendar&amp;property=%s&amp;form=%s%s', %d, %d)" 2343 "'%s?@template=calendar&amp;property=%s&amp;form=%s%s', %d, %d)"
2344 '">%s</a>'%(self.cgi_escape_attrs(**data_attr),self._classname, self._name, form, date, width, 2344 '">%s</a>'%(self.cgi_escape_attrs(**data_attr),
2345 height, label)) 2345 self._classname, self._name, form, date, width,
2346 height, label))
2346 2347
2347 2348
2348 class IntervalHTMLProperty(HTMLProperty): 2349 class IntervalHTMLProperty(HTMLProperty):
2349 def __init__(self, client, classname, nodeid, prop, name, value, 2350 def __init__(self, client, classname, nodeid, prop, name, value,
2350 anonymous=0): 2351 anonymous=0):
2676 """ 2677 """
2677 2678
2678 # use 2 if NoneFirst is False to sort None last 2679 # use 2 if NoneFirst is False to sort None last
2679 # 0 to sort to sort None first 2680 # 0 to sort to sort None first
2680 # 1 is used to sort the integer values. 2681 # 1 is used to sort the integer values.
2681 NoneCode = (2,0)[NoneFirst] 2682 NoneCode = (2, 0)[NoneFirst]
2682 2683
2683 value = list(self.__iter__()) 2684 value = list(self.__iter__())
2684 2685
2685 if not value: 2686 if not value:
2686 # return empty list, nothing to sort. 2687 # return empty list, nothing to sort.
2907 (hyperdb.Multilink, MultilinkHTMLProperty), 2908 (hyperdb.Multilink, MultilinkHTMLProperty),
2908 ] 2909 ]
2909 2910
2910 2911
2911 def register_propclass(prop, cls): 2912 def register_propclass(prop, cls):
2912 for index,propclass in enumerate(propclasses): 2913 for index, propclass in enumerate(propclasses):
2913 p, c = propclass 2914 p, c = propclass
2914 if prop == p: 2915 if prop == p:
2915 propclasses[index] = (prop, cls) 2916 propclasses[index] = (prop, cls)
2916 break 2917 break
2917 else: 2918 else:
3188 def __str__(self): 3189 def __str__(self):
3189 d = {} 3190 d = {}
3190 d.update(self.__dict__) 3191 d.update(self.__dict__)
3191 f = '' 3192 f = ''
3192 for k in self.form.keys(): 3193 for k in self.form.keys():
3193 f += '\n %r=%r'%(k,handleListCGIValue(self.form[k])) 3194 f += '\n %r=%r'%(k, handleListCGIValue(self.form[k]))
3194 d['form'] = f 3195 d['form'] = f
3195 e = '' 3196 e = ''
3196 for k,v in self.env.items(): 3197 for k, v in self.env.items():
3197 e += '\n %r=%r'%(k, v) 3198 e += '\n %r=%r'%(k, v)
3198 d['env'] = e 3199 d['env'] = e
3199 return """ 3200 return """
3200 form: %(form)s 3201 form: %(form)s
3201 base: %(base)r 3202 base: %(base)r
3246 add(sc+'group', ','.join(val)) 3247 add(sc+'group', ','.join(val))
3247 if filter and self.filter: 3248 if filter and self.filter:
3248 add(sc+'filter', ','.join(self.filter)) 3249 add(sc+'filter', ','.join(self.filter))
3249 if self.classname and filterspec: 3250 if self.classname and filterspec:
3250 cls = self.client.db.getclass(self.classname) 3251 cls = self.client.db.getclass(self.classname)
3251 for k,v in self.filterspec.items(): 3252 for k, v in self.filterspec.items():
3252 if k in exclude: 3253 if k in exclude:
3253 continue 3254 continue
3254 if isinstance(v, list): 3255 if isinstance(v, list):
3255 # id's are stored as strings but should be treated 3256 # id's are stored as strings but should be treated
3256 # as integers in lists. 3257 # as integers in lists.
3280 dispname otherwise the parameter will be omitted 3281 dispname otherwise the parameter will be omitted
3281 from the url. 3282 from the url.
3282 """ 3283 """
3283 q = urllib_.quote 3284 q = urllib_.quote
3284 sc = self.special_char 3285 sc = self.special_char
3285 l = ['%s=%s'%(k,is_us(v) and q(v) or v) 3286 l = ['%s=%s'%(k, is_us(v) and q(v) or v)
3286 for k,v in args.items() if v is not None] 3287 for k, v in args.items() if v is not None]
3287 # pull out the special values (prefixed by @ or :) 3288 # pull out the special values (prefixed by @ or :)
3288 specials = {} 3289 specials = {}
3289 for key in args.keys(): 3290 for key in args.keys():
3290 if key[0] in '@:': 3291 if key[0] in '@:':
3291 specials[key[1:]] = args[key] 3292 specials[key[1:]] = args[key]
3319 l.append(sc+'startwith=%s'%self.startwith) 3320 l.append(sc+'startwith=%s'%self.startwith)
3320 3321
3321 # finally, the remainder of the filter args in the request 3322 # finally, the remainder of the filter args in the request
3322 if self.classname and self.filterspec: 3323 if self.classname and self.filterspec:
3323 cls = self.client.db.getclass(self.classname) 3324 cls = self.client.db.getclass(self.classname)
3324 for k,v in self.filterspec.items(): 3325 for k, v in self.filterspec.items():
3325 if k not in args: 3326 if k not in args:
3326 if isinstance(v, list): 3327 if isinstance(v, list):
3327 prop = cls.get_transitive_prop(k) 3328 prop = cls.get_transitive_prop(k)
3328 if k != 'id' and isinstance(prop, hyperdb.String): 3329 if k != 'id' and isinstance(prop, hyperdb.String):
3329 l.append('%s=%s'%(k, '%20'.join([q(i) for i in v]))) 3330 l.append('%s=%s'%(k, '%20'.join([q(i) for i in v])))
3350 function help_window(helpurl, width, height) { 3351 function help_window(helpurl, width, height) {
3351 HelpWin = window.open('%s' + helpurl, 'RoundupHelpWindow', 'scrollbars=yes,resizable=yes,toolbar=no,height='+height+',width='+width); 3352 HelpWin = window.open('%s' + helpurl, 'RoundupHelpWindow', 'scrollbars=yes,resizable=yes,toolbar=no,height='+height+',width='+width);
3352 HelpWin.focus () 3353 HelpWin.focus ()
3353 } 3354 }
3354 </script> 3355 </script>
3355 """%(self._client.client_nonce,self.base) 3356 """%(self._client.client_nonce, self.base)
3356 3357
3357 def batch(self, permission='View'): 3358 def batch(self, permission='View'):
3358 """ Return a batch object for results from the "current search" 3359 """ Return a batch object for results from the "current search"
3359 """ 3360 """
3360 check = self._client.db.security.hasPermission 3361 check = self._client.db.security.hasPermission

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