GoldyBot.files

  1from __future__ import annotations
  2import io
  3import os
  4import re
  5import threading
  6import time
  7from typing import IO, Any, Callable
  8
  9import GoldyBot
 10import requests
 11
 12MODULE_NAME = "FILES"
 13
 14class File(object):
 15    """Goldy Bot's File Handler."""
 16    def __init__(self, path):
 17        self.file_path = path
 18
 19        if self.exists() == False:
 20            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] Umm, that file doesn't exist, so I'm going to create it myself.")
 21            self.create()
 22
 23    def read(self) -> Any|None:
 24        """Commands Goldy to return the value of a file."""
 25        try:
 26            with self.get_file() as file:
 27                file_context = file.read()
 28                GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've read the file '{self.file_path}'.")
 29                return file_context
 30
 31        except Exception as e:
 32            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] Oops, I Couldn't read the file '{self.file_path}', so I'm returning 'None'. \nError --> {e}")
 33            return None
 34
 35    def write(self, value) -> None:
 36        """Commands Goldy to write to the file with the following value."""
 37        try:
 38            # Try to edit value of file.
 39            with self.get_file() as file:
 40                file.seek(0)
 41                file.write(str(value))
 42                file.truncate()
 43
 44            GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've written to '{self.file_path}'.")
 45        
 46        except Exception:
 47            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] I Couldn't edit '{self.file_path}' with the value '{value}'!")
 48
 49    def create(self) -> None:
 50        """Commands Goldy to create a file or directory."""
 51        if self.file_path[-1] == "/": # Create directory.
 52            os.mkdir(self.file_path)
 53            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a directory at '{self.file_path}'.")
 54        else: # Create file.
 55            open(self.file_path, "a+")
 56            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a file at '{self.file_path}'.")
 57
 58    def delete(self) -> None:
 59        """Commands Goldy to delete this file."""
 60        if self.file_path[-1] == "/": # Delete as directly.
 61            os.rmdir(self.file_path)
 62            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the directory at '{self.file_path}'.")
 63        else: # Delete as file.
 64            os.remove(self.file_path)
 65            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the file at '{self.file_path}'.")
 66        
 67
 68    def exists(self) -> bool:
 69        """Checks if the file exists."""
 70        if os.path.exists(self.file_path):
 71            return True
 72        else:
 73            return False
 74
 75    def get_file(self, mode="r+") -> IO:
 76        """Commands Goldy to open the file."""
 77        if mode == "wb": return open(self.file_path, mode) # For writing binary.
 78
 79        return open(self.file_path, mode, encoding='utf-8')
 80
 81class WebFile():
 82    """A web file is a class that partially inherits the GoldyBot.File() class but instead of taking in file path it takes in a URL of a file on the web."""
 83    def __init__(self, url:str, download_to_disk:bool=False, time_until_deletion:int|float=10):
 84        self._url = url
 85        self._download_to_disk = download_to_disk
 86        self._time_until_deletion = time_until_deletion
 87        self._request = requests.get(self._url, stream=True)
 88        self._request.raw.decode_content = True # Content-Encoding
 89
 90        self.file_path = self._url
 91
 92        self._file_object = io.BytesIO(self._request.content)
 93
 94        # Getting file name.
 95        try:
 96            self._file_object.name = re.findall("filename=(.+)", self._request.headers['Content-Disposition'])[0]
 97
 98        except KeyError: # If fail to get file name then fallback to default.
 99            GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Failed to find the web file's file name so I'm giving it a default name.")
100
101            content_type = self._request.headers['Content-Type']
102            self._file_object.name = f"uwu_file.{content_type[content_type.index('/')+1:]}"
103
104        # Download to disk temporary if 'download_to_disk' is True.
105        if download_to_disk:
106            self.download_to_disk(self._time_until_deletion)
107
108    @property
109    def url(self) -> str:
110        """Returns url of file."""
111        return self._url
112
113    @property
114    def downloaded_to_disk(self) -> bool:
115        """Has this file been downloaded to disk."""
116        return self._download_to_disk
117
118    @property
119    def file_name(self) -> str:
120        """Returns name of file."""
121        return self._file_object.name
122
123    @property
124    def raw_bytes(self) -> bytes:
125        """Returns 🥩raw bytes of file. Sometimes this is more preferred by other libraries."""
126        return self._request.content
127
128    def download_to_disk(self, time_until_deletion:int|float=10) -> None:
129        """Downloads file to disk temporary. The file deletes itself by default in 5 seconds."""
130        File("./temp/") # Create temp folder.
131        
132        self.temp_file = File(f"./temp/{self._file_object.name}")
133
134        with self.temp_file.get_file(mode="wb") as file:
135            file.seek(0)
136            file.write(self._file_object.getvalue())
137            file.truncate()
138            file.close()
139
140        def delete_file_later(): time.sleep(time_until_deletion); self.temp_file.delete()
141
142        threading.Thread(target=delete_file_later).start()
143
144    def get_file(self) -> io.BytesIO|str:
145        """Returns file IO object but if 'download_to_disk' is True this will return the temporary path to the file."""
146        if self.downloaded_to_disk:
147            return f"./temp/{self._file_object.name}"
148        else:
149            return self._file_object
150    
151    # Inheriting read method from GoldyBot.File class.
152    read:Callable[[], Any|None] = File.__dict__["read"]
153    """Commands Goldy to return the value of a file."""
class File:
15class File(object):
16    """Goldy Bot's File Handler."""
17    def __init__(self, path):
18        self.file_path = path
19
20        if self.exists() == False:
21            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] Umm, that file doesn't exist, so I'm going to create it myself.")
22            self.create()
23
24    def read(self) -> Any|None:
25        """Commands Goldy to return the value of a file."""
26        try:
27            with self.get_file() as file:
28                file_context = file.read()
29                GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've read the file '{self.file_path}'.")
30                return file_context
31
32        except Exception as e:
33            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] Oops, I Couldn't read the file '{self.file_path}', so I'm returning 'None'. \nError --> {e}")
34            return None
35
36    def write(self, value) -> None:
37        """Commands Goldy to write to the file with the following value."""
38        try:
39            # Try to edit value of file.
40            with self.get_file() as file:
41                file.seek(0)
42                file.write(str(value))
43                file.truncate()
44
45            GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've written to '{self.file_path}'.")
46        
47        except Exception:
48            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] I Couldn't edit '{self.file_path}' with the value '{value}'!")
49
50    def create(self) -> None:
51        """Commands Goldy to create a file or directory."""
52        if self.file_path[-1] == "/": # Create directory.
53            os.mkdir(self.file_path)
54            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a directory at '{self.file_path}'.")
55        else: # Create file.
56            open(self.file_path, "a+")
57            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a file at '{self.file_path}'.")
58
59    def delete(self) -> None:
60        """Commands Goldy to delete this file."""
61        if self.file_path[-1] == "/": # Delete as directly.
62            os.rmdir(self.file_path)
63            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the directory at '{self.file_path}'.")
64        else: # Delete as file.
65            os.remove(self.file_path)
66            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the file at '{self.file_path}'.")
67        
68
69    def exists(self) -> bool:
70        """Checks if the file exists."""
71        if os.path.exists(self.file_path):
72            return True
73        else:
74            return False
75
76    def get_file(self, mode="r+") -> IO:
77        """Commands Goldy to open the file."""
78        if mode == "wb": return open(self.file_path, mode) # For writing binary.
79
80        return open(self.file_path, mode, encoding='utf-8')

Goldy Bot's File Handler.

File(path)
17    def __init__(self, path):
18        self.file_path = path
19
20        if self.exists() == False:
21            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] Umm, that file doesn't exist, so I'm going to create it myself.")
22            self.create()
def read(self) -> Optional[Any]:
24    def read(self) -> Any|None:
25        """Commands Goldy to return the value of a file."""
26        try:
27            with self.get_file() as file:
28                file_context = file.read()
29                GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've read the file '{self.file_path}'.")
30                return file_context
31
32        except Exception as e:
33            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] Oops, I Couldn't read the file '{self.file_path}', so I'm returning 'None'. \nError --> {e}")
34            return None

Commands Goldy to return the value of a file.

def write(self, value) -> None:
36    def write(self, value) -> None:
37        """Commands Goldy to write to the file with the following value."""
38        try:
39            # Try to edit value of file.
40            with self.get_file() as file:
41                file.seek(0)
42                file.write(str(value))
43                file.truncate()
44
45            GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've written to '{self.file_path}'.")
46        
47        except Exception:
48            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] I Couldn't edit '{self.file_path}' with the value '{value}'!")

Commands Goldy to write to the file with the following value.

def create(self) -> None:
50    def create(self) -> None:
51        """Commands Goldy to create a file or directory."""
52        if self.file_path[-1] == "/": # Create directory.
53            os.mkdir(self.file_path)
54            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a directory at '{self.file_path}'.")
55        else: # Create file.
56            open(self.file_path, "a+")
57            GoldyBot.logging.print_and_log(f"[{MODULE_NAME}] I've created a file at '{self.file_path}'.")

Commands Goldy to create a file or directory.

def delete(self) -> None:
59    def delete(self) -> None:
60        """Commands Goldy to delete this file."""
61        if self.file_path[-1] == "/": # Delete as directly.
62            os.rmdir(self.file_path)
63            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the directory at '{self.file_path}'.")
64        else: # Delete as file.
65            os.remove(self.file_path)
66            GoldyBot.logging.print_and_log("info_5", f"[{MODULE_NAME}] I've removed the file at '{self.file_path}'.")

Commands Goldy to delete this file.

def exists(self) -> bool:
69    def exists(self) -> bool:
70        """Checks if the file exists."""
71        if os.path.exists(self.file_path):
72            return True
73        else:
74            return False

Checks if the file exists.

def get_file(self, mode='r+') -> <class 'IO'>:
76    def get_file(self, mode="r+") -> IO:
77        """Commands Goldy to open the file."""
78        if mode == "wb": return open(self.file_path, mode) # For writing binary.
79
80        return open(self.file_path, mode, encoding='utf-8')

Commands Goldy to open the file.

class WebFile:
 82class WebFile():
 83    """A web file is a class that partially inherits the GoldyBot.File() class but instead of taking in file path it takes in a URL of a file on the web."""
 84    def __init__(self, url:str, download_to_disk:bool=False, time_until_deletion:int|float=10):
 85        self._url = url
 86        self._download_to_disk = download_to_disk
 87        self._time_until_deletion = time_until_deletion
 88        self._request = requests.get(self._url, stream=True)
 89        self._request.raw.decode_content = True # Content-Encoding
 90
 91        self.file_path = self._url
 92
 93        self._file_object = io.BytesIO(self._request.content)
 94
 95        # Getting file name.
 96        try:
 97            self._file_object.name = re.findall("filename=(.+)", self._request.headers['Content-Disposition'])[0]
 98
 99        except KeyError: # If fail to get file name then fallback to default.
100            GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Failed to find the web file's file name so I'm giving it a default name.")
101
102            content_type = self._request.headers['Content-Type']
103            self._file_object.name = f"uwu_file.{content_type[content_type.index('/')+1:]}"
104
105        # Download to disk temporary if 'download_to_disk' is True.
106        if download_to_disk:
107            self.download_to_disk(self._time_until_deletion)
108
109    @property
110    def url(self) -> str:
111        """Returns url of file."""
112        return self._url
113
114    @property
115    def downloaded_to_disk(self) -> bool:
116        """Has this file been downloaded to disk."""
117        return self._download_to_disk
118
119    @property
120    def file_name(self) -> str:
121        """Returns name of file."""
122        return self._file_object.name
123
124    @property
125    def raw_bytes(self) -> bytes:
126        """Returns 🥩raw bytes of file. Sometimes this is more preferred by other libraries."""
127        return self._request.content
128
129    def download_to_disk(self, time_until_deletion:int|float=10) -> None:
130        """Downloads file to disk temporary. The file deletes itself by default in 5 seconds."""
131        File("./temp/") # Create temp folder.
132        
133        self.temp_file = File(f"./temp/{self._file_object.name}")
134
135        with self.temp_file.get_file(mode="wb") as file:
136            file.seek(0)
137            file.write(self._file_object.getvalue())
138            file.truncate()
139            file.close()
140
141        def delete_file_later(): time.sleep(time_until_deletion); self.temp_file.delete()
142
143        threading.Thread(target=delete_file_later).start()
144
145    def get_file(self) -> io.BytesIO|str:
146        """Returns file IO object but if 'download_to_disk' is True this will return the temporary path to the file."""
147        if self.downloaded_to_disk:
148            return f"./temp/{self._file_object.name}"
149        else:
150            return self._file_object
151    
152    # Inheriting read method from GoldyBot.File class.
153    read:Callable[[], Any|None] = File.__dict__["read"]
154    """Commands Goldy to return the value of a file."""

A web file is a class that partially inherits the GoldyBot.File() class but instead of taking in file path it takes in a URL of a file on the web.

WebFile( url: str, download_to_disk: bool = False, time_until_deletion: int | float = 10)
 84    def __init__(self, url:str, download_to_disk:bool=False, time_until_deletion:int|float=10):
 85        self._url = url
 86        self._download_to_disk = download_to_disk
 87        self._time_until_deletion = time_until_deletion
 88        self._request = requests.get(self._url, stream=True)
 89        self._request.raw.decode_content = True # Content-Encoding
 90
 91        self.file_path = self._url
 92
 93        self._file_object = io.BytesIO(self._request.content)
 94
 95        # Getting file name.
 96        try:
 97            self._file_object.name = re.findall("filename=(.+)", self._request.headers['Content-Disposition'])[0]
 98
 99        except KeyError: # If fail to get file name then fallback to default.
100            GoldyBot.logging.log("warn", f"[{MODULE_NAME}] Failed to find the web file's file name so I'm giving it a default name.")
101
102            content_type = self._request.headers['Content-Type']
103            self._file_object.name = f"uwu_file.{content_type[content_type.index('/')+1:]}"
104
105        # Download to disk temporary if 'download_to_disk' is True.
106        if download_to_disk:
107            self.download_to_disk(self._time_until_deletion)
url: str

Returns url of file.

downloaded_to_disk: bool

Has this file been downloaded to disk.

file_name: str

Returns name of file.

raw_bytes: bytes

Returns 🥩raw bytes of file. Sometimes this is more preferred by other libraries.

def download_to_disk(self, time_until_deletion: int | float = 10) -> None:
129    def download_to_disk(self, time_until_deletion:int|float=10) -> None:
130        """Downloads file to disk temporary. The file deletes itself by default in 5 seconds."""
131        File("./temp/") # Create temp folder.
132        
133        self.temp_file = File(f"./temp/{self._file_object.name}")
134
135        with self.temp_file.get_file(mode="wb") as file:
136            file.seek(0)
137            file.write(self._file_object.getvalue())
138            file.truncate()
139            file.close()
140
141        def delete_file_later(): time.sleep(time_until_deletion); self.temp_file.delete()
142
143        threading.Thread(target=delete_file_later).start()

Downloads file to disk temporary. The file deletes itself by default in 5 seconds.

def get_file(self) -> _io.BytesIO | str:
145    def get_file(self) -> io.BytesIO|str:
146        """Returns file IO object but if 'download_to_disk' is True this will return the temporary path to the file."""
147        if self.downloaded_to_disk:
148            return f"./temp/{self._file_object.name}"
149        else:
150            return self._file_object

Returns file IO object but if 'download_to_disk' is True this will return the temporary path to the file.

def read(self) -> Optional[Any]:
24    def read(self) -> Any|None:
25        """Commands Goldy to return the value of a file."""
26        try:
27            with self.get_file() as file:
28                file_context = file.read()
29                GoldyBot.logging.print_and_log(None, f"[{MODULE_NAME}] I've read the file '{self.file_path}'.")
30                return file_context
31
32        except Exception as e:
33            GoldyBot.logging.print_and_log("error", f"[{MODULE_NAME}] Oops, I Couldn't read the file '{self.file_path}', so I'm returning 'None'. \nError --> {e}")
34            return None

Commands Goldy to return the value of a file.