1717
1818import github
1919import gitlab
20- import pyforgejo
2120import requests
2221
2322from ogr .deprecation import deprecate_and_set_removal
2423from ogr .exceptions import (
2524 APIException ,
26- ForgejoAPIException ,
2725 GitForgeInternalError ,
2826 GithubAPIException ,
2927 GitlabAPIException ,
@@ -61,11 +59,7 @@ def __check_for_internal_failure(ex: APIException):
6159
6260
6361def __wrap_exception (
64- ex : Union [
65- github .GithubException ,
66- gitlab .GitlabError ,
67- pyforgejo .core .api_error .ApiError ,
68- ],
62+ ex : Union [github .GithubException , gitlab .GitlabError ],
6963) -> APIException :
7064 """
7165 Wraps uncaught exception in one of ogr exceptions.
@@ -82,7 +76,6 @@ def __wrap_exception(
8276 MAPPING = {
8377 github .GithubException : GithubAPIException ,
8478 gitlab .GitlabError : GitlabAPIException ,
85- pyforgejo .core .api_error .ApiError : ForgejoAPIException ,
8679 }
8780
8881 for caught_exception , ogr_exception in MAPPING .items ():
@@ -121,11 +114,7 @@ def wrapper(*args, **kwargs):
121114 ) from ex
122115 except APIException as ex :
123116 __check_for_internal_failure (ex )
124- except (
125- github .GithubException ,
126- gitlab .GitlabError ,
127- pyforgejo .core .api_error .ApiError ,
128- ) as ex :
117+ except (github .GithubException , gitlab .GitlabError ) as ex :
129118 __check_for_internal_failure (__wrap_exception (ex ))
130119
131120 return wrapper
@@ -168,34 +157,15 @@ def __repr__(self) -> str:
168157
169158
170159class Reaction (OgrAbstractClass ):
171- def __init__ (
172- self ,
173- raw_reaction : Any ,
174- reaction_id : Optional [int ] = None ,
175- parent : Optional [Any ] = None ,
176- ) -> None :
160+ def __init__ (self , raw_reaction : Any ) -> None :
177161 self ._raw_reaction = raw_reaction
178- self ._id = reaction_id
179- self ._parent = parent
180162
181163 def __str__ (self ):
182164 return f"Reaction(raw_reaction={ self ._raw_reaction } )"
183165
184166 def delete (self ) -> None :
185167 """Delete a reaction."""
186- if not self ._id :
187- raise ValueError ("Cannot delete a reaction without an ID." )
188- if not self ._parent :
189- raise ValueError ("Cannot delete a reaction without a parent object." )
190- if not self ._raw_reaction or "content" not in self ._raw_reaction :
191- raise ValueError ("Invalid raw reaction data." )
192-
193- self ._parent .client .issue .delete_comment_reaction (
194- owner = self ._parent .repo_namespace ,
195- repo = self ._parent .repo_name ,
196- id = self ._id ,
197- content = self ._raw_reaction ["content" ],
198- )
168+ raise NotImplementedError ()
199169
200170
201171class Comment (OgrAbstractClass ):
@@ -234,11 +204,7 @@ def __str__(self) -> str:
234204
235205 def _from_raw_comment (self , raw_comment : Any ) -> None :
236206 """Constructs Comment object from raw_comment given from API."""
237- self ._id = raw_comment ["id" ]
238- self ._body = raw_comment ["body" ]
239- self ._author = raw_comment ["user" ]["login" ]
240- self ._created = raw_comment ["created_at" ]
241- self ._edited = raw_comment .get ("updated_at" )
207+ raise NotImplementedError ()
242208
243209 @property
244210 def body (self ) -> str :
@@ -270,15 +236,7 @@ def edited(self) -> datetime.datetime:
270236
271237 def get_reactions (self ) -> list [Reaction ]:
272238 """Returns list of reactions."""
273- if not self ._id or not self ._parent :
274- raise ValueError ("Cannot fetch reactions without a comment ID and parent." )
275-
276- reactions_data = self ._parent .client .issue .get_comment_reactions (
277- owner = self ._parent .repo_namespace ,
278- repo = self ._parent .repo_name ,
279- id = self ._id ,
280- )
281- return [Reaction (raw_reaction = react ) for react in reactions_data ]
239+ raise NotImplementedError ()
282240
283241 def add_reaction (self , reaction : str ) -> Reaction :
284242 """
@@ -292,16 +250,7 @@ def add_reaction(self, reaction: str) -> Reaction:
292250 Returns:
293251 Object representing newly added reaction.
294252 """
295- if not self ._id or not self ._parent :
296- raise ValueError ("Cannot add reaction without a comment ID and parent." )
297-
298- reaction_data = self ._parent .client .issue .add_comment_reaction (
299- owner = self ._parent .repo_namespace ,
300- repo = self ._parent .repo_name ,
301- id = self ._id ,
302- content = reaction ,
303- )
304- return Reaction (raw_reaction = reaction_data )
253+ raise NotImplementedError ()
305254
306255
307256class IssueComment (Comment ):
@@ -324,6 +273,125 @@ def __str__(self) -> str:
324273 return "PR" + super ().__str__ ()
325274
326275
276+ class ForgejoAPI :
277+
278+ def __init__ (self , base_url , token ):
279+ self .base_url = base_url .rstrip ("/" )
280+ self .headers = {
281+ "Authorization" : f"token { token } " ,
282+ "Content-Type" : "application/json" ,
283+ }
284+
285+ def create_comment (self , owner , repo , issue_index , body ):
286+ """Create a comment on an issue/pull request"""
287+ url = (
288+ f"{ self .base_url } /api/v1/repos/{ owner } /{ repo } /issues/{ issue_index } /comments"
289+ )
290+ payload = {"body" : body }
291+ response = requests .post (url , headers = self .headers , json = payload )
292+ response .raise_for_status ()
293+ return response .json ()
294+
295+ def list_comments (self , owner , repo , issue_index ):
296+ """List all comments on an issue/pull request"""
297+ url = (
298+ f"{ self .base_url } /api/v1/repos/{ owner } /{ repo } /issues/{ issue_index } /comments"
299+ )
300+ response = requests .get (url , headers = self .headers )
301+ response .raise_for_status ()
302+ return response .json ()
303+
304+ def add_reaction (self , owner , repo , comment_id , reaction_type ):
305+ """Add a reaction to a comment"""
306+ url = f"{ self .base_url } /api/v1/repos/{ owner } /{ repo } /issues/comments/{ comment_id } /reactions"
307+ payload = {"content" : reaction_type }
308+ response = requests .post (url , headers = self .headers , json = payload )
309+ response .raise_for_status ()
310+ return response .json ()
311+
312+ def delete_reaction (self , owner , repo , comment_id , reaction_type ):
313+ """Remove a reaction from a comment"""
314+ url = f"{ self .base_url } /api/v1/repos/{ owner } /{ repo } /issues/comments/{ comment_id } /reactions"
315+ params = {"content" : reaction_type }
316+ response = requests .delete (url , headers = self .headers , params = params )
317+ response .raise_for_status ()
318+ return response .json ()
319+
320+ def list_reactions (self , owner , repo , comment_id ):
321+ """List reactions on a comment"""
322+ url = f"{ self .base_url } /api/v1/repos/{ owner } /{ repo } /issues/comments/{ comment_id } /reactions"
323+ response = requests .get (url , headers = self .headers )
324+ response .raise_for_status ()
325+ return response .json ()
326+
327+
328+ class ForgejoReaction (Reaction ):
329+ def __init__ (self , raw_reaction , api_client , owner , repo , comment_id ):
330+ super ().__init__ (raw_reaction )
331+ self ._api = api_client
332+ self ._owner = owner
333+ self ._repo = repo
334+ self ._comment_id = comment_id
335+ self .reaction_type = raw_reaction .get ("content" )
336+
337+ def delete (self ) -> None :
338+ self ._api .delete_reaction (
339+ self ._owner ,
340+ self ._repo ,
341+ self ._comment_id ,
342+ self .reaction_type ,
343+ )
344+
345+
346+ class ForgejoIssueComment (IssueComment ):
347+ def _from_raw_comment (self , raw_comment : dict ) -> None :
348+ self ._body = raw_comment .get ("body" )
349+ self ._id = raw_comment .get ("id" )
350+ self ._author = raw_comment .get ("user" , {}).get ("login" )
351+ self ._created = datetime .datetime .fromisoformat (raw_comment .get ("created_at" ))
352+ self ._edited = (
353+ datetime .datetime .fromisoformat (raw_comment ["updated_at" ])
354+ if raw_comment .get ("updated_at" )
355+ else None
356+ )
357+
358+ def get_reactions (self ) -> list [Reaction ]:
359+ owner = self ._parent .project .owner
360+ repo = self ._parent .project .repo
361+ reactions = self ._parent .service .forgejo_api .list_reactions (
362+ owner ,
363+ repo ,
364+ self .id ,
365+ )
366+ return [
367+ ForgejoReaction (
368+ raw_reaction = r ,
369+ api_client = self ._parent .service .forgejo_api ,
370+ owner = owner ,
371+ repo = repo ,
372+ comment_id = self .id ,
373+ )
374+ for r in reactions
375+ ]
376+
377+ def add_reaction (self , reaction : str ) -> ForgejoReaction :
378+ owner = self ._parent .project .owner
379+ repo = self ._parent .project .repo
380+ reaction_data = self ._parent .service .forgejo_api .add_reaction (
381+ owner ,
382+ repo ,
383+ self .id ,
384+ reaction ,
385+ )
386+ return ForgejoReaction (
387+ raw_reaction = reaction_data ,
388+ api_client = self ._parent .service .forgejo_api ,
389+ owner = owner ,
390+ repo = repo ,
391+ comment_id = self .id ,
392+ )
393+
394+
327395class IssueStatus (IntEnum ):
328396 """Enumeration for issue statuses."""
329397
0 commit comments