##// END OF EJS Templates
added caching layer into RSS/ATOM feeds...
marcink -
r3018:023f7873 beta
parent child Browse files
Show More
@@ -28,12 +28,14 b' import logging'
28 28 from pylons import url, response, tmpl_context as c
29 29 from pylons.i18n.translation import _
30 30
31 from beaker.cache import cache_region, region_invalidate
31 32 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
32 33
33 34 from rhodecode.lib import helpers as h
34 35 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
35 36 from rhodecode.lib.base import BaseRepoController
36 from rhodecode.lib.diffs import DiffProcessor
37 from rhodecode.lib.diffs import DiffProcessor, LimitedDiffContainer
38 from rhodecode.model.db import CacheInvalidation
37 39
38 40 log = logging.getLogger(__name__)
39 41
@@ -51,6 +53,9 b' class FeedController(BaseRepoController)'
51 53 self.language = 'en-us'
52 54 self.ttl = "5"
53 55 self.feed_nr = 20
56 # we need to protect from parsing huge diffs here other way
57 # we can kill the server, 32*1024 chars is a reasonable limit
58 self.feed_diff_limit = 32 * 1024
54 59
55 60 def _get_title(self, cs):
56 61 return "%s" % (
@@ -59,26 +64,28 b' class FeedController(BaseRepoController)'
59 64
60 65 def __changes(self, cs):
61 66 changes = []
62 _diff = cs.diff()
63 # we need to protect from parsing huge diffs here other way
64 # we can kill the server, 32*1024 chars is a reasonable limit
65 HUGE_DIFF = 32 * 1024
66 if len(_diff) > HUGE_DIFF:
67 changes = ['\n ' + _('Changeset was too big and was cut off...')]
68 return changes
69 diffprocessor = DiffProcessor(_diff)
70 stats = diffprocessor.prepare(inline_diff=False)
71 for st in stats:
67 diff_processor = DiffProcessor(cs.diff(),
68 diff_limit=self.feed_diff_limit)
69 _parsed = diff_processor.prepare(inline_diff=False)
70 limited_diff = False
71 if isinstance(_parsed, LimitedDiffContainer):
72 limited_diff = True
73
74 for st in _parsed:
72 75 st.update({'added': st['stats'][0],
73 76 'removed': st['stats'][1]})
74 77 changes.append('\n %(operation)s %(filename)s '
75 78 '(%(added)s lines added, %(removed)s lines removed)'
76 79 % st)
80 if limited_diff:
81 changes = changes + ['\n ' +
82 _('Changeset was too big and was cut off...')]
77 83 return changes
78 84
79 85 def __get_desc(self, cs):
80 86 desc_msg = []
81 desc_msg.append('%s %s %s:<br/>' % (cs.author, _('commited on'),
87 desc_msg.append('%s %s %s<br/>' % (h.person(cs.author),
88 _('commited on'),
82 89 h.fmt_date(cs.date)))
83 90 #branches, tags, bookmarks
84 91 if cs.branch:
@@ -102,6 +109,9 b' class FeedController(BaseRepoController)'
102 109
103 110 def atom(self, repo_name):
104 111 """Produce an atom-1.0 feed via feedgenerator module"""
112
113 @cache_region('long_term')
114 def _get_feed_from_cache(key):
105 115 feed = Atom1Feed(
106 116 title=self.title % repo_name,
107 117 link=url('summary_home', repo_name=repo_name,
@@ -123,8 +133,18 b' class FeedController(BaseRepoController)'
123 133 response.content_type = feed.mime_type
124 134 return feed.writeString('utf-8')
125 135
136 key = repo_name + '_ATOM'
137 inv = CacheInvalidation.invalidate(key)
138 if inv is not None:
139 region_invalidate(_get_feed_from_cache, None, key)
140 CacheInvalidation.set_valid(inv.cache_key)
141 return _get_feed_from_cache(key)
142
126 143 def rss(self, repo_name):
127 144 """Produce an rss2 feed via feedgenerator module"""
145
146 @cache_region('long_term')
147 def _get_feed_from_cache(key):
128 148 feed = Rss201rev2Feed(
129 149 title=self.title % repo_name,
130 150 link=url('summary_home', repo_name=repo_name,
@@ -145,3 +165,11 b' class FeedController(BaseRepoController)'
145 165
146 166 response.content_type = feed.mime_type
147 167 return feed.writeString('utf-8')
168
169 key = repo_name + '_RSS'
170 inv = CacheInvalidation.invalidate(key)
171 if inv is not None:
172 region_invalidate(_get_feed_from_cache, None, key)
173 CacheInvalidation.set_valid(inv.cache_key)
174 return _get_feed_from_cache(key)
175
@@ -279,6 +279,18 b' def safe_str(unicode_, to_encoding=None)'
279 279 return safe_str
280 280
281 281
282 def remove_suffix(s, suffix):
283 if s.endswith(suffix):
284 s = s[:-1 * len(suffix)]
285 return s
286
287
288 def remove_prefix(s, prefix):
289 if s.startswith(prefix):
290 s = s[:-1 * len(prefix)]
291 return s
292
293
282 294 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
283 295 """
284 296 Custom engine_from_config functions that makes sure we use NullPool for
@@ -46,7 +46,7 b' from rhodecode.lib.vcs.exceptions import'
46 46 from rhodecode.lib.vcs.utils.lazy import LazyProperty
47 47
48 48 from rhodecode.lib.utils2 import str2bool, safe_str, get_changeset_safe, \
49 safe_unicode
49 safe_unicode, remove_suffix
50 50 from rhodecode.lib.compat import json
51 51 from rhodecode.lib.caching_query import FromCache
52 52
@@ -941,6 +941,7 b' class Repository(Base, BaseModel):'
941 941
942 942 @LazyProperty
943 943 def scm_instance(self):
944 return self.scm_instance_cached()
944 945 return self.__get_instance()
945 946
946 947 def scm_instance_cached(self, cache_map=None):
@@ -1440,7 +1441,11 b' class CacheInvalidation(Base, BaseModel)'
1440 1441 iid = rhodecode.CONFIG.get('instance_id')
1441 1442 if iid:
1442 1443 prefix = iid
1443 return "%s%s" % (prefix, key), prefix, key.rstrip('_README')
1444 #remove specific suffixes like _README or _RSS
1445 key = remove_suffix(key, '_README')
1446 key = remove_suffix(key, '_RSS')
1447 key = remove_suffix(key, '_ATOM')
1448 return "%s%s" % (prefix, key), prefix, key
1444 1449
1445 1450 @classmethod
1446 1451 def get_by_key(cls, key):
General Comments 0
You need to be logged in to leave comments. Login now