{"id":44190202,"url":"https://github.com/christianromney/my-tube.el","last_synced_at":"2026-02-09T17:03:33.332Z","repository":{"id":303905560,"uuid":"1017086419","full_name":"christianromney/my-tube.el","owner":"christianromney","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-10T06:58:00.000Z","size":291,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-10T11:52:25.354Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/christianromney.png","metadata":{"files":{"readme":"readme.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.org","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-10T02:26:49.000Z","updated_at":"2025-07-10T06:58:03.000Z","dependencies_parsed_at":"2025-07-10T11:59:46.712Z","dependency_job_id":"f420a097-b779-4f4c-ab5a-b892a6d97602","html_url":"https://github.com/christianromney/my-tube.el","commit_stats":null,"previous_names":["christianromney/my-tube.el"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/christianromney/my-tube.el","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianromney%2Fmy-tube.el","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianromney%2Fmy-tube.el/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianromney%2Fmy-tube.el/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianromney%2Fmy-tube.el/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christianromney","download_url":"https://codeload.github.com/christianromney/my-tube.el/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianromney%2Fmy-tube.el/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29273141,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T13:47:44.167Z","status":"ssl_error","status_checked_at":"2026-02-09T13:47:43.721Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-09T17:03:16.064Z","updated_at":"2026-02-09T17:03:33.321Z","avatar_url":"https://github.com/christianromney.png","language":"Emacs Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"* my-tube.el\nThis project is a simple minor mode for Emacs to interact with the YouTube Data\nAPI v3.\n\n** What Problems Does It Solve?\nThis mode allows the user to perform basic YouTube playlist management from\nwithin Emacs. It does not aim to provide comprehensive coverage of the YouTube\nData API.\n\n** Use Cases\n- I want to list the items I've saved in one of my YouTube playlists, choose\n  one, and open it in a browser.\n- Given a URL for a YouTube video, I want to add it to one of my playlists.\n- I want to remove an item from one of my playlists.\n\n** Primary Operations\nThis mode exposes commands to:\n- ~list-playlists~ :: list a user's playlists\n- ~create-playlist~ :: creates a new named playlist for a user\n- ~delete-playlist~ :: deletes a playlist for a user\n- ~list-playlist-items~ :: list the items in a user's given playlist\n- ~add-item-to-playlist~ :: adds an item to a user's playlist\n- ~remove-item-from-playlist~ :: removes an item from a user's playlist\n\n** Installation\n\n*** Prerequisites\n- Emacs 26.1 or higher\n- Internet connection for API access\n- Google account for YouTube API access\n\n*** Step 1: Install the Package\n1. Download ~my-tube.el~ to your Emacs load path\n2. Add to your Emacs configuration:\n   #+begin_src emacs-lisp\n   (require 'my-tube)\n   #+end_src\n\n*** Step 2: Create Google Cloud Project and OAuth Credentials\n1. Go to the [[https://console.cloud.google.com/][Google Cloud Console]]\n2. Create a new project or select an existing one\n3. Navigate to \"APIs \u0026 Services\" \u003e \"Library\"\n4. Search for \"YouTube Data API v3\" and enable it\n5. Go to \"APIs \u0026 Services\" \u003e \"Credentials\"\n6. Click \"Create Credentials\" \u003e \"OAuth 2.0 Client IDs\"\n7. If prompted, configure the OAuth consent screen:\n   - Choose \"External\" user type\n   - Fill in required fields (app name, user support email, developer contact)\n   - Add your email to test users\n8. For application type, select \"Desktop application\"\n9. Give it a name (e.g., \"My Tube Emacs\")\n10. Click \"Create\"\n11. Download the JSON file or copy the Client ID and Client Secret\n\n*** Step 3: Store Credentials Securely\n\n**** Option A: Using macOS Keychain (Recommended for macOS users)\n1. Open Terminal and run:\n   #+begin_src bash\n   security add-generic-password -a \"YOUR_CLIENT_ID\" -s \"youtube-api\" -w \"YOUR_CLIENT_SECRET\"\n   #+end_src\n   Replace ~YOUR_CLIENT_ID~ and ~YOUR_CLIENT_SECRET~ with your actual values.\n\n2. Configure auth-source in your Emacs configuration:\n   #+begin_src emacs-lisp\n   (setq auth-sources '(macos-keychain-generic))\n   #+end_src\n\n**** Option B: Using .authinfo.gpg file (Cross-platform)\n1. Create an encrypted file ~~/.authinfo.gpg~:\n   #+begin_src\n   machine youtube-api login YOUR_CLIENT_ID password YOUR_CLIENT_SECRET\n   #+end_src\n   Replace ~YOUR_CLIENT_ID~ and ~YOUR_CLIENT_SECRET~ with your actual values.\n\n2. Configure auth-source in your Emacs configuration:\n   #+begin_src emacs-lisp\n   (setq auth-sources '(\"~/.authinfo.gpg\"))\n   #+end_src\n\n**** Option C: Using Emacs Variables (Less secure)\nAdd to your Emacs configuration:\n#+begin_src emacs-lisp\n(setq my-tube-client-id \"YOUR_CLIENT_ID\")\n(setq my-tube-client-secret \"YOUR_CLIENT_SECRET\")\n#+end_src\n\n** Usage\n\n*** Initial Setup\n1. Enable the minor mode:\n   #+begin_src\n   M-x my-tube-mode\n   #+end_src\n\n2. Authenticate with YouTube:\n   #+begin_src\n   M-x my-tube-authenticate\n   #+end_src\n   or press ~C-c y A~\n\n   This will:\n   - Open your browser to Google's OAuth consent page\n   - Ask you to authorize the application\n   - Prompt you to enter the authorization code in Emacs\n\n*** Available Commands\n\n**** Key Bindings (when my-tube-mode is enabled)\n- ~C-c y l~ :: List your playlists\n- ~C-c y c~ :: Create a new playlist\n- ~C-c y d~ :: Delete a playlist\n- ~C-c y i~ :: List items in a playlist\n- ~C-c y a~ :: Add a video to a playlist\n- ~C-c y r~ :: Remove an item from a playlist\n- ~C-c y A~ :: Authenticate with YouTube\n\n**** Interactive Commands\n- ~M-x my-tube-list-playlists~ :: Display all your playlists in a buffer\n- ~M-x my-tube-create-playlist~ :: Create a new playlist with title and description\n- ~M-x my-tube-delete-playlist~ :: Delete a playlist (with confirmation)\n- ~M-x my-tube-list-playlist-items~ :: Browse items in a selected playlist\n- ~M-x my-tube-add-item-to-playlist~ :: Add a YouTube video URL to a playlist\n- ~M-x my-tube-remove-item-from-playlist~ :: Remove an item from a playlist\n\n*** Example Workflow\n1. ~C-c y l~ to see your playlists\n2. ~C-c y a~ to add a video URL to a playlist\n3. ~C-c y i~ to browse playlist contents\n4. ~C-c y r~ to remove unwanted items\n\n*** Troubleshooting\n- If you get authentication errors, try running ~M-x my-tube-authenticate~ again\n- Check that your OAuth credentials are correctly stored\n- Ensure the YouTube Data API v3 is enabled in your Google Cloud project\n- For debugging, check the *Messages* buffer for error details\n\n** Implementation Choices\n- Sensitive credentials such as Oauth client ids and credentials or API keys\n  should be stored securely using a method which is idiomatic for Emacs Lisp code.\n  + Built-in libraries and modes should be used.\n  + If an API is complex or requires several steps, a simplified wrapper API\n    should be created to streamline its use.\n- Many users of this project will use Mac OS. Consider this when devising the\n  best implementation approach. For example, it may (or may not) be a good idea\n  to use the Mac OS Keychain. Consider the pros and cons before selecting the\n  best choice.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristianromney%2Fmy-tube.el","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristianromney%2Fmy-tube.el","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristianromney%2Fmy-tube.el/lists"}