Skip to content

Commit

Permalink
Update 0.6.0
Browse files Browse the repository at this point in the history
- The parameters in the configurator have been changed to dynamic
- Restructuring code
  • Loading branch information
romanin-rf committed Nov 27, 2023
1 parent 2d0a2ea commit 0e9034c
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 54 deletions.
16 changes: 11 additions & 5 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
from pathlib import Path
from typing import Dict, List

if platform.system() == "Windows": ds = ";"
elif platform.system() == "Linux": ds = ":"
else: raise RuntimeError("Your operating system is not supported.")
if platform.system() == "Windows":
ds = ";"
elif platform.system() == "Linux":
ds = ":"
else:
raise RuntimeError("Your operating system is not supported.")

LOCALDIR = os.getcwd()
TRASH_FILES = [ "build", "SeaPlayer.spec" ]
Expand Down Expand Up @@ -68,8 +71,11 @@
"seaplayer/assets/image-not-found.png": "seaplayer/assets/"
}

def localize(path: str) -> str: return os.path.join(LOCALDIR, path.replace('/', os.sep).replace('\\', os.sep))
def add_datas(data: Dict[str, str]) -> List[str]: return [f"--add-data \"{localize(path)}{ds}{data[path]}\"" for path in data]
def localize(path: str) -> str:
return os.path.join(LOCALDIR, path.replace('/', os.sep).replace('\\', os.sep))

def add_datas(data: Dict[str, str]) -> List[str]:
return [f"--add-data \"{localize(path)}{ds}{data[path]}\"" for path in data]

COMMAND_LINE = [
"pyinstaller", "--noconfirm", "--console", "--clean", "--onefile",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "SeaPlayer"
version = "0.5.8"
version = "0.6.0"
description = "SeaPlayer is a player that works in the terminal."
repository = "https://github.com/romanin-rf/SeaPlayer"
authors = ["Romanin <[email protected]>"]
Expand Down
27 changes: 15 additions & 12 deletions seaplayer/screens/Configurate.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,14 @@ async def aio_nofy(
# ! Update Placeholder from InputField
def _upfif(self, attr_name: str) -> str:
return "Currect: " + str(eval(f"self.{attr_name}"))

def gupfif(self, attr_name: str):
return lambda: self._upfif(attr_name)

# ! Update App Config
async def _uac(self, attr_name: str, input: InputField, value: str) -> None:
exec(f"self.{attr_name} = value")
self.app.update_bindings()
await self.aio_nofy("Saved!")

if INIT_SOUNDDEVICE:
Expand All @@ -94,7 +96,8 @@ async def n_ucsdi(option: DataOption) -> None:
return n_ucsdi

def guac(self, attr_name: str):
async def an_uac(input: InputField, value: str) -> None: await self._uac(attr_name, input, value)
async def an_uac(input: InputField, value: str) -> None:
await self._uac(attr_name, input, value)
return an_uac

# ! Configurator Generators
Expand All @@ -114,7 +117,7 @@ def create_configurator_type(
submit=self.guac(attr_name),
update_placeholder=self.gupfif(attr_name)
),
title="[red]{"+group+"}[/red]: "+title+f" ({richefication(type_alias)})",
title="[red]{"+group+"}[/red]: "+f"{title} ({richefication(type_alias)})",
desc=desc+(" [red](restart required)[/red]" if restart_required else ""),
height=5
)
Expand All @@ -131,7 +134,7 @@ def create_configurator_keys(
submit=self.guac(attr_name),
update_placeholder=self.gupfif(attr_name)
),
title="[red]{Key}[/red]: "+title+f" ({richefication(str)})",
title="[red]{Key}[/red]: "+f"{title} ({richefication(str)})",
desc=desc+(" [red](restart required)[/red]" if restart_required else ""),
height=5
)
Expand Down Expand Up @@ -179,19 +182,19 @@ def compose(self) -> ComposeResult:
"app.config.volume_change_percent",
"Playback", "Volume Change Percent",
"Percentage by which the volume changes when the special keys are pressed.",
float, float
float, float, False
)
yield self.create_configurator_type(
"app.config.rewind_count_seconds",
"Playback", "Rewind Count Seconds",
"The value of the seconds by which the current sound will be rewound.",
int, int
int, int, False
)
yield self.create_configurator_type(
"app.config.max_volume_percent",
"Playback", "Max Volume Percent",
"Maximum volume value.",
float, float
float, float, False
)
yield self.create_configurator_type(
"app.config.recursive_search",
Expand All @@ -203,11 +206,11 @@ def compose(self) -> ComposeResult:
"app.config.log_menu_enable",
"Debag", "Log Menu Enable",
"Menu with logs for the current session.",
conv.boolean, bool
conv.boolean, bool, False
)
yield self.create_configurator_keys("app.config.key_quit", "Quit", "Сlose the app.")
yield self.create_configurator_keys("app.config.key_rewind_forward", "Rewind Forward", "Forwards rewinding.")
yield self.create_configurator_keys("app.config.key_rewind_back", "Rewind Back", "Backwards rewinding.")
yield self.create_configurator_keys("app.config.key_volume_up", "Volume +", "Turn up the volume.")
yield self.create_configurator_keys("app.config.key_volume_down", "Volume -", "Turn down the volume.")
yield self.create_configurator_keys("app.config.key_quit", "Quit", "Сlose the app.", False)
yield self.create_configurator_keys("app.config.key_rewind_forward", "Rewind Forward", "Forwards rewinding.", False)
yield self.create_configurator_keys("app.config.key_rewind_back", "Rewind Back", "Backwards rewinding.", False)
yield self.create_configurator_keys("app.config.key_volume_up", "Volume +", "Turn up the volume.", False)
yield self.create_configurator_keys("app.config.key_volume_down", "Volume -", "Turn down the volume.", False)
yield Footer()
34 changes: 18 additions & 16 deletions seaplayer/seaplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import asyncio
# > Graphics
from textual import on
from textual.binding import Binding
from textual.binding import Binding, _Bindings
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical
from textual.widgets import Header, Footer, Static, Label, Button
Expand Down Expand Up @@ -53,21 +53,21 @@
if ENABLE_PLUGIN_SYSTEM:
from .plug import PluginLoader

# ! Main Functions
def build_bindings(config: SeaPlayerConfig):
yield Binding(config.key_quit, "quit", "Quit")
yield Binding("c,с", "push_screen('configurate')", "Configurate")
if config.log_menu_enable:
yield Binding("l,д", "app.toggle_class('.log-menu', '-hidden')", 'Logs')
yield Binding(config.key_rewind_back, "minus_rewind", f"Rewind -{config.rewind_count_seconds} sec")
yield Binding(config.key_rewind_forward, "plus_rewind", f"Rewind +{config.rewind_count_seconds} sec")
yield Binding(config.key_volume_down, "minus_volume", f"Volume -{round(config.volume_change_percent*100)}%")
yield Binding(config.key_volume_up, "plus_volume", f"Volume +{round(config.volume_change_percent*100)}%")
yield Binding("ctrl+s", "screenshot", "Screenshot")
yield Binding(UNKNOWN_OPEN_KEY, "push_screen('unknown')", "None", show=False)

# ! Main
class SeaPlayer(App):
# ! Pre-Initialization Functions
def build_bindings(config: SeaPlayerConfig):
yield Binding(config.key_quit, "quit", "Quit")
yield Binding("c,с", "push_screen('configurate')", "Configurate")
if config.log_menu_enable:
yield Binding("l,д", "app.toggle_class('.log-menu', '-hidden')", 'Logs')
yield Binding(config.key_rewind_back, "minus_rewind", f"Rewind -{config.rewind_count_seconds} sec")
yield Binding(config.key_rewind_forward, "plus_rewind", f"Rewind +{config.rewind_count_seconds} sec")
yield Binding(config.key_volume_down, "minus_volume", f"Volume -{round(config.volume_change_percent*100)}%")
yield Binding(config.key_volume_up, "plus_volume", f"Volume +{round(config.volume_change_percent*100)}%")
yield Binding("ctrl+s", "screenshot", "Screenshot")
yield Binding(UNKNOWN_OPEN_KEY, "push_screen('unknown')", "None", show=False)

# ! Textual Configuration
TITLE = f"{__title__} v{__version__}"
CSS_PATH = [
Expand All @@ -84,7 +84,6 @@ def build_bindings(config: SeaPlayerConfig):
# ! SeaPlayer Configuration
cache = Cacher(CACHE_DIRPATH)
config = SeaPlayerConfig(CONFIG_FILEPATH)
max_volume_percent: float = config.max_volume_percent
image_type: Optional[Union[Type[AsyncImageLabel], Type[StandartImageLabel]]] = None

# ! Textual Keys Configuration
Expand Down Expand Up @@ -126,6 +125,9 @@ def __init__(self, *args, **kwargs) -> None:
self.plugin_loader = PluginLoader(self)
self.plugin_loader.on_init()

def update_bindings(self) -> None:
self._bindings = _Bindings(list(build_bindings(self.config)))

# ! Inherited Functions
async def action_push_screen(self, screen: str) -> None:
if self.SCREENS[screen].id != self.screen.id:
Expand Down Expand Up @@ -473,7 +475,7 @@ async def action_minus_rewind(self):

async def action_plus_volume(self) -> None:
if (sound:=await self.aio_gcs()) is not None:
if (vol:=round(sound.get_volume()+self.config.volume_change_percent, 2)) <= self.max_volume_percent:
if (vol:=round(sound.get_volume()+self.config.volume_change_percent, 2)) <= self.config.max_volume_percent:
self.currect_volume = vol
sound.set_volume(vol)

Expand Down
6 changes: 4 additions & 2 deletions seaplayer/types/Cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def write_var(self, value: Any, name: str, *, group: str="main") -> None: self.w
def read_var(self, name: str, default: D, *, group: str="main") -> D: return self.read(os.path.join(self.vars_dirpath, f"{name}-{group}.pycache"), default)

def var(self, name: str, default: D, *, group: str="main") -> D:
def setter(s, value: D) -> None: self.write_var(value, name, group=group)
def getter(s) -> D: return self.read_var(name, default, group=group)
def setter(s, value: D) -> None:
self.write_var(value, name, group=group)
def getter(s) -> D:
return self.read_var(name, default, group=group)
return property(getter, setter)
36 changes: 24 additions & 12 deletions seaplayer/types/Convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ def __init__(self, *args, **kwargs) -> None:

@staticmethod
def conv(tp: type, value: str) -> Tuple[bool, Optional[Any]]:
try: return True, tp(value)
except: return False, None
try:
return True, tp(value)
except:
return False, None

@staticmethod
async def aio_conv(tp: type, value: str) -> Tuple[bool, Optional[Any]]:
try: return True, tp(value)
except: return False, None
try:
return True, tp(value)
except:
return False, None

def gen_conv(self, tp: type):
def conv_wrapper(value: str) -> Tuple[bool, Optional[Any]]:
Expand All @@ -36,22 +40,27 @@ async def aio_conv_wrapper(value: str) -> Tuple[bool, Optional[Any]]:
@staticmethod
def path(value: str) -> str:
"""Checking the existence of a `path`."""
if not Path(value).exists(): raise PathNotExistsError(value)
if not Path(value).exists():
raise PathNotExistsError(value)
return value

@staticmethod
def filepath(value: str) -> str:
"""Check if there is a file on the path."""
path = Path(value)
if not(path.exists() and path.is_file()): raise PathNotExistsError(value)
if not(path.exists() and path.is_file()):
raise PathNotExistsError(value)
return value

@staticmethod
def boolean(value: str) -> bool:
"""Converting to `bool`."""
if value.lower() == "true": return True
elif value.lower() == "false": return False
else: raise NotBooleanError(value)
if value.lower() == "true":
return True
elif value.lower() == "false":
return False
else:
raise NotBooleanError(value)

@staticmethod
def optional(tp: type):
Expand All @@ -65,14 +74,17 @@ def optional_wrapper(value: str):
def union(*tps: type):
def union_wrapper(value: str):
for tp in tps:
try: return tp(value)
except: pass
try:
return tp(value)
except:
pass
raise TypeError(f"Could not convert to any of the listed types: {tps}")
return union_wrapper

@staticmethod
def literal_string(*values: str):
def literal_string_wrapper(value: str):
if value in values: return value
if value in values:
return value
raise RuntimeError(f"The value ({repr(value)}) is not in the list of values.")
return literal_string_wrapper
24 changes: 18 additions & 6 deletions seaplayer/types/MusicList.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,41 @@
# ! Main Class
class MusicList:
@staticmethod
def get_file_sha1(sound: CodecBase, buffer_size: int=65536) -> str: return sound.__sha1__(buffer_size)
def get_file_sha1(sound: CodecBase, buffer_size: int=65536) -> str:
return sound.__sha1__(buffer_size)

@staticmethod
async def aio_get_file_sha1(sound: CodecBase, buffer_size: int=65536) -> str: return await sound.__aio_sha1__(buffer_size)
async def aio_get_file_sha1(sound: CodecBase, buffer_size: int=65536) -> str:
return await sound.__aio_sha1__(buffer_size)

def __init__(self, **child_sounds: CodecBase) -> None:
self.sounds: Dict[str, CodecBase] = {}
for key in child_sounds:
if isinstance(child_sounds[key], CodecBase):
self.sounds[key] = child_sounds[key]

def exists(self, sound_uuid: str) -> bool: return sound_uuid in self.sounds.keys()
def get(self, sound_uuid: str) -> Optional[CodecBase]: return self.sounds.get(sound_uuid)
def exists(self, sound_uuid: str) -> bool:
return sound_uuid in self.sounds.keys()

def get(self, sound_uuid: str) -> Optional[CodecBase]:
return self.sounds.get(sound_uuid)

def add(self, sound: CodecBase) -> str:
self.sounds[(sound_uuid:=self.get_file_sha1(sound))] = sound
return sound_uuid

def exists_sha1(self, sound: CodecBase) -> bool:
return self.get_file_sha1(sound) in self.sounds.keys()

async def aio_exists(self, sound_uuid: str): return sound_uuid in self.sounds.keys()
async def aio_get(self, sound_uuid: str): return self.sounds.get(sound_uuid)
async def aio_exists(self, sound_uuid: str):
return sound_uuid in self.sounds.keys()

async def aio_get(self, sound_uuid: str):
return self.sounds.get(sound_uuid)

async def aio_add(self, sound: CodecBase):
self.sounds[(sound_uuid:=await self.aio_get_file_sha1(sound))] = sound
return sound_uuid

async def aio_exists_sha1(self, sound: CodecBase) -> bool:
return await self.aio_get_file_sha1(sound) in self.sounds.keys()

0 comments on commit 0e9034c

Please sign in to comment.