From 166712515df699f3f53cf9331867d4238d15814c Mon Sep 17 00:00:00 2001 From: DjMaestr0 Date: Wed, 19 Feb 2025 08:34:32 +0100 Subject: [PATCH 1/2] updated History class --- shadowtube/history.py | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/shadowtube/history.py b/shadowtube/history.py index fbc2766..84b0702 100644 --- a/shadowtube/history.py +++ b/shadowtube/history.py @@ -1,18 +1,36 @@ +import json + class History: #Abstract class - def __init__(self, filename): - self.history = list() + def __init__(self, filename: str): + #self.history = list() + pass def __size__(self): - return len(history) - - def parse_history(self, filename): - return history + pass - def is_this_type(self, filename): # bool function, - return false # returns false if Youtube history + @staticmethod + def parse_history(self, filename: str): + parsed_data = [] - def get_video(self, index): - return history[index] + with open(filename, "r", encoding="utf-8") as file: + for line in file: + line = line.strip() + if not line: + continue + try: + parsed_data.append(json.loads(line)) + except json.JSONDecodeError: + fixed_line = fix_unquoted_values(line) + parsed_data.append(json.loads(fixed_line)) + + return parsed_data + + def is_this_type(self, filename: str): # bool function, + pass # returns false if Youtube history + + def get_video(self, index: int): + pass def __iter__(self): - return iter(history) + pass + -- 2.45.2 From fbc843ad6d8f526889089472c76c206b8c96f40e Mon Sep 17 00:00:00 2001 From: fedir Date: Wed, 26 Feb 2025 20:36:11 +0100 Subject: [PATCH 2/2] Finished the History class --- shadowtube/history.py | 77 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/shadowtube/history.py b/shadowtube/history.py index 84b0702..3f3eb77 100644 --- a/shadowtube/history.py +++ b/shadowtube/history.py @@ -1,15 +1,33 @@ import json +from typing import Iterator +from .types import Video +from abc import ABC, abstractmethod -class History: #Abstract class - def __init__(self, filename: str): - #self.history = list() - pass - - def __size__(self): + +class History(ABC): # Abstract class + @abstractmethod + def __len__(self) -> int: pass - @staticmethod - def parse_history(self, filename: str): + @staticmethod + def parse_history(filename: str) -> "History": + return FreeTubeHistory(filename) + + @abstractmethod + def is_this_type(self, filename: str) -> bool: + pass + + @abstractmethod + def get_video(self, index: int) -> Video: + pass + + @abstractmethod + def __iter__(self) -> Iterator[Video]: + pass + + +class FreeTubeHistory(History): + def __init__(self, filename: str) -> None: parsed_data = [] with open(filename, "r", encoding="utf-8") as file: @@ -20,17 +38,44 @@ class History: #Abstract class try: parsed_data.append(json.loads(line)) except json.JSONDecodeError: - fixed_line = fix_unquoted_values(line) + fixed_line = FreeTubeHistory._fix_unquoted_values(line) parsed_data.append(json.loads(fixed_line)) - return parsed_data + self._parsed_data = parsed_data - def is_this_type(self, filename: str): # bool function, - pass # returns false if Youtube history + @staticmethod + def _fix_unquoted_values(line: str) -> str: + """Attempts to fix unquoted values by adding quotes around them.""" + import re - def get_video(self, index: int): - pass + def replacer(match): + key, value = match.groups() + if not (value.startswith('"') and value.endswith('"')): + value = f'"{value}"' # Add quotes around the value + return f'"{key}":{value}' + + fixed_line = re.sub(r'"(\w+)":(\w+)', replacer, line) + return fixed_line + + @staticmethod + def _to_video(entry) -> Video: + return Video( + id=entry["videoId"], + title=entry["title"], + description=entry["description"], + watch_time=entry["timeWatched"], + watch_progress=entry["watchProgress"], + ) + + def __len__(self): + return len(self._parsed_data) + + def is_this_type(self, filename: str) -> bool: + raise NotImplementedError() + + def get_video(self, index: int) -> Video: + return FreeTubeHistory._to_video(self._parsed_data[index]) def __iter__(self): - pass - + for entry in self._parsed_data: + yield FreeTubeHistory._to_video(entry) -- 2.45.2