gitextract_e3m8bq15/ ├── .dockerignore ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ ├── discussion.yml │ │ ├── feature_request.yml │ │ ├── parser_bug.yml │ │ ├── rename_bug.yml │ │ └── rfc.yml │ ├── PULL_REQUEST_TEMPLATE/ │ │ └── pull_request_template.md │ └── workflows/ │ └── build.yml ├── .gitignore ├── .vscode/ │ ├── extensions.json │ ├── launch.json │ └── settings.json ├── CHANGELOG.md ├── CLAUDE.md ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── SECURITY.md ├── backend/ │ ├── .pre-commit-config.yaml │ ├── .vscode/ │ │ └── settings.json │ ├── dev.sh │ ├── pyproject.toml │ ├── scripts/ │ │ └── pip-lock-version.sh │ └── src/ │ ├── dev_server.py │ ├── main.py │ ├── module/ │ │ ├── __init__.py │ │ ├── ab_decorator/ │ │ │ ├── __init__.py │ │ │ └── timeout.py │ │ ├── api/ │ │ │ ├── __init__.py │ │ │ ├── auth.py │ │ │ ├── bangumi.py │ │ │ ├── config.py │ │ │ ├── downloader.py │ │ │ ├── log.py │ │ │ ├── notification.py │ │ │ ├── passkey.py │ │ │ ├── program.py │ │ │ ├── response.py │ │ │ ├── rss.py │ │ │ ├── search.py │ │ │ └── setup.py │ │ ├── checker/ │ │ │ ├── __init__.py │ │ │ └── checker.py │ │ ├── conf/ │ │ │ ├── __init__.py │ │ │ ├── config.py │ │ │ ├── const.py │ │ │ ├── log.py │ │ │ ├── parse.py │ │ │ ├── search_provider.py │ │ │ └── uvicorn_logging.py │ │ ├── core/ │ │ │ ├── __init__.py │ │ │ ├── offset_scanner.py │ │ │ ├── program.py │ │ │ ├── status.py │ │ │ └── sub_thread.py │ │ ├── database/ │ │ │ ├── __init__.py │ │ │ ├── bangumi.py │ │ │ ├── combine.py │ │ │ ├── engine.py │ │ │ ├── passkey.py │ │ │ ├── rss.py │ │ │ ├── torrent.py │ │ │ └── user.py │ │ ├── downloader/ │ │ │ ├── __init__.py │ │ │ ├── client/ │ │ │ │ ├── __init__.py │ │ │ │ ├── aria2_downloader.py │ │ │ │ ├── mock_downloader.py │ │ │ │ ├── qb_downloader.py │ │ │ │ └── tr_downloader.py │ │ │ ├── download_client.py │ │ │ ├── exceptions.py │ │ │ └── path.py │ │ ├── manager/ │ │ │ ├── __init__.py │ │ │ ├── collector.py │ │ │ ├── renamer.py │ │ │ └── torrent.py │ │ ├── mcp/ │ │ │ ├── __init__.py │ │ │ ├── resources.py │ │ │ ├── security.py │ │ │ ├── server.py │ │ │ └── tools.py │ │ ├── models/ │ │ │ ├── __init__.py │ │ │ ├── api.py │ │ │ ├── bangumi.py │ │ │ ├── config.py │ │ │ ├── passkey.py │ │ │ ├── response.py │ │ │ ├── rss.py │ │ │ ├── torrent.py │ │ │ └── user.py │ │ ├── network/ │ │ │ ├── __init__.py │ │ │ ├── request_contents.py │ │ │ ├── request_url.py │ │ │ └── site/ │ │ │ ├── __init__.py │ │ │ └── mikan.py │ │ ├── notification/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── manager.py │ │ │ ├── notification.py │ │ │ ├── plugin/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bark.py │ │ │ │ ├── server_chan.py │ │ │ │ ├── slack.py │ │ │ │ ├── telegram.py │ │ │ │ └── wecom.py │ │ │ └── providers/ │ │ │ ├── __init__.py │ │ │ ├── bark.py │ │ │ ├── discord.py │ │ │ ├── gotify.py │ │ │ ├── pushover.py │ │ │ ├── server_chan.py │ │ │ ├── telegram.py │ │ │ ├── webhook.py │ │ │ └── wecom.py │ │ ├── parser/ │ │ │ ├── __init__.py │ │ │ ├── analyser/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bgm_calendar.py │ │ │ │ ├── bgm_parser.py │ │ │ │ ├── mikan_parser.py │ │ │ │ ├── offset_detector.py │ │ │ │ ├── openai.py │ │ │ │ ├── raw_parser.py │ │ │ │ ├── tmdb_parser.py │ │ │ │ └── torrent_parser.py │ │ │ └── title_parser.py │ │ ├── rss/ │ │ │ ├── __init__.py │ │ │ ├── analyser.py │ │ │ └── engine.py │ │ ├── searcher/ │ │ │ ├── __init__.py │ │ │ ├── provider.py │ │ │ └── searcher.py │ │ ├── security/ │ │ │ ├── __init__.py │ │ │ ├── api.py │ │ │ ├── auth_strategy.py │ │ │ ├── jwt.py │ │ │ └── webauthn.py │ │ ├── update/ │ │ │ ├── __init__.py │ │ │ ├── cross_version.py │ │ │ ├── data_migration.py │ │ │ ├── rss.py │ │ │ ├── startup.py │ │ │ └── version_check.py │ │ └── utils/ │ │ ├── __init__.py │ │ ├── bangumi_data.py │ │ ├── cache_image.py │ │ └── json_config.py │ ├── test/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── e2e/ │ │ │ ├── Dockerfile.mock-rss │ │ │ ├── __init__.py │ │ │ ├── conftest.py │ │ │ ├── docker-compose.test.yml │ │ │ ├── fixtures/ │ │ │ │ └── mikan.xml │ │ │ ├── mock_rss_server.py │ │ │ └── test_e2e_workflow.py │ │ ├── factories.py │ │ ├── test_api_auth.py │ │ ├── test_api_bangumi.py │ │ ├── test_api_bangumi_extended.py │ │ ├── test_api_config.py │ │ ├── test_api_downloader.py │ │ ├── test_api_log.py │ │ ├── test_api_passkey.py │ │ ├── test_api_program.py │ │ ├── test_api_rss.py │ │ ├── test_api_search.py │ │ ├── test_auth.py │ │ ├── test_config.py │ │ ├── test_database.py │ │ ├── test_download_client.py │ │ ├── test_integration.py │ │ ├── test_issue_bugs.py │ │ ├── test_mcp_resources.py │ │ ├── test_mcp_security.py │ │ ├── test_mcp_tools.py │ │ ├── test_migration.py │ │ ├── test_mock_downloader.py │ │ ├── test_notification.py │ │ ├── test_openai.py │ │ ├── test_path.py │ │ ├── test_path_parser.py │ │ ├── test_qb_downloader.py │ │ ├── test_raw_parser.py │ │ ├── test_renamer.py │ │ ├── test_rss_engine.py │ │ ├── test_rss_engine_new.py │ │ ├── test_searcher.py │ │ ├── test_setup.py │ │ ├── test_title_parser.py │ │ ├── test_tmdb.py │ │ └── test_torrent_parser.py │ └── test_passkey_server.py ├── docs/ │ ├── .vitepress/ │ │ ├── config.ts │ │ └── theme/ │ │ ├── components/ │ │ │ └── HomePreviewWebUI.vue │ │ ├── index.ts │ │ └── style.css │ ├── api/ │ │ └── index.md │ ├── changelog/ │ │ ├── 2.6.md │ │ ├── 3.0.md │ │ ├── 3.1.md │ │ ├── 3.2-zh.md │ │ └── 3.2.md │ ├── config/ │ │ ├── downloader.md │ │ ├── experimental.md │ │ ├── manager.md │ │ ├── notifier.md │ │ ├── parser.md │ │ ├── program.md │ │ ├── proxy.md │ │ └── rss.md │ ├── deploy/ │ │ ├── docker-cli.md │ │ ├── docker-compose.md │ │ ├── dsm.md │ │ ├── local.md │ │ └── quick-start.md │ ├── dev/ │ │ ├── database.md │ │ ├── e2e-test-guide.md │ │ └── index.md │ ├── en/ │ │ ├── api/ │ │ │ └── index.md │ │ ├── changelog/ │ │ │ ├── 2.6.md │ │ │ ├── 3.0.md │ │ │ ├── 3.1.md │ │ │ └── 3.2.md │ │ ├── config/ │ │ │ ├── downloader.md │ │ │ ├── experimental.md │ │ │ ├── manager.md │ │ │ ├── notifier.md │ │ │ ├── parser.md │ │ │ ├── program.md │ │ │ ├── proxy.md │ │ │ └── rss.md │ │ ├── deploy/ │ │ │ ├── docker-cli.md │ │ │ ├── docker-compose.md │ │ │ ├── dsm.md │ │ │ ├── local.md │ │ │ └── quick-start.md │ │ ├── dev/ │ │ │ ├── database.md │ │ │ └── index.md │ │ ├── faq/ │ │ │ ├── index.md │ │ │ ├── network.md │ │ │ └── troubleshooting.md │ │ ├── feature/ │ │ │ ├── bangumi.md │ │ │ ├── calendar.md │ │ │ ├── rename.md │ │ │ ├── rss.md │ │ │ └── search.md │ │ ├── home/ │ │ │ ├── index.md │ │ │ └── pipline.md │ │ └── index.md │ ├── faq/ │ │ ├── index.md │ │ ├── network.md │ │ └── troubleshooting.md │ ├── feature/ │ │ ├── bangumi.md │ │ ├── calendar.md │ │ ├── rename.md │ │ ├── rss.md │ │ └── search.md │ ├── home/ │ │ ├── index.md │ │ └── pipline.md │ ├── index.md │ ├── ja/ │ │ ├── api/ │ │ │ └── index.md │ │ ├── changelog/ │ │ │ ├── 2.6.md │ │ │ ├── 3.0.md │ │ │ ├── 3.1.md │ │ │ └── 3.2.md │ │ ├── config/ │ │ │ ├── downloader.md │ │ │ ├── experimental.md │ │ │ ├── manager.md │ │ │ ├── notifier.md │ │ │ ├── parser.md │ │ │ ├── program.md │ │ │ ├── proxy.md │ │ │ └── rss.md │ │ ├── deploy/ │ │ │ ├── docker-cli.md │ │ │ ├── docker-compose.md │ │ │ ├── dsm.md │ │ │ ├── local.md │ │ │ └── quick-start.md │ │ ├── dev/ │ │ │ ├── database.md │ │ │ └── index.md │ │ ├── faq/ │ │ │ ├── index.md │ │ │ ├── network.md │ │ │ └── troubleshooting.md │ │ ├── feature/ │ │ │ ├── bangumi.md │ │ │ ├── calendar.md │ │ │ ├── rename.md │ │ │ ├── rss.md │ │ │ └── search.md │ │ ├── home/ │ │ │ ├── index.md │ │ │ └── pipline.md │ │ └── index.md │ ├── package.json │ ├── plans/ │ │ ├── 2026-01-25-search-panel-redesign.md │ │ └── 2026-02-23-calendar-drag-organize-design.md │ ├── resource/ │ │ ├── docker-compose/ │ │ │ ├── AutoBangumi/ │ │ │ │ └── docker-compose.yml │ │ │ └── qBittorrent+AutoBangumi/ │ │ │ └── docker-compose.yml │ │ └── unraid.xml │ ├── tsconfig.json │ └── vercel.json ├── entrypoint.sh ├── scripts/ │ └── generate-beta-notes.sh └── webui/ ├── .eslintignore ├── .eslintrc.json ├── .husky/ │ └── pre-commit ├── .neoconf.json ├── .npmrc ├── .prettierignore ├── .prettierrc.json ├── .storybook/ │ ├── main.ts │ └── preview.ts ├── .vscode/ │ ├── extensions.json │ └── settings.json ├── LICENSE ├── README.md ├── index.html ├── package.json ├── public/ │ └── robots.txt ├── src/ │ ├── App.vue │ ├── api/ │ │ ├── __tests__/ │ │ │ ├── auth.test.ts │ │ │ ├── bangumi.test.ts │ │ │ └── rss.test.ts │ │ ├── auth.ts │ │ ├── bangumi.ts │ │ ├── check.ts │ │ ├── config.ts │ │ ├── download.ts │ │ ├── downloader.ts │ │ ├── log.ts │ │ ├── notification.ts │ │ ├── passkey.ts │ │ ├── program.ts │ │ ├── rss.ts │ │ ├── search.ts │ │ └── setup.ts │ ├── components/ │ │ ├── ab-add-rss.vue │ │ ├── ab-bangumi-card.vue │ │ ├── ab-change-account.vue │ │ ├── ab-container.vue │ │ ├── ab-edit-rule.vue │ │ ├── ab-fold-panel.vue │ │ ├── ab-image.vue │ │ ├── ab-label.vue │ │ ├── ab-popup.vue │ │ ├── ab-rule.vue │ │ ├── ab-search-bar.vue │ │ ├── ab-setting.vue │ │ ├── ab-status-bar.vue │ │ ├── basic/ │ │ │ ├── __tests__/ │ │ │ │ ├── ab-button.test.ts │ │ │ │ └── ab-switch.test.ts │ │ │ ├── ab-adaptive-modal.vue │ │ │ ├── ab-add.stories.ts │ │ │ ├── ab-add.vue │ │ │ ├── ab-bottom-sheet.vue │ │ │ ├── ab-button-multi.stories.ts │ │ │ ├── ab-button-multi.vue │ │ │ ├── ab-button.stories.ts │ │ │ ├── ab-button.vue │ │ │ ├── ab-checkbox.stories.ts │ │ │ ├── ab-checkbox.vue │ │ │ ├── ab-data-list.vue │ │ │ ├── ab-offset-mismatch-dialog.vue │ │ │ ├── ab-page-title.stories.ts │ │ │ ├── ab-page-title.vue │ │ │ ├── ab-pull-refresh.vue │ │ │ ├── ab-search.stories.ts │ │ │ ├── ab-search.vue │ │ │ ├── ab-select.stories.ts │ │ │ ├── ab-select.vue │ │ │ ├── ab-status.stories.ts │ │ │ ├── ab-status.vue │ │ │ ├── ab-swipe-container.vue │ │ │ ├── ab-switch.stories.ts │ │ │ ├── ab-switch.vue │ │ │ ├── ab-tag.stories.ts │ │ │ └── ab-tag.vue │ │ ├── layout/ │ │ │ ├── ab-mobile-nav.vue │ │ │ ├── ab-sidebar.vue │ │ │ └── ab-topbar.vue │ │ ├── media-query.vue │ │ ├── search/ │ │ │ ├── ab-search-card.vue │ │ │ ├── ab-search-confirm.vue │ │ │ ├── ab-search-filters.vue │ │ │ └── ab-search-modal.vue │ │ ├── setting/ │ │ │ ├── config-download.vue │ │ │ ├── config-manage.vue │ │ │ ├── config-normal.vue │ │ │ ├── config-notification.vue │ │ │ ├── config-openai.vue │ │ │ ├── config-parser.vue │ │ │ ├── config-passkey.vue │ │ │ ├── config-player.vue │ │ │ ├── config-proxy.vue │ │ │ ├── config-search-provider.vue │ │ │ └── config-security.vue │ │ └── setup/ │ │ ├── wizard-container.vue │ │ ├── wizard-step-account.vue │ │ ├── wizard-step-downloader.vue │ │ ├── wizard-step-notification.vue │ │ ├── wizard-step-review.vue │ │ ├── wizard-step-rss.vue │ │ └── wizard-step-welcome.vue │ ├── hooks/ │ │ ├── __tests__/ │ │ │ ├── useApi.test.ts │ │ │ └── useAuth.test.ts │ │ ├── useAddRss.ts │ │ ├── useApi.ts │ │ ├── useAppInfo.ts │ │ ├── useAuth.ts │ │ ├── useBreakpointQuery.ts │ │ ├── useDarkMode.ts │ │ ├── useMessage.ts │ │ ├── useMyI18n.ts │ │ ├── usePasskey.ts │ │ └── useSafeArea.ts │ ├── i18n/ │ │ ├── en.json │ │ └── zh-CN.json │ ├── main.ts │ ├── pages/ │ │ ├── index/ │ │ │ ├── bangumi.vue │ │ │ ├── calendar.vue │ │ │ ├── config.vue │ │ │ ├── downloader.vue │ │ │ ├── log.vue │ │ │ ├── player.vue │ │ │ └── rss.vue │ │ ├── index.vue │ │ ├── login.vue │ │ └── setup.vue │ ├── router/ │ │ └── index.ts │ ├── services/ │ │ └── webauthn.ts │ ├── store/ │ │ ├── __tests__/ │ │ │ ├── bangumi.test.ts │ │ │ └── rss.test.ts │ │ ├── bangumi.ts │ │ ├── config.ts │ │ ├── downloader.ts │ │ ├── log.ts │ │ ├── player.ts │ │ ├── program.ts │ │ ├── rss.ts │ │ ├── search.ts │ │ └── setup.ts │ ├── style/ │ │ ├── global.scss │ │ ├── mixin.scss │ │ ├── transition.scss │ │ └── var.scss │ ├── test/ │ │ ├── mocks/ │ │ │ └── api.ts │ │ └── setup.ts │ └── utils/ │ ├── axios.ts │ └── poster.ts ├── tsconfig.json ├── tsconfig.node.json ├── types/ │ ├── api.ts │ ├── auth.ts │ ├── bangumi.ts │ ├── components.ts │ ├── config.ts │ ├── downloader.ts │ ├── dts/ │ │ ├── auto-imports.d.ts │ │ ├── components.d.ts │ │ ├── html.d.ts │ │ ├── router-type.d.ts │ │ └── vite-env.d.ts │ ├── passkey.ts │ ├── rss.ts │ ├── setup.ts │ ├── torrent.ts │ └── utils.ts ├── unocss.config.ts ├── vite.config.ts └── vitest.config.ts