Index: doxygentrac/doxygentrac.py
===================================================================
--- doxygentrac/doxygentrac.py (revision 417)
+++ doxygentrac/doxygentrac.py (working copy)
@@ -6,14 +6,18 @@
from __future__ import generators
import os
+import os.path
import time
import posixpath
import re
+import mimetypes
from trac.core import *
from trac.web import IRequestHandler
from trac.web.chrome import INavigationContributor, ITemplateProvider
from trac.Search import ISearchSource
+from trac.perm import IPermissionRequestor
+from trac.wiki import IWikiSyntaxProvider
from trac.util import Markup
def compare_rank(x, y):
@@ -21,45 +25,84 @@
return 0
elif x['rank'] > y['rank']:
return -1
-
return 1
class DoxygenPlugin(Component):
- implements(INavigationContributor, IRequestHandler, ITemplateProvider, ISearchSource)
+ implements(IPermissionRequestor, INavigationContributor, IRequestHandler,
+ ITemplateProvider, ISearchSource, IWikiSyntaxProvider)
+ # IPermissionRequestor methods
+
+ def get_permission_actions(self):
+ return ['DOXYGEN_VIEW']
+
# INavigationContributor methods
def get_active_navigation_item(self, req):
return 'doxygen'
def get_navigation_items(self, req):
- yield ('mainnav', 'doxygen', Markup('Doxygen', self.env.href.doxygen()))
+ if not req.perm.has_permission('DOXYGEN_VIEW'):
+ return
+ yield 'mainnav', 'doxygen', Markup('%s' % \
+ (self.env.href.doxygen(), self.env.config.get('doxygen',
+ 'title', 'Doxygen')))
# IRequestHandler methods
def match_request(self, req):
- if req.path_info == '/doxygen':
- req.args['path'] = ''.join([self.config.get('doxygen', 'path'), '/main.html'])
+ # getting config values
+ ext = self.config.get('doxygen', 'ext')
+ if ext:
+ ext = '|'.join(ext.split(' '))
+ else:
+ ext = 'htm|html|png'
+
+ path = self.config.get('doxygen', 'path')
+ wiki_index = self.config.get('doxygen', 'wiki_index')
+
+ # don't know why my trac append slash at end of DoxygenPlugin URI.
+ if re.match('^%s[/]*$' % (self.env.href.doxygen()), req.path_info):
+ req.args['path'] = self.env.href.wiki(wiki_index)
+ req.args['type'] = 'index'
return True
- elif re.match(r'''^/.*[.]html$''', req.path_info):
- self.log.debug("path = %s" % (req.path_info))
- path = ''.join([self.config.get('doxygen', 'path'), req.path_info])
+ elif re.match('^%s/.*/search.php$' % (self.env.href.doxygen()),
+ req.path_info):
+ req.args['type'] = 'text/html'
+ return True
+ elif re.match('^%s/.*[.](%s)$' % (self.env.href.doxygen(), ext),
+ req.path_info):
+ file = re.sub('^%s' % (self.env.href.doxygen()), '', req.path_info)
+ path = self.env.href(path, file)
req.args['path'] = path
+ req.args['type'] = mimetypes.guess_type(path)[0]
return os.path.exists(path)
-
return False
def process_request(self, req):
- req.hdf['doxygen.path'] = req.args['path']
- return 'doxygen.cs', 'text/html'
+ if req.args.has_key('query'):
+ req.redirect('/search?q=%s&doxygen=on' % (req.args['query']))
+ return None
+ elif req.args['type'] == 'index':
+ req.redirect(req.args['path'])
+ return None
+ elif req.args['type'] == 'text/html':
+ req.hdf['doxygen.path'] = req.args['path']
+ else:
+ req.send_file(req.args['path'], req.args['type'])
+ return 'doxygen.cs', req.args['type']
# ITemplateProvider methods
+ def get_htdocs_dirs(self):
+ from pkg_resources import resource_filename
+ return [('doxygen', resource_filename(__name__, 'htdocs'))]
+
def get_templates_dirs(self):
from pkg_resources import resource_filename
return [resource_filename(__name__, 'templates')]
# ISearchProvider methods
-
+
def get_search_filters(self, req):
yield('doxygen', 'Doxygen')
@@ -70,34 +113,43 @@
keywords = [query[1:-1]]
else:
keywords = query.split(' ')
-
+
path = self.config.get('doxygen', 'path')
- path = ''.join([path, '/search.idx'])
- if os.path.exists(path):
- fd = open(path)
-
- results = []
- for keyword in keywords:
- results += self._search(fd, keyword)
-
- results.sort(compare_rank)
-
- # use the creation time for the search.idx file for all results
- creation = os.path.getctime(path)
+ for dir in os.listdir(path):
+ if os.path.isdir(os.path.join(path, dir)):
+ index = os.path.join(path, dir, 'search.idx')
+ fd = open(index)
- for result in results:
- yield result['url'], result['name'], creation, 'doxygen', None
-
+ results = []
+ for keyword in keywords:
+ results += self._search(fd, keyword)
+
+ results.sort(compare_rank)
+
+ # use the creation time for the search.idx file for all results
+ creation = os.path.getctime(path)
+
+ for result in results:
+ yield (self.env.href('doxygen', dir, str(result['url'])),
+ result['name'], creation, 'doxygen', None)
+
+ # IWikiSyntaxProvider
+ def get_link_resolvers(self):
+ yield ('doxygen', self._doxygen_link)
+
+ def get_wiki_syntax(self):
+ return []
+
# internal methods
-
+
def _search(self, fd, word):
results = []
index = self._computeIndex(word)
if index != -1:
fd.seek(index * 4 + 4, 0)
index = self._readInt(fd)
-
+
if index:
fd.seek(index)
w = self._readString(fd)
@@ -108,7 +160,7 @@
if w.find(low) != -1:
matches.append({'word' : word, 'match' : w, 'index' : statIdx, 'full' : len(low) == len(w)})
w = self._readString(fd)
-
+
count = 0
totalHi = 0
totalFreqHi = 0
@@ -121,7 +173,7 @@
fd.seek(match['index'])
numDocs = self._readInt(fd)
-
+
for i in range(numDocs):
idx = self._readInt(fd)
freq = self._readInt(fd)
@@ -131,7 +183,7 @@
totalFreqHi += freq * multiplier
else:
totalFreqLo += freq * multiplier
-
+
for i in range(numDocs):
fd.seek(results[count]['idx'])
name = self._readString(fd)
@@ -139,7 +191,7 @@
results[count]['name'] = name
results[count]['url'] = url
count += 1
-
+
totalFreq = (totalHi + 1) * totalFreqLo + totalFreqHi
for i in range(count):
freq = results[i]['freq']
@@ -148,40 +200,44 @@
results[i]['rank'] = float((freq * multi + totalFreqLo)) / float(totalFreq)
else:
results[i]['rank'] = float((freq * multi)) / float(totalFreq)
-
+
return results
def _computeIndex(self, word):
if len(word) < 2:
return -1
-
+
hi = ord(word[0].lower())
if hi == 0:
return -1
-
+
lo = ord(word[1].lower())
if lo == 0:
return -1
-
+
return hi * 256 + lo
-
+
def _readInt(self, fd):
b1 = fd.read(1)
b2 = fd.read(1)
b3 = fd.read(1)
b4 = fd.read(1)
-
+
return (ord(b1) << 24) | (ord(b2) << 16) | (ord(b3) << 8) | ord(b4)
-
-
+
def _readString(self, fd):
- byte = fd.read(1)
- if byte == '\0':
- return ""
- result = byte
- while byte != '\0':
- byte = fd.read(1)
- result = ''.join([result, byte])
-
- return result
+ result = ''
+ while True:
+ byte = fd.read(1)
+ if byte == '\0':
+ return result
+ else:
+ result = ''.join([result, byte])
+ def _doxygen_link(self, formatter, ns, params, label):
+ if ns == 'doxygen':
+ return '%s' % \
+ (self.env.href.doxygen(params), params, label)
+ else:
+ return '%s?' % \
+ (self.env.href.doxygen(), label)
Index: setup.py
===================================================================
--- setup.py (revision 417)
+++ setup.py (working copy)
@@ -42,5 +42,5 @@
""",
zip_safe=True,
packages=['doxygentrac'],
- package_data={'doxygentrac': ['templates/*.cs']},
+ package_data={'doxygentrac': ['templates/*.cs', 'htdocs/css/*.css']},
entry_points={'trac.plugins': 'doxygentrac = doxygentrac.doxygentrac'})