Changeset 52
- Timestamp:
- 03/07/08 15:30:10 (6 months ago)
- Files:
-
- branches/trac.upstream-r6669/cgi-bin/trac.cgi (modified) (1 prop)
- branches/trac.upstream-r6669/cgi-bin/trac.fcgi (modified) (1 prop)
- branches/trac.upstream-r6669/contrib/checkwiki.py (modified) (1 prop)
- branches/trac.upstream-r6669/contrib/htdigest.py (modified) (1 prop)
- branches/trac.upstream-r6669/contrib/htpasswd.py (added)
- branches/trac.upstream-r6669/contrib/rpm/makerpm (modified) (1 prop)
- branches/trac.upstream-r6669/contrib/trac-post-commit-hook (modified) (1 prop)
- branches/trac.upstream-r6669/contrib/workflow/migrate_original_to_basic.py (modified) (1 prop)
- branches/trac.upstream-r6669/contrib/workflow/showworkflow (modified) (1 prop)
- branches/trac.upstream-r6669/contrib/workflow/workflow_parser.py (modified) (1 prop)
- branches/trac.upstream-r6669/sample-plugins/permissions/vulnerability_tickets.py (modified) (2 diffs)
- branches/trac.upstream-r6669/setup.py (modified) (1 prop)
- branches/trac.upstream-r6669/trac/admin/console.py (modified) (1 prop)
- branches/trac.upstream-r6669/trac/admin/web_ui.py (modified) (3 diffs)
- branches/trac.upstream-r6669/trac/attachment.py (modified) (3 diffs)
- branches/trac.upstream-r6669/trac/db/mysql_backend.py (modified) (2 diffs)
- branches/trac.upstream-r6669/trac/htdocs/css/about.css (modified) (1 diff)
- branches/trac.upstream-r6669/trac/htdocs/css/report.css (modified) (1 diff)
- branches/trac.upstream-r6669/trac/htdocs/js/blame.js (modified) (1 diff)
- branches/trac.upstream-r6669/trac/htdocs/js/query.js (modified) (1 diff)
- branches/trac.upstream-r6669/trac/mimeview/rst.py (modified) (2 diffs)
- branches/trac.upstream-r6669/trac/resource.py (modified) (3 diffs)
- branches/trac.upstream-r6669/trac/templates/layout.html (modified) (2 diffs)
- branches/trac.upstream-r6669/trac/test.py (modified) (1 prop)
- branches/trac.upstream-r6669/trac/tests/config.py (modified) (1 diff)
- branches/trac.upstream-r6669/trac/ticket/admin.py (modified) (1 diff)
- branches/trac.upstream-r6669/trac/ticket/default_workflow.py (modified) (3 diffs)
- branches/trac.upstream-r6669/trac/ticket/model.py (modified) (2 diffs)
- branches/trac.upstream-r6669/trac/ticket/templates/ticket_notify_email.txt (modified) (1 diff)
- branches/trac.upstream-r6669/trac/ticket/web_ui.py (modified) (2 diffs)
- branches/trac.upstream-r6669/trac/util/compat.py (modified) (1 diff)
- branches/trac.upstream-r6669/trac/util/datefmt.py (modified) (1 diff)
- branches/trac.upstream-r6669/trac/versioncontrol/web_ui/browser.py (modified) (4 diffs)
- branches/trac.upstream-r6669/trac/versioncontrol/web_ui/util.py (modified) (1 diff)
- branches/trac.upstream-r6669/trac/web/cgi_frontend.py (modified) (1 prop)
- branches/trac.upstream-r6669/trac/web/chrome.py (modified) (2 diffs)
- branches/trac.upstream-r6669/trac/web/fcgi_frontend.py (modified) (1 prop)
- branches/trac.upstream-r6669/trac/web/standalone.py (modified) (1 prop)
- branches/trac.upstream-r6669/trac/wiki/macros.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/trac.upstream-r6669/cgi-bin/trac.cgi
- Property svn:executable set to *
branches/trac.upstream-r6669/cgi-bin/trac.fcgi
- Property svn:executable set to *
branches/trac.upstream-r6669/contrib/checkwiki.py
- Property svn:executable set to *
branches/trac.upstream-r6669/contrib/htdigest.py
- Property svn:executable set to *
branches/trac.upstream-r6669/contrib/rpm/makerpm
- Property svn:executable set to *
branches/trac.upstream-r6669/contrib/trac-post-commit-hook
- Property svn:executable set to *
branches/trac.upstream-r6669/contrib/workflow/migrate_original_to_basic.py
- Property svn:executable set to *
branches/trac.upstream-r6669/contrib/workflow/showworkflow
- Property svn:executable set to *
branches/trac.upstream-r6669/contrib/workflow/workflow_parser.py
- Property svn:executable set to *
branches/trac.upstream-r6669/sample-plugins/permissions/vulnerability_tickets.py
r46 r52 2 2 from trac.perm import IPermissionPolicy, IPermissionRequestor 3 3 4 revision = "$Rev: 2$"4 revision = "$Rev: 41 $" 5 5 url = "$URL: /mirror/sample-plugins/permissions/vulnerability_tickets.py $" 6 6 … … 41 41 db = self.env.get_db_cnx() 42 42 cursor = db.cursor() 43 for keywords, summary in cursor.execute("SELECT keywords, summary "44 " FROM ticket WHERE id=%s",45 (resource.id,)):43 cursor.execute("SELECT keywords, summary FROM ticket WHERE id=%s", 44 (resource.id,)) 45 for keywords, summary in cursor: 46 46 fields = ''.join([f for f in (keywords, summary) if f]).lower() 47 47 if 'security' in fields or 'vulnerability' in fields: branches/trac.upstream-r6669/setup.py
- Property svn:executable set to *
branches/trac.upstream-r6669/trac/admin/console.py
- Property svn:executable set to *
branches/trac.upstream-r6669/trac/admin/web_ui.py
r46 r52 31 31 from trac.util import get_pkginfo, get_module_path 32 32 from trac.util.compat import partial 33 from trac.util.text import to_unicode 33 34 from trac.util.translation import _ 34 35 from trac.web import HTTPNotFound, IRequestHandler … … 396 397 raise TracError(_('No file uploaded')) 397 398 upload = req.args['plugin_file'] 398 if not upload.filename:399 if isinstance(upload, unicode) or not upload.filename: 399 400 raise TracError(_('No file uploaded')) 400 401 plugin_filename = upload.filename.replace('\\', '/').replace(':', '/') … … 481 482 plugin_filename = os.path.basename(dist.location) 482 483 483 description = inspect.getdoc(component)484 description = to_unicode(inspect.getdoc(component)) 484 485 if description: 485 486 description = description.split('.', 1)[0] + '.' branches/trac.upstream-r6669/trac/attachment.py
r46 r52 372 372 parent_id = '/'.join(segments[:-1]) 373 373 filename = len(segments) > 1 and segments[-1] 374 if not filename: # if there's a trailing '/', show the list375 return self._render_list(req, parent_realm(id=parent_id))376 374 377 375 parent = parent_realm(id=parent_id) 376 377 # Link the attachment page to parent resource 378 parent_name = get_resource_name(self.env, parent) 379 parent_url = get_resource_url(self.env, parent, req.href) 380 add_link(req, 'up', parent_url, parent_name) 381 add_ctxtnav(req, _('Back to %(parent)s', parent=parent_name), 382 parent_url) 383 384 if action != 'new' and not filename: 385 # there's a trailing '/', show the list 386 return self._render_list(req, parent) 387 378 388 attachment = Attachment(self.env, parent.child('attachment', filename)) 379 380 add_link(req, 'up', get_resource_url(self.env, parent, req.href),381 get_resource_name(self.env, parent))382 389 383 390 if req.method == 'POST': … … 394 401 395 402 add_stylesheet(req, 'common/css/code.css') 396 add_ctxtnav(req, _('Back to %(parent)s',397 parent=get_resource_name(self.env, parent)),398 req.chrome['links']['up'][0]['href'])399 403 return 'attachment.html', data, None 400 404 … … 613 617 } 614 618 615 add_link(req, 'up', get_resource_url(self.env, parent, req.href),616 get_resource_name(self.env, parent))617 618 619 return 'attachment.html', data, None 619 620 620 621 def _render_view(self, req, attachment): 621 622 req.perm(attachment.resource).require('ATTACHMENT_VIEW') 622 req.check_modified(attachment.date) 623 can_delete = 'ATTACHMENT_DELETE' in req.perm(attachment.resource) 624 req.check_modified(attachment.date, str(can_delete)) 623 625 624 626 data = {'mode': 'view', branches/trac.upstream-r6669/trac/db/mysql_backend.py
r46 r52 1 # -*- coding: iso8859-1-*-1 # -*- coding: utf-8 -*- 2 2 # 3 3 # Copyright (C) 2005-2006 Edgewall Software … … 177 177 if type == 'int': 178 178 type = 'signed' 179 elif type == 'text': 180 type = 'char' 179 181 return 'CAST(%s AS %s)' % (column, type) 180 182 branches/trac.upstream-r6669/trac/htdocs/css/about.css
r46 r52 14 14 padding: 3px; 15 15 } 16 #content.about #config td.value { font-family: monospace; } 17 #content.about #config tr.modified { background: #fee; } 18 #content.about #config tr.modified td.value { font-weight: bold; } 16 #content.about #config tr.modified { background: #ffd; } 17 #content.about #config tr.modified td.value { font-style: italic; } 19 18 #content.about #config td.doc { padding: 3px 1em; } branches/trac.upstream-r6669/trac/htdocs/css/report.css
r46 r52 21 21 #query fieldset, #query fieldset input, #query fieldset select { font-size: 11px } 22 22 #query fieldset { margin-top: 1em } 23 #query fieldset.collapsed { border-width: 0 } 23 #query fieldset.collapsed { 24 border-width: 0; 25 margin-bottom: 0pt; 26 padding: 0pt .5em; 27 } 24 28 #query .option, #query .option input, #query .option select { font-size: 11px } 25 29 #query .option { float: left; line-height: 2em; margin: .9em 2.5em 0 .5em; padding: 0 0 .1em } branches/trac.upstream-r6669/trac/htdocs/js/blame.js
r46 r52 79 79 80 80 // workaround non-clickable "Close" issue in Firefox 81 if ($.browser == 'mozilla')81 if ($.browser.mozilla) 82 82 message.find("div.inlinebuttons").next().css("clear", "right"); 83 83 branches/trac.upstream-r6669/trac/htdocs/js/query.js
r46 r52 134 134 // Convenience function for creating an <input type="radio"> 135 135 function createRadio(name, value, id) { 136 var input = document.createElement("input"); 137 input.type = "radio"; 138 if (name) input.name = name; 139 if (value) input.value = value; 140 if (id) input.id = id; 141 return input; 136 var str = '<input type="radio"'; 137 if (name) str += ' name="' + name + '"'; 138 if (value) str += ' value="' + value + '"'; 139 if (id) str += ' id="' + id + '"'; 140 str += '/>'; 141 var span = document.createElement('span'); 142 // create radio button with innerHTML to avoid IE mangling it. 143 span.innerHTML = str; 144 return span; 142 145 } 143 146 branches/trac.upstream-r6669/trac/mimeview/rst.py
r46 r52 27 27 from distutils.version import StrictVersion 28 28 import re 29 try: 30 from docutils import nodes 31 from docutils.core import publish_parts 32 from docutils.parsers import rst 33 from docutils import __version__ 34 has_docutils = True 35 except ImportError: 36 has_docutils = False 29 37 30 38 from trac.core import * … … 48 56 49 57 def render(self, context, mimetype, content, filename=None, rev=None): 50 try: 51 from docutils import nodes 52 from docutils.core import publish_parts 53 from docutils.parsers import rst 54 from docutils import __version__ 55 except ImportError: 58 global has_docutils 59 if not has_docutils: 56 60 raise TracError(_('Docutils not found')) 57 61 if StrictVersion(__version__) < StrictVersion('0.3.9'): branches/trac.upstream-r6669/trac/resource.py
r46 r52 105 105 if r.id: 106 106 name += ':' + unicode(r.id) # id can be numerical 107 if r.version :107 if r.version is not None: 108 108 name += '@' + unicode(r.version) 109 109 path.append(name) … … 149 149 "<Resource u'wiki:WikiStart@3'>" 150 150 151 >>> main0 = main3(version=0) 152 >>> repr(main0) 153 "<Resource u'wiki:WikiStart@0'>" 154 151 155 In a copy, if `id` is overriden, then the original `version` value 152 156 will not be reused. … … 160 164 realm = resource_or_realm 161 165 if isinstance(resource_or_realm, Resource): 162 if (id, version, parent) == (False, False, False):166 if id is False and version is False and parent is False: 163 167 return resource_or_realm 164 168 else: # copy and override branches/trac.upstream-r6669/trac/templates/layout.html
r46 r52 39 39 <div id="banner"> 40 40 <div id="header" py:choose=""> 41 <a py:when="chrome.logo.src" id="logo" href="${chrome.logo.link }"><img41 <a py:when="chrome.logo.src" id="logo" href="${chrome.logo.link or href.wiki('TracIni')+'#header_logo-section'}"><img 42 42 src="${chrome.logo.src}" alt="${chrome.logo.alt}" 43 43 height="${chrome.logo.height or None}" width="${chrome.logo.width or None}" /></a> … … 90 90 <script type="text/javascript" py:if="chrome.late_links"> 91 91 <py:for each="link in chrome.late_links.get('stylesheet')"> 92 $.loadStyleSheet("${link.href}", "${link.title}");92 jQuery.loadStyleSheet("${link.href}", "${link.title}"); 93 93 </py:for> 94 94 </script> branches/trac.upstream-r6669/trac/test.py
- Property svn:executable set to *
branches/trac.upstream-r6669/trac/tests/config.py
r46 r52 212 212 config = self._read() 213 213 self.assertEquals('x', config.get('a', 'option')) 214 time.sleep(1) # needed because of low mtime granularity 214 time.sleep(2) # needed because of low mtime granularity, 215 # especially on fat filesystems 215 216 216 217 self._write(['[a]', 'option = y']) branches/trac.upstream-r6669/trac/ticket/admin.py
r46 r52 114 114 in self.env.get_known_users() 115 115 if valid_owner(username)] 116 data['owners'].insert(0, '') 117 data['owners'].sort() 116 118 else: 117 119 data['owners'] = None branches/trac.upstream-r6669/trac/ticket/default_workflow.py
r46 r52 216 216 hints = [] 217 217 if 'reset_workflow' in operations: 218 control.append(tag("from invalid state "))218 control.append(tag("from invalid state ")) 219 219 hints.append(_("Current state no longer exists")) 220 220 if 'del_owner' in operations: … … 240 240 hints.append(_("The owner will change")) 241 241 elif len(owners) == 1: 242 control.append(tag('to %s ' % owners[0]))242 control.append(tag('to %s ' % owners[0])) 243 243 hints.append(_("The owner will change to %s") % owners[0]) 244 244 else: … … 272 272 hints.append(_("The resolution will be set")) 273 273 if 'leave_status' in operations: 274 control.append('as ' +ticket['status'])274 control.append('as %s ' % ticket['status']) 275 275 else: 276 276 if status != '*': branches/trac.upstream-r6669/trac/ticket/model.py
r46 r52 613 613 raise ResourceNotFound('Milestone %s does not exist.' % name, 614 614 'Invalid Milestone Name') 615 self._from_database(row) 616 617 exists = property(fget=lambda self: self._old_name is not None) 618 is_completed = property(fget=lambda self: self.completed is not None) 619 is_late = property(fget=lambda self: self.due and \ 620 self.due.date() < date.today()) 621 622 def _from_database(self, row): 615 623 name, due, completed, description = row 616 self.name = name624 self.name = self._old_name = name 617 625 self.due = due and datetime.fromtimestamp(int(due), utc) or None 618 626 self.completed = completed and \ 619 627 datetime.fromtimestamp(int(completed), utc) or None 620 628 self.description = description or '' 621 622 exists = property(fget=lambda self: self._old_name is not None)623 is_completed = property(fget=lambda self: self.completed is not None)624 is_late = property(fget=lambda self: self.due and \625 self.due.date() < date.today())626 629 627 630 def delete(self, retarget_to=None, author=None, db=None): … … 702 705 cursor.execute(sql) 703 706 milestones = [] 704 for name,due,completed,descriptionin cursor:707 for row in cursor: 705 708 milestone = Milestone(env) 706 milestone.name = milestone._old_name = name 707 milestone.due = due and datetime.fromtimestamp(int(due), utc) or None 708 if completed: 709 milestone.completed = datetime.fromtimestamp(int(completed), utc) 710 else: 711 milestone.completed = None 712 milestone.description = description or '' 709 milestone._from_database(row) 713 710 milestones.append(milestone) 714 711 def milestone_order(m): branches/trac.upstream-r6669/trac/ticket/templates/ticket_notify_email.txt
r46 r52 29 29 -- 30 30 Ticket URL: <$ticket.link> 31 $project.name <${ abs_href()}>31 $project.name <${project.url or abs_href()}> 32 32 $project.descr branches/trac.upstream-r6669/trac/ticket/web_ui.py
r46 r52 179 179 sql, args = search_to_sql(db, ['b.newvalue'], terms) 180 180 sql2, args2 = search_to_sql(db, ['summary', 'keywords', 'description', 181 'reporter', 'cc', 'id'], terms) 181 'reporter', 'cc', 182 db.cast('id', 'text')], terms) 182 183 cursor = db.cursor() 183 184 cursor.execute("SELECT DISTINCT a.summary,a.description,a.reporter, " … … 413 414 'view')) 414 415 415 data = {'ticket': ticket, 'comment': None}416 416 data = self._prepare_data(req, ticket) 417 417 data['comment'] = None branches/trac.upstream-r6669/trac/util/compat.py
r46 r52 66 66 return _getitem 67 67 68 class py_groupby(object): 69 def __init__(self, iterable, key=None): 70 if key is None: 71 key = lambda x: x 72 self.keyfunc = key 73 self.it = iter(iterable) 74 self.tgtkey = self.currkey = self.currvalue = xrange(0) 75 def __iter__(self): 76 return self 77 def next(self): 78 while self.currkey == self.tgtkey: 79 self.currvalue = self.it.next() # Exit on StopIteration 80 self.currkey = self.keyfunc(self.currvalue) 81 self.tgtkey = self.currkey 82 return (self.currkey, self._grouper(self.tgtkey)) 83 def _grouper(self, tgtkey): 84 while self.currkey == tgtkey: 85 yield self.currvalue 86 self.currvalue = self.it.next() # Exit on StopIteration 87 self.currkey = self.keyfunc(self.currvalue) 68 88 try: 69 89 from itertools import groupby 70 90 except ImportError: 71 class groupby(object): 72 def __init__(self, iterable, key=None): 73 if key is None: 74 key = lambda x: x 75 self.keyfunc = key 76 self.it = iter(iterable) 77 self.tgtkey = self.currkey = self.currvalue = xrange(0) 78 def __iter__(self): 79 return self 80 def next(self): 81 while self.currkey == self.tgtkey: 82 self.currvalue = self.it.next() # Exit on StopIteration 83 self.currkey = self.keyfunc(self.currvalue) 84 self.tgtkey = self.currkey 85 return (self.currkey, self._grouper(self.tgtkey)) 86 def _grouper(self, tgtkey): 87 while self.currkey == tgtkey: 88 yield self.currvalue 89 self.currvalue = self.it.next() # Exit on StopIteration 90 self.currkey = self.keyfunc(self.currvalue) 91 groupby = py_groupby 91 92 92 93 try: branches/trac.upstream-r6669/trac/util/datefmt.py
r46 r52 82 82 if resolution and age_s < resolution: 83 83 return '' 84 if age_s < 60:84 if age_s <= 60 * 1.9: 85 85 return '%i second%s' % (age_s, age_s != 1 and 's' or '') 86 86 for u, unit, unit_plural in units: 87 87 r = float(age_s) / float(u) 88 if r >= 0.9:88 if r >= 1.9: 89 89 r = int(round(r)) 90 90 return '%d %s' % (r, r == 1 and unit or unit_plural) branches/trac.upstream-r6669/trac/versioncontrol/web_ui/browser.py
r46 r52 330 330 order = req.args.get('order', None) 331 331 desc = req.args.get('desc', None) 332 xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest' 332 333 333 334 # Find node for the requested path/rev … … 355 356 'created_path': node.created_path, 356 357 'created_rev': node.created_rev, 357 'properties': self.render_properties('browser', context,358 node.get_properties()),358 'properties': xhr or self.render_properties('browser', context, 359 node.get_properties()), 359 360 'path_links': path_links, 360 361 'dir': node.isdir and self._render_dir(req, repos, node, rev), 361 362 'file': node.isfile and self._render_file(req, context, repos, 362 363 node, rev), 363 'quickjump_entries': list(repos.get_quickjump_entries(rev)),364 'quickjump_entries': xhr or list(repos.get_quickjump_entries(rev)), 364 365 'wiki_format_messages': 365 366 self.config['changeset'].getbool('wiki_format_messages') 366 367 } 368 if xhr: # render and return the content only 369 data['xhr'] = True 370 return 'dir_entries.html', data, None 371 372 # Links for contextual navigation 367 373 add_ctxtnav(req, tag.a(_('Last Change'), 368 374 href=req.href.changeset(node.rev, node.created_path))) … … 381 387 rev=node.rev, 382 388 annotate=1)) 383 384 389 add_ctxtnav(req, _('Revision Log'), 385 390 href=req.href.log(path, rev=rev)) 386 391 387 xhr = req.get_header('X-Requested-With') == 'XMLHttpRequest'388 if xhr: # render and return the content only389 data['xhr'] = True390 return 'dir_entries.html', data, None391 392 392 add_stylesheet(req, 'common/css/browser.css') 393 393 return 'browser.html', data, None … … 399 399 400 400 # Entries metadata 401 entries = list(node.get_entries()) 401 class entry(object): 402 __slots__ = 'name rev kind isdir path content_length'.split() 403 def __init__(self, node): 404 for f in entry.__slots__: 405 setattr(self, f, getattr(n, f)) 406 407 entries = [entry(n) for n in node.get_entries()] 402 408 changes = get_changes(repos, [i.rev for i in entries]) 403 409 branches/trac.upstream-r6669/trac/versioncontrol/web_ui/util.py
r46 r52 33 33 changes = {} 34 34 for rev in revs: 35 if rev in changes: 36 continue 35 37 try: 36 38 changeset = repos.get_changeset(rev) branches/trac.upstream-r6669/trac/web/cgi_frontend.py
- Property svn:executable set to *
branches/trac.upstream-r6669/trac/web/chrome.py
r46 r52 255 255 listed by IDs. See also TracNavigation.""") 256 256 257 logo_link = Option('header_logo', 'link', ' http://example.org/',257 logo_link = Option('header_logo', 'link', '', 258 258 """URL to link to from header logo.""") 259 259 260 logo_src = Option('header_logo', 'src', ' common/trac_banner.png',260 logo_src = Option('header_logo', 'src', 'site/your_project_logo.png', 261 261 """URL of the image to use as header logo.""") 262 262 263 logo_alt = Option('header_logo', 'alt', '', 263 logo_alt = Option('header_logo', 'alt', 264 "(please configure the [header_logo] section in trac.ini)", 264 265 """Alternative text for the header logo.""") 265 266 … … 289 290 'gettext': translation.gettext, 290 291 'group': presentation.group, 291 'groupby': compat. groupby,292 'groupby': compat.py_groupby, 292 293 'http_date': http_date, 293 294 'istext': presentation.istext, branches/trac.upstream-r6669/trac/web/fcgi_frontend.py
- Property svn:executable set to *
branches/trac.upstream-r6669/trac/web/standalone.py
- Property svn:executable set to *
branches/trac.upstream-r6669/trac/wiki/macros.py
r46 r52 30 30 from trac.util.compat import sorted, groupby, any, set 31 31 from trac.util.html import escape 32 from trac.util.text import unquote 32 from trac.util.text import unquote, to_unicode 33 33 from trac.util.translation import _ 34 34 from trac.wiki.api import IWikiMacroProvider, WikiSystem, parse_args … … 54 54 def get_macro_description(self, name): 55 55 """Return the subclass's docstring.""" 56 return inspect.getdoc(self.__class__)56 return to_unicode(inspect.getdoc(self.__class__)) 57 57 58 58 def parse_macro(self, parser, name, content):