noapi.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #
  2. # This file is part of stov, written by Helmut Pozimski 2012-2014.
  3. #
  4. # stov is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, version 2 of the License.
  7. #
  8. # stov is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with stov. If not, see <http://www.gnu.org/licenses/>.
  15. # -*- coding: utf8 -*-
  16. import subprocess
  17. import sys
  18. import lxml.html
  19. if sys.version_info >= (3,):
  20. import urllib.request as urllib2
  21. else:
  22. import urllib2
  23. from lib_stov import youtubeAPI
  24. from lib_stov import stov_exceptions
  25. class Connector(object):
  26. """This class will retrieve all the necessary data from youtube using
  27. youtube-dl, thus bypassing the API.
  28. """
  29. def __init__(self, type, name, conf, search = ""):
  30. """Populates the object with all necessary data."""
  31. self._type = type
  32. self._name = name
  33. self._search = search
  34. self._conf = conf
  35. self._title = ""
  36. self._url = ""
  37. self._construct_url()
  38. def _construct_url(self):
  39. if self._type == "channel":
  40. self._url = "https://www.youtube.com/user/%s" \
  41. % urllib2.quote(self._name)
  42. elif self._type == "search":
  43. self._url = "https://www.youtube.com/results?search_query=%s"\
  44. % urllib2.quote(self._search)
  45. elif self._type == "playlist":
  46. self._url = "https://www.youtube.com/playlist?list=%s" \
  47. % urllib2.quote(self._search)
  48. def _fetch_title(self):
  49. """Retrieves the title of the HTML page to use as a title for the
  50. subscription."""
  51. data = urllib2.urlopen(self._url)
  52. parsed_html = lxml.html.parse(data)
  53. i = 0
  54. for item in parsed_html.iter("title"):
  55. if i == 0:
  56. self._title = item.text_content().strip().replace("\n", "")
  57. i += 1
  58. def _fetch_videos(self):
  59. """Retrieves all the relevant videos in a subscription."""
  60. videos_list = []
  61. if self._type == "channel" and self._search != "":
  62. try:
  63. video_ids = subprocess.check_output([self._conf.values["youtube-dl"], "--max-downloads",
  64. self._conf.values["maxvideos"],
  65. "--match-title",
  66. self._search,
  67. "--get-id",
  68. self._url])
  69. except subprocess.CalledProcessError as e:
  70. video_ids = e.output.strip()
  71. else:
  72. try:
  73. video_ids = subprocess.check_output([self._conf.values["youtube-dl"], "--max-downloads",
  74. self._conf.values["maxvideos"],
  75. "--get-id",
  76. self._url])
  77. except subprocess.CalledProcessError as e:
  78. video_ids = e.output.strip()
  79. for video_id in video_ids.split("\n"):
  80. try:
  81. video_title = subprocess.check_output([
  82. self._conf.values["youtube-dl"], "--get-title",
  83. "https://www.youtube.com/watch?v=%s"
  84. % video_id]).strip()
  85. video_description = subprocess.check_output([
  86. self._conf.values["youtube-dl"], "--get-description",
  87. "https://www.youtube.com/watch?v=%s"
  88. % video_id]).strip()
  89. except subprocess.CalledProcessError:
  90. raise stov_exceptions.YoutubeDlCallFailed()
  91. else:
  92. videos_list.append(youtubeAPI.YtVideo(video_title,
  93. video_description,
  94. video_id))
  95. return videos_list
  96. def ParseAPIData(self):
  97. """This method calls all necessary methods to retrieve the data
  98. and assembles them into a Channel object. The naming of this
  99. method is set according to the method in youtubeAPI to be
  100. compatible.
  101. """
  102. self._fetch_title()
  103. videos = self._fetch_videos()
  104. channel = youtubeAPI.YtChannel()
  105. channel.title = self._title
  106. channel.videos = videos
  107. return channel