~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/__init__.py

  • Committer: Michael Hudson
  • Date: 2010-05-07 01:03:17 UTC
  • mfrom: (414.1.1 loggerhead)
  • Revision ID: michael.hudson@canonical.com-20100507010317-kr5ipx6qgn65636o
(mkanat) use a global lock to protect access to the lru cache

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
 
2
# Copyright (C) 2008  Canonical Ltd.
2
3
# Copyright (C) 2006  Robey Pointer <robey@lag.net>
3
4
# Copyright (C) 2006  Goffredo Baroncelli <kreijack@inwind.it>
4
5
#
15
16
# You should have received a copy of the GNU General Public License
16
17
# along with this program; if not, write to the Free Software
17
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
#
19
19
 
20
 
import logging
21
 
import sys
22
20
import time
23
21
 
24
 
from configobj import ConfigObj
25
 
 
26
 
import turbogears
27
 
from turbogears import controllers
28
 
from cherrypy import HTTPRedirect, NotFound
29
 
 
30
 
my_config = ConfigObj('loggerhead.conf', encoding='utf-8')
31
 
extra_path = my_config.get('bzrpath', None)
32
 
if extra_path:
33
 
    sys.path.insert(0, extra_path)
 
22
from paste.request import path_info_pop, parse_querystring
34
23
 
35
24
from loggerhead import util
36
 
from loggerhead.branchview import BranchView
37
 
from loggerhead.history import History
38
 
 
39
 
log = logging.getLogger("loggerhead.controllers")
40
 
 
41
 
 
42
 
class Root (controllers.RootController):
43
 
    def __init__(self):
44
 
        global my_config
45
 
        self._views = []
46
 
        for branch_name in my_config.sections:
47
 
            log.debug('Configuring branch %r...', branch_name)
48
 
            view = BranchView(branch_name, my_config[branch_name])
49
 
            setattr(self, branch_name, view)
50
 
            self._views.append(view)
51
 
        
52
 
    @turbogears.expose()
53
 
    def index(self):
54
 
        # FIXME - display list of branches
55
 
        raise HTTPRedirect(turbogears.url('/bazaar-dev/changes'))
56
 
 
57
 
    def check_rebuild(self):
58
 
        for v in self._views:
59
 
            v.check_rebuild()
60
 
 
61
 
 
62
 
# singleton:
63
 
Root = Root()
64
 
 
65
 
# re-index every 6 hours
66
 
index_freq = 6 * 3600
67
 
 
68
 
turbogears.scheduler.add_interval_task(initialdelay=1, interval=index_freq, action=Root.check_rebuild)
69
 
 
70
 
# for use in profiling the very-slow get_change() method:
71
 
#h = util.get_history()
72
 
#w = list(h.get_revision_history())
73
 
#h._get_changes_profiled(w[:100])
74
 
 
 
25
from loggerhead.templatefunctions import templatefunctions
 
26
from loggerhead.zptsupport import load_template
 
27
 
 
28
 
 
29
class BufferingWriter(object):
 
30
 
 
31
    def __init__(self, writefunc, buf_limit):
 
32
        self.bytes = 0
 
33
        self.buf = []
 
34
        self.buflen = 0
 
35
        self.writefunc = writefunc
 
36
        self.buf_limit = buf_limit
 
37
 
 
38
    def flush(self):
 
39
        self.writefunc(''.join(self.buf))
 
40
        self.buf = []
 
41
        self.buflen = 0
 
42
 
 
43
    def write(self, data):
 
44
        self.buf.append(data)
 
45
        self.buflen += len(data)
 
46
        self.bytes += len(data)
 
47
        if self.buflen > self.buf_limit:
 
48
            self.flush()
 
49
 
 
50
 
 
51
class TemplatedBranchView(object):
 
52
 
 
53
    template_path = None
 
54
 
 
55
    def __init__(self, branch, history_callable):
 
56
        self._branch = branch
 
57
        self._history_callable = history_callable
 
58
        self.__history = None
 
59
        self.log = branch.log
 
60
 
 
61
    @property
 
62
    def _history(self):
 
63
        if self.__history is not None:
 
64
            return self.__history
 
65
        self.__history = self._history_callable()
 
66
        return self.__history
 
67
 
 
68
    def __call__(self, environ, start_response):
 
69
        z = time.time()
 
70
        kwargs = dict(parse_querystring(environ))
 
71
        util.set_context(kwargs)
 
72
        args = []
 
73
        while True:
 
74
            arg = path_info_pop(environ)
 
75
            if arg is None:
 
76
                break
 
77
            args.append(arg)
 
78
 
 
79
        path = None
 
80
        if len(args) > 1:
 
81
            path = unicode('/'.join(args[1:]), 'utf-8')
 
82
        self.args = args
 
83
 
 
84
        vals = {
 
85
            'static_url': self._branch.static_url,
 
86
            'branch': self._branch,
 
87
            'util': util,
 
88
            'url': self._branch.context_url,
 
89
        }
 
90
        vals.update(templatefunctions)
 
91
        headers = {}
 
92
 
 
93
        vals.update(self.get_values(path, kwargs, headers))
 
94
 
 
95
        self.log.info('Getting information for %s: %r secs' % (
 
96
            self.__class__.__name__, time.time() - z))
 
97
        if 'Content-Type' not in headers:
 
98
            headers['Content-Type'] = 'text/html'
 
99
        writer = start_response("200 OK", headers.items())
 
100
        template = load_template(self.template_path)
 
101
        z = time.time()
 
102
        w = BufferingWriter(writer, 8192)
 
103
        template.expand_into(w, **vals)
 
104
        w.flush()
 
105
        self.log.info(
 
106
            'Rendering %s: %r secs, %s bytes' % (
 
107
                self.__class__.__name__, time.time() - z, w.bytes))
 
108
        return []
 
109
 
 
110
    def get_revid(self):
 
111
        h = self._history
 
112
        if h is None:
 
113
            return None
 
114
        if len(self.args) > 0 and self.args != ['']:
 
115
            return h.fix_revid(self.args[0])
 
116
        else:
 
117
            return h.last_revid