clean: remove stats playground
This commit is contained in:
141
stats.py
141
stats.py
@@ -1,141 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Stats playground for Audible TUI - get your listening stats"""
|
|
||||||
|
|
||||||
import logging
|
|
||||||
from datetime import date
|
|
||||||
from getpass import getpass
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import audible
|
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
logging.getLogger("audible").setLevel(logging.WARNING)
|
|
||||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
|
||||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
|
||||||
|
|
||||||
|
|
||||||
class AudibleStats:
|
|
||||||
"""Class to handle Audible authentication and stats retrieval."""
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
"""Initialize the stats handler with authentication."""
|
|
||||||
self.auth: audible.Authenticator | None = None
|
|
||||||
self.client: audible.Client | None = None
|
|
||||||
self.home = Path.home()
|
|
||||||
|
|
||||||
def authenticate(self) -> None:
|
|
||||||
"""Authenticate with Audible and store auth and client."""
|
|
||||||
auth_path = self.home / ".config" / "auditui" / "auth.json"
|
|
||||||
auth_path.parent.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
if auth_path.exists():
|
|
||||||
try:
|
|
||||||
self.auth = audible.Authenticator.from_file(str(auth_path))
|
|
||||||
self.client = audible.Client(auth=self.auth)
|
|
||||||
return
|
|
||||||
except Exception:
|
|
||||||
logger.info(
|
|
||||||
"Failed to load existing auth. Re-authenticating.\n")
|
|
||||||
|
|
||||||
email = input("Email: ")
|
|
||||||
password = getpass("Password: ")
|
|
||||||
marketplace = (
|
|
||||||
input("Marketplace locale (default: US): ").strip().upper() or "US"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.auth = audible.Authenticator.from_login(
|
|
||||||
username=email, password=password, locale=marketplace
|
|
||||||
)
|
|
||||||
self.auth.to_file(str(auth_path))
|
|
||||||
self.client = audible.Client(auth=self.auth)
|
|
||||||
|
|
||||||
def get_signup_year(self) -> int:
|
|
||||||
"""Get signup year by checking activity in each month, each year."""
|
|
||||||
current_year = date.today().year
|
|
||||||
start_year = 1995
|
|
||||||
|
|
||||||
try:
|
|
||||||
stats = self.client.get(
|
|
||||||
"1.0/stats/aggregates",
|
|
||||||
monthly_listening_interval_duration="12",
|
|
||||||
monthly_listening_interval_start_date=f"{current_year}-01",
|
|
||||||
store="Audible",
|
|
||||||
)
|
|
||||||
monthly_stats = stats.get("aggregated_monthly_listening_stats", [])
|
|
||||||
if not monthly_stats or not any(
|
|
||||||
stat.get("aggregated_sum", 0) > 0 for stat in monthly_stats
|
|
||||||
):
|
|
||||||
logger.warning("Could not determine signup year")
|
|
||||||
return 0
|
|
||||||
except Exception:
|
|
||||||
logger.warning("Could not determine signup year")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
left, right = start_year, current_year
|
|
||||||
earliest_year = current_year
|
|
||||||
|
|
||||||
while left <= right:
|
|
||||||
middle = (left + right) // 2
|
|
||||||
try:
|
|
||||||
stats = self.client.get(
|
|
||||||
"1.0/stats/aggregates",
|
|
||||||
monthly_listening_interval_duration="12",
|
|
||||||
monthly_listening_interval_start_date=f"{middle}-01",
|
|
||||||
store="Audible",
|
|
||||||
)
|
|
||||||
monthly_stats = stats.get(
|
|
||||||
"aggregated_monthly_listening_stats", [])
|
|
||||||
has_activity = bool(
|
|
||||||
monthly_stats
|
|
||||||
and any(stat.get("aggregated_sum", 0) > 0 for stat in monthly_stats)
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
has_activity = False
|
|
||||||
|
|
||||||
if has_activity:
|
|
||||||
earliest_year = middle
|
|
||||||
right = middle - 1
|
|
||||||
else:
|
|
||||||
left = middle + 1
|
|
||||||
|
|
||||||
return earliest_year
|
|
||||||
|
|
||||||
def get_current_month_listening_time(self) -> tuple[int, int, int]:
|
|
||||||
"""Get total listening time for the current month as (hours, minutes, seconds)."""
|
|
||||||
try:
|
|
||||||
stats = self.client.get(
|
|
||||||
"1.0/stats/aggregates",
|
|
||||||
monthly_listening_interval_duration="1",
|
|
||||||
monthly_listening_interval_start_date=date.today().strftime("%Y-%m"),
|
|
||||||
store="Audible",
|
|
||||||
)
|
|
||||||
monthly_stats = stats.get("aggregated_monthly_listening_stats", [])
|
|
||||||
if not monthly_stats:
|
|
||||||
return (0, 0, 0)
|
|
||||||
|
|
||||||
total_milliseconds = sum(
|
|
||||||
stat.get("aggregated_sum", 0) for stat in monthly_stats
|
|
||||||
)
|
|
||||||
total_seconds = int(total_milliseconds // 1000)
|
|
||||||
hours, remainder = divmod(total_seconds, 3600)
|
|
||||||
minutes, seconds = divmod(remainder, 60)
|
|
||||||
return (hours, minutes, seconds)
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(f"Could not get current month listening time: {e}")
|
|
||||||
return (0, 0, 0)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
"""Main entry point."""
|
|
||||||
worker = AudibleStats()
|
|
||||||
worker.authenticate()
|
|
||||||
print(worker.get_signup_year())
|
|
||||||
hours, minutes, seconds = worker.get_current_month_listening_time()
|
|
||||||
print(f"Total listening time this month: {hours}h {minutes}m {seconds}s")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user