4od-dl.rb 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #Written by Mike Worth
  2. #http://www.mike-worth.com/2012/11/19/a-script-to-download-4od/
  3. #https://github.com/MikeWorth
  4. require 'hpricot'
  5. require 'open-uri'
  6. #First lookup the programme, list available if not found
  7. begin
  8. showid=ARGV.first#TODO sanitise
  9. doc = Hpricot(open('http://www.youtube.com/show/'+showid))
  10. serieslinks=doc.search("[@class~='playlists-wide']").search("[@class='yt-uix-tile-link']")
  11. series=Hash.new
  12. serieslinks.each do |serieslink|
  13. series[serieslink.inner_text.strip.match(/Season ([0-9]*) Episodes/)[1]]=serieslink.attributes['href']#TODO what if there are playlists that we don`t get a match for
  14. end
  15. rescue
  16. puts 'Show not found, available shows:'
  17. begin
  18. doc = Hpricot(open('http://www.youtube.com/user/4oD'))
  19. shows=doc.search("[@class='channel-summary-list']").search("[@class~='yt-uix-tile-link']")
  20. shows.each do |showlink|
  21. puts showlink.inner_text.strip + ' ' + showlink.attributes['href'].gsub('/show/','') + "\n"
  22. end
  23. rescue
  24. puts 'Error fetching listings'
  25. end
  26. Kernel::exit
  27. end
  28. #Then the series and episode, list available if not found
  29. begin
  30. class NoSeries<StandardError; end
  31. class NoEpisode<StandardError; end#TODO are these the best way to handle this?
  32. raise NoSeries if ARGV[1].nil?
  33. seriesid=ARGV[1]#TODO sanitise
  34. seriespage=Hpricot(open('http://www.youtube.com'+series[seriesid]))
  35. episodelinks=seriespage.search("[@class~='playlist-landing']").search("[@class~='yt-uix-tile-link']")
  36. raise NoEpisode if ARGV[2].nil?
  37. episodeid=ARGV[2].to_i#TODO sanitise
  38. episodehref=episodelinks[episodeid-1].attributes['href']
  39. episodeyid=episodehref.to_s.match(/v=([a-zA-Z0-9\-_]{11})&/)[1]
  40. rescue
  41. begin
  42. series.sort.each do |s|
  43. puts 'Series '+s[0]+':'
  44. seriespage=Hpricot(open('http://www.youtube.com'+s[1]))
  45. episodelinks=seriespage.search("[@class~='playlist-landing']").search("[@class~='yt-uix-tile-link']")
  46. i=1
  47. episodelinks.each do |es|
  48. puts ' '+i.to_s+': '+es.inner_text.strip
  49. i+=1
  50. end
  51. end
  52. rescue
  53. puts 'Error fetching listings'
  54. end
  55. Kernel::exit
  56. end
  57. #Now actually download it:
  58. puts 'Downloading: ' + episodelinks[episodeid-1].inner_text.strip + ': ' + episodeyid
  59. filename=showid.to_s + '.' + seriesid.to_s + '.' + episodeid.to_s
  60. system('youtube-dl -o ' + filename + '.flv.tmp http://www.youtube.com/watch?v=' +episodeyid)#give the full youtube path in case yid starts with a -
  61. system('avconv -i ' + filename + '.flv.tmp -acodec copy -b 1024k ' + filename + '.avi')
  62. File.delete(filename + '.flv.tmp')