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.
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.
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)
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.