logdetective 0.6.0__py3-none-any.whl → 0.9.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- logdetective/prompts.yml +4 -4
- logdetective/server/compressors.py +144 -0
- logdetective/server/database/base.py +3 -0
- logdetective/server/database/models/__init__.py +21 -0
- logdetective/server/database/models/merge_request_jobs.py +515 -0
- logdetective/server/database/{models.py → models/metrics.py} +105 -100
- logdetective/server/metric.py +40 -16
- logdetective/server/models.py +12 -3
- logdetective/server/remote_log.py +109 -0
- logdetective/server/server.py +287 -136
- logdetective/utils.py +9 -37
- {logdetective-0.6.0.dist-info → logdetective-0.9.1.dist-info}/METADATA +11 -6
- logdetective-0.9.1.dist-info/RECORD +28 -0
- {logdetective-0.6.0.dist-info → logdetective-0.9.1.dist-info}/WHEEL +1 -1
- logdetective-0.6.0.dist-info/RECORD +0 -24
- {logdetective-0.6.0.dist-info → logdetective-0.9.1.dist-info}/LICENSE +0 -0
- {logdetective-0.6.0.dist-info → logdetective-0.9.1.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
import datetime
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import backoff
|
|
6
|
+
|
|
7
|
+
from sqlalchemy import (
|
|
8
|
+
Enum,
|
|
9
|
+
Column,
|
|
10
|
+
BigInteger,
|
|
11
|
+
DateTime,
|
|
12
|
+
String,
|
|
13
|
+
ForeignKey,
|
|
14
|
+
UniqueConstraint,
|
|
15
|
+
desc,
|
|
16
|
+
)
|
|
17
|
+
from sqlalchemy.orm import relationship
|
|
18
|
+
from sqlalchemy.exc import OperationalError
|
|
19
|
+
from logdetective.server.database.base import Base, transaction, DB_MAX_RETRIES
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Forge(str, enum.Enum):
|
|
23
|
+
"""List of forges managed by logdetective"""
|
|
24
|
+
|
|
25
|
+
gitlab_com = "https://gitlab.com" # pylint: disable=(invalid-name)
|
|
26
|
+
gitlab_cee_redhat_com = "http://gitlab.cee.redhat.com/" # pylint: disable=(invalid-name)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class GitlabMergeRequestJobs(Base):
|
|
30
|
+
"""Store details for the merge request jobs
|
|
31
|
+
which triggered logdetective.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
__tablename__ = "gitlab_merge_request_jobs"
|
|
35
|
+
|
|
36
|
+
id = Column(BigInteger, primary_key=True)
|
|
37
|
+
forge = Column(Enum(Forge), nullable=False, index=True, comment="The forge name")
|
|
38
|
+
project_id = Column(
|
|
39
|
+
BigInteger,
|
|
40
|
+
nullable=False,
|
|
41
|
+
index=True,
|
|
42
|
+
comment="The project gitlab id",
|
|
43
|
+
)
|
|
44
|
+
mr_iid = Column(
|
|
45
|
+
BigInteger,
|
|
46
|
+
nullable=False,
|
|
47
|
+
index=False,
|
|
48
|
+
comment="The merge request gitlab iid",
|
|
49
|
+
)
|
|
50
|
+
job_id = Column(
|
|
51
|
+
BigInteger,
|
|
52
|
+
nullable=False,
|
|
53
|
+
index=True,
|
|
54
|
+
comment="The job gitlab id",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
__table_args__ = (
|
|
58
|
+
UniqueConstraint("forge", "job_id", name="uix_forge_job"),
|
|
59
|
+
UniqueConstraint(
|
|
60
|
+
"forge", "project_id", "mr_iid", "job_id", name="uix_mr_project_job"
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
comment = relationship(
|
|
65
|
+
"Comments", back_populates="merge_request_job", uselist=False
|
|
66
|
+
) # 1 comment for 1 job
|
|
67
|
+
|
|
68
|
+
request_metrics = relationship("AnalyzeRequestMetrics", back_populates="mr_job")
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
@backoff.on_exception(backoff.expo, OperationalError, max_tries=DB_MAX_RETRIES)
|
|
72
|
+
def create(
|
|
73
|
+
cls,
|
|
74
|
+
forge: Forge,
|
|
75
|
+
project_id: int,
|
|
76
|
+
mr_iid: int,
|
|
77
|
+
job_id: int,
|
|
78
|
+
) -> int:
|
|
79
|
+
"""Create a new merge request job entry,
|
|
80
|
+
returns its PostgreSQL id
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
forge: forge name
|
|
84
|
+
project_id: forge project id
|
|
85
|
+
mr_iid: merge request forge iid
|
|
86
|
+
job_id: forge job id
|
|
87
|
+
"""
|
|
88
|
+
with transaction(commit=True) as session:
|
|
89
|
+
mr = cls()
|
|
90
|
+
mr.forge = forge
|
|
91
|
+
mr.project_id = project_id
|
|
92
|
+
mr.mr_iid = mr_iid
|
|
93
|
+
mr.job_id = job_id
|
|
94
|
+
session.add(mr)
|
|
95
|
+
session.flush()
|
|
96
|
+
return mr.id
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def get_by_id(
|
|
100
|
+
cls,
|
|
101
|
+
id_: int,
|
|
102
|
+
) -> Optional["GitlabMergeRequestJobs"]:
|
|
103
|
+
"""Search for a given PostgreSQL id"""
|
|
104
|
+
with transaction(commit=False) as session:
|
|
105
|
+
mr = session.query(cls).filter_by(id=id_).first()
|
|
106
|
+
return mr
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def get_by_details(
|
|
110
|
+
cls,
|
|
111
|
+
forge: Forge,
|
|
112
|
+
project_id: int,
|
|
113
|
+
mr_iid: int,
|
|
114
|
+
job_id: int,
|
|
115
|
+
) -> Optional["GitlabMergeRequestJobs"]:
|
|
116
|
+
"""Search for a detailed merge request.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
forge: forge name
|
|
120
|
+
project_id: forge project id
|
|
121
|
+
mr_iid: merge request forge iid
|
|
122
|
+
job_id: forge job id
|
|
123
|
+
"""
|
|
124
|
+
with transaction(commit=False) as session:
|
|
125
|
+
mr = (
|
|
126
|
+
session.query(cls)
|
|
127
|
+
.filter_by(
|
|
128
|
+
forge=forge, project_id=project_id, mr_iid=mr_iid, job_id=job_id
|
|
129
|
+
)
|
|
130
|
+
.first()
|
|
131
|
+
)
|
|
132
|
+
return mr
|
|
133
|
+
|
|
134
|
+
@classmethod
|
|
135
|
+
def get_or_create(
|
|
136
|
+
cls,
|
|
137
|
+
forge: Forge,
|
|
138
|
+
project_id: int,
|
|
139
|
+
mr_iid: int,
|
|
140
|
+
job_id: int,
|
|
141
|
+
) -> Optional["GitlabMergeRequestJobs"]:
|
|
142
|
+
"""Search for a detailed merge request
|
|
143
|
+
or create a new one if not found.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
forge: forge name
|
|
147
|
+
project_id: forge project id
|
|
148
|
+
mr_iid: merge request forge iid
|
|
149
|
+
job_id: forge job id
|
|
150
|
+
"""
|
|
151
|
+
mr = GitlabMergeRequestJobs.get_by_details(forge, project_id, mr_iid, job_id)
|
|
152
|
+
if mr is None:
|
|
153
|
+
id_ = GitlabMergeRequestJobs.create(forge, project_id, mr_iid, job_id)
|
|
154
|
+
mr = GitlabMergeRequestJobs.get_by_id(id_)
|
|
155
|
+
return mr
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class Comments(Base):
|
|
159
|
+
"""Store details for comments
|
|
160
|
+
created by logdetective for a merge request job."""
|
|
161
|
+
|
|
162
|
+
__tablename__ = "comments"
|
|
163
|
+
|
|
164
|
+
id = Column(BigInteger, primary_key=True)
|
|
165
|
+
merge_request_job_id = Column(
|
|
166
|
+
BigInteger,
|
|
167
|
+
ForeignKey("gitlab_merge_request_jobs.id"),
|
|
168
|
+
nullable=False,
|
|
169
|
+
unique=True, # 1 comment for 1 job
|
|
170
|
+
index=True,
|
|
171
|
+
comment="The associated merge request job (db) id",
|
|
172
|
+
)
|
|
173
|
+
forge = Column(
|
|
174
|
+
Enum(Forge),
|
|
175
|
+
nullable=False,
|
|
176
|
+
index=True,
|
|
177
|
+
comment="The forge name"
|
|
178
|
+
)
|
|
179
|
+
comment_id = Column(
|
|
180
|
+
String(50), # e.g. 'd5a3ff139356ce33e37e73add446f16869741b50'
|
|
181
|
+
nullable=False,
|
|
182
|
+
index=True,
|
|
183
|
+
comment="The comment gitlab id",
|
|
184
|
+
)
|
|
185
|
+
created_at = Column(
|
|
186
|
+
DateTime, nullable=False, comment="Timestamp when the comment was created"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
__table_args__ = (
|
|
190
|
+
UniqueConstraint("forge", "comment_id", name="uix_forge_comment_id"),
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
merge_request_job = relationship("GitlabMergeRequestJobs", back_populates="comment")
|
|
194
|
+
reactions = relationship("Reactions", back_populates="comment")
|
|
195
|
+
|
|
196
|
+
@classmethod
|
|
197
|
+
@backoff.on_exception(backoff.expo, OperationalError, max_tries=DB_MAX_RETRIES)
|
|
198
|
+
def create( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
|
|
199
|
+
cls,
|
|
200
|
+
forge: Forge,
|
|
201
|
+
project_id: int,
|
|
202
|
+
mr_iid: int,
|
|
203
|
+
job_id: int,
|
|
204
|
+
comment_id: str,
|
|
205
|
+
metrics: Optional["AnalyzeRequestMetrics"] = None, # noqa: F821
|
|
206
|
+
) -> int:
|
|
207
|
+
"""Create a new comment id entry,
|
|
208
|
+
returns its PostgreSQL id.
|
|
209
|
+
A Gitlab comment id is unique within a
|
|
210
|
+
gitlab instance.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
forge: forge name
|
|
214
|
+
project_id: forge project id
|
|
215
|
+
mr_iid: merge request forge iid
|
|
216
|
+
job_id: forge job id
|
|
217
|
+
comment_id: forge comment id
|
|
218
|
+
"""
|
|
219
|
+
with transaction(commit=True) as session:
|
|
220
|
+
mr_job = GitlabMergeRequestJobs.get_or_create(
|
|
221
|
+
forge, project_id, mr_iid, job_id
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
if metrics:
|
|
225
|
+
metrics.mr_job = mr_job
|
|
226
|
+
session.add(metrics)
|
|
227
|
+
|
|
228
|
+
comment = cls()
|
|
229
|
+
comment.forge = forge
|
|
230
|
+
comment.comment_id = comment_id
|
|
231
|
+
comment.created_at = datetime.datetime.now(datetime.timezone.utc)
|
|
232
|
+
comment.merge_request_job_id = mr_job.id
|
|
233
|
+
session.add(comment)
|
|
234
|
+
session.flush()
|
|
235
|
+
return comment.id
|
|
236
|
+
|
|
237
|
+
@classmethod
|
|
238
|
+
def get_by_id(
|
|
239
|
+
cls,
|
|
240
|
+
id_: int,
|
|
241
|
+
) -> Optional["Comments"]:
|
|
242
|
+
"""Search for a given PostgreSQL id"""
|
|
243
|
+
with transaction(commit=False) as session:
|
|
244
|
+
comment = session.query(cls).filter_by(id=id_).first()
|
|
245
|
+
return comment
|
|
246
|
+
|
|
247
|
+
@classmethod
|
|
248
|
+
def get_by_gitlab_id(
|
|
249
|
+
cls,
|
|
250
|
+
forge: Forge,
|
|
251
|
+
comment_id: str,
|
|
252
|
+
) -> Optional["Comments"]:
|
|
253
|
+
"""Search for a detailed comment
|
|
254
|
+
by its unique forge comment id.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
forge: forge name
|
|
258
|
+
comment_id: forge comment id
|
|
259
|
+
"""
|
|
260
|
+
with transaction(commit=False) as session:
|
|
261
|
+
comment = (
|
|
262
|
+
session.query(cls)
|
|
263
|
+
.join(
|
|
264
|
+
GitlabMergeRequestJobs,
|
|
265
|
+
cls.merge_request_job_id == GitlabMergeRequestJobs.id,
|
|
266
|
+
)
|
|
267
|
+
.filter(
|
|
268
|
+
GitlabMergeRequestJobs.forge == forge,
|
|
269
|
+
cls.comment_id == comment_id,
|
|
270
|
+
)
|
|
271
|
+
.first()
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
return comment
|
|
275
|
+
|
|
276
|
+
@classmethod
|
|
277
|
+
def get_latest_comment(
|
|
278
|
+
cls,
|
|
279
|
+
forge: Forge,
|
|
280
|
+
project_id: int,
|
|
281
|
+
mr_iid: int,
|
|
282
|
+
) -> Optional["Comments"]:
|
|
283
|
+
"""Search for the latest comment in the merge request.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
forge: forge name
|
|
287
|
+
project_id: forge project id
|
|
288
|
+
mr_iid: merge request forge iid
|
|
289
|
+
"""
|
|
290
|
+
with transaction(commit=False) as session:
|
|
291
|
+
comment = (
|
|
292
|
+
session.query(cls)
|
|
293
|
+
.join(
|
|
294
|
+
GitlabMergeRequestJobs,
|
|
295
|
+
cls.merge_request_job_id == GitlabMergeRequestJobs.id,
|
|
296
|
+
)
|
|
297
|
+
.filter(
|
|
298
|
+
GitlabMergeRequestJobs.forge == forge,
|
|
299
|
+
GitlabMergeRequestJobs.project_id == project_id,
|
|
300
|
+
GitlabMergeRequestJobs.mr_iid == mr_iid,
|
|
301
|
+
)
|
|
302
|
+
.order_by(desc(cls.created_at))
|
|
303
|
+
.first()
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
return comment
|
|
307
|
+
|
|
308
|
+
@classmethod
|
|
309
|
+
def get_mr_comments(
|
|
310
|
+
cls,
|
|
311
|
+
forge: Forge,
|
|
312
|
+
project_id: int,
|
|
313
|
+
mr_iid: int,
|
|
314
|
+
) -> Optional["Comments"]:
|
|
315
|
+
"""Search for all merge request comments.
|
|
316
|
+
|
|
317
|
+
Args:
|
|
318
|
+
forge: forge name
|
|
319
|
+
project_id: forge project id
|
|
320
|
+
mr_iid: merge request forge iid
|
|
321
|
+
"""
|
|
322
|
+
with transaction(commit=False) as session:
|
|
323
|
+
comments = (
|
|
324
|
+
session.query(cls)
|
|
325
|
+
.join(
|
|
326
|
+
GitlabMergeRequestJobs,
|
|
327
|
+
cls.merge_request_job_id == GitlabMergeRequestJobs.id,
|
|
328
|
+
)
|
|
329
|
+
.filter(
|
|
330
|
+
GitlabMergeRequestJobs.forge == forge,
|
|
331
|
+
GitlabMergeRequestJobs.project_id == project_id,
|
|
332
|
+
GitlabMergeRequestJobs.mr_iid == mr_iid,
|
|
333
|
+
)
|
|
334
|
+
.order_by(desc(cls.created_at))
|
|
335
|
+
.all()
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
return comments
|
|
339
|
+
|
|
340
|
+
@classmethod
|
|
341
|
+
def get_or_create( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
|
|
342
|
+
cls,
|
|
343
|
+
forge: Forge,
|
|
344
|
+
project_id: int,
|
|
345
|
+
mr_iid: int,
|
|
346
|
+
job_id: int,
|
|
347
|
+
comment_id: str,
|
|
348
|
+
) -> Optional["Comments"]:
|
|
349
|
+
"""Search for a detailed comment
|
|
350
|
+
or create a new one if not found.
|
|
351
|
+
|
|
352
|
+
Args:
|
|
353
|
+
forge: forge name
|
|
354
|
+
project_id: forge project id
|
|
355
|
+
mr_iid: merge request forge iid
|
|
356
|
+
job_id: forge job id
|
|
357
|
+
comment_id: forge comment id
|
|
358
|
+
"""
|
|
359
|
+
comment = Comments.get_by_gitlab_id(forge, comment_id)
|
|
360
|
+
if comment is None:
|
|
361
|
+
id_ = Comments.create(forge, project_id, mr_iid, job_id, comment_id)
|
|
362
|
+
comment = GitlabMergeRequestJobs.get_by_id(id_)
|
|
363
|
+
return comment
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class Reactions(Base):
|
|
367
|
+
"""Store and count reactions received for
|
|
368
|
+
logdetective comments"""
|
|
369
|
+
|
|
370
|
+
__tablename__ = "reactions"
|
|
371
|
+
|
|
372
|
+
id = Column(BigInteger, primary_key=True)
|
|
373
|
+
comment_id = Column(
|
|
374
|
+
BigInteger,
|
|
375
|
+
ForeignKey("comments.id"),
|
|
376
|
+
nullable=False,
|
|
377
|
+
index=True,
|
|
378
|
+
comment="The associated comment (db) id",
|
|
379
|
+
)
|
|
380
|
+
reaction_type = Column(
|
|
381
|
+
String(127), # e.g. 'thumbs-up'
|
|
382
|
+
nullable=False,
|
|
383
|
+
comment="The type of reaction",
|
|
384
|
+
)
|
|
385
|
+
count = Column(
|
|
386
|
+
BigInteger,
|
|
387
|
+
nullable=False,
|
|
388
|
+
comment="The number of reactions, of this type, given in the comment",
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
__table_args__ = (
|
|
392
|
+
UniqueConstraint("comment_id", "reaction_type", name="uix_comment_reaction"),
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
comment = relationship("Comments", back_populates="reactions")
|
|
396
|
+
|
|
397
|
+
@classmethod
|
|
398
|
+
@backoff.on_exception(backoff.expo, OperationalError, max_tries=DB_MAX_RETRIES)
|
|
399
|
+
def create_or_update( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
|
|
400
|
+
cls,
|
|
401
|
+
forge: Forge,
|
|
402
|
+
project_id: int,
|
|
403
|
+
mr_iid: int,
|
|
404
|
+
job_id: int,
|
|
405
|
+
comment_id: str,
|
|
406
|
+
reaction_type: str,
|
|
407
|
+
count: int,
|
|
408
|
+
) -> int:
|
|
409
|
+
"""Create or update the given reaction, and its associated count,
|
|
410
|
+
for a specified comment.
|
|
411
|
+
|
|
412
|
+
Args:
|
|
413
|
+
forge: forge name
|
|
414
|
+
project_id: forge project id
|
|
415
|
+
mr_iid: merge request forge iid
|
|
416
|
+
job_id: forge job id
|
|
417
|
+
comment_id: forge comment id
|
|
418
|
+
reaction_type: a str, ex. thumb_up
|
|
419
|
+
count: number of reactions, of this type, given in the comment
|
|
420
|
+
"""
|
|
421
|
+
comment = Comments.get_or_create(forge, project_id, mr_iid, job_id, comment_id)
|
|
422
|
+
reaction = cls.get_reaction_by_type(
|
|
423
|
+
forge, project_id, mr_iid, job_id, comment_id, reaction_type
|
|
424
|
+
)
|
|
425
|
+
with transaction(commit=True) as session:
|
|
426
|
+
if reaction:
|
|
427
|
+
reaction.count = count # just update
|
|
428
|
+
else:
|
|
429
|
+
reaction = cls()
|
|
430
|
+
reaction.comment_id = comment.id
|
|
431
|
+
reaction.reaction_type = reaction_type
|
|
432
|
+
reaction.count = count
|
|
433
|
+
session.add(reaction)
|
|
434
|
+
session.flush()
|
|
435
|
+
return reaction.id
|
|
436
|
+
|
|
437
|
+
@classmethod
|
|
438
|
+
def get_all_reactions( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
|
|
439
|
+
cls,
|
|
440
|
+
forge: Forge,
|
|
441
|
+
project_id: int,
|
|
442
|
+
mr_iid: int,
|
|
443
|
+
job_id: int,
|
|
444
|
+
comment_id: str,
|
|
445
|
+
) -> int:
|
|
446
|
+
"""Get all reactions for a comment
|
|
447
|
+
|
|
448
|
+
Args:
|
|
449
|
+
forge: forge name
|
|
450
|
+
project_id: forge project id
|
|
451
|
+
mr_iid: merge request forge iid
|
|
452
|
+
job_id: forge job id
|
|
453
|
+
comment_id: forge comment id
|
|
454
|
+
"""
|
|
455
|
+
with transaction(commit=False) as session:
|
|
456
|
+
reactions = (
|
|
457
|
+
session.query(cls)
|
|
458
|
+
.join(Comments, cls.comment_id == Comments.id)
|
|
459
|
+
.join(
|
|
460
|
+
GitlabMergeRequestJobs,
|
|
461
|
+
Comments.merge_request_job_id == GitlabMergeRequestJobs.id,
|
|
462
|
+
)
|
|
463
|
+
.filter(
|
|
464
|
+
Comments.comment_id == comment_id,
|
|
465
|
+
GitlabMergeRequestJobs.forge == forge,
|
|
466
|
+
GitlabMergeRequestJobs.project_id == project_id,
|
|
467
|
+
GitlabMergeRequestJobs.mr_iid == mr_iid,
|
|
468
|
+
GitlabMergeRequestJobs.job_id == job_id,
|
|
469
|
+
)
|
|
470
|
+
.all()
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
return reactions
|
|
474
|
+
|
|
475
|
+
@classmethod
|
|
476
|
+
def get_reaction_by_type( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
|
|
477
|
+
cls,
|
|
478
|
+
forge: Forge,
|
|
479
|
+
project_id: int,
|
|
480
|
+
mr_iid: int,
|
|
481
|
+
job_id: int,
|
|
482
|
+
comment_id: str,
|
|
483
|
+
reaction_type: str,
|
|
484
|
+
) -> int:
|
|
485
|
+
"""Get reaction, of a given type,
|
|
486
|
+
for a comment
|
|
487
|
+
|
|
488
|
+
Args:
|
|
489
|
+
forge: forge name
|
|
490
|
+
project_id: forge project id
|
|
491
|
+
mr_iid: merge request forge iid
|
|
492
|
+
job_id: forge job id
|
|
493
|
+
comment_id: forge comment id
|
|
494
|
+
reaction_type: str like "thumb-up"
|
|
495
|
+
"""
|
|
496
|
+
with transaction(commit=False) as session:
|
|
497
|
+
reaction = (
|
|
498
|
+
session.query(cls)
|
|
499
|
+
.join(Comments, cls.comment_id == Comments.id)
|
|
500
|
+
.join(
|
|
501
|
+
GitlabMergeRequestJobs,
|
|
502
|
+
Comments.merge_request_job_id == GitlabMergeRequestJobs.id,
|
|
503
|
+
)
|
|
504
|
+
.filter(
|
|
505
|
+
Comments.comment_id == comment_id,
|
|
506
|
+
GitlabMergeRequestJobs.forge == forge,
|
|
507
|
+
GitlabMergeRequestJobs.project_id == project_id,
|
|
508
|
+
GitlabMergeRequestJobs.mr_iid == mr_iid,
|
|
509
|
+
GitlabMergeRequestJobs.job_id == job_id,
|
|
510
|
+
Reactions.reaction_type == reaction_type,
|
|
511
|
+
)
|
|
512
|
+
.first()
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
return reaction
|