import os import datetime from dotenv import load_dotenv from googleapiclient.discovery import build from googleapiclient.errors import HttpError from dto.post import Post from dto.comment import Comment from server.connectors.base import BaseConnector load_dotenv() API_KEY = os.getenv("YOUTUBE_API_KEY") class YouTubeAPI(BaseConnector): source_name: str = "youtube" display_name: str = "YouTube" search_enabled: bool = True categories_enabled: bool = False def __init__(self): self.youtube = build('youtube', 'v3', developerKey=API_KEY) def get_new_posts_by_search(self, search: str, category: str, post_limit: int ) -> list[Post]: videos = self._search_videos(search, post_limit) posts = [] for video in videos: video_id = video['id']['videoId'] snippet = video['snippet'] title = snippet['title'] description = snippet['description'] published_at = datetime.datetime.strptime(snippet['publishedAt'], "%Y-%m-%dT%H:%M:%SZ").timestamp() channel_title = snippet['channelTitle'] comments = [] comments_data = self._get_video_comments(video_id) for comment_thread in comments_data: comment_snippet = comment_thread['snippet']['topLevelComment']['snippet'] comment = Comment( id=comment_thread['id'], post_id=video_id, content=comment_snippet['textDisplay'], author=comment_snippet['authorDisplayName'], timestamp=datetime.datetime.strptime(comment_snippet['publishedAt'], "%Y-%m-%dT%H:%M:%SZ").timestamp(), reply_to=None, source=self.source_name ) comments.append(comment) post = Post( id=video_id, content=f"{title}\n\n{description}", author=channel_title, timestamp=published_at, url=f"https://www.youtube.com/watch?v={video_id}", title=title, source=self.source_name, comments=comments ) posts.append(post) return posts def category_exists(self, category): return True def _search_videos(self, query, limit): request = self.youtube.search().list( q=query, part='snippet', type='video', maxResults=limit ) response = request.execute() return response.get('items', []) def _get_video_comments(self, video_id): request = self.youtube.commentThreads().list( part='snippet', videoId=video_id, textFormat='plainText' ) try: response = request.execute() except HttpError as e: print(f"Error fetching comments for video {video_id}: {e}") return [] return response.get('items', [])