Changeset 3065 for breadcrumbsnavplugin
- Timestamp:
- 01/15/08 20:34:48 (10 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
breadcrumbsnavplugin/0.11/breadcrumbsnavplugin/breadcrumbs.py
r3050 r3065 1 from trac.core import Component, implements 2 from trac.config import Option, IntOption 1 from trac.core import Component, implements, TracError 2 from trac.config import Option, IntOption, ListOption 3 3 from trac.web import IRequestFilter 4 4 from trac.wiki import parse_args … … 8 8 from genshi.builder import tag 9 9 from genshi.filters.transform import Transformer 10 import re 10 import re, cPickle 11 from trac.env import IEnvironmentSetupParticipant 11 12 12 13 class BreadCrumbsSystem(Component): 13 implements(IRequestFilter, ITemplateProvider, ITemplateStreamFilter )14 implements(IRequestFilter, ITemplateProvider, ITemplateStreamFilter, IEnvironmentSetupParticipant) 14 15 15 16 ignore_pattern = Option('breadcrumbs', 'ignore pattern', None, … … 17 18 the breadcrumbs trail.""") 18 19 19 max_crumbs = IntOption('breadcrumbs', 'max crumbs', 6,20 max_crumbs = IntOption('breadcrumbs', 'max_crumbs', 6, 20 21 doc="""Indicates the maximum number of breadcrumbs to store per user.""") 21 22 23 supported_paths = ListOption('breadcrumbs', 'paths', '/wiki*,/ticket*,/milestone*', 24 doc='List of URL paths to allow breadcrumb tracking. Globs are supported.') 25 22 26 compiled_ignore_pattern = None 27 28 ## IEnvironmentSetupParticipant 29 def environment_created(self): 30 self._upgrade_db(self.env.get_db_cnx()) 31 32 def environment_needs_upgrade(self, db): 33 cursor = db.cursor() 34 35 try: 36 cursor.execute( 37 "SELECT count(*) FROM session_attribute WHERE name = %s", 38 ("breadcrumbs list",) 39 ) 40 result = cursor.fetchone() 41 if int(result[0]): 42 return True 43 44 return False 45 except: 46 db.rollback() 47 return True 48 49 def upgrade_environment(self, db): 50 self._upgrade_db(db) 51 52 def _upgrade_db(self, db): 53 try: 54 from trac.db import DatabaseManager 55 db_backend, _ = DatabaseManager(self.env)._get_connector() 56 57 cursor = db.cursor() 58 cursor.execute("DELETE FROM session_attribute WHERE name = %s", ("breadcrumbs list",)) 59 60 except Exception, e: 61 db.rollback() 62 self.log.error(e, exc_info=True) 63 raise TracError(str(e)) 64 23 65 24 66 ## IRequestFilter … … 27 69 return handler 28 70 29 def _get_crumbs(self, req): 30 sess = req.session 31 71 def _get_crumbs(self, sess): 32 72 crumbs = [] 33 if 'breadcrumbs list' in sess:34 raw = sess['breadcrumbs list']73 if 'breadcrumbs_list' in sess: 74 raw = sess['breadcrumbs_list'] 35 75 try: 36 crumbs = [x.replace('@COMMA@', ',') for x in raw.split(',')]76 crumbs = cPickle.loads(raw.encode('ascii', 'ignore')) 37 77 except: 38 pass78 del sess['breadcrumbs_list'] 39 79 40 80 return crumbs … … 43 83 if self.compiled_ignore_pattern is None and self.ignore_pattern: 44 84 self.compiled_ignore_pattern = re.compile(self.ignore_pattern) 85 86 path = req.path_info 87 try: 88 if path.count('/') >= 2: 89 _, realm, resource = path.split('/', 2) 45 90 46 try: 47 path = req.path_info 48 if path.count('/') >= 2: 49 _, realm, rest = path.split('/', 2) 91 supported = False 92 93 for pattern in self.supported_paths: 94 if re.match(pattern, path): 95 supported = True 96 break 50 97 51 if realm in ('wiki', 'ticket', 'milestone'): 52 if '#' in rest: 53 name = rest[0:rest.index('#')] 54 else: 55 name = rest 98 if not supported or (self.compiled_ignore_pattern and 99 self.compiled_ignore_pattern.match(resource)): 100 return template, data, content_type 101 102 if '&' in resource: 103 resource = resource[0:resource.index('&')] 104 105 sess = req.session 106 crumbs = self._get_crumbs(sess) 107 108 current = '/'.join( (realm, resource) ) 109 if current in crumbs: 110 crumbs.remove(current) 111 crumbs.insert(0, current) 112 else: 113 crumbs.insert(0, current) 114 crumbs = crumbs[0:self.max_crumbs] 56 115 57 if '&' in name: 58 name = name[0:name.index('&')] 59 60 id = name 61 if realm == "ticket": 62 name = "#" + name 63 64 if self.compiled_ignore_pattern and self.compiled_ignore_pattern.match(id): 65 return template, data, content_type 66 67 sess = req.session 68 69 crumbs = self._get_crumbs(req) 70 71 current = "%s:%s" % (name, req.href("%s/%s" % (realm, id))) 72 if current not in crumbs: 73 crumbs.insert(0, current) 74 crumbs = crumbs[0:self.max_crumbs] 75 else: 76 crumbs.remove(current) 77 crumbs.insert(0, current) 78 79 sess['breadcrumbs list'] = ','.join( 80 x.replace(',', '@COMMA@') for x in crumbs 81 ) 116 sess['breadcrumbs_list'] = cPickle.dumps(crumbs) 82 117 except: 83 118 self.log.exception("Breadcrumb failed :(") 84 119 85 120 86 121 return template, data, content_type 87 122 … … 98 133 99 134 def filter_stream(self, req, method, filename, stream, data): 100 crumbs = self._get_crumbs(req )135 crumbs = self._get_crumbs(req.session) 101 136 if not crumbs: 102 137 return stream … … 108 143 109 144 for crumb in crumbs: 110 title, link = crumb.split(':', 1) 145 realm, resource = crumb.split('/', 1) 146 name = resource.replace('_', ' ') 147 148 if realm == "ticket": 149 name = "#" + resource 150 elif realm != "wiki": 151 name = "%s:%s" % (realm, name) 152 153 link = req.href(realm, resource) 154 111 155 li.append( 112 156 tag.li( 113 tag.a(title= title, href=link,114 )( title)157 tag.a(title=name, href=link, 158 )(name) 115 159 ) 116 160 )
