diff --git a/anime_dl/anime_dl.py b/anime_dl/anime_dl.py index ad0954a..643a8ec 100644 --- a/anime_dl/anime_dl.py +++ b/anime_dl/anime_dl.py @@ -18,33 +18,40 @@ def main(url: str) -> None: - url = unquote(url) - if re.search(regex.URL["xgcartoon"]["domain"], url): - scrapper = XgCartoonCreator() - elif re.search(regex.URL["anime1.me"]["domain"], url): - scrapper = Anime1MeCreator() - elif re.search(regex.URL["anime1.in"]["domain"], url): - scrapper = Anime1InCreator() - elif re.search(regex.URL["yhdm.one"]["domain"], url): - scrapper = YhdmOneCreator() - else: - raise Exception(f"Unsupported URL: {url}") - - # scrapping - episodes = scrapper.get_episodes(url) - - # validator - video_url_validator = VideoUrlValidator() - series_name_validator = SeriesNameValidator() - season_validator = SeasonValidator() - episode_name_validator = EpisodeNameValidator() - video_url_validator.set_next(series_name_validator).set_next( - season_validator - ).set_next(episode_name_validator) - - # downloader - ffmpeg_strategy = FfmpegStrategy() - downloader = Downloader(ffmpeg_strategy) - for episode in episodes: - video_url_validator.validate(episode) - downloader.download(episode) + try: + url = unquote(url) + + if re.search(regex.URL["lincartoon"]["domain"], url): + url = url.replace("lincartoon.com", "xgcartoon.com") + + if re.search(regex.URL["xgcartoon"]["domain"], url): + scrapper = XgCartoonCreator() + elif re.search(regex.URL["anime1.me"]["domain"], url): + scrapper = Anime1MeCreator() + elif re.search(regex.URL["anime1.in"]["domain"], url): + scrapper = Anime1InCreator() + elif re.search(regex.URL["yhdm.one"]["domain"], url): + scrapper = YhdmOneCreator() + else: + raise Exception(f"Unsupported URL: {url}") + + # scrapping + episodes = scrapper.get_episodes(url) + + # validator + video_url_validator = VideoUrlValidator() + series_name_validator = SeriesNameValidator() + season_validator = SeasonValidator() + episode_name_validator = EpisodeNameValidator() + video_url_validator.set_next(series_name_validator).set_next( + season_validator + ).set_next(episode_name_validator) + + # downloader + ffmpeg_strategy = FfmpegStrategy() + downloader = Downloader(ffmpeg_strategy) + for episode in episodes: + video_url_validator.validate(episode) + downloader.download(episode) + except: + logger.error(traceback.format_exc()) \ No newline at end of file diff --git a/anime_dl/const/regex.py b/anime_dl/const/regex.py index d2cadf3..63bcd8f 100644 --- a/anime_dl/const/regex.py +++ b/anime_dl/const/regex.py @@ -4,6 +4,11 @@ "series": "^https?:\/\/www\.xgcartoon\.com\/detail\/([_a-zA-Z0-9\-]+)$", "episode": "^https?:\/\/www\.xgcartoon\.com\/video\/([_a-zA-Z0-9\-]+)\/([_a-zA-Z0-9\-]+)\.html$", }, + "lincartoon": { + "domain": "^https?:\/\/www\.lincartoon\.com\/.+$", + "series": "^https?:\/\/www\.lincartoon\.com\/detail\/([_a-zA-Z0-9\-]+)$", + "episode": "^https?:\/\/www\.lincartoon\.com\/video\/([_a-zA-Z0-9\-]+)\/([_a-zA-Z0-9\-]+)\.html$", + }, "anime1.me": { "domain": "^https?:\/\/anime1\.me\/.+$", "series_s": "^https?:\/\/anime1\.me\/\?cat=[0-9]+$", diff --git a/anime_dl/downloader/ffmpeg_strategy.py b/anime_dl/downloader/ffmpeg_strategy.py index c44e895..a113f53 100644 --- a/anime_dl/downloader/ffmpeg_strategy.py +++ b/anime_dl/downloader/ffmpeg_strategy.py @@ -25,11 +25,12 @@ def download(self, episode: Episode) -> None: ) os.makedirs(os.path.dirname(output), exist_ok=True) if os.path.exists(output) is False: + logger.info(f"started download: {filename}") stream = ffmpeg.input(url) stream = ffmpeg.output(stream, output, vcodec="copy", acodec="copy") ffmpeg.run(stream) - logger.info(f"downloaded {filename}") + logger.info(f"downloaded: {filename}") else: - logger.warn(f"file existed: {filename}") + logger.warning(f"file existed: {filename}") except: logger.error(traceback.format_exc()) diff --git a/anime_dl/utils/logger.py b/anime_dl/utils/logger.py index 86f5c25..03a4d87 100644 --- a/anime_dl/utils/logger.py +++ b/anime_dl/utils/logger.py @@ -1,12 +1,48 @@ import logging +from logging.config import dictConfig from anime_dl.utils.config_loader import ConfigLoader config_loader = ConfigLoader() -logging.basicConfig( - level=int(config_loader.get(section="LOGGING", key="level")), - format="[%(asctime)s] %(name)s [%(levelname)-8s]: %(message)s", -) +logging_level = int(config_loader.get(section="LOGGING", key="level")) +webui_log = config_loader.get(section="WEBUI", key="log") + +# logging.basicConfig( +# level=logging_level, +# format="[%(asctime)s] %(name)s [%(levelname)-8s]: %(message)s", +# handlers=[ +# logging.FileHandler(filename=webui_log), +# logging.StreamHandler(), +# ], +# ) +logging_config = { + "version": 1, + "handlers": { + "console_handler": { + "class": "logging.StreamHandler", # console + "level": logging_level, + "formatter": "console_formatter", + }, + "file_handler": { + "class": "logging.FileHandler", + "filename": webui_log, + "level": logging_level, + "formatter": "file_formatter", + }, + }, + "formatters": { + "console_formatter": {"format": "[%(asctime)s] %(name)s [%(levelname)-8s]: %(message)s"}, + "file_formatter": {"format": "[%(asctime)s][%(levelname)-8s]: %(message)s"}, + }, + "loggers": { + "": { + "handlers": ["console_handler", "file_handler"], + "level": "DEBUG", + "propagate": True, + } + }, +} +dictConfig(logging_config) class LoggerMeta(type): @@ -34,3 +70,13 @@ def warning(self, *messages) -> None: def error(self, *messages) -> None: for message in messages: self.logger.error(message) + + def reset_webui_log(self) -> None: + with open(webui_log, "w") as file: + file.truncate(0) + + def read_webui_log(self) -> str: + content = "" + with open(webui_log, "r") as f: + content = f.readlines() + return "".join(content[-15:]) diff --git a/config.ini b/config.ini index ca47e6b..1c8d6ea 100644 --- a/config.ini +++ b/config.ini @@ -3,4 +3,7 @@ level=20 [DIRECTORY] -output=./output/ +output=./output + +[WEBUI] +log=./gradio.log \ No newline at end of file diff --git a/webUI.py b/webUI.py new file mode 100644 index 0000000..7ea43e8 --- /dev/null +++ b/webUI.py @@ -0,0 +1,32 @@ +import logging +import gradio as gr + +from anime_dl import anime_dl +from anime_dl.utils.logger import Logger + +# disable https logs +logging.getLogger("httpx").setLevel(logging.WARNING) + +logger = Logger() +logger.reset_webui_log() + +with gr.Blocks( + title="Anime-dl", analytics_enabled=False, theme=gr.themes.Soft() +) as webui: + gr.Markdown("Anime-dl") + with gr.Row(): + inp = gr.Textbox(label="URL", max_lines=1) + btn = gr.Button("Download", scale=0) + out = gr.Label(show_label=False, scale=0) + btn.click(fn=anime_dl.main, inputs=inp, outputs=out) + logs = gr.Code( + label="Log", + language="shell", + interactive=False, + container=True, + lines=15, + ) + webui.load(logger.read_webui_log, None, logs, every=1) + +if __name__ == "__main__": + webui.launch()