##// END OF EJS Templates
chore(warnings): fixed sqlalchemy warning for use of cases syntax
super-admin -
r5200:382130ed default
parent child Browse files
Show More
@@ -1,237 +1,237 b''
1 # Copyright (C) 2011-2023 RhodeCode GmbH
1 # Copyright (C) 2011-2023 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19
19
20 """
20 """
21 Model for integrations
21 Model for integrations
22 """
22 """
23
23
24
24
25 import logging
25 import logging
26
26
27 from sqlalchemy import or_, and_
27 from sqlalchemy import or_, and_
28
28
29 from rhodecode import events
29 from rhodecode import events
30 from rhodecode.integrations.types.base import EEIntegration
30 from rhodecode.integrations.types.base import EEIntegration
31 from rhodecode.lib.caching_query import FromCache
31 from rhodecode.lib.caching_query import FromCache
32 from rhodecode.model import BaseModel
32 from rhodecode.model import BaseModel
33 from rhodecode.model.db import Integration, Repository, RepoGroup, true, false, case, null
33 from rhodecode.model.db import Integration, Repository, RepoGroup, true, false, case, null
34 from rhodecode.integrations import integration_type_registry
34 from rhodecode.integrations import integration_type_registry
35
35
36 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
37
37
38
38
39 class IntegrationModel(BaseModel):
39 class IntegrationModel(BaseModel):
40
40
41 cls = Integration
41 cls = Integration
42
42
43 def __get_integration(self, integration):
43 def __get_integration(self, integration):
44 if isinstance(integration, Integration):
44 if isinstance(integration, Integration):
45 return integration
45 return integration
46 elif isinstance(integration, int):
46 elif isinstance(integration, int):
47 return self.sa.query(Integration).get(integration)
47 return self.sa.query(Integration).get(integration)
48 else:
48 else:
49 if integration:
49 if integration:
50 raise Exception('integration must be int or Instance'
50 raise Exception('integration must be int or Instance'
51 ' of Integration got %s' % type(integration))
51 ' of Integration got %s' % type(integration))
52
52
53 def create(self, IntegrationType, name, enabled, repo, repo_group, child_repos_only, settings):
53 def create(self, IntegrationType, name, enabled, repo, repo_group, child_repos_only, settings):
54 """ Create an IntegrationType integration """
54 """ Create an IntegrationType integration """
55 integration = Integration()
55 integration = Integration()
56 integration.integration_type = IntegrationType.key
56 integration.integration_type = IntegrationType.key
57 self.sa.add(integration)
57 self.sa.add(integration)
58 self.update_integration(integration, name, enabled, repo, repo_group,
58 self.update_integration(integration, name, enabled, repo, repo_group,
59 child_repos_only, settings)
59 child_repos_only, settings)
60 self.sa.commit()
60 self.sa.commit()
61 return integration
61 return integration
62
62
63 def update_integration(self, integration, name, enabled, repo, repo_group,
63 def update_integration(self, integration, name, enabled, repo, repo_group,
64 child_repos_only, settings):
64 child_repos_only, settings):
65 integration = self.__get_integration(integration)
65 integration = self.__get_integration(integration)
66
66
67 integration.repo = repo
67 integration.repo = repo
68 integration.repo_group = repo_group
68 integration.repo_group = repo_group
69 integration.child_repos_only = child_repos_only
69 integration.child_repos_only = child_repos_only
70 integration.name = name
70 integration.name = name
71 integration.enabled = enabled
71 integration.enabled = enabled
72 integration.settings = settings
72 integration.settings = settings
73
73
74 return integration
74 return integration
75
75
76 def delete(self, integration):
76 def delete(self, integration):
77 integration = self.__get_integration(integration)
77 integration = self.__get_integration(integration)
78 if integration:
78 if integration:
79 self.sa.delete(integration)
79 self.sa.delete(integration)
80 return True
80 return True
81 return False
81 return False
82
82
83 def get_integration_handler(self, integration):
83 def get_integration_handler(self, integration):
84 TypeClass = integration_type_registry.get(integration.integration_type)
84 TypeClass = integration_type_registry.get(integration.integration_type)
85 if not TypeClass:
85 if not TypeClass:
86 log.error('No class could be found for integration type: {}'.format(
86 log.error('No class could be found for integration type: {}'.format(
87 integration.integration_type))
87 integration.integration_type))
88 return None
88 return None
89 elif isinstance(TypeClass, EEIntegration) or issubclass(TypeClass, EEIntegration):
89 elif isinstance(TypeClass, EEIntegration) or issubclass(TypeClass, EEIntegration):
90 log.error('EE integration cannot be '
90 log.error('EE integration cannot be '
91 'executed for integration type: {}'.format(
91 'executed for integration type: {}'.format(
92 integration.integration_type))
92 integration.integration_type))
93 return None
93 return None
94
94
95 return TypeClass(integration.settings)
95 return TypeClass(integration.settings)
96
96
97 def send_event(self, integration, event):
97 def send_event(self, integration, event):
98 """ Send an event to an integration """
98 """ Send an event to an integration """
99 handler = self.get_integration_handler(integration)
99 handler = self.get_integration_handler(integration)
100 if handler:
100 if handler:
101 log.debug(
101 log.debug(
102 'events: sending event %s on integration %s using handler %s',
102 'events: sending event %s on integration %s using handler %s',
103 event, integration, handler)
103 event, integration, handler)
104 handler.send_event(event)
104 handler.send_event(event)
105
105
106 def get_integrations(self, scope, IntegrationType=None):
106 def get_integrations(self, scope, IntegrationType=None):
107 """
107 """
108 Return integrations for a scope, which must be one of:
108 Return integrations for a scope, which must be one of:
109
109
110 'all' - every integration, global/repogroup/repo
110 'all' - every integration, global/repogroup/repo
111 'global' - global integrations only
111 'global' - global integrations only
112 <Repository> instance - integrations for this repo only
112 <Repository> instance - integrations for this repo only
113 <RepoGroup> instance - integrations for this repogroup only
113 <RepoGroup> instance - integrations for this repogroup only
114 """
114 """
115
115
116 if isinstance(scope, Repository):
116 if isinstance(scope, Repository):
117 query = self.sa.query(Integration).filter(
117 query = self.sa.query(Integration).filter(
118 Integration.repo == scope)
118 Integration.repo == scope)
119 elif isinstance(scope, RepoGroup):
119 elif isinstance(scope, RepoGroup):
120 query = self.sa.query(Integration).filter(
120 query = self.sa.query(Integration).filter(
121 Integration.repo_group == scope)
121 Integration.repo_group == scope)
122 elif scope == 'global':
122 elif scope == 'global':
123 # global integrations
123 # global integrations
124 query = self.sa.query(Integration).filter(
124 query = self.sa.query(Integration).filter(
125 and_(Integration.repo_id == null(), Integration.repo_group_id == null())
125 and_(Integration.repo_id == null(), Integration.repo_group_id == null())
126 )
126 )
127 elif scope == 'root-repos':
127 elif scope == 'root-repos':
128 query = self.sa.query(Integration).filter(
128 query = self.sa.query(Integration).filter(
129 and_(Integration.repo_id == null(),
129 and_(Integration.repo_id == null(),
130 Integration.repo_group_id == null(),
130 Integration.repo_group_id == null(),
131 Integration.child_repos_only == true())
131 Integration.child_repos_only == true())
132 )
132 )
133 elif scope == 'all':
133 elif scope == 'all':
134 query = self.sa.query(Integration)
134 query = self.sa.query(Integration)
135 else:
135 else:
136 raise Exception(
136 raise Exception(
137 "invalid `scope`, must be one of: "
137 "invalid `scope`, must be one of: "
138 "['global', 'all', <Repository>, <RepoGroup>]")
138 "['global', 'all', <Repository>, <RepoGroup>]")
139
139
140 if IntegrationType is not None:
140 if IntegrationType is not None:
141 query = query.filter(
141 query = query.filter(
142 Integration.integration_type==IntegrationType.key)
142 Integration.integration_type==IntegrationType.key)
143
143
144 result = []
144 result = []
145 for integration in query.all():
145 for integration in query.all():
146 IntType = integration_type_registry.get(integration.integration_type)
146 IntType = integration_type_registry.get(integration.integration_type)
147 result.append((IntType, integration))
147 result.append((IntType, integration))
148 return result
148 return result
149
149
150 def get_for_event(self, event, cache=False):
150 def get_for_event(self, event, cache=False):
151 """
151 """
152 Get integrations that match an event
152 Get integrations that match an event
153 """
153 """
154 # base query
154 # base query
155 query = self.sa.query(
155 query = self.sa.query(
156 Integration
156 Integration
157 ).filter(
157 ).filter(
158 Integration.enabled == true()
158 Integration.enabled == true()
159 )
159 )
160
160
161 global_integrations_filter = and_(
161 global_integrations_filter = and_(
162 Integration.repo_id == null(),
162 Integration.repo_id == null(),
163 Integration.repo_group_id == null(),
163 Integration.repo_group_id == null(),
164 Integration.child_repos_only == false(),
164 Integration.child_repos_only == false(),
165 )
165 )
166
166
167 if isinstance(event, events.RepoEvent):
167 if isinstance(event, events.RepoEvent):
168 root_repos_integrations_filter = and_(
168 root_repos_integrations_filter = and_(
169 Integration.repo_id == null(),
169 Integration.repo_id == null(),
170 Integration.repo_group_id == null(),
170 Integration.repo_group_id == null(),
171 Integration.child_repos_only == true(),
171 Integration.child_repos_only == true(),
172 )
172 )
173
173
174 clauses = [
174 clauses = [
175 global_integrations_filter,
175 global_integrations_filter,
176 ]
176 ]
177 cases = [
177 cases = [
178 (global_integrations_filter, 1),
178 (global_integrations_filter, 1),
179 (root_repos_integrations_filter, 2),
179 (root_repos_integrations_filter, 2),
180 ]
180 ]
181
181
182 # repo group integrations
182 # repo group integrations
183 if event.repo.group:
183 if event.repo.group:
184 # repo group with only root level repos
184 # repo group with only root level repos
185 group_child_repos_filter = and_(
185 group_child_repos_filter = and_(
186 Integration.repo_group_id == event.repo.group.group_id,
186 Integration.repo_group_id == event.repo.group.group_id,
187 Integration.child_repos_only == true()
187 Integration.child_repos_only == true()
188 )
188 )
189
189
190 clauses.append(group_child_repos_filter)
190 clauses.append(group_child_repos_filter)
191 cases.append(
191 cases.append(
192 (group_child_repos_filter, 3),
192 (group_child_repos_filter, 3),
193 )
193 )
194
194
195 # repo group cascade to kids
195 # repo group cascade to kids
196 group_recursive_repos_filter = and_(
196 group_recursive_repos_filter = and_(
197 Integration.repo_group_id.in_(
197 Integration.repo_group_id.in_(
198 [group.group_id for group in event.repo.groups_with_parents]
198 [group.group_id for group in event.repo.groups_with_parents]
199 ),
199 ),
200 Integration.child_repos_only == false()
200 Integration.child_repos_only == false()
201 )
201 )
202 clauses.append(group_recursive_repos_filter)
202 clauses.append(group_recursive_repos_filter)
203 cases.append(
203 cases.append(
204 (group_recursive_repos_filter, 4),
204 (group_recursive_repos_filter, 4),
205 )
205 )
206
206
207 if not event.repo.group: # root repo
207 if not event.repo.group: # root repo
208 clauses.append(root_repos_integrations_filter)
208 clauses.append(root_repos_integrations_filter)
209
209
210 # repo integrations
210 # repo integrations
211 if event.repo.repo_id: # pre create events dont have a repo_id yet
211 if event.repo.repo_id: # pre create events dont have a repo_id yet
212 specific_repo_filter = Integration.repo_id == event.repo.repo_id
212 specific_repo_filter = Integration.repo_id == event.repo.repo_id
213 clauses.append(specific_repo_filter)
213 clauses.append(specific_repo_filter)
214 cases.append(
214 cases.append(
215 (specific_repo_filter, 5),
215 (specific_repo_filter, 5),
216 )
216 )
217
217
218 order_by_criterion = case(cases)
218 order_by_criterion = case(*cases)
219
219
220 query = query.filter(or_(*clauses))
220 query = query.filter(or_(*clauses))
221 query = query.order_by(order_by_criterion)
221 query = query.order_by(order_by_criterion)
222
222
223 if cache:
223 if cache:
224 cache_key = f"get_enabled_repo_integrations_{event.repo.repo_id}"
224 cache_key = f"get_enabled_repo_integrations_{event.repo.repo_id}"
225 query = query.options(
225 query = query.options(
226 FromCache("sql_cache_short", cache_key))
226 FromCache("sql_cache_short", cache_key))
227 else: # only global integrations
227 else: # only global integrations
228 order_by_criterion = Integration.integration_id
228 order_by_criterion = Integration.integration_id
229
229
230 query = query.filter(global_integrations_filter)
230 query = query.filter(global_integrations_filter)
231 query = query.order_by(order_by_criterion)
231 query = query.order_by(order_by_criterion)
232 if cache:
232 if cache:
233 query = query.options(
233 query = query.options(
234 FromCache("sql_cache_short", "get_enabled_global_integrations"))
234 FromCache("sql_cache_short", "get_enabled_global_integrations"))
235
235
236 result = query.all()
236 result = query.all()
237 return result
237 return result
General Comments 0
You need to be logged in to leave comments. Login now