Source code for TwVideoManager.misc.models

import os
from _io import BufferedReader
from dataclasses import dataclass
# For variable static typing
from datetime import datetime
from typing import Any, List, Optional, Union

from ..models import Video


[docs]@dataclass() class File: """Wrap class for sub-files on :class:`Directory`. :arg str name: the name of the file (without extension). :arg str path: the path of the file (with full filename with the extension). :arg int size: the size of the file (in Bytes) :arg Any meta: metadata of the file. :arg str extension: the extension of the file, starting with a dot. Can be `None` if the file extension is unexplicit. """ name: str path: str _size: Optional[int] meta: Any extension: str def __init__(self, name: str, path: str, size=None, meta: Any=''): self.name, self.extension = os.path.splitext(name) self.path = path self._size = size self.meta = meta def __repr__(self) -> str: return """File('{}{}')""".format(self.name, self.extension) def __pretty__(self) -> str: return self.name @property def size(self) -> int: if not isinstance(self._size, int): self._size = os.path.getsize(self.path) return self._size
[docs]@dataclass() class Directory: """Wrap class for sub-files and sub-directories. :arg str name: the name of the directory. :arg str path: the path of the directory. :arg Directory parent: the parent :class:`Directory` containing this directory. :arg List[File,Directory] siblings: the sub-directories and sub-files, and each is wrapped with the wrapping class. """ name: str path: str parent: Any siblings: Optional[List[File]] @property def subdirectories(self) -> list: return [*filter(lambda x: isinstance(x, Directory), self.siblings)] @property def subfiles(self) -> List[File]: return [*filter(lambda x: isinstance(x, File), self.siblings)] @property def names(self) -> List[str]: return [x.name for x in self.siblings] @property def size(self) -> int: return sum(x.size for x in self.siblings) def __pretty__(self, depth=0) -> str: # TODO: prettify printing out = '' if depth == 0: out += self.name + '\n' for dir in self.subdirectories: out += dir.__pretty__(depth=depth+1) + '\n' else: return '│ ' * (depth - 1) + '├─' + self.name return out
[docs]@dataclass() class VideoFile(Video, File): """Video files in local data directory :arg str name: The name of the video file :arg str extension: The extension of the video file :arg TextIOWrapper file: File object of the video file :arg str author: Streamer ID of the video file :arg Optional[datetime] date: Record-Started time of the video file """ name: str extension: str file: BufferedReader def __repr__(self): return f"""<VideoFile `{self.name}` of `{self.author}`>"""
[docs] @staticmethod def from_file(file: Union[BufferedReader, File], author=None, date=None): # TODO: Doc this func if isinstance(file, BufferedReader): if file.mode != "rb": raise TypeError("Video file must be opened with binary mode.") full_path = os.path.abspath(file.name).replace("\\", "/") name: str= full_path.split("/")[-1] if "." not in name: extension = None else: extension, name = name[::-1].split(".", 1) name, extension = name[::-1], extension[::-1] vid_author: str = os.path.dirname(file.name).replace("\\", "/").split("/")[-1] vid_date: datetime = VideoFile.parse_time(name) return VideoFile(name=name, extension=extension, file=file, author=author or vid_author, date=date or vid_date) elif isinstance(file, File): if author == None or date == None: raise TypeError('author and date must be provided if the file is an instance of `File` model.') name = file.name extension = file.extension file: BufferedReader = open(os.path.join(file.path, file.name), 'rb') return VideoFile(author, date, name, extension, file) else: raise TypeError('File must be subcalss of `File` or `TextIOWrapper.')