gminick / sphinx-gsoc2009

fork of sphinx

A support for per-paragraph comments and user/developer interface for submitting/committing fixes.

commit 1569: ae72a8b254e8
parent 1568: 413f8c6b53f2
branch: default
Add basics for theming on webapp level
Wojtek Walczak / gminick
7 months ago

Changed (Δ2.0 KB):

raw changeset »

sphinx/builders/webapp/webapp.py (6 lines added, 4 lines removed)

sphinx/web/middleware/appserver.py (96 lines added, 44 lines removed)

Up to file-list sphinx/builders/webapp/webapp.py:

@@ -101,10 +101,12 @@ class WebAppBuilder(SerializingHTMLBuild
101
101
            except Exception, err:
102
102
                raise SphinxError(err)
103
103
104
        src_dir = path.join(path.dirname(__file__), '../../themes/basic/static')
105
        dst_dir = path.join(self.outdir, 'public/_static')
106
        shutil.copytree(src_dir, dst_dir)
107
104
        sphinx_dirs = (('../../themes/basic/static', 'public/_static'),
105
                       ('../../themes', 'themes'))
106
        for sdir in sphinx_dirs:
107
            src_dir = path.join(path.dirname(__file__), sdir[0])
108
            dst_dir = path.join(self.outdir, sdir[1])
109
            shutil.copytree(src_dir, dst_dir)
108
110
109
111
    ###
110
112
    ### Xapian search engine

Up to file-list sphinx/web/middleware/appserver.py:

10
10
    :license: BSD, see LICENSE for details.
11
11
"""
12
12
13
import json
13
try:
14
    import json
15
except ImportError:
16
    try:
17
        import simplejson as json
18
    except ImportError:
19
        raise ImportError('json module not found')
20
21
import os
14
22
import time
15
23
import locale
16
24
import cPickle
17
25
from os import path
18
from hashlib import md5
19
26
from difflib import Differ
20
27
21
28
from jinja2 import Environment, FileSystemLoader, Template
22
29
from webob import Request, Response
23
30
24
from sphinx.application import TemplateBridge
31
from sphinx.application import TemplateBridge, Sphinx
32
from sphinx.environment import BuildEnvironment
25
33
from sphinx.errors import SphinxError
34
from sphinx.highlighting import PygmentsBridge
35
from sphinx.jinja2glue import BuiltinTemplateLoader
26
36
from sphinx.theming import Theme
37
from sphinx.builders.html import StandaloneHTMLBuilder
38
from sphinx.util import relative_uri
39
from sphinx.writers.html import HTMLTranslator
27
40
28
# it's here only temporarily, until I get all the theming problems resolved
41
29
42
tmp_template = """
30
<html>
31
<head>
32
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
33
<link rel="stylesheet" href="_static/basic.css" type="text/css" />
34
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
35
<script type="text/javascript">
36
    var DOCUMENTATION_OPTIONS = {
37
       URL_ROOT:    '',
38
       VERSION:     '0.5.2',
39
       COLLAPSE_MODINDEX: false,
40
       FILE_SUFFIX: '.html',
41
       HAS_SOURCE:  true
42
    };
43
</script>
44
<script type="text/javascript" src="_static/jquery.js"></script>
45
<script type="text/javascript" src="_static/jquery.form.js"></script>
46
<script type="text/javascript" src="_static/comments.js"></script>
47
<script type="text/javascript" src="_static/doctools.js"></script>
48
</head>
49
<body>
50
{{ body }}
51
</body>
52
</html>
43
{%% extends "basic/layout.html" %%}
44
{%% block body %%} %(body)s {%% endblock %%}
53
45
"""
54
46
47
55
48
def load_comments(db_path):
56
49
    """Open a 'db_path' file, dejsonify the loaded data and return it.
57
50
    On error return empty list."""
@@ -154,6 +147,63 @@ def get_sorted_by_thread(data):
154
147
    return comments_sorted
155
148
156
149
150
class SinglefileHTMLBuilder(StandaloneHTMLBuilder, Sphinx):
151
    """Render a file when requested using data from a pickled archive.
152
    Handle theming."""
153
    def __init__(self, www_dir):
154
        self.outdir = www_dir
155
156
        try:
157
            w = open(path.join(self.outdir, 'globalcontext.pickle'))
158
            self.globalcontext = cPickle.load(w)
159
            w.close()
160
        except Exception, err:
161
            raise SphinxError(err)
162
 
163
        self.cwd = os.getcwd()
164
        self.srcdir = self.cwd
165
        self.confdir = self.cwd
166
        self.doctreedir = path.join(self.cwd, www_dir)
167
168
        self.env = None
169
        self.freshenv = None
170
171
#        self.config = {}
172
#        self.env = BuildEnvironment.frompickle(self.config, self.envdir)
173
#        self.config = self.env.config
174
175
        confdir = path.join(self.cwd, '../../')
176
        self.app = Sphinx(self.srcdir, confdir, '.', 'public', 'html', {}, None)
177
        self.info = self.app.info
178
        self.warn = self.app.warn
179
        self.config = self.app.config
180
        self.config.html_theme_path = 'themes/' + self.config.html_theme
181
182
        self.load_i18n()
183
        self.load_env()
184
185
        StandaloneHTMLBuilder.init(self)
186
        self.style = self.theme.get_confstr('theme', 'stylesheet')
187
188
    def render_file(self, filename, ctx):
189
        ctx.update(self.globalcontext.copy())
190
        # current_page_name is backwards compatibility
191
        ctx['pagename'] = ctx['current_page_name'] = filename
192
        def pathto(otheruri, resource=False,
193
                   baseuri=self.get_target_uri(filename)):
194
            if not resource:
195
                otheruri = self.get_target_uri(otheruri)
196
            return relative_uri(baseuri, otheruri)
197
        ctx['pathto'] = pathto
198
        ctx['hasdoc'] = lambda name: name in self.env.all_docs
199
        pgname = path.basename(filename).split('.')[0]
200
        ctx['customsidebar'] = self.config.html_sidebars.get(pgname)
201
        ctx['encoding'] = encoding = self.config.html_output_encoding
202
        ctx['toctree'] = lambda **kw: self._get_local_toctree(filename, **kw)
203
        ctx['style'] = self.style
204
        
205
        return self.templates.render_string(tmp_template % (ctx), ctx)
206
157
207
class AppServer(object):
158
208
    """This middleware is responsible for serving the docs (the docs are
159
209
    pickled files, so it has to load a file from a pickle) and for handling
@@ -165,6 +215,7 @@ class AppServer(object):
165
215
        self.www_dir = www_dir
166
216
        self.template_vals = {}
167
217
218
        self.htmlbuilder = SinglefileHTMLBuilder(self.www_dir)
168
219
        self.init_templates()
169
220
170
221
        # an argument for 'reverse' option of sorted function:
@@ -197,21 +248,7 @@ class AppServer(object):
197
248
        elif SW('/fixes/'):
198
249
            resp = self.doReadFixes(req, resp)
199
250
        elif req.path.endswith('.html'):
200
            file_path = self.constructPath(req)
201
            try:
202
                if file_path.endswith('.pkl'):
203
                    file_contents = cPickle.loads(open(file_path).read())['body']
204
                else:
205
                    file_contents = open(file_path, 'rb').read()
206
            except:
207
                file_contents = '<html><body>doHTMLFile(): 404!</body></html>'
208
209
            resp.status = 200
210
            resp.body = file_contents.encode('utf8')
211
212
            # Regular HTML file
213
            if req.path.endswith('.html'):
214
                resp = self.doHTMLFile(req, resp)
251
            resp = self.doHTMLFile(req, resp)
215
252
        else:
216
253
            return self.app(environ, start_response)
217
254
@@ -380,7 +417,21 @@ class AppServer(object):
380
417
        resp.content_type = 'text/html'
381
418
        resp.charset = 'utf8'
382
419
383
        rendered = Template(tmp_template).render({'body': resp.body.decode('utf8')})
420
        file_path = self.constructPath(req)
421
        try:
422
            if file_path.endswith('.pkl'):
423
                file_contents = cPickle.loads(open(file_path).read())
424
            else:
425
                file_contents = open(file_path, 'rb').read()
426
                resp.body = file_contents.encode('utf8')
427
                resp.status = 200
428
                return resp
429
        except:
430
            file_contents = '<html><body>doHTMLFile(): 404!</body></html>'
431
            return resp
432
433
        resp.body = self.htmlbuilder.render_file(file_path,
434
                                                 file_contents).encode('utf8')
384
435
385
436
#        html_code = unicode(file_contents,
386
437
#                            locale.getpreferredencoding(), 'replace')
@@ -388,7 +439,8 @@ class AppServer(object):
388
439
389
440
#        self.render_openid(environ)
390
441
#        rendered = self.env.from_string(html_code).render(self.template_vals)
391
        resp.body = rendered.encode('utf8')
442
        #resp.body = rendered.encode('utf8')
443
        resp.status = 200
392
444
        return resp
393
445
394
446