@@ -633,4 +633,199 @@ def get_current_user(self) -> Dict[str, Any]:
633633 Dictionary containing the current user data
634634 """
635635 endpoint = self .get_endpoint ("user_current" )
636- return self .get (endpoint )
636+ return self .get (endpoint )
637+
638+ def get_custom_fields (self ) -> List [Dict [str , Any ]]:
639+ """
640+ Get all custom fields defined in the Jira instance.
641+
642+ Returns:
643+ List of custom field definitions
644+ """
645+ endpoint = self .get_endpoint ("field" )
646+
647+ try :
648+ fields = self .get (endpoint )
649+ # Filter for custom fields only (custom fields have customfield_ prefix in their id)
650+ return [field for field in fields if field .get ("id" , "" ).startswith ("customfield_" )]
651+ except Exception as e :
652+ log .error (f"Failed to retrieve custom fields: { e } " )
653+ raise
654+
655+ def get_project_issues (
656+ self ,
657+ project_id_or_key : str ,
658+ fields : Union [str , List [str ]] = "*all" ,
659+ start_at : int = 0 ,
660+ max_results : Optional [int ] = None
661+ ) -> List [Dict [str , Any ]]:
662+ """
663+ Get all issues for a project.
664+
665+ Args:
666+ project_id_or_key: Project ID or key
667+ fields: Fields to include in the response (comma-separated string or list)
668+ start_at: Index of the first issue to return
669+ max_results: Maximum number of issues to return
670+
671+ Returns:
672+ List of issues in the project
673+ """
674+ jql = f'project = "{ project_id_or_key } " ORDER BY key'
675+
676+ # Handle fields parameter
677+ if isinstance (fields , list ):
678+ fields = "," .join (fields )
679+
680+ # Get search results
681+ result = self .search_issues (
682+ jql = jql ,
683+ start_at = start_at ,
684+ max_results = max_results or 50 ,
685+ fields = fields
686+ )
687+
688+ return result .get ("issues" , [])
689+
690+ def get_project_issues_count (self , project_id_or_key : str ) -> int :
691+ """
692+ Get the number of issues in a project.
693+
694+ Args:
695+ project_id_or_key: Project ID or key
696+
697+ Returns:
698+ Number of issues in the project
699+ """
700+ jql = f'project = "{ project_id_or_key } "'
701+
702+ # Search with no fields to minimize response size
703+ result = self .search_issues (jql = jql , fields = ["key" ], max_results = 1 )
704+
705+ return result .get ("total" , 0 )
706+
707+ def get_issue_remotelinks (
708+ self ,
709+ issue_id_or_key : str ,
710+ global_id : Optional [str ] = None
711+ ) -> List [Dict [str , Any ]]:
712+ """
713+ Get remote links for an issue.
714+
715+ Args:
716+ issue_id_or_key: Issue ID or key
717+ global_id: Filter by global ID
718+
719+ Returns:
720+ List of remote links
721+ """
722+ issue_id_or_key = self .validate_id_or_key (issue_id_or_key , "issue_id_or_key" )
723+ endpoint = self .get_endpoint ("issue_remotelinks" , id = issue_id_or_key )
724+
725+ params = {}
726+ if global_id :
727+ params ["globalId" ] = global_id
728+
729+ try :
730+ return self .get (endpoint , params = params )
731+ except Exception as e :
732+ log .error (f"Failed to retrieve remote links for issue { issue_id_or_key } : { e } " )
733+ raise
734+
735+ def get_issue_watchers (self , issue_id_or_key : str ) -> Dict [str , Any ]:
736+ """
737+ Get watchers for an issue.
738+
739+ Args:
740+ issue_id_or_key: Issue ID or key
741+
742+ Returns:
743+ Dictionary containing watchers information
744+ """
745+ issue_id_or_key = self .validate_id_or_key (issue_id_or_key , "issue_id_or_key" )
746+ endpoint = self .get_endpoint ("issue_watchers" , id = issue_id_or_key )
747+
748+ try :
749+ return self .get (endpoint )
750+ except Exception as e :
751+ log .error (f"Failed to retrieve watchers for issue { issue_id_or_key } : { e } " )
752+ raise
753+
754+ def get_issue_remote_link_by_id (self , issue_id_or_key : str , link_id : str ) -> Dict [str , Any ]:
755+ """
756+ Get a specific remote link for an issue.
757+
758+ Args:
759+ issue_id_or_key: Issue ID or key
760+ link_id: Remote link ID
761+
762+ Returns:
763+ Remote link details
764+ """
765+ issue_id_or_key = self .validate_id_or_key (issue_id_or_key , "issue_id_or_key" )
766+ endpoint = f"{ self .get_endpoint ('issue_remotelinks' , id = issue_id_or_key )} /{ link_id } "
767+
768+ try :
769+ return self .get (endpoint )
770+ except Exception as e :
771+ log .error (f"Failed to retrieve remote link { link_id } for issue { issue_id_or_key } : { e } " )
772+ raise
773+
774+ def create_or_update_issue_remote_link (
775+ self ,
776+ issue_id_or_key : str ,
777+ link_url : str ,
778+ title : str ,
779+ global_id : Optional [str ] = None ,
780+ relationship : Optional [str ] = None ,
781+ icon_url : Optional [str ] = None ,
782+ icon_title : Optional [str ] = None ,
783+ status_resolved : bool = False
784+ ) -> Dict [str , Any ]:
785+ """
786+ Create or update a remote link for an issue.
787+
788+ Args:
789+ issue_id_or_key: Issue ID or key
790+ link_url: URL of the remote link
791+ title: Title of the remote link
792+ global_id: Global ID for the remote link (used for updates)
793+ relationship: Relationship of the link to the issue
794+ icon_url: URL of an icon for the link
795+ icon_title: Title for the icon
796+ status_resolved: Whether the remote link is resolved
797+
798+ Returns:
799+ Created or updated remote link
800+ """
801+ issue_id_or_key = self .validate_id_or_key (issue_id_or_key , "issue_id_or_key" )
802+ endpoint = self .get_endpoint ("issue_remotelinks" , id = issue_id_or_key )
803+
804+ # Build the payload
805+ data = {
806+ "object" : {
807+ "url" : link_url ,
808+ "title" : title ,
809+ "status" : {"resolved" : status_resolved }
810+ }
811+ }
812+
813+ if global_id :
814+ data ["globalId" ] = global_id
815+
816+ if relationship :
817+ data ["relationship" ] = relationship
818+
819+ if icon_url or icon_title :
820+ icon_data = {}
821+ if icon_url :
822+ icon_data ["url16x16" ] = icon_url
823+ if icon_title :
824+ icon_data ["title" ] = icon_title
825+ data ["object" ]["icon" ] = icon_data
826+
827+ try :
828+ return self .post (endpoint , data = data )
829+ except Exception as e :
830+ log .error (f"Failed to create/update remote link for issue { issue_id_or_key } : { e } " )
831+ raise
0 commit comments