diff --git a/rwx/fs/__init__.py b/rwx/fs/__init__.py index 6abcce7..205746d 100644 --- a/rwx/fs/__init__.py +++ b/rwx/fs/__init__.py @@ -2,6 +2,7 @@ import os import shutil +import tomllib from pathlib import Path from rwx import ps @@ -94,6 +95,19 @@ def read_file_bytes(file_path: Path) -> bytes: return file_object.read() +def read_file_dict(file_path: Path, charset: str = CHARSET) -> dict: + """Read whole file as toml object. + + :param file_path: source input file + :type file_path: Path + :param charset: charset to use for decoding input + :type charset: str + :rtype: dict + """ + text = read_file_text(file_path, charset) + return tomllib.loads(text) + + def read_file_lines(file_path: Path, charset: str = CHARSET) -> list[str]: """Read whole file lines. diff --git a/rwx/sw/freetube/__init__.py b/rwx/sw/freetube/__init__.py new file mode 100644 index 0000000..250b9c3 --- /dev/null +++ b/rwx/sw/freetube/__init__.py @@ -0,0 +1 @@ +"""Configure FreeTube.""" diff --git a/rwx/sw/freetube/channels.py b/rwx/sw/freetube/channels.py new file mode 100644 index 0000000..30777e9 --- /dev/null +++ b/rwx/sw/freetube/channels.py @@ -0,0 +1,29 @@ +"""FreeTube channels.""" + +from rwx import Class + + +class Channel(Class): + """FreeTube channel.""" + + def __init__(self, uid: str, name: str) -> None: + """Set uid & name. + + :param uid: unique identifier + :type uid: str + :param name: label + :type name: str + """ + self.uid = uid + self.name = name + + def to_db(self) -> str: + """Return identifier as db. + + :rtype: str + """ + return f"""\ +{{\ +"id":"{self.uid}"\ +}}\ +""" diff --git a/rwx/sw/freetube/db.py b/rwx/sw/freetube/db.py new file mode 100644 index 0000000..e3eb31e --- /dev/null +++ b/rwx/sw/freetube/db.py @@ -0,0 +1,21 @@ +"""Output FreeTube db.""" + + +def to_db(value: object) -> str: + """Render value as string. + + :param value: value to render + :type value: object + :rtype: str + """ + match value: + case bool(): + text = str(value).lower() + case dict(): + sub = ",".join([f'"{i}":{to_db(v)}' for i, v in value.items()]) + text = f"{{{sub}}}" + case float() | str(): + text = f'"{value}"' + case _: + text = str(value) + return text diff --git a/rwx/sw/freetube/playlists.py b/rwx/sw/freetube/playlists.py new file mode 100644 index 0000000..4183336 --- /dev/null +++ b/rwx/sw/freetube/playlists.py @@ -0,0 +1,47 @@ +"""FreeTube playlists.""" + +from rwx import Class + +from .videos import Video + + +class Playlist(Class): + """FreeTube playlist.""" + + def __init__(self, uid: str, name: str) -> None: + """Set uid & name. + + :param uid: identifier + :type uid: str + :param name: label + :type name: str + """ + self.uid = uid + self.name = name + self.videos: list[Video] = [] + + def add(self, video: Video) -> None: + """Add video. + + :param video: video to add + :type video: Video + """ + self.videos.append(video) + + def to_db(self) -> str: + """Return identifier, name & videos. + + :rtype: str + """ + videos = ",".join([video.to_db() for video in self.videos]) + return f"""\ +{{\ +"_id":"{self.uid}"\ +,\ +"playlistName":"{self.name}"\ +,\ +"protected":true\ +,\ +"videos":[{videos}]\ +}}\ +""" diff --git a/rwx/sw/freetube/profiles.py b/rwx/sw/freetube/profiles.py new file mode 100644 index 0000000..ffb0adc --- /dev/null +++ b/rwx/sw/freetube/profiles.py @@ -0,0 +1,45 @@ +"""FreeTube profiles.""" + +from rwx import Class + +from .channels import Channel + + +class Profile(Class): + """FreeTube profile.""" + + def __init__(self, uid: str, name: str) -> None: + """Set uid & name. + + :param uid: unique identifier + :type uid: str + :param name: label + :type name: str + """ + self.id = uid + self.name = name + self.channels: list[Channel] = [] + + def add(self, channel: Channel) -> None: + """Add channel. + + :param channel: channel to add + :type channel: Channel + """ + self.channels.append(channel) + + def to_db(self) -> str: + """Return identifier, name & channels. + + :rtype: str + """ + channels = ",".join([channel.to_db() for channel in self.channels]) + return f"""\ +{{\ +"_id":"{self.id}"\ +,\ +"name":"{self.name}"\ +,\ +"subscriptions":[{channels}]\ +}}\ +""" diff --git a/rwx/sw/freetube/settings.py b/rwx/sw/freetube/settings.py new file mode 100644 index 0000000..67bb084 --- /dev/null +++ b/rwx/sw/freetube/settings.py @@ -0,0 +1,33 @@ +"""FreeTube settings.""" + +from rwx import Class + +from .db import to_db + + +class Setting(Class): + """FreeTube setting.""" + + def __init__(self, uid: str, value: object) -> None: + """Set uid & value. + + :param uid: unique identifier + :type uid: str + :param value: value + :type value: object + """ + self.uid = uid + self.value = value + + def to_db(self) -> str: + """Return uid & value as db string. + + :rtype: str + """ + return f"""\ +{{\ +"_id":"{self.uid}"\ +,\ +"value":{to_db(self.value)}\ +}}\ +""" diff --git a/rwx/sw/freetube/videos.py b/rwx/sw/freetube/videos.py new file mode 100644 index 0000000..8a53713 --- /dev/null +++ b/rwx/sw/freetube/videos.py @@ -0,0 +1,33 @@ +"""FreeTube videos.""" + +from rwx import Class + + +class Video(Class): + """FreeTube video.""" + + def __init__(self, uid: str, name: str) -> None: + """Set id & name. + + :param uid: identifier + :type uid: str + :param name: label + :type name: str + """ + self.uid = uid + self.name = name + + def to_db(self) -> str: + """Return identifier, zero length & title. + + :rtype: str + """ + return f"""\ +{{\ +"videoId":"{self.uid}"\ +,\ +"lengthSeconds":0\ +,\ +"title":"{self.name}"\ +}}\ +"""