Browse Source

refactor quality ID detection and video URL handling to prepare for additional video sites

Helmut Pozimski 6 years ago
parent
commit
8f2e3fa25b
9 changed files with 100 additions and 76 deletions
  1. 2 2
      doc/conf.py
  2. 0 40
      lib_stov/configuration.py
  3. 4 6
      lib_stov/database.py
  4. 18 6
      lib_stov/generic_video.py
  5. 1 1
      lib_stov/main.py
  6. 1 9
      lib_stov/program.py
  7. 6 2
      lib_stov/subscription.py
  8. 67 9
      lib_stov/yt_noapi.py
  9. 1 1
      setup.py

+ 2 - 2
doc/conf.py

@@ -52,9 +52,9 @@ copyright = (u"2017, Helmut Pozimski License GPLv2, GNU GPL version 2 "
 # built documents.
 #
 # The short X.Y version.
-version = '1.0'
+version = '1.1'
 # The full version, including alpha/beta/rc tags.
-release = '1.0'
+release = '1.1wip'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

+ 0 - 40
lib_stov/configuration.py

@@ -196,46 +196,6 @@ class Conf(object):
             self.values["db_version"] = str(currentdbversion)
             return True
 
-    def get_youtube_parameter(self):
-        """Determines which itag value results from codec and resolution
-        settings and returns it
-
-        """
-        itag_value = 0
-        if self.values["videocodec"] == "flv":
-            if self.values["maxresolution"] == "240p":
-                itag_value = 5
-            elif self.values["maxresolution"] == "270p":
-                itag_value = 6
-            elif self.values["maxresolution"] == "360p":
-                itag_value = 34
-            elif self.values["maxresolution"] == "480p":
-                itag_value = 35
-        elif self.values["videocodec"] == "webm":
-            if self.values["maxresolution"] == "360p":
-                itag_value = 43
-            elif self.values["maxresolution"] == "480p":
-                itag_value = 44
-            elif self.values["maxresolution"] == "720p":
-                itag_value = 45
-            elif self.values["maxresolution"] == "1080p":
-                itag_value = 46
-        elif self.values["videocodec"] == "mp4":
-            if self.values["maxresolution"] == "360p":
-                itag_value = 18
-            elif self.values["maxresolution"] == "720p":
-                itag_value = 22
-            elif self.values["maxresolution"] == "1080p":
-                itag_value = 37
-            elif self.values["maxresolution"] == "3072p":
-                itag_value = 38
-        if itag_value:
-            return itag_value
-        else:
-            LOGGER.debug(_("Could not determine an itag value "
-                           "from the configuration"))
-            return 38
-
     def assist(self):
         """ Ask the user to set all required configuration parameters """
 

+ 4 - 6
lib_stov/database.py

@@ -21,7 +21,7 @@ import sqlite3
 import logging
 
 from lib_stov import stov_exceptions
-from lib_stov import youtube
+from lib_stov import generic_video
 from lib_stov import subscription
 
 LOGGER = logging.getLogger("stov")
@@ -191,11 +191,9 @@ class Db(object):
         cursor = self._execute_statement(video_query, (subscription_id,))
         result = cursor.fetchall()
         for video in result:
-            videos_list.append(youtube.Video(video_id=video[0], title=video[1],
-                                             ytid=video[2],
-                                             downloaded=video[3],
-                                             failcount=video[4],
-                                             conf=conf))
+            videos_list.append(generic_video.Video(
+                video_id=video[0], title=video[1], site_id=video[2],
+                downloaded=video[3], failcount=video[4], conf=conf))
         return videos_list
 
     def video_in_database(self, ytid):

+ 18 - 6
lib_stov/youtube.py → lib_stov/generic_video.py

@@ -28,20 +28,33 @@ LOGGER = logging.getLogger("stov")
 
 
 class Video(object):
-    """This class stores all the attributes of a single youtube video and is
+    """This class stores all the attributes of a single video and is
     also able to download it using youtube-dl.
     """
-    def __init__(self, title, ytid, conf, downloaded, failcount=0,
+    def __init__(self, title, site_id, conf, downloaded, failcount=0,
                  video_id=0):
         self._id = video_id
         self.title = title
-        self.ytid = ytid
+        self.site_id = site_id
         self.__conf = conf
         self.downloaded = downloaded
         self.failcnt = int(failcount)
 
-    def download_video(self, directory, itag_value, video_codec):
-        """Downloads the video by calling youtube-dl as an external process"""
+    def download_video(self, directory, itag_value, video_codec, url):
+        """
+        Downloads the video by calling youtube-dl as an external process"
+
+        :param directory: directory to download to
+        :type directory: str
+        :param itag_value: quality specifier
+        :type itag_value: int
+        :param video_codec: video codec to download
+        :type video_codec: str
+        :param url: url to the video
+        :type url: str
+        :return: boolean value
+        :rtype: bool
+        """
         targetdir = self.__conf.values["downloaddir"] + "/" + directory
         if not os.access(targetdir, os.F_OK):
             try:
@@ -53,7 +66,6 @@ class Video(object):
         os.chdir(targetdir)
         if self.downloaded == 0:
             try:
-                url = "http://www.youtube.com/watch?v=%s" % self.ytid
                 youtubedl_wrapper.download_video(self.__conf, url,
                                                  itag_value, video_codec)
             except stov_exceptions.YoutubeDlCallFailed:

+ 1 - 1
lib_stov/main.py

@@ -71,7 +71,7 @@ def main():
     elif arguments.license:
         program.print_license()
     elif arguments.version:
-        logger.info("1.0")
+        logger.info("1.1wip")
     else:
         parser.print_help()
     helpers.remove_lock()

+ 1 - 9
lib_stov/program.py

@@ -209,21 +209,13 @@ def download_videos(database, conf):
     """
     video_titles = []
     subscriptions_list = database.get_subscriptions(conf)
-    LOGGER.debug(_("Trying to determine the itag value for youtube-dl from"
-                   " your quality and codec settings."))
-    itag = conf.get_youtube_parameter()
-    LOGGER.debug(_("Found value: %s."), itag)
-    if itag == 0:
-        LOGGER.debug(_("Codec and resolution could not be determined, using "
-                       "maximum possible value."))
-        itag = 38
     videos_downloaded = 0
     videos_failed = 0
     for sub in subscriptions_list:
         videos = database.get_videos(sub.get_id(), conf)
         sub.gather_videos(videos)
         try:
-            sub.download_videos(itag)
+            sub.download_videos()
         except stov_exceptions.SubscriptionDisabledException as error:
             LOGGER.debug(error)
         for entry in sub.downloaded_videos:

+ 6 - 2
lib_stov/subscription.py

@@ -85,17 +85,21 @@ class Sub(object):
         """
         self._video_list = video_list
 
-    def download_videos(self, itag_value):
+    def download_videos(self):
         """Uses the DownloadVideo method of the video object to download all
         videos contained in the subscription and adds them to the list of
         downloaded videos if the download succeeds.
 
         """
         if not self.disabled:
+            itag_value = self._connector.get_quality_parameter(self._conf)
             for video in self._video_list:
                 if video.downloaded == 0:
+                    video_url = self._connector.costruct_video_url(
+                        video.site_id)
                     if video.download_video(self._directory, itag_value,
-                                            self._conf.values["videocodec"]):
+                                            self._conf.values["videocodec"],
+                                            video_url):
                         self.downloaded_videos.append(video)
                     else:
                         self.failed_videos_count += 1

+ 67 - 9
lib_stov/yt_noapi.py

@@ -34,10 +34,10 @@ LOGGER = logging.getLogger("stov")
 
 class YtChannel(object):
     """Stores the relevant attributes of a youtube channel."""
-    def __init__(self):
-        self.type = ""
-        self.title = ""
-        self.videos = []
+    def __init__(self, _type, title, videos=[]):
+        self.type = _type
+        self.title = title
+        self.videos = videos
 
 
 class YtVideo(object):
@@ -129,7 +129,7 @@ class Connector(object):
                 video_exists = False
                 if existing_videos:
                     for existing_video in existing_videos:
-                        if video_id == existing_video.ytid:
+                        if video_id == existing_video.site_id:
                             video_exists = True
                             break
                 if not video_exists:
@@ -153,8 +153,66 @@ class Connector(object):
         """
         self._fetch_title()
         videos = self._fetch_videos(existing_videos)
-        channel = YtChannel()
-        channel.title = self._title
-        channel.videos = videos
-        channel.type = self._type
+        channel = YtChannel(self._type, self._title, videos)
         return channel
+
+    @staticmethod
+    def costruct_video_url(ytid):
+        """
+        Resturns the URL to a specified youtube video
+
+        :param ytid: Youtube ID of the video
+        :type ytid: str
+        :return: Video URL
+        :rtype: str
+        """
+        url = "https://www.youtube.com/watch?v=%s" % ytid
+        return url
+
+    @staticmethod
+    def get_quality_parameter(config):
+        """Determines which itag value results from codec and resolution
+        settings and returns it
+
+        :param config: configuration object
+        :type config: lib_stov.configuration.Conf
+        :return: itag value
+        :rtype: str
+        """
+        LOGGER.debug(_("Trying to determine the itag value for youtube-dl from"
+                       " your quality and codec settings."))
+        itag_value = 0
+        if config.values["videocodec"] == "flv":
+            if config.values["maxresolution"] == "240p":
+                itag_value = 5
+            elif config.values["maxresolution"] == "270p":
+                itag_value = 6
+            elif config.values["maxresolution"] == "360p":
+                itag_value = 34
+            elif config.values["maxresolution"] == "480p":
+                itag_value = 35
+        elif config.values["videocodec"] == "webm":
+            if config.values["maxresolution"] == "360p":
+                itag_value = 43
+            elif config.values["maxresolution"] == "480p":
+                itag_value = 44
+            elif config.values["maxresolution"] == "720p":
+                itag_value = 45
+            elif config.values["maxresolution"] == "1080p":
+                itag_value = 46
+        elif config.values["videocodec"] == "mp4":
+            if config.values["maxresolution"] == "360p":
+                itag_value = 18
+            elif config.values["maxresolution"] == "720p":
+                itag_value = 22
+            elif config.values["maxresolution"] == "1080p":
+                itag_value = 37
+            elif config.values["maxresolution"] == "3072p":
+                itag_value = 38
+        if itag_value:
+            LOGGER.debug(_("Found value: %s."), itag_value)
+            return str(itag_value)
+        else:
+            LOGGER.debug(_("Could not determine an itag value "
+                           "from the configuration"))
+            return "38"

+ 1 - 1
setup.py

@@ -24,7 +24,7 @@ from distutils.core import setup
 
 setup(
     name="stov",
-    version="1.0",
+    version="1.1wip",
     author="Helmut Pozimski",
     author_email="helmut@pozimski.eu",
     description=("a program to subscribe to channels and users from youtube and"