1 """Objects interacting together to provides the external page embeding |
1 """Objects interacting together to provides the external page embeding |
2 functionality. |
2 functionality. |
3 |
3 |
4 |
4 |
5 :organization: Logilab |
5 :organization: Logilab |
6 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
6 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
7 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
7 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
8 """ |
8 """ |
9 __docformat__ = "restructuredtext en" |
9 __docformat__ = "restructuredtext en" |
10 |
10 |
11 import re |
11 import re |
15 from logilab.mtconverter import guess_encoding |
15 from logilab.mtconverter import guess_encoding |
16 |
16 |
17 from cubicweb import urlquote # XXX should use view.url_quote method |
17 from cubicweb import urlquote # XXX should use view.url_quote method |
18 from cubicweb.interfaces import IEmbedable |
18 from cubicweb.interfaces import IEmbedable |
19 from cubicweb.common.uilib import soup2xhtml |
19 from cubicweb.common.uilib import soup2xhtml |
20 from cubicweb.common.selectors import (one_line_rset, score_entity_selector, |
20 from cubicweb.common.selectors import (one_line_rset, score_entity, |
21 match_search_state, implement_interface) |
21 match_search_state, implements) |
22 from cubicweb.common.view import NOINDEX, NOFOLLOW |
22 from cubicweb.common.view import NOINDEX, NOFOLLOW |
23 from cubicweb.web.controller import Controller |
23 from cubicweb.web.controller import Controller |
24 from cubicweb.web.action import Action |
24 from cubicweb.web.action import Action |
25 from cubicweb.web.views import basetemplates |
25 from cubicweb.web.views import basetemplates |
26 |
26 |
73 body = '<h2>%s</h2><h3>%s</h3>' % ( |
73 body = '<h2>%s</h2><h3>%s</h3>' % ( |
74 _('error while embedding page'), err) |
74 _('error while embedding page'), err) |
75 return self.vreg.main_template(req, self.template, body=body) |
75 return self.vreg.main_template(req, self.template, body=body) |
76 |
76 |
77 |
77 |
|
78 def entity_has_embedable_url(entity): |
|
79 """return 1 if the entity provides an allowed embedable url""" |
|
80 url = entity.embeded_url() |
|
81 if not url or not url.strip(): |
|
82 return 0 |
|
83 allowed = entity.config['embed-allowed'] |
|
84 if allowed is None or not allowed.match(url): |
|
85 return 0 |
|
86 return 1 |
|
87 |
|
88 |
78 class EmbedAction(Action): |
89 class EmbedAction(Action): |
79 """display an 'embed' link on entity implementing `embeded_url` method |
90 """display an 'embed' link on entity implementing `embeded_url` method |
80 if the returned url match embeding configuration |
91 if the returned url match embeding configuration |
81 """ |
92 """ |
82 id = 'embed' |
93 id = 'embed' |
83 controller = 'embed' |
94 __selectors__ = (one_line_rset, match_search_state('normal'), |
84 __selectors__ = (one_line_rset, match_search_state, |
95 implements(IEmbedable), |
85 implement_interface, score_entity_selector) |
96 score_entity(entity_has_embedable_url)) |
86 accepts_interfaces = (IEmbedable,) |
|
87 |
97 |
88 title = _('embed') |
98 title = _('embed') |
89 |
99 controller = 'embed' |
90 @classmethod |
|
91 def score_entity(cls, entity): |
|
92 """return a score telling how well I can display the given |
|
93 entity instance (required by the value_selector) |
|
94 """ |
|
95 url = entity.embeded_url() |
|
96 if not url or not url.strip(): |
|
97 return 0 |
|
98 allowed = cls.config['embed-allowed'] |
|
99 if allowed is None or not allowed.match(url): |
|
100 return 0 |
|
101 return 1 |
|
102 |
100 |
103 def url(self, row=0): |
101 def url(self, row=0): |
104 entity = self.rset.get_entity(row, 0) |
102 entity = self.rset.get_entity(row, 0) |
105 url = urljoin(self.req.base_url(), entity.embeded_url()) |
103 url = urljoin(self.req.base_url(), entity.embeded_url()) |
106 if self.req.form.has_key('rql'): |
104 if self.req.form.has_key('rql'): |
130 url = '%s&custom_css=%s' % (url, self.custom_css) |
128 url = '%s&custom_css=%s' % (url, self.custom_css) |
131 else: |
129 else: |
132 url = '%s?custom_css=%s' % (url, self.custom_css) |
130 url = '%s?custom_css=%s' % (url, self.custom_css) |
133 return '<a href="%s"' % url |
131 return '<a href="%s"' % url |
134 |
132 |
|
133 |
135 class absolutize_links: |
134 class absolutize_links: |
136 def __init__(self, embedded_url, tag, custom_css=None): |
135 def __init__(self, embedded_url, tag, custom_css=None): |
137 self.embedded_url = embedded_url |
136 self.embedded_url = embedded_url |
138 self.tag = tag |
137 self.tag = tag |
139 self.custom_css = custom_css |
138 self.custom_css = custom_css |
150 (SRC_RGX, absolutize_links(embedded_url, '<img src')), |
149 (SRC_RGX, absolutize_links(embedded_url, '<img src')), |
151 (HREF_RGX, replace_href(prefix, custom_css))) |
150 (HREF_RGX, replace_href(prefix, custom_css))) |
152 for rgx, repl in filters: |
151 for rgx, repl in filters: |
153 body = rgx.sub(repl, body) |
152 body = rgx.sub(repl, body) |
154 return body |
153 return body |
155 |
154 |
|
155 |
156 def embed_external_page(url, prefix, headers=None, custom_css=None): |
156 def embed_external_page(url, prefix, headers=None, custom_css=None): |
157 req = Request(url, headers=(headers or {})) |
157 req = Request(url, headers=(headers or {})) |
158 content = urlopen(req).read() |
158 content = urlopen(req).read() |
159 page_source = unicode(content, guess_encoding(content), 'replace') |
159 page_source = unicode(content, guess_encoding(content), 'replace') |
160 page_source =page_source |
160 page_source =page_source |