main.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import os
  2. import datetime
  3. import pickle
  4. from googleapiclient.discovery import build
  5. import subprocess
  6. from google.auth.transport.requests import Request
  7. # Output directory for Emby
  8. OUTPUT_DIR = "/media/media/YouTube"
  9. # Days to look back for videos
  10. DAYS_BACK = 5
  11. # Token file
  12. TOKEN_FILE = "youtube_token.pickle"
  13. def authenticate_with_token():
  14. """Authenticate using the saved token."""
  15. if not os.path.exists(TOKEN_FILE):
  16. raise FileNotFoundError(f"Token file '{TOKEN_FILE}' not found. Please run the token retrieval script first.")
  17. with open(TOKEN_FILE, "rb") as token:
  18. creds = pickle.load(token)
  19. # Refresh the token if needed
  20. if creds and creds.expired and creds.refresh_token:
  21. creds.refresh(Request())
  22. youtube = build("youtube", "v3", credentials=creds)
  23. return youtube
  24. def get_subscribed_channels(youtube):
  25. """Fetch the list of subscribed channels."""
  26. channels = []
  27. request = youtube.subscriptions().list(
  28. part="snippet",
  29. mine=True,
  30. maxResults=50
  31. )
  32. while request:
  33. response = request.execute()
  34. for item in response["items"]:
  35. channels.append(item["snippet"]["resourceId"]["channelId"])
  36. request = youtube.subscriptions().list_next(request, response)
  37. return channels
  38. def get_recent_videos(youtube, channel_id):
  39. """Fetch videos from a channel published in the last `DAYS_BACK` days."""
  40. recent_videos = []
  41. published_after = (datetime.datetime.now() - datetime.timedelta(days=DAYS_BACK)).isoformat("T") + "Z"
  42. request = youtube.search().list(
  43. part="snippet",
  44. channelId=channel_id,
  45. publishedAfter=published_after,
  46. maxResults=50,
  47. type="video",
  48. order="date"
  49. )
  50. response = request.execute()
  51. for item in response["items"]:
  52. recent_videos.append({
  53. "video_id": item["id"]["videoId"],
  54. "title": item["snippet"]["title"],
  55. "description": item["snippet"]["description"],
  56. "published_at": item["snippet"]["publishedAt"],
  57. "channel_title": item["snippet"]["channelTitle"]
  58. })
  59. return recent_videos
  60. def download_video(video_id, output_path):
  61. """Download a YouTube video using yt-dlp."""
  62. command = [
  63. "yt-dlp",
  64. f"https://www.youtube.com/watch?v={video_id}",
  65. "-o", os.path.join(output_path, "%(title)s.%(ext)s")
  66. ]
  67. subprocess.run(command, check=True)
  68. def create_nfo_file(video_data, file_path):
  69. """Create an Emby-compatible NFO file."""
  70. nfo_content = f"""<?xml version="1.0" encoding="utf-8" standalone="yes"?>
  71. <movie>
  72. <title>{video_data['title']}</title>
  73. <plot>{video_data['description']}</plot>
  74. <year>{video_data['published_at'][:4]}</year>
  75. <premiered>{video_data['published_at']}</premiered>
  76. <studio>{video_data['channel_title']}</studio>
  77. </movie>
  78. """
  79. with open(file_path, "w", encoding="utf-8") as nfo_file:
  80. nfo_file.write(nfo_content)
  81. def main():
  82. # Authenticate YouTube API
  83. print("Authenticating with token...")
  84. youtube = authenticate_with_token()
  85. if not os.path.exists(OUTPUT_DIR):
  86. os.makedirs(OUTPUT_DIR)
  87. # Fetch subscribed channels
  88. print("Fetching subscribed channels...")
  89. channels = get_subscribed_channels(youtube)
  90. # Fetch and process recent videos
  91. for channel_id in channels:
  92. print(f"Fetching recent videos for channel: {channel_id}")
  93. videos = get_recent_videos(youtube, channel_id)
  94. for video in videos:
  95. print(f"Processing video: {video['title']}")
  96. # Create a folder for the video
  97. video_dir = os.path.join(OUTPUT_DIR, video["title"].replace("/", "_"))
  98. os.makedirs(video_dir, exist_ok=True)
  99. # Download the video
  100. download_video(video["video_id"], video_dir)
  101. # Create the NFO file
  102. nfo_file_path = os.path.join(video_dir, "movie.nfo")
  103. create_nfo_file(video, nfo_file_path)
  104. print("All videos processed successfully!")
  105. if __name__ == "__main__":
  106. main()