Skip to content

Instantly share code, notes, and snippets.

@VaeterchenFrost
Last active April 16, 2023 18:56
Show Gist options
  • Save VaeterchenFrost/44117c499d147d167d4172263dd9c533 to your computer and use it in GitHub Desktop.
Save VaeterchenFrost/44117c499d147d167d4172263dd9c533 to your computer and use it in GitHub Desktop.
Code snippet to continously monitor the first youtube tab opened in Mozilla Firefox windows.
"""
Code snippet to continuously monitor the first youtube tab opened in Mozilla Firefox windows.
Output name and id into file '~/youtubesong.txt'
Logs to console.
Loads GOOGLEAPI_KEY1 and RECOVERY_JSONLZ4 variables from the environment.
GOOGLEAPI_KEY1: Provide access via https://console.cloud.google.com/apis/credentials to YouTube Data API v3
RECOVERY_JSONLZ4: Filesystem path to users 'sessionstore-backups/recovery.jsonlz4'
Tested with:
python 3.9
certifi==2022.12.7
charset-normalizer==3.1.0
idna==3.4
lz4==4.3.2
requests==2.28.2
urllib3==1.26.15
"""
import logging
import lz4.block as lz4
import json, os, re, requests
from pathlib import Path
from time import sleep, time
from urllib.parse import *
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s %(name)s %(levelname)s: %(message)s",
datefmt="%H:%M:%S",
handlers=[logging.StreamHandler()],
)
# Name the logger
logger = logging.getLogger("FirefoxSessionMusic")
# Hide API key in case of error
logging.getLogger("urllib3").setLevel(logging.INFO)
# Google Youtube API
api_key = os.environ.get("GOOGLEAPI_KEY1")
assert (
len(api_key) == 39
), "Provide access via https://console.cloud.google.com/apis/credentials to YouTube Data API v3 "
scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
api_service_name = "youtube"
api_version = "v3"
# User specific recovery file
jsonlz4 = os.environ.get("RECOVERY_JSONLZ4")
assert jsonlz4.endswith("recovery.jsonlz4")
assert Path(jsonlz4).exists()
def get_video_details(id: str):
try:
resp = requests.get(
"https://youtube.googleapis.com/youtube/v3/videos",
params={"id": id, "key": api_key, "part": "snippet"},
)
resp.raise_for_status()
except requests.HTTPError as err:
logger.error(
"Response status: %d %s", err.response.status_code, err.response.reason
)
logger.error(err.response.text)
raise requests.HTTPError(err.response.status_code, err.response.reason)
contentDetails = json.loads(resp.content.decode())
item = contentDetails["items"][0]
output = " https://youtu.be/".join([item["snippet"]["title"], item["id"]]) + " "
return output
# clear the data in the outfile
outfile: Path = Path.home() / "youtubesong.txt"
logger.info("Storing in %s", outfile)
with open(outfile, "w") as file:
pass
lastid: str = "" # store currently displayed id
stopwatch: float = 0
sleep_seconds: float = 1
while True:
sleep(sleep_seconds)
if stopwatch + 10 < time():
logger.info("Checking every %d seconds...", sleep_seconds)
stopwatch = time()
with open(jsonlz4, "rb") as fd:
try:
fd.read(8) # b"mozLz40\0"
jdata = json.loads(lz4.decompress(fd.read()).decode("utf-8"))
found = False
for win in jdata.get("windows"):
if found:
break
for tab in win.get("tabs"):
if found:
break
site: str = tab["entries"][tab["index"] - 1]["url"]
if site.find("youtube.com/watch") > 0:
query: str = urlparse(site).query
id: str = re.search(r"(?<=(v=))[^&]*", query).group()
if id == lastid:
found = True
continue
else:
lastid = id
logger.debug(site)
logger.info(id)
output = get_video_details(id)
with open(outfile, "w") as file:
logger.info(output)
file.write(output)
# take only the first youtube page
found = True
except Exception as err:
logger.error(err)
pass
@VaeterchenFrost
Copy link
Author

VaeterchenFrost commented Apr 8, 2023

Following is a step-by-step description of a setup on a fresh Windows machine


Running on a fresh 🖥️

OsOperatingSystemSKU  : WindowsHome  
OsVersion             : 10.0.19045 
  1. Open Windows Powershell as Administrator

  2. Install chocolatey (see chocolatey.org/install)

    For example paste this copied command into your shell and press Enter:

    Set-ExecutionPolicy Bypass -Scope Process -Force; 
    [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; 
    Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
    # installed choco software manager
  3. Wait a few seconds for the command to complete
    If you don't see any errors, you are ready to use Chocolatey!

    Test availability by entering choco
    and press enter. It should return a short message about version and help menu.

  4. Install firefox
    In the administrator shell enter and execute:

    choco install firefox -y

    After completion of the installation the firefox icon should appear and firefox itself can be started.
    Click through the setup (safely skip or read through the questions).

  5. Go to https://gist.github.com/VaeterchenFrost/44117c499d147d167d4172263dd9c533
    Copy the content to the $file Location.
    In powershell this can be done via

    $file = Join-Path $HOME "FirefoxSessionTabs.py"
    $url = "https://gist.githubusercontent.com/VaeterchenFrost/44117c499d147d167d4172263dd9c533/raw/58a7d0c2bdbb7f6987066ea1c4fc38b615c1e74f/FirefoxSessionTabs.py"
    Invoke-WebRequest -Uri $url -OutFile $file 
    $hash = Get-FileHash $file -Algorithm SHA256
    $errmsg = "HASHES DON'T MATCH!! Please retry download and contact the author!"
    if($hash.Hash -ne "8285498A22412FFB05EF133F5F0C84D7AB1C6AA7CB0D315CB853FF03B68701FA")
    {Remove-Item $file; Write-Error $errmsg;} 
    # downloaded FirefoxSessionTabs.py revision 9
  6. Install python3.9 (or newer, not tested)

    choco install python39 -y

  7. Install/Upgrade pip

    python3.9.exe -m pip install --upgrade pip

  8. Install dependencies

    python3.9.exe -m pip install lz4~=4.3
    python3.9.exe -m pip install requests~=2.28
  9. Add Google API Key

    1. Login/Create Google Account and go to
      https://console.cloud.google.com/apis/credentials

      It should show the "Google Cloud" website.

      Create Project.
      Give it a (random) name.
      Should only take a few seconds.

    2. Enable YouTube Data API v3

      Under "Enabled APIs and services" or
      https://console.cloud.google.com/apis/api/youtube.googleapis.com

      Click on "ENABLE" to Enable accessing the API

    3. After completion:

    In the credentials tab: click +CREATE CREDENTIALS

    We could skip securing and copy the key as is.

    1. For safety reasons we can Edit API Key or click on it in the user interface.
      Under "API restrictions" (bottom) choose Restrict key.

      "Select APIs" -> filter for "Youtube Data API" and select.

      Click SAVE down below.

      The key should be secured to the YouTube API and get a green checkmark.

    2. Copy the key to the clipboard via "SHOW KEY".

    3. Complete the Command between the '' with YOUR KEY and enter in powershell:

    $env:GOOGLEAPI_KEY1 = 'YOURKEYHERE'
    [System.Environment]::SetEnvironmentVariable("GOOGLEAPI_KEY1",$env:GOOGLEAPI_KEY1,"USER")
    # add to environment GOOGLEAPI_KEY1 
  10. Select the valid Firefox sessionstore file:

    $relpath = "~/AppData/Roaming/Mozilla/Firefox/Profiles/*.default-release/sessionstore-backups/recovery.jsonlz4"
    $env:RECOVERY_JSONLZ4 = Resolve-Path $relpath
    [System.Environment]::SetEnvironmentVariable("RECOVERY_JSONLZ4",$env:RECOVERY_JSONLZ4,"USER")
    # add to environment  RECOVERY_JSONLZ4 
  11. Run the python file from a shell with loaded environment:
    python3.9.exe $file


Should be running fine and continuously monitor the first youtube tab opened in Mozilla Firefox windows.

It will output name and id into file '$HOME/youtubesong.txt' 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment