mirror of
https://github.com/Benexl/FastAnime.git
synced 2026-01-07 02:03:49 -08:00
feat: lazy load all cli commands for fasster start times
This commit is contained in:
@@ -6,18 +6,14 @@ from .. import __version__
|
||||
from ..libs.anime_provider import anime_sources
|
||||
from ..libs.anime_provider.allanime.constants import SERVERS_AVAILABLE
|
||||
from ..Utility.data import anilist_sort_normalizer
|
||||
from .commands.anilist import anilist
|
||||
from .commands.config import configure
|
||||
from .commands.download import download
|
||||
from .commands.downloads import downloads
|
||||
from .commands.search import search
|
||||
from .commands import LazyGroup
|
||||
|
||||
commands = {
|
||||
"search": search,
|
||||
"download": download,
|
||||
"anilist": anilist,
|
||||
"config": configure,
|
||||
"downloads": downloads,
|
||||
"search": "search.search",
|
||||
"download": "download.download",
|
||||
"anilist": "anilist.anilist",
|
||||
"config": "config.config",
|
||||
"downloads": "downloads.downloads",
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +31,8 @@ signal.signal(signal.SIGINT, handle_exit)
|
||||
|
||||
|
||||
@click.group(
|
||||
commands=commands,
|
||||
lazy_subcommands=commands,
|
||||
cls=LazyGroup,
|
||||
help="A command line application for streaming anime that provides a complete and featureful interface",
|
||||
short_help="Stream Anime",
|
||||
)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# in lazy_group.py
|
||||
import importlib
|
||||
|
||||
import click
|
||||
|
||||
|
||||
class LazyGroup(click.Group):
|
||||
def __init__(self, *args, lazy_subcommands=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# lazy_subcommands is a map of the form:
|
||||
#
|
||||
# {command-name} -> {module-name}.{command-object-name}
|
||||
#
|
||||
self.lazy_subcommands = lazy_subcommands or {}
|
||||
|
||||
def list_commands(self, ctx):
|
||||
base = super().list_commands(ctx)
|
||||
lazy = sorted(self.lazy_subcommands.keys())
|
||||
return base + lazy
|
||||
|
||||
def get_command(self, ctx, cmd_name): # pyright:ignore
|
||||
if cmd_name in self.lazy_subcommands:
|
||||
return self._lazy_load(cmd_name)
|
||||
return super().get_command(ctx, cmd_name)
|
||||
|
||||
def _lazy_load(self, cmd_name: str):
|
||||
# lazily loading a command, first get the module name and attribute name
|
||||
import_path: str = self.lazy_subcommands[cmd_name]
|
||||
modname, cmd_object_name = import_path.rsplit(".", 1)
|
||||
# do the import
|
||||
mod = importlib.import_module(f".{modname}", package="fastanime.cli.commands")
|
||||
# get the Command object from that module
|
||||
cmd_object = getattr(mod, cmd_object_name)
|
||||
# check the result to make debugging easier
|
||||
if not isinstance(cmd_object, click.BaseCommand):
|
||||
raise ValueError(
|
||||
f"Lazy loading of {import_path} failed by returning "
|
||||
"a non-command object"
|
||||
)
|
||||
return cmd_object
|
||||
|
||||
@@ -1,45 +1,31 @@
|
||||
import click
|
||||
|
||||
from ...utils.tools import QueryDict
|
||||
from .completed import completed
|
||||
from .dropped import dropped
|
||||
from .favourites import favourites
|
||||
from .login import login
|
||||
from .notifier import notifier
|
||||
from .paused import paused
|
||||
from .planning import planning
|
||||
from .popular import popular
|
||||
from .random_anime import random_anime
|
||||
from .recent import recent
|
||||
from .rewatching import rewatching
|
||||
from .scores import scores
|
||||
from .search import search
|
||||
from .trending import trending
|
||||
from .upcoming import upcoming
|
||||
from .watching import watching
|
||||
from .__lazyloader__ import LazyGroup
|
||||
|
||||
commands = {
|
||||
"trending": trending,
|
||||
"recent": recent,
|
||||
"search": search,
|
||||
"upcoming": upcoming,
|
||||
"scores": scores,
|
||||
"popular": popular,
|
||||
"favourites": favourites,
|
||||
"random": random_anime,
|
||||
"login": login,
|
||||
"watching": watching,
|
||||
"paused": paused,
|
||||
"rewatching": rewatching,
|
||||
"dropped": dropped,
|
||||
"completed": completed,
|
||||
"planning": planning,
|
||||
"notifier": notifier,
|
||||
"trending": "trending.trending",
|
||||
"recent": "recent.recent",
|
||||
"search": "search.search",
|
||||
"upcoming": "upcoming.upcoming",
|
||||
"scores": "scores.scores",
|
||||
"popular": "popular.popular",
|
||||
"favourites": "favourites.favourites",
|
||||
"random": "random_anime.random_anime",
|
||||
"login": "login.login",
|
||||
"watching": "watching.watching",
|
||||
"paused": "paused.paused",
|
||||
"rewatching": "rewatching.rewatching",
|
||||
"dropped": "dropped.dropped",
|
||||
"completed": "completed.completed",
|
||||
"planning": "planning.planning",
|
||||
"notifier": "notifier.notifier",
|
||||
}
|
||||
|
||||
|
||||
@click.group(
|
||||
commands=commands,
|
||||
lazy_subcommands=commands,
|
||||
cls=LazyGroup,
|
||||
invoke_without_command=True,
|
||||
help="A beautiful interface that gives you access to a commplete streaming experience",
|
||||
short_help="Access all streaming options",
|
||||
|
||||
42
fastanime/cli/commands/anilist/__lazyloader__.py
Normal file
42
fastanime/cli/commands/anilist/__lazyloader__.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# in lazy_group.py
|
||||
import importlib
|
||||
|
||||
import click
|
||||
|
||||
|
||||
class LazyGroup(click.Group):
|
||||
def __init__(self, *args, lazy_subcommands=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
# lazy_subcommands is a map of the form:
|
||||
#
|
||||
# {command-name} -> {module-name}.{command-object-name}
|
||||
#
|
||||
self.lazy_subcommands = lazy_subcommands or {}
|
||||
|
||||
def list_commands(self, ctx):
|
||||
base = super().list_commands(ctx)
|
||||
lazy = sorted(self.lazy_subcommands.keys())
|
||||
return base + lazy
|
||||
|
||||
def get_command(self, ctx, cmd_name): # pyright:ignore
|
||||
if cmd_name in self.lazy_subcommands:
|
||||
return self._lazy_load(cmd_name)
|
||||
return super().get_command(ctx, cmd_name)
|
||||
|
||||
def _lazy_load(self, cmd_name: str):
|
||||
# lazily loading a command, first get the module name and attribute name
|
||||
import_path: str = self.lazy_subcommands[cmd_name]
|
||||
modname, cmd_object_name = import_path.rsplit(".", 1)
|
||||
# do the import
|
||||
mod = importlib.import_module(
|
||||
f".{modname}", package="fastanime.cli.commands.anilist"
|
||||
)
|
||||
# get the Command object from that module
|
||||
cmd_object = getattr(mod, cmd_object_name)
|
||||
# check the result to make debugging easier
|
||||
if not isinstance(cmd_object, click.BaseCommand):
|
||||
raise ValueError(
|
||||
f"Lazy loading of {import_path} failed by returning "
|
||||
"a non-command object"
|
||||
)
|
||||
return cmd_object
|
||||
@@ -13,7 +13,7 @@ import click
|
||||
is_flag=True,
|
||||
)
|
||||
# @click.pass_obj
|
||||
def configure(path, desktop_entry):
|
||||
def config(path, desktop_entry):
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
Reference in New Issue
Block a user