##// END OF EJS Templates
events: cleanup code, pep8, better logging.
marcink -
r2920:c35ca856 default
parent child Browse files
Show More
@@ -1,43 +1,44 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import logging
22 22
23 23 from rhodecode import events
24 24 from rhodecode.lib import rc_cache
25 25
26 26 log = logging.getLogger(__name__)
27 27
28 28
29 29 def trigger_user_permission_flush(event):
30 30 """
31 31 Subscriber to the `UserPermissionsChange`. This triggers the
32 32 automatic flush of permission caches, so the users affected receive new permissions
33 33 Right Away
34 34 """
35
35 36 affected_user_ids = set(event.user_ids)
36 37 for user_id in affected_user_ids:
37 38 cache_namespace_uid = 'cache_user_auth.{}'.format(user_id)
38 39 del_keys = rc_cache.clear_cache_namespace('cache_perms', cache_namespace_uid)
39 40 log.debug('Deleted %s cache keys for user_id: %s', del_keys, user_id)
40 41
41 42
42 43 def includeme(config):
43 44 config.add_subscriber(trigger_user_permission_flush, events.UserPermissionsChange)
@@ -1,84 +1,84 b''
1 1 # Copyright (C) 2016-2018 RhodeCode GmbH
2 2 #
3 3 # This program is free software: you can redistribute it and/or modify
4 4 # it under the terms of the GNU Affero General Public License, version 3
5 5 # (only), as published by the Free Software Foundation.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU Affero General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 #
15 15 # This program is dual-licensed. If you wish to learn more about the
16 16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 19 import logging
20 20 from pyramid.threadlocal import get_current_registry
21 21 from rhodecode.events.base import RhodecodeEvent
22 22
23 23
24 24 log = logging.getLogger(__name__)
25 25
26 26
27 27 def trigger(event, registry=None):
28 28 """
29 29 Helper method to send an event. This wraps the pyramid logic to send an
30 30 event.
31 31 """
32 32 # For the first step we are using pyramids thread locals here. If the
33 33 # event mechanism works out as a good solution we should think about
34 34 # passing the registry as an argument to get rid of it.
35 35 registry = registry or get_current_registry()
36 36 registry.notify(event)
37 log.debug('event %s triggered using registry %s', event, registry)
37 log.debug('event %s triggered using registry %s', event.__class__, registry)
38 38
39 39 # Until we can work around the problem that VCS operations do not have a
40 40 # pyramid context to work with, we send the events to integrations directly
41 41
42 42 # Later it will be possible to use regular pyramid subscribers ie:
43 43 # config.add_subscriber(
44 44 # 'rhodecode.integrations.integrations_event_handler',
45 45 # 'rhodecode.events.RhodecodeEvent')
46 46 # trigger(event, request.registry)
47 47
48 48 from rhodecode.integrations import integrations_event_handler
49 49 if isinstance(event, RhodecodeEvent):
50 50 integrations_event_handler(event)
51 51
52 52
53 53 from rhodecode.events.user import ( # noqa
54 54 UserPreCreate,
55 55 UserPostCreate,
56 56 UserPreUpdate,
57 57 UserRegistered,
58 58 UserPermissionsChange,
59 59 )
60 60
61 61 from rhodecode.events.repo import ( # noqa
62 62 RepoEvent,
63 63 RepoPreCreateEvent, RepoCreateEvent,
64 64 RepoPreDeleteEvent, RepoDeleteEvent,
65 65 RepoPrePushEvent, RepoPushEvent,
66 66 RepoPrePullEvent, RepoPullEvent,
67 67 )
68 68
69 69 from rhodecode.events.repo_group import ( # noqa
70 70 RepoGroupEvent,
71 71 RepoGroupCreateEvent,
72 72 RepoGroupUpdateEvent,
73 73 RepoGroupDeleteEvent,
74 74 )
75 75
76 76 from rhodecode.events.pullrequest import ( # noqa
77 77 PullRequestEvent,
78 78 PullRequestCreateEvent,
79 79 PullRequestUpdateEvent,
80 80 PullRequestCommentEvent,
81 81 PullRequestReviewEvent,
82 82 PullRequestMergeEvent,
83 83 PullRequestCloseEvent,
84 84 )
@@ -1,222 +1,221 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2011-2018 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 """
23 23 Model for integrations
24 24 """
25 25
26 26
27 27 import logging
28 28
29 29 from sqlalchemy import or_, and_
30 30
31 31 import rhodecode
32 32 from rhodecode import events
33 33 from rhodecode.integrations.types.base import EEIntegration
34 34 from rhodecode.lib.caching_query import FromCache
35 35 from rhodecode.model import BaseModel
36 from rhodecode.model.db import Integration, Repository, RepoGroup
36 from rhodecode.model.db import Integration, Repository, RepoGroup, true, false
37 37 from rhodecode.integrations import integration_type_registry
38 38
39 39 log = logging.getLogger(__name__)
40 40
41 41
42 42 class IntegrationModel(BaseModel):
43 43
44 44 cls = Integration
45 45
46 46 def __get_integration(self, integration):
47 47 if isinstance(integration, Integration):
48 48 return integration
49 49 elif isinstance(integration, (int, long)):
50 50 return self.sa.query(Integration).get(integration)
51 51 else:
52 52 if integration:
53 53 raise Exception('integration must be int, long or Instance'
54 54 ' of Integration got %s' % type(integration))
55 55
56 56 def create(self, IntegrationType, name, enabled, repo, repo_group,
57 57 child_repos_only, settings):
58 58 """ Create an IntegrationType integration """
59 59 integration = Integration()
60 60 integration.integration_type = IntegrationType.key
61 61 self.sa.add(integration)
62 62 self.update_integration(integration, name, enabled, repo, repo_group,
63 63 child_repos_only, settings)
64 64 self.sa.commit()
65 65 return integration
66 66
67 67 def update_integration(self, integration, name, enabled, repo, repo_group,
68 68 child_repos_only, settings):
69 69 integration = self.__get_integration(integration)
70 70
71 71 integration.repo = repo
72 72 integration.repo_group = repo_group
73 73 integration.child_repos_only = child_repos_only
74 74 integration.name = name
75 75 integration.enabled = enabled
76 76 integration.settings = settings
77 77
78 78 return integration
79 79
80 80 def delete(self, integration):
81 81 integration = self.__get_integration(integration)
82 82 if integration:
83 83 self.sa.delete(integration)
84 84 return True
85 85 return False
86 86
87 87 def get_integration_handler(self, integration):
88 88 TypeClass = integration_type_registry.get(integration.integration_type)
89 89 if not TypeClass:
90 90 log.error('No class could be found for integration type: {}'.format(
91 91 integration.integration_type))
92 92 return None
93 93 elif isinstance(TypeClass, EEIntegration) or issubclass(TypeClass, EEIntegration):
94 94 log.error('EE integration cannot be '
95 95 'executed for integration type: {}'.format(
96 96 integration.integration_type))
97 97 return None
98 98
99 99 return TypeClass(integration.settings)
100 100
101 101 def send_event(self, integration, event):
102 102 """ Send an event to an integration """
103 103 handler = self.get_integration_handler(integration)
104 104 if handler:
105 105 log.debug(
106 106 'events: sending event %s on integration %s using handler %s',
107 107 event, integration, handler)
108 108 handler.send_event(event)
109 109
110 110 def get_integrations(self, scope, IntegrationType=None):
111 111 """
112 112 Return integrations for a scope, which must be one of:
113 113
114 114 'all' - every integration, global/repogroup/repo
115 115 'global' - global integrations only
116 116 <Repository> instance - integrations for this repo only
117 117 <RepoGroup> instance - integrations for this repogroup only
118 118 """
119 119
120 120 if isinstance(scope, Repository):
121 121 query = self.sa.query(Integration).filter(
122 Integration.repo==scope)
122 Integration.repo == scope)
123 123 elif isinstance(scope, RepoGroup):
124 124 query = self.sa.query(Integration).filter(
125 Integration.repo_group==scope)
125 Integration.repo_group == scope)
126 126 elif scope == 'global':
127 127 # global integrations
128 128 query = self.sa.query(Integration).filter(
129 and_(Integration.repo_id==None, Integration.repo_group_id==None)
129 and_(Integration.repo_id == None, Integration.repo_group_id == None)
130 130 )
131 131 elif scope == 'root-repos':
132 132 query = self.sa.query(Integration).filter(
133 and_(Integration.repo_id==None,
134 Integration.repo_group_id==None,
135 Integration.child_repos_only==True)
133 and_(Integration.repo_id == None,
134 Integration.repo_group_id == None,
135 Integration.child_repos_only == true())
136 136 )
137 137 elif scope == 'all':
138 138 query = self.sa.query(Integration)
139 139 else:
140 140 raise Exception(
141 141 "invalid `scope`, must be one of: "
142 142 "['global', 'all', <Repository>, <RepoGroup>]")
143 143
144 144 if IntegrationType is not None:
145 145 query = query.filter(
146 146 Integration.integration_type==IntegrationType.key)
147 147
148 148 result = []
149 149 for integration in query.all():
150 150 IntType = integration_type_registry.get(integration.integration_type)
151 151 result.append((IntType, integration))
152 152 return result
153 153
154 154 def get_for_event(self, event, cache=False):
155 155 """
156 156 Get integrations that match an event
157 157 """
158 158 query = self.sa.query(
159 159 Integration
160 160 ).filter(
161 Integration.enabled==True
161 Integration.enabled == true()
162 162 )
163 163
164 164 global_integrations_filter = and_(
165 Integration.repo_id==None,
166 Integration.repo_group_id==None,
167 Integration.child_repos_only==False,
165 Integration.repo_id == None,
166 Integration.repo_group_id == None,
167 Integration.child_repos_only == False,
168 168 )
169 169
170 170 if isinstance(event, events.RepoEvent):
171 171 root_repos_integrations_filter = and_(
172 Integration.repo_id==None,
173 Integration.repo_group_id==None,
174 Integration.child_repos_only==True,
172 Integration.repo_id == None,
173 Integration.repo_group_id == None,
174 Integration.child_repos_only == true(),
175 175 )
176 176
177 177 clauses = [
178 178 global_integrations_filter,
179 179 ]
180 180
181 181 # repo integrations
182 if event.repo.repo_id: # pre create events dont have a repo_id yet
182 if event.repo.repo_id: # pre create events dont have a repo_id yet
183 183 clauses.append(
184 Integration.repo_id==event.repo.repo_id
184 Integration.repo_id == event.repo.repo_id
185 185 )
186 186
187 187 if event.repo.group:
188 188 clauses.append(
189 189 and_(
190 Integration.repo_group_id==event.repo.group.group_id,
191 Integration.child_repos_only==True
190 Integration.repo_group_id == event.repo.group.group_id,
191 Integration.child_repos_only == true()
192 192 )
193 193 )
194 194 # repo group cascade to kids
195 195 clauses.append(
196 196 and_(
197 197 Integration.repo_group_id.in_(
198 198 [group.group_id for group in
199 event.repo.groups_with_parents]
199 event.repo.groups_with_parents]
200 200 ),
201 Integration.child_repos_only==False
201 Integration.child_repos_only == false()
202 202 )
203 203 )
204 204
205
206 if not event.repo.group: # root repo
205 if not event.repo.group: # root repo
207 206 clauses.append(root_repos_integrations_filter)
208 207
209 208 query = query.filter(or_(*clauses))
210 209
211 210 if cache:
212 211 cache_key = "get_enabled_repo_integrations_%i" % event.repo.repo_id
213 212 query = query.options(
214 213 FromCache("sql_cache_short", cache_key))
215 else: # only global integrations
214 else: # only global integrations
216 215 query = query.filter(global_integrations_filter)
217 216 if cache:
218 217 query = query.options(
219 218 FromCache("sql_cache_short", "get_enabled_global_integrations"))
220 219
221 220 result = query.all()
222 return result No newline at end of file
221 return result
General Comments 0
You need to be logged in to leave comments. Login now