##// END OF EJS Templates
fixed #746 unicodeDedode errors on feed controllers
marcink -
r3292:2464ac75 beta
parent child Browse files
Show More
@@ -1,182 +1,182 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.feed
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Feed controller for rhodecode
7 7
8 8 :created_on: Apr 23, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import logging
27 27
28 28 from pylons import url, response, tmpl_context as c
29 29 from pylons.i18n.translation import _
30 30
31 31 from beaker.cache import cache_region, region_invalidate
32 32 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
33 33
34 34 from rhodecode.lib import helpers as h
35 35 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
36 36 from rhodecode.lib.base import BaseRepoController
37 37 from rhodecode.lib.diffs import DiffProcessor, LimitedDiffContainer
38 38 from rhodecode.model.db import CacheInvalidation
39 from rhodecode.lib.utils2 import safe_int, str2bool
39 from rhodecode.lib.utils2 import safe_int, str2bool, safe_unicode
40 40
41 41 log = logging.getLogger(__name__)
42 42
43 43
44 44 class FeedController(BaseRepoController):
45 45
46 46 @LoginRequired(api_access=True)
47 47 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
48 48 'repository.admin')
49 49 def __before__(self):
50 50 super(FeedController, self).__before__()
51 51 #common values for feeds
52 52 self.description = _('Changes on %s repository')
53 53 self.title = self.title = _('%s %s feed') % (c.rhodecode_name, '%s')
54 54 self.language = 'en-us'
55 55 self.ttl = "5"
56 56 import rhodecode
57 57 CONF = rhodecode.CONFIG
58 58 self.include_diff = str2bool(CONF.get('rss_include_diff', False))
59 59 self.feed_nr = safe_int(CONF.get('rss_items_per_page', 20))
60 60 # we need to protect from parsing huge diffs here other way
61 61 # we can kill the server
62 62 self.feed_diff_limit = safe_int(CONF.get('rss_cut_off_limit', 32 * 1024))
63 63
64 64 def _get_title(self, cs):
65 65 return "%s" % (
66 66 h.shorter(cs.message, 160)
67 67 )
68 68
69 69 def __changes(self, cs):
70 70 changes = []
71 71 diff_processor = DiffProcessor(cs.diff(),
72 72 diff_limit=self.feed_diff_limit)
73 73 _parsed = diff_processor.prepare(inline_diff=False)
74 74 limited_diff = False
75 75 if isinstance(_parsed, LimitedDiffContainer):
76 76 limited_diff = True
77 77
78 78 for st in _parsed:
79 79 st.update({'added': st['stats'][0],
80 80 'removed': st['stats'][1]})
81 81 changes.append('\n %(operation)s %(filename)s '
82 82 '(%(added)s lines added, %(removed)s lines removed)'
83 83 % st)
84 84 if limited_diff:
85 85 changes = changes + ['\n ' +
86 86 _('Changeset was too big and was cut off...')]
87 87 return diff_processor, changes
88 88
89 89 def __get_desc(self, cs):
90 90 desc_msg = []
91 91 desc_msg.append('%s %s %s<br/>' % (h.person(cs.author),
92 92 _('commited on'),
93 93 h.fmt_date(cs.date)))
94 94 #branches, tags, bookmarks
95 95 if cs.branch:
96 96 desc_msg.append('branch: %s<br/>' % cs.branch)
97 97 if h.is_hg(c.rhodecode_repo):
98 98 for book in cs.bookmarks:
99 99 desc_msg.append('bookmark: %s<br/>' % book)
100 100 for tag in cs.tags:
101 101 desc_msg.append('tag: %s<br/>' % tag)
102 102 diff_processor, changes = self.__changes(cs)
103 103 # rev link
104 104 _url = url('changeset_home', repo_name=cs.repository.name,
105 105 revision=cs.raw_id, qualified=True)
106 106 desc_msg.append('changesest: <a href="%s">%s</a>' % (_url, cs.raw_id[:8]))
107 107
108 108 desc_msg.append('<pre>')
109 109 desc_msg.append(cs.message)
110 110 desc_msg.append('\n')
111 111 desc_msg.extend(changes)
112 112 if self.include_diff:
113 113 desc_msg.append('\n\n')
114 114 desc_msg.append(diff_processor.as_raw())
115 115 desc_msg.append('</pre>')
116 return desc_msg
116 return map(safe_unicode, desc_msg)
117 117
118 118 def atom(self, repo_name):
119 119 """Produce an atom-1.0 feed via feedgenerator module"""
120 120
121 121 @cache_region('long_term')
122 122 def _get_feed_from_cache(key):
123 123 feed = Atom1Feed(
124 124 title=self.title % repo_name,
125 125 link=url('summary_home', repo_name=repo_name,
126 126 qualified=True),
127 127 description=self.description % repo_name,
128 128 language=self.language,
129 129 ttl=self.ttl
130 130 )
131 131
132 132 for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])):
133 133 feed.add_item(title=self._get_title(cs),
134 134 link=url('changeset_home', repo_name=repo_name,
135 135 revision=cs.raw_id, qualified=True),
136 136 author_name=cs.author,
137 137 description=''.join(self.__get_desc(cs)),
138 138 pubdate=cs.date,
139 139 )
140 140
141 141 response.content_type = feed.mime_type
142 142 return feed.writeString('utf-8')
143 143
144 144 key = repo_name + '_ATOM'
145 145 inv = CacheInvalidation.invalidate(key)
146 146 if inv is not None:
147 147 region_invalidate(_get_feed_from_cache, None, key)
148 148 CacheInvalidation.set_valid(inv.cache_key)
149 149 return _get_feed_from_cache(key)
150 150
151 151 def rss(self, repo_name):
152 152 """Produce an rss2 feed via feedgenerator module"""
153 153
154 154 @cache_region('long_term')
155 155 def _get_feed_from_cache(key):
156 156 feed = Rss201rev2Feed(
157 157 title=self.title % repo_name,
158 158 link=url('summary_home', repo_name=repo_name,
159 159 qualified=True),
160 160 description=self.description % repo_name,
161 161 language=self.language,
162 162 ttl=self.ttl
163 163 )
164 164
165 165 for cs in reversed(list(c.rhodecode_repo[-self.feed_nr:])):
166 166 feed.add_item(title=self._get_title(cs),
167 167 link=url('changeset_home', repo_name=repo_name,
168 168 revision=cs.raw_id, qualified=True),
169 169 author_name=cs.author,
170 170 description=''.join(self.__get_desc(cs)),
171 171 pubdate=cs.date,
172 172 )
173 173
174 174 response.content_type = feed.mime_type
175 175 return feed.writeString('utf-8')
176 176
177 177 key = repo_name + '_RSS'
178 178 inv = CacheInvalidation.invalidate(key)
179 179 if inv is not None:
180 180 region_invalidate(_get_feed_from_cache, None, key)
181 181 CacheInvalidation.set_valid(inv.cache_key)
182 182 return _get_feed_from_cache(key)
General Comments 0
You need to be logged in to leave comments. Login now