Guest User

Untitled

a guest
Nov 19th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.63 KB | None | 0 0
  1. require 'google/apis/youtube_v3'
  2. require 'googleauth'
  3. require 'googleauth/stores/file_token_store'
  4. require 'fileutils'
  5. require 'json'
  6. require 'redd'
  7. require 'dotenv'
  8. Dotenv.load
  9.  
  10. SUBREDDIT = ARGV[0] || 'hiphopheads'
  11. PLAYLIST_ID = ARGV[1] || 'PLGt3gNR-AoFkJR021gXUKlmqZWFosjXFm'
  12. INTERVAL = ARGV[2] || 'day'
  13.  
  14. DONE_IDS = begin
  15. File.readlines('/tmp/youtube-' + SUBREDDIT + '.txt').map(&:strip)
  16. rescue
  17. []
  18. end
  19.  
  20. SERVICE = Google::Apis::YoutubeV3::YouTubeService.new
  21.  
  22. def authorize
  23. credentials_path = File.join(Dir.home, '.credentials','youtube-api.yaml')
  24.  
  25. FileUtils.mkdir_p(File.dirname(credentials_path))
  26.  
  27. client_id = Google::Auth::ClientId.from_file(__dir__ + "/client_secret.json")
  28. token_store = Google::Auth::Stores::FileTokenStore.new(file: credentials_path)
  29. authorizer = Google::Auth::UserAuthorizer.new(client_id, Google::Apis::YoutubeV3::AUTH_YOUTUBE, token_store)
  30. user_id = 'default'
  31. credentials = authorizer.get_credentials(user_id)
  32. if credentials.nil?
  33. url = authorizer.get_authorization_url(base_url: 'urn:ietf:wg:oauth:2.0:oob')
  34. puts "Open the following URL in the browser and enter the resulting code after authorization:"
  35. puts url
  36. code = gets
  37. credentials = authorizer.get_and_store_credentials_from_code(user_id: user_id, code: code, base_url: 'urn:ietf:wg:oauth:2.0:oob')
  38. end
  39. credentials
  40. end
  41.  
  42. # --- main program starts here
  43.  
  44. SERVICE.authorization = authorize
  45.  
  46. class YouTubePlaylist
  47. def initialize(id)
  48. @id = id
  49. end
  50.  
  51. def include?(video_id)
  52. begin
  53. item = SERVICE.list_playlist_items('snippet', playlist_id: @id, video_id: video_id)
  54. rescue Google::Apis::ClientError => e
  55. if e.status_code
  56. return false
  57. end
  58. end
  59.  
  60. item.items.size > 0
  61. end
  62.  
  63. def add_video(video_id)
  64. playlist_item = Google::Apis::YoutubeV3::PlaylistItem.new
  65. playlist_item.snippet = Google::Apis::YoutubeV3::PlaylistItemSnippet.new(playlist_id: @id)
  66. playlist_item.snippet.resource_id = Google::Apis::YoutubeV3::ResourceId.new(video_id: video_id, kind: 'youtube#video')
  67.  
  68. begin
  69. SERVICE.insert_playlist_item('snippet', playlist_item)
  70. return true
  71. rescue
  72. return false
  73. end
  74. end
  75.  
  76. def add_video_unique(video_id)
  77. add_video(video_id) unless self.include?(video_id)
  78. end
  79. end
  80.  
  81. class YouTube
  82. def initialize
  83. @client = SERVICE
  84. end
  85.  
  86. def get_video(video_id)
  87. vid = SERVICE.list_videos('snippet,contentDetails', id: video_id).items.first
  88. title = vid.snippet.title
  89. duration_parts = vid.content_details.duration.match(/(\d+)M(\d+)S/)
  90. duration_in_seconds = (duration_parts[1].to_i * 60) + duration_parts[2].to_i
  91.  
  92. { title: title, duration: duration_in_seconds }
  93. rescue
  94. nil
  95. end
  96. end
  97.  
  98. REDDIT = Redd.it(:script, ENV['REDDIT_CLIENT_ID'], ENV['REDDIT_SECRET'], ENV['REDDIT_USERNAME'], ENV['REDDIT_PASSWORD'], user_agent: ENV['REDDIT_USER_AGENT'])
  99. playlist = YouTubePlaylist.new(PLAYLIST_ID)
  100.  
  101. items = REDDIT.get_top(SUBREDDIT, t: INTERVAL, limit: 100)
  102.  
  103. items.each do |item|
  104. next unless item.url =~ /youtube\.com\/watch/
  105. next if item.title =~ /(interview|trailer)/i
  106. next unless item.ups > 4
  107.  
  108. video_id = item.url[/v=(.{11})/, 1]
  109. if DONE_IDS.include?(video_id)
  110. STDERR.puts "Already done #{video_id} - skipping"
  111. next
  112. end
  113.  
  114. File.open('/tmp/youtube-' + SUBREDDIT + '.txt', 'a') do |f|
  115. f.puts video_id
  116. end
  117.  
  118. STDERR.puts "Doing #{video_id}"
  119.  
  120. video = YouTube.new.get_video(video_id)
  121.  
  122. if video && !video[:duration].between?(120, 480)
  123. STDERR.puts "- video is too short or long at #{video[:duration]} seconds, skipping"
  124. next
  125. end
  126.  
  127. if playlist.add_video_unique(video_id)
  128. STDERR.puts "- Done"
  129. else
  130. STDERR.puts "- Already in playlist, or failed"
  131. end
  132. end
Add Comment
Please, Sign In to add comment