Skip to main content

Remove some now-unused YouTube scripts

ID
987d70b
date
2024-08-09 17:31:50+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
c6426b2
message
Remove some now-unused YouTube scripts
changed files
3 files, 160 deletions

Changed files

requirements.in (353) → requirements.in (293)

diff --git a/requirements.in b/requirements.in
index f499098..0451412 100644
--- a/requirements.in
+++ b/requirements.in
@@ -4,8 +4,6 @@ beautifulsoup4
 cogapp
 datasette
 datasette-render-image-tags
-google-api-python-client==1.7.2
-google-auth-oauthlib==1.2.1
 httpx
 humanize
 hyperlink

web/list_liked_youtube_videos.py (4880) → web/list_liked_youtube_videos.py (0)

diff --git a/web/list_liked_youtube_videos.py b/web/list_liked_youtube_videos.py
deleted file mode 100755
index 122591c..0000000
--- a/web/list_liked_youtube_videos.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python3
-"""
-Get a list of my Liked videos on YouTube.
-
-It prints the URL of each video, newest first.
-
-Example use:
-
-    $ python3 web/list_liked_youtube_videos.py > liked_videos.$(date +"%Y-%m-%d").txt
-
-"""
-
-import contextlib
-import datetime
-import json
-import sys
-
-import google.oauth2.credentials
-import googleapiclient.discovery  # pip install google-api-python-client==1.7.2
-import google_auth_oauthlib.flow  # pip install google-auth-oauthlib==0.4.1
-import keyring
-
-
-class YouTubeClient:
-    def __init__(self, label: str):
-        self.api_service_name = "youtube"
-        self.api_version = "v3"
-        self.scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
-
-        self.youtube = self.create_youtube_client(label)
-
-    def create_youtube_client(self, label: str):
-        """
-        Get an authenticated OAuth client for YouTube.
-
-        It gets the OAuth config from the system keychain, and caches
-        per-user credentials in the keychain under ("youtube", label).
-        """
-        # Try to retrieve a stored OAuth access token from the keychain.
-        #
-        # This saves me going through the in-browser authentication flow
-        # if I've already run the script.
-        stored_credentials = keyring.get_password("youtube", label)
-
-        if stored_credentials is not None:
-            json_credentials = json.loads(stored_credentials)
-
-            if "expiry" in json_credentials:
-                expiry = datetime.datetime.fromisoformat(json_credentials["expiry"])
-                expiry = expiry.replace(tzinfo=None)
-                json_credentials["expiry"] = expiry
-
-            credentials = google.oauth2.credentials.Credentials(**json_credentials)
-
-        # If there are no stored credentials, fetch new ones.
-        else:
-            # Retrieve the OAuth client credentials from the keychain.
-            #
-            # This contains the contents of the JSON file that I downloaded
-            # from the Google Cloud console, but now those credentials aren't
-            # just saved as a plaintext file on disk.
-            stored_client_secrets = keyring.get_password("youtube", "client_secrets")
-            if stored_client_secrets is None:
-                raise ValueError("Could not find OAuth client secrets in keychain!")
-
-            flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_config(
-                client_config=json.loads(stored_client_secrets), scopes=self.scopes
-            )
-
-            with contextlib.redirect_stdout(sys.stderr):
-                credentials = flow.run_local_server()
-
-            # Save these credentials in the system keychain, so they can be
-            # retrieved later.
-            keyring.set_password("youtube", label, credentials.to_json())
-
-        youtube = googleapiclient.discovery.build(
-            self.api_service_name, self.api_version, credentials=credentials
-        )
-
-        # The OAuth credentials don't last forever -- they seem to expire after
-        # a week.  This is a slightly ropey attempt to work around that.
-        #
-        # If we call the API and the saved token is expired, just delete
-        # it and get new creds -- sending me back through the in-browser flow.
-        #
-        # Notes:
-        #
-        #   - There are ways to refresh OAuth tokens that don't involve
-        #     sending me back through the in-browser flow, but I didn't
-        #     look at them as part of this project.
-        #   - Catching all exceptions is a bit broad.  This code should really
-        #     retry only if it gets a "credentials expired" exception, and
-        #     throw any other exceptions immediately.
-        #
-        try:
-            request = youtube.channels().list(part="snippet", mine=True)
-            request.execute()
-        except Exception:
-            keyring.delete_password("youtube", label)
-            return self.create_youtube_client(label)
-        else:
-            return youtube
-
-    def get_liked_videos(self):
-        """
-        Generate a list of videos that this YouTube account has liked.
-        """
-        kwargs = {"part": "snippet", "playlistId": "LL", "maxResults": "50"}
-
-        while True:
-            request = self.youtube.playlistItems().list(**kwargs)
-            response = request.execute()
-
-            for item in response["items"]:
-                if item["snippet"]["title"] in {"Deleted video", "Private video"}:
-                    continue
-
-                yield item
-
-            try:
-                kwargs["pageToken"] = response["nextPageToken"]
-            except KeyError:
-                break
-
-
-if __name__ == "__main__":
-    youtube = YouTubeClient(label="download_liked_videos")
-
-    for video in youtube.get_liked_videos():
-        video_id = video["snippet"]["resourceId"]["videoId"]
-        print(f"https://www.youtube.com/watch?v={video_id}")

web/test_save_youtube_videos.py (768) → web/test_save_youtube_videos.py (0)

diff --git a/web/test_save_youtube_videos.py b/web/test_save_youtube_videos.py
deleted file mode 100644
index 2561439..0000000
--- a/web/test_save_youtube_videos.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import pathlib
-
-import pytest
-
-from save_youtube_videos import classify_file_type
-
-
-@pytest.mark.parametrize(
-    ["video_id", "filename", "file_type"],
-    [
-        ("3VvioE0ziPk", "Who is the loudest sea lion? [3VvioE0ziPk].mkv", "video"),
-        (
-            "TE8KMnGm2Xw",
-            "Warning, biters ! - A Factorio Short [TE8KMnGm2Xw].webp",
-            "thumbnail",
-        ),
-        ("AfsnHVaScjg", "Ravens can talk! [AfsnHVaScjg].info.json", "info"),
-        (
-            "IjCylxs8hZU",
-            "Soviet Flying Aircraft Carriers Were Ingenious [IjCylxs8hZU].en.vtt",
-            "subtitles",
-        ),
-    ],
-)
-def test_classify_file_type(video_id, filename, file_type):
-    assert classify_file_type(video_id, pathlib.Path(filename)) == file_type