summaryrefslogtreecommitdiffstats
path: root/template.py
blob: a992c083a8e5a5b3afda7e0475d4eb3393807c1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#! /usr/bin/env python
# -*- coding: utf-8 -*-

class RemoteTemplate(object):
    def __init__(self, source):
        self.source = source
        from wcs.qommon.misc import simplify
        import os, urlparse
        self.cache_key = simplify(urlparse.urlunparse(urlparse.urlparse(self.source)[:3] + ('', '', '')))
        self.cache_dirpath = os.path.join(publisher.app_dir, 'skeleton-cache')
        self.cache_filepath = os.path.join(self.cache_dirpath, self.cache_key)
        self.theme_skeleton_url = publisher.get_site_option('theme_skeleton_url')
        self.skip_cache = (request.response.status_code != 200)

    def get_template_content(self):
        import time, os, threading
        if self.skip_cache:
            return self.update_content()
        from quixote import get_response, get_publisher
        CACHE_REFRESH_TIMEOUT = 300
        self.response = get_response()
        self.static_path = get_publisher().get_application_static_files_root_url()
        try:
            cache_filepath_mtime = min((
                os.stat(self.cache_filepath).st_mtime,
                os.lstat(self.cache_filepath).st_mtime))
        except OSError: # missing file
            return self.update_content()
        else:
            template_content = open(self.cache_filepath).read()
            if time.time() > (cache_filepath_mtime + CACHE_REFRESH_TIMEOUT):
                threading.Thread(target=self.update_content).start()
            return template_content

    def update_content(self):
        import requests

        r = requests.get(self.theme_skeleton_url, params={'source': self.source, 'format': 'ezt'})
        r.raise_for_status()

        body = """
             [if-any bigdiv]<div id="[bigdiv]" [if-any breadcrumb]class="has-breadcrumb"[end]>[end]
<!-- [breadcrumb] -->
             [if-any title]<h2>[title]</h2>[end]
             [body]
             [if-any bigdiv]</div>[end]
        """

        extra_head = """
[script]
<script type="text/javascript" src="/themes/vincennes-2014/dataview.js"></script>
<link rel="stylesheet" type="text/css" href="[css]">
"""

        extra_top_head = """
"""

        user_name = """[if-any user][session_user_display_name][else]Compte Citoyen[end]"""
        left_menu_links = """
    [if-any user]
                                   <li><a href="[idp_url]accounts/">Mon compte</a></li>
                                   <li><a href="[portal_url]demarches-en-cours/">Mes démarches en cours</a></li>
                                   <li><a href="[portal_url]">Démarches en ligne</a></li>
                                   <li><a href="[root_url]logout">Déconnexion</a></li>
[else]
                                   <li><a href="[portal_url]login/">Connexion</a></li>
                                   <li><a href="[idp_url]accounts/register/">Créer un compte</a></li>
                                   <li><a href="[portal_url]">Démarches en ligne</a></li>
                                   <li><a href="[portal_url]aide/">Aide</a></li>
[end]
        """

        right_column = """ [if-any gauche]
<div class="steplist"><div class="panel panel-defaults">
            <div class="panel-body">
            [gauche]
            </div>
</div></div>
    [end]"""


        custom_breadcrumb = ''
        from quixote.html import htmlescape
        response = self.response
        if hasattr(response, 'breadcrumb') and response.breadcrumb:
            s = []
            path = self.static_path
            for i, (component, label) in enumerate(response.breadcrumb[1:]):
                if component.startswith('http:') or component.startswith('https:'):
                    s.append('<li><a href="%s">%s</a></li>' % (component, label))
                    continue
                if type(label) is str:
                    label = htmlescape(label)
                    if i == len(response.breadcrumb)-2: # last
                        s.append('<li class="active">%s</li>' % label)
                    else:
                        s.append('<li><a href="%s%s">%s</a></li>' % (path, component, label))
                path += component
            custom_breadcrumb = ' '.join(s)

        template_content = r.text.encode('utf-8')
        template_content = template_content.replace('[if-any content][content][end]', body)
        template_content = template_content.replace(
                '[if-any breadcrumb-elements][breadcrumb-elements][end]',
                custom_breadcrumb)
        template_content = template_content.replace('[if-any extra-top-head][extra-top-head][end]', extra_top_head)
        template_content = template_content.replace('[if-any extra-head][extra-head][end]', extra_head)
        template_content = template_content.replace('[if-any left-menu-links][left-menu-links][end]', left_menu_links)
        template_content = template_content.replace('[if-any user-name][user-name][end]', user_name)
        template_content = template_content.replace(
                '[if-any right-column][right-column][end]', right_column)
        template_content = template_content.replace(
                '<div id="main-content">',
                '<div id="main-content" [if-any gauche][else]class="no-right-column"[end]>')
        if not self.skip_cache:
            self.cache(template_content, page_id=r.headers.get('X-Combo-Page-Id'))
        return template_content

    def cache(self, template_body, page_id=None):
        import os
        from qommon.storage import atomic_write
        if not os.path.exists(self.cache_dirpath):
            os.mkdir(self.cache_dirpath)
        if page_id:
            # if there's a page id we store the content under the page id
            # filename and create a symlink from the cache key
            cache_filepath = os.path.join(self.cache_dirpath, page_id)
            atomic_write(cache_filepath, template_body)
            # always recreate symlink to get an updated mtime
            if os.path.exists(self.cache_filepath):
                os.unlink(self.cache_filepath)
            os.symlink(page_id, self.cache_filepath)
        else:
            atomic_write(self.cache_filepath, template_body)

template_content = RemoteTemplate(request.get_url()).get_template_content()