From 6793efb32950e3741a17277355fe84094c1b8a32 Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Thu, 17 Oct 2019 14:23:13 +0200
Subject: [PATCH] python script that also downloads the videos via youtube-dl

---
 Pipfile           |  13 ++++++
 Pipfile.lock      | 101 ++++++++++++++++++++++++++++++++++++++++
 SaveMyPlaylist.py | 115 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 229 insertions(+)
 create mode 100644 Pipfile
 create mode 100644 Pipfile.lock
 create mode 100644 SaveMyPlaylist.py

diff --git a/Pipfile b/Pipfile
new file mode 100644
index 0000000..f054529
--- /dev/null
+++ b/Pipfile
@@ -0,0 +1,13 @@
+[[source]]
+url = "https://pypi.python.org/simple"
+verify_ssl = true
+name = "pypi"
+
+[requires]
+python_version = "3.7"
+
+[packages]
+google-api-python-client = "==1.7.11"
+youtube_dl = "==2019.10.16"
+
+[dev-packages]
diff --git a/Pipfile.lock b/Pipfile.lock
new file mode 100644
index 0000000..e1a7e2a
--- /dev/null
+++ b/Pipfile.lock
@@ -0,0 +1,101 @@
+{
+    "_meta": {
+        "hash": {
+            "sha256": "0b25aa17f2c8f2ecd8768ad8eb85313cdf7682655c8179c7fb62068bf0e4ed9d"
+        },
+        "pipfile-spec": 6,
+        "requires": {
+            "python_version": "3.7"
+        },
+        "sources": [
+            {
+                "name": "pypi",
+                "url": "https://pypi.python.org/simple",
+                "verify_ssl": true
+            }
+        ]
+    },
+    "default": {
+        "cachetools": {
+            "hashes": [
+                "sha256:428266a1c0d36dc5aca63a2d7c5942e88c2c898d72139fca0e97fdd2380517ae",
+                "sha256:8ea2d3ce97850f31e4a08b0e2b5e6c34997d7216a9d2c98e0f3978630d4da69a"
+            ],
+            "version": "==3.1.1"
+        },
+        "google-api-python-client": {
+            "hashes": [
+                "sha256:3121d55d106ef1a2756e8074239512055bd99eb44da417b3dd680f9a1385adec",
+                "sha256:a8a88174f66d92aed7ebbd73744c2c319b4b1ce828e565f9ec721352d2e2fb8c"
+            ],
+            "index": "pypi",
+            "version": "==1.7.11"
+        },
+        "google-auth": {
+            "hashes": [
+                "sha256:0f7c6a64927d34c1a474da92cfc59e552a5d3b940d3266606c6a28b72888b9e4",
+                "sha256:20705f6803fd2c4d1cc2dcb0df09d4dfcb9a7d51fd59e94a3a28231fd93119ed"
+            ],
+            "version": "==1.6.3"
+        },
+        "google-auth-httplib2": {
+            "hashes": [
+                "sha256:098fade613c25b4527b2c08fa42d11f3c2037dda8995d86de0745228e965d445",
+                "sha256:f1c437842155680cf9918df9bc51c1182fda41feef88c34004bd1978c8157e08"
+            ],
+            "version": "==0.0.3"
+        },
+        "httplib2": {
+            "hashes": [
+                "sha256:34537dcdd5e0f2386d29e0e2c6d4a1703a3b982d34c198a5102e6e5d6194b107",
+                "sha256:409fa5509298f739b34d5a652df762cb0042507dc93f6633e306b11289d6249d"
+            ],
+            "version": "==0.14.0"
+        },
+        "pyasn1": {
+            "hashes": [
+                "sha256:62cdade8b5530f0b185e09855dd422bc05c0bbff6b72ff61381c09dac7befd8c",
+                "sha256:a9495356ca1d66ed197a0f72b41eb1823cf7ea8b5bd07191673e8147aecf8604"
+            ],
+            "version": "==0.4.7"
+        },
+        "pyasn1-modules": {
+            "hashes": [
+                "sha256:0c35a52e00b672f832e5846826f1fb7507907f7d52fba6faa9e3c4cbe874fe4b",
+                "sha256:b6ada4f840fe51abf5a6bd545b45bf537bea62221fa0dde2e8a553ed9f06a4e3"
+            ],
+            "version": "==0.2.7"
+        },
+        "rsa": {
+            "hashes": [
+                "sha256:14ba45700ff1ec9eeb206a2ce76b32814958a98e372006c8fb76ba820211be66",
+                "sha256:1a836406405730121ae9823e19c6e806c62bbad73f890574fff50efa4122c487"
+            ],
+            "version": "==4.0"
+        },
+        "six": {
+            "hashes": [
+                "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
+                "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
+            ],
+            "version": "==1.12.0"
+        },
+        "uritemplate": {
+            "hashes": [
+                "sha256:01c69f4fe8ed503b2951bef85d996a9d22434d2431584b5b107b2981ff416fbd",
+                "sha256:1b9c467a940ce9fb9f50df819e8ddd14696f89b9a8cc87ac77952ba416e0a8fd",
+                "sha256:c02643cebe23fc8adb5e6becffe201185bf06c40bda5c0b4028a93f1527d011d"
+            ],
+            "version": "==3.0.0"
+        },
+        "youtube-dl": {
+            "hashes": [
+                "sha256:2d93776170dad5ef7b2d2cafdd0bdfb3db625e71d55ab66d725e04d05ce64d75",
+                "sha256:7c78705c4b43f032df751d7791821bea80a80bc26a024514e194e2b7cdd3a643"
+            ],
+            "index": "pypi",
+            "version": "==2019.10.16"
+        }
+    },
+    "develop": {}
+}
diff --git a/SaveMyPlaylist.py b/SaveMyPlaylist.py
new file mode 100644
index 0000000..871c7c8
--- /dev/null
+++ b/SaveMyPlaylist.py
@@ -0,0 +1,115 @@
+from __future__ import unicode_literals
+
+import os
+
+import googleapiclient.discovery
+import googleapiclient.errors
+import youtube_dl
+
+
+class MyLogger(object):
+    def debug(self, msg):
+        pass
+
+    def warning(self, msg):
+        pass
+
+    def error(self, msg):
+        print(msg)
+
+
+def my_hook(d):
+    if d['status'] == 'finished':
+        print('Download finished!')
+
+
+class SaveMyPlaylist:
+    SCOPES = ['https://www.googleapis.com/auth/youtube.readonly']
+    API_NAME = 'youtube'
+    API_VERSION = 'v3'
+
+    CHANNEL = 0
+    TITLE = 1
+    VIDEO_ID = 2
+
+
+    ILLEGAL_CHARS = ['NUL', '\',''//', ':', '*', '"', '<', '>', '|']
+
+    def __init__(self, apiKey, playlistId):
+        self.__apiKey = apiKey
+        self.__playlistId = playlistId
+        self.__items = self.__fetch_playlist_items()
+
+    def __fetch_playlist_items(self):
+        youtube = googleapiclient.discovery.build(self.API_NAME, self.API_VERSION, developerKey=self.__apiKey)
+        request = youtube.playlistItems().list(
+            part='snippet',
+            playlistId=self.__playlistId,
+            maxResults=50,
+        )
+
+        response = request.execute()
+
+        items = []
+
+        for item in response['items']:
+            snippet = item['snippet']
+            title = snippet['title']
+            channel = snippet['channelTitle']
+            videoId = snippet['resourceId']['videoId']
+            items.append((channel, title, videoId))
+            print('{} - {} ({})'.format(channel, title, videoId))
+
+        print('\n>>> Found {} items\n'.format(len(items)))
+        return items
+
+    def download_items(self, destinationFolder, debug=False):
+        print('>>> Scanning destination folder...')
+        downloadedVideos = [f for f in os.listdir(destinationFolder) if
+                            os.path.isfile(os.path.join(destinationFolder, f))]
+
+        print('>>> Found {} already downloaded videos'.format(len(downloadedVideos)))
+
+        print('\n>>> Started Downloading...')
+        newVideos = []
+        for idx, item in enumerate(self.__items):
+            fileName = '{} - {}.mp4'.format(item[self.TITLE], item[self.CHANNEL])
+            fileName = self.__escape_file_name(fileName)
+            if fileName in downloadedVideos:
+                print('Skipping {}/{}: "{}" as it already exists'.format(idx + 1, len(self.__items), fileName))
+                continue
+
+            print('Downloading {}/{}: "{}"'.format(idx + 1, len(self.__items), fileName))
+            newVideos.append(item)
+
+            ydl_opts = {
+                'format': 'bestaudio/best',
+                'merge_output_format': 'mp4',
+                'outtmpl': os.path.join(destinationFolder, fileName),
+                'logger': MyLogger(),
+                'progress_hooks': [my_hook],
+            }
+
+            if debug:
+                continue
+
+            with youtube_dl.YoutubeDL(ydl_opts) as ydl:
+                ydl.download(['https://www.youtube.com/watch?v={}'.format(item[self.VIDEO_ID])])
+
+        print('\n>>> Finished Downloading')
+        print('Downloaded {} new videos'.format(len(newVideos)))
+
+    def __escape_file_name(self, fileName):
+        for char in self.ILLEGAL_CHARS:
+            fileName = fileName.replace(char, '')
+
+        return fileName
+
+
+if __name__ == '__main__':
+    API_KEY = 'AIzaSyD1cQOPzYDRe5pylXEFsQw6u-MaBSOX09Y'
+    PLAYLIST_ID = 'PL7F-5FkCMt0F86pdKUaiTStIloZYDVfzl'
+    DESTINATION_FOLDER = 'C:/Users/ROGO2/Desktop/123'
+
+    saveMyPlaylist = SaveMyPlaylist(API_KEY, PLAYLIST_ID)
+    saveMyPlaylist.download_items(DESTINATION_FOLDER, True)
-- 
GitLab