~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2008-07-26 14:52:44 UTC
  • mto: This revision was merged to the branch mainline in revision 185.
  • Revision ID: john@arbash-meinel.com-20080726145244-l7h1ndtlu5mnm9tg
Add Copyright information to most files.

Fix the documentation for start/stop in the README.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# You should have received a copy of the GNU General Public License
16
16
# along with this program; if not, write to the Free Software
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
#
19
18
 
20
 
import logging
21
19
import re
22
 
import sys
23
20
import time
24
21
 
25
 
from configobj import ConfigObj
26
 
 
27
 
import turbogears
28
 
from turbogears import controllers
29
 
from cherrypy import HTTPRedirect, NotFound
30
 
 
31
 
my_config = ConfigObj('loggerhead.conf', encoding='utf-8')
32
 
extra_path = my_config.get('bzrpath', None)
33
 
if extra_path:
34
 
    sys.path.insert(0, extra_path)
 
22
from paste.request import path_info_pop, parse_querystring
35
23
 
36
24
from loggerhead import util
37
 
from loggerhead.branchview import BranchView
38
 
from loggerhead.history import History
39
 
 
40
 
log = logging.getLogger("loggerhead.controllers")
41
 
 
42
 
 
43
 
def cherrypy_friendly(s):
44
 
    """
45
 
    convert a config section name into a name that pleases cherrypy.
46
 
    """
47
 
    return re.sub(r'[^\w\d_]', '_', s)
48
 
 
49
 
 
50
 
class Group (object):
51
 
    def __init__(self, name, config):
52
 
        self.name = name
53
 
        self.friendly_name = config.get('name', name)
54
 
        self.description = config.get('description', '')
55
 
        
56
 
        self._views = []
57
 
        for view_name in config.sections:
58
 
            log.debug('Configuring (group %r) branch %r...', name, view_name)
59
 
            c_view_name = cherrypy_friendly(view_name)
60
 
            view = BranchView(name, c_view_name, config[view_name])
61
 
            self._views.append(view)
62
 
            setattr(self, c_view_name, view)
63
 
    
64
 
    views = property(lambda self: self._views)
65
 
 
66
 
 
67
 
class Root (controllers.RootController):
68
 
    def __init__(self):
69
 
        global my_config
70
 
        self._groups = []
71
 
        for group_name in my_config.sections:
72
 
            # FIXME: clean out any non-python chars
73
 
            c_group_name = cherrypy_friendly(group_name)
74
 
            group = Group(c_group_name, my_config[group_name])
75
 
            self._groups.append(group)
76
 
            setattr(self, c_group_name, group)
77
 
        
78
 
    @turbogears.expose(template='loggerhead.templates.browse')
79
 
    def index(self):
80
 
        return {
81
 
            'groups': self._groups,
 
25
from loggerhead.templatefunctions import templatefunctions
 
26
from loggerhead.zptsupport import load_template
 
27
 
 
28
class BufferingWriter(object):
 
29
 
 
30
    def __init__(self, writefunc, buf_limit):
 
31
        self.bytes = 0
 
32
        self.buf = []
 
33
        self.buflen = 0
 
34
        self.writefunc = writefunc
 
35
        self.bytes_saved = 0
 
36
        self.buf_limit = buf_limit
 
37
 
 
38
    def flush(self):
 
39
        chunk = ''.join(self.buf)
 
40
        chunk = re.sub(r'\s*\n\s*', '\n', chunk)
 
41
        chunk = re.sub(r'[ \t]+', ' ', chunk)
 
42
        self.bytes_saved += self.buflen - len(chunk)
 
43
        self.writefunc(chunk)
 
44
        self.buf = []
 
45
        self.buflen = 0
 
46
 
 
47
    def write(self, data):
 
48
        self.buf.append(data)
 
49
        self.buflen += len(data)
 
50
        self.bytes += len(data)
 
51
        if self.buflen > self.buf_limit:
 
52
            self.flush()
 
53
 
 
54
class TemplatedBranchView(object):
 
55
 
 
56
    template_path = None
 
57
 
 
58
    def __init__(self, branch, history):
 
59
        self._branch = branch
 
60
        self._history = history
 
61
        self.log = branch.log
 
62
 
 
63
    def __call__(self, environ, start_response):
 
64
        z = time.time()
 
65
        h = self._history
 
66
        kw = dict(parse_querystring(environ))
 
67
        util.set_context(kw)
 
68
        args = []
 
69
        while 1:
 
70
            arg = path_info_pop(environ)
 
71
            if arg is None:
 
72
                break
 
73
            args.append(arg)
 
74
 
 
75
        vals = {
 
76
            'branch': self._branch,
82
77
            'util': util,
83
 
            'title': my_config.get('title', ''),
 
78
            'history': h,
 
79
            'url': self._branch.context_url,
84
80
        }
85
 
 
86
 
    def _check_rebuild(self):
87
 
        for g in self._groups:
88
 
            for v in g.views:
89
 
                v.check_rebuild()
90
 
 
91
 
 
92
 
# singleton:
93
 
Root = Root()
94
 
 
95
 
# re-index every 6 hours
96
 
index_freq = 6 * 3600
97
 
 
98
 
turbogears.scheduler.add_interval_task(initialdelay=1, interval=index_freq, action=Root._check_rebuild)
99
 
 
100
 
# for use in profiling the very-slow get_change() method:
101
 
#h = util.get_history()
102
 
#w = list(h.get_revision_history())
103
 
#h._get_changes_profiled(w[:100])
104
 
 
 
81
        vals.update(templatefunctions)
 
82
        headers = {}
 
83
        vals.update(self.get_values(h, args, kw, headers))
 
84
 
 
85
        self.log.info('Getting information for %s: %r secs' % (
 
86
            self.__class__.__name__, time.time() - z,))
 
87
        if 'Content-Type' not in headers:
 
88
            headers['Content-Type'] = 'text/html'
 
89
        writer = start_response("200 OK", headers.items())
 
90
        template = load_template(self.template_path)
 
91
        z = time.time()
 
92
        w = BufferingWriter(writer, 8192)
 
93
        template.expand_into(w, **vals)
 
94
        w.flush()
 
95
        self.log.info('Rendering %s: %r secs, %s bytes, %s (%2.1f%%) bytes saved' % (
 
96
            self.__class__.__name__, time.time() - z, w.bytes, w.bytes_saved, 100.0*w.bytes_saved/w.bytes))
 
97
        return []