Skip to content

Commit

Permalink
Allow cache config shorthand & clarify functionality. (#2363)
Browse files Browse the repository at this point in the history
* StorageLimitBytes now with notation conversion.

* Clarify/Document cache options in example_options.ini

* Function name consistency.

* Linux instead of *nix
  • Loading branch information
itsTheFae committed Dec 2, 2023
1 parent 10371b5 commit 330b111
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 10 deletions.
4 changes: 3 additions & 1 deletion config/example_options.ini
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,13 @@ SaveVideos = yes

# Set a time limit for stored files. Set to 0 to disable.
# Files which aren't used for this period of time will be removed.
# On Linux/Mac, this uses last-access time. On Windows, file-creation time is used.
# Only applies when SaveVideos option is enabled.
StorageLimitDays = 0

# Set a size limit for the entire cache. Set to 0 to disable.
# When storage exceeds this size, files with older access times are removed first.
# Accepts exact number of bytes or a shorthand notation like 20 MB
# When storage exceeds this size, files with older access/creation times are removed first.
# Only applies when SaveVideos option is enabled.
StorageLimitBytes = 0

Expand Down
14 changes: 7 additions & 7 deletions musicbot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
_func_,
_get_variable,
format_song_duration,
format_size_bytes,
format_size_from_bytes,
)

load_opus_lib()
Expand Down Expand Up @@ -291,8 +291,8 @@ def _unlink_path(path: pathlib.Path):
log.debug(
"Deleted {0} files from cache, total of {1}. Cache is now {2} over {3} file(s).".format(
removed_count,
format_size_bytes(removed_size),
format_size_bytes(cached_size),
format_size_from_bytes(removed_size),
format_size_from_bytes(cached_size),
len(cached_files) - removed_count,
)
)
Expand Down Expand Up @@ -743,7 +743,7 @@ async def on_player_play(self, player, entry):
self.cached_audio_bytes = self.cached_audio_bytes + entry.downloaded_bytes
if self.cached_audio_bytes > self.config.storage_limit_bytes:
log.debug(
f"Cache level requires cleanup. {format_size_bytes(self.cached_audio_bytes)}"
f"Cache level requires cleanup. {format_size_from_bytes(self.cached_audio_bytes)}"
)
self._delete_old_audiocache()

Expand Down Expand Up @@ -1408,7 +1408,7 @@ async def on_ready(self):
f" Delete if unused for {self.config.storage_limit_days} days"
)
if self.config.save_videos and self.config.storage_limit_bytes:
size = format_size_bytes(self.config.storage_limit_bytes)
size = format_size_from_bytes(self.config.storage_limit_bytes)
log.info(f" Delete if size exceeds {size}")

if self.config.status_message:
Expand Down Expand Up @@ -3771,7 +3771,7 @@ async def cmd_cache(self, leftover_args, opt="info"):
if opt == "info":
save_videos = ["Disabled", "Enabled"][self.config.save_videos]
time_limit = f"{self.config.storage_limit_days} days"
size_limit = format_size_bytes(self.config.storage_limit_bytes)
size_limit = format_size_from_bytes(self.config.storage_limit_bytes)
size_now = ""

if not self.config.storage_limit_bytes:
Expand All @@ -3787,7 +3787,7 @@ async def cmd_cache(self, leftover_args, opt="info"):
cached_files += 1
cached_bytes += os.path.getsize(cache_file)
self.cached_audio_bytes = cached_bytes
cached_size = format_size_bytes(cached_bytes)
cached_size = format_size_from_bytes(cached_bytes)
size_now = self.str.get(
"cmd-cache-size-now", "\n\n**Cached Now:** {0} in {1} file(s)"
).format(cached_size, cached_files)
Expand Down
16 changes: 15 additions & 1 deletion musicbot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from .exceptions import HelpfulError
from .constants import VERSION as BOTVERSION
from .utils import format_size_to_bytes

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -116,7 +117,7 @@ def __init__(self, config_file):
self.save_videos = config.getboolean(
"MusicBot", "SaveVideos", fallback=ConfigDefaults.save_videos
)
self.storage_limit_bytes = config.getint(
self.storage_limit_bytes = config.get(
"MusicBot", "StorageLimitBytes", fallback=ConfigDefaults.storage_limit_bytes
)
self.storage_limit_days = config.getint(
Expand Down Expand Up @@ -404,6 +405,19 @@ def run_checks(self):
if not self.footer_text:
self.footer_text = ConfigDefaults.footer_text

if self.storage_limit_bytes:
try:
self.storage_limit_bytes = format_size_to_bytes(
self.storage_limit_bytes
)
except ValueError:
log.exception(
"StorageLimitBytes has invalid config value '{}' using default instead.".format(
self.storage_limit_bytes,
),
)
self.storage_limit_bytes = ConfigDefaults.storage_limit_bytes

# TODO: Add save function for future editing of options with commands
# Maybe add warnings about fields missing from the config file

Expand Down
57 changes: 56 additions & 1 deletion musicbot/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,66 @@ def format_song_duration(ftd):
)


def format_size_bytes(size: int):
def format_size_from_bytes(size: int):
suffix = {0: "", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
power = 1024
i = 0
while size > power:
size /= power
i += 1
return f"{size:.3f} {suffix[i]}B"


def format_size_to_bytes(size_str: str, strict_si=False) -> int:
"""Convert human-friendly *bytes notation into integer.
Note: this function is not intended to convert Bits notation.
Option `strict_si` will use 1000 rather than 1024 for SI suffixes.
"""
si_units = 1024
if strict_si:
si_units = 1000
suffix_list = {
"kilobyte": si_units,
"megabyte": si_units**2,
"gigabyte": si_units**3,
"terabyte": si_units**4,
"petabyte": si_units**5,
"exabyte": si_units**6,
"zetabyte": si_units**7,
"yottabyte": si_units**8,
"kb": si_units,
"mb": si_units**2,
"gb": si_units**3,
"tb": si_units**4,
"pb": si_units**5,
"eb": si_units**6,
"zb": si_units**7,
"yb": si_units**8,
"kibibyte": 1024,
"mebibyte": 1024**2,
"gibibyte": 1024**3,
"tebibyte": 1024**4,
"pebibyte": 1024**5,
"exbibyte": 1024**6,
"zebibyte": 1024**7,
"yobibyte": 1024**8,
"kib": 1024,
"mib": 1024**2,
"gib": 1024**3,
"tib": 1024**4,
"pib": 1024**5,
"eib": 1024**6,
"zib": 1024**7,
"yib": 1024**8,
}
size_str = size_str.lower().strip().strip("s")
for suffix in suffix_list:
if size_str.endswith(suffix):
return int(float(size_str[0 : -len(suffix)]) * suffix_list[suffix])
else:
if size_str.endswith("b"):
size_str = size_str[0:-1]
elif size_str.endswith("byte"):
size_str = size_str[0:-4]
return int(size_str)

0 comments on commit 330b111

Please sign in to comment.