├── .github ├── actions │ ├── test-backend │ │ └── action.yml │ ├── test-desktop-tool │ │ └── action.yml │ ├── test-frontend │ │ └── action.yml │ └── test-pre-commit │ │ └── action.yml ├── issue_template.md ├── pull_request_template.md └── workflows │ ├── auto-author-assign.yml │ ├── build-desktop-tool.yml │ ├── build-frontend.yml │ ├── test-backend.yml │ ├── test-desktop-tool.yml │ ├── test-frontend.yml │ ├── test-pre-commit.yml │ └── tests.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .prettierignore ├── .run ├── Backend - Collect Static.run.xml ├── Backend - Dev Server.run.xml ├── Backend - Import Sources.run.xml ├── Backend - Run Migrations.run.xml ├── Backend - Update DFCs.run.xml ├── Backend - Update Database.run.xml ├── Backend - Worker.run.xml ├── Desktop Client - Run Tests.run.xml ├── Desktop Tool - Build Executable.run.xml ├── Desktop Tool - Run with Skip Setup.run.xml ├── Desktop Tool - Run.run.xml ├── Dev Server.run.xml ├── Frontend - Dev Server.run.xml ├── Web Project - Docker Compose.run.xml ├── Web Project - Run Tests + Update Snapshots.run.xml └── Web Project - Run Tests.run.xml ├── LICENSE.md ├── MPCAutofill ├── MPCAutofill │ ├── .env.dist │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── accounts │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── forms.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── templates │ │ ├── __init__.py │ │ └── accounts │ │ │ └── projects.html │ ├── tests.py │ ├── urls.py │ └── views.py ├── cardpicker │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── constants.py │ ├── dfc_pairs.py │ ├── documents.py │ ├── integrations │ │ ├── __init__.py │ │ ├── game │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ └── mtg.py │ │ ├── integrations.py │ │ └── patreon.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ │ ├── __init__.py │ │ │ ├── __pycache__ │ │ │ └── update_database.cpython-38.pyc │ │ │ ├── db_image_size.py │ │ │ ├── export_sources.py │ │ │ ├── import_sources.py │ │ │ ├── refresh_patreon.py │ │ │ ├── update_database.py │ │ │ └── update_dfcs.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20210120_2349.py │ │ ├── 0003_source_date.py │ │ ├── 0004_auto_20210214_1126.py │ │ ├── 0005_auto_20210405_0019.py │ │ ├── 0006_auto_20210405_0037.py │ │ ├── 0007_auto_20210405_0043.py │ │ ├── 0008_auto_20210405_1030.py │ │ ├── 0009_remove_source_avgdpi.py │ │ ├── 0010_auto_20210517_2034.py │ │ ├── 0011_auto_20210518_2306.py │ │ ├── 0012_auto_20210518_2352.py │ │ ├── 0013_alter_source_drive_link.py │ │ ├── 0014_auto_20210612_1655.py │ │ ├── 0015_auto_20210614_2157.py │ │ ├── 0016_populate_searchq_keyword.py │ │ ├── 0017_auto_20210815_2107.py │ │ ├── 0018_auto_20210922_1827.py │ │ ├── 0019_alter_source_drive_link.py │ │ ├── 0020_refactor_primary_key.py │ │ ├── 0021_alter_source_options_rename_order_source_ordinal.py │ │ ├── 0022_source_name.py │ │ ├── 0023_source_source_type.py │ │ ├── 0024_rename_drive_id_to_identifier.py │ │ ├── 0025_card_folder_location_cardback_folder_location_and_more.py │ │ ├── 0026_remove_token_source_card_card_type_delete_cardback_and_more.py │ │ ├── 0027_project_projectmember_and_more.py │ │ ├── 0028_source_user.py │ │ ├── 0029_alter_project_key.py │ │ ├── 0030_alter_project_key_alter_source_description.py │ │ ├── 0031_card_tags.py │ │ ├── 0032_remove_projectmember_card_projectmember_card_id.py │ │ ├── 0033_card_language.py │ │ ├── 0034_tag.py │ │ ├── 0035_alter_card_tags_alter_tag_aliases.py │ │ ├── 0036_remove_dfcpair_back_searchable_and_more.py │ │ ├── 0037_tag_parent.py │ │ ├── 0038_tag_is_enabled_by_default.py │ │ ├── 0039_remove_card_searchq_keyword.py │ │ ├── 0040_rename_date_card_date_created.py │ │ ├── 0041_card_date_modified.py │ │ ├── 0042_remove_projectmember_projectmember_unique_and_more.py │ │ ├── 0043_auto_20250529_0233.py │ │ ├── __init__.py │ │ └── __pycache__ │ │ │ ├── 0002_auto_20210120_2349.cpython-38.pyc │ │ │ ├── 0003_source_date.cpython-38.pyc │ │ │ └── 0004_auto_20210214_1126.cpython-38.pyc │ ├── models.py │ ├── schema_types.py │ ├── search │ │ ├── __init__.py │ │ ├── sanitisation.py │ │ └── search_functions.py │ ├── sources │ │ ├── __init__.py │ │ ├── api.py │ │ ├── source_types.py │ │ └── update_database.py │ ├── static │ │ └── cardpicker │ │ │ └── favicon.ico │ ├── tags.py │ ├── tests │ │ ├── __init__.py │ │ ├── __snapshots__ │ │ │ ├── test_dfc_pairs.ambr │ │ │ ├── test_frontend.ambr │ │ │ ├── test_integrations.ambr │ │ │ ├── test_sources.ambr │ │ │ └── test_views.ambr │ │ ├── conftest.py │ │ ├── constants.py │ │ ├── factories.py │ │ ├── test_dfc_pairs.py │ │ ├── test_integrations.py │ │ ├── test_sources.py │ │ ├── test_utils.py │ │ └── test_views.py │ ├── urls.py │ ├── utils.py │ └── views.py ├── drives.example.csv ├── manage.py ├── pytest.ini ├── readme.md └── requirements.txt ├── desktop-tool ├── autofill.py ├── favicon.ico ├── post-launch.html ├── readme.md ├── requirements.txt ├── src │ ├── __init__.py │ ├── constants.py │ ├── driver.py │ ├── exc.py │ ├── formatting.py │ ├── io.py │ ├── logging.py │ ├── order.py │ ├── pdf_maker.py │ ├── processing.py │ ├── utils.py │ ├── web_server.py │ └── webdrivers.py └── tests │ ├── __init__.py │ ├── cards │ ├── Simple Lotus.png │ └── test_image.png │ ├── mangled.xml │ ├── test_desktop_client.py │ └── test_order.xml ├── docker ├── .env.dist ├── django │ ├── Dockerfile │ ├── check_client_secrets.sh │ ├── check_drives.sh │ ├── copy_env_file.sh │ └── entrypoint.sh ├── docker-compose.prod.yml ├── docker-compose.yml ├── docker_clean_all.bat ├── docker_clean_all.sh └── nginx │ ├── Dockerfile │ └── nginx.conf ├── frontend ├── .env.dist ├── .env.test ├── .eslintrc.js ├── .eslintrc.json ├── .gitignore ├── .swcrc ├── .vscode │ └── settings.json ├── custom.d.ts ├── jest.config.mjs ├── jest.setup.ts ├── next.config.js ├── package-lock.json ├── package.json ├── public │ ├── .nojekyll │ ├── arrow.svg │ ├── blank.png │ ├── error_404.png │ ├── error_404_med.png │ ├── favicon.ico │ ├── logo-blank.png │ └── logolowres.png ├── readme.md ├── scripts │ └── whyDidYouRender.ts ├── sentry.edge.config.ts ├── sentry.server.config.ts ├── src │ ├── common │ │ ├── StyledDropdownTreeSelect.tsx │ │ ├── constants.ts │ │ ├── cookies.test.ts │ │ ├── cookies.ts │ │ ├── dropzone.tsx │ │ ├── processing.test.ts │ │ ├── processing.ts │ │ ├── schema_types.ts │ │ ├── test-constants.ts │ │ ├── test-utils.tsx │ │ ├── types.ts │ │ └── utils.ts │ ├── components │ │ ├── AutofillCollapse.tsx │ │ ├── AutofillTable.tsx │ │ ├── BlurrableRow.tsx │ │ ├── ClickToCopy.tsx │ │ ├── Coffee.tsx │ │ ├── DisableSSR.tsx │ │ ├── Jumbotron.tsx │ │ ├── NoBackendDefault.tsx │ │ ├── OverflowCol.tsx │ │ ├── OverflowList.tsx │ │ ├── ProjectEditor.tsx │ │ ├── RenderIfVisible.tsx │ │ ├── Ribbon.tsx │ │ ├── Spinner.tsx │ │ └── icon.tsx │ ├── features │ │ ├── backend │ │ │ └── BackendConfig.tsx │ │ ├── bulkManagement │ │ │ ├── SelectedImagesRibbon.test.tsx │ │ │ └── SelectedImagesRibbon.tsx │ │ ├── card │ │ │ ├── AddCardToProjectForm.test.tsx │ │ │ ├── AddCardToProjectForm.tsx │ │ │ ├── Card.test.tsx │ │ │ ├── Card.tsx │ │ │ ├── CardFooter.tsx │ │ │ ├── CardGrid.tsx │ │ │ ├── CardResultSet.tsx │ │ │ ├── CardSlot.test.tsx │ │ │ ├── CardSlot.tsx │ │ │ ├── CommonCardback.test.tsx │ │ │ ├── CommonCardback.tsx │ │ │ └── __snapshots__ │ │ │ │ ├── Card.test.tsx.snap │ │ │ │ ├── CardSlot.test.tsx.snap │ │ │ │ └── CommonCardback.test.tsx.snap │ │ ├── cardDetailedView │ │ │ ├── CardDetailedViewModal.test.tsx │ │ │ ├── CardDetailedViewModal.tsx │ │ │ └── __snapshots__ │ │ │ │ └── CardDetailedViewModal.test.tsx.snap │ │ ├── changeQuery │ │ │ ├── ChangeQueryModal.test.tsx │ │ │ └── ChangeQueryModal.tsx │ │ ├── contributions │ │ │ └── Contributions.tsx │ │ ├── download │ │ │ ├── DownloadManager.tsx │ │ │ ├── download.ts │ │ │ ├── downloadDecklist.ts │ │ │ ├── downloadImages.ts │ │ │ └── downloadXML.ts │ │ ├── explore │ │ │ └── Explore.tsx │ │ ├── export │ │ │ ├── Export.tsx │ │ │ ├── ExportDecklist.test.tsx │ │ │ ├── ExportDecklist.tsx │ │ │ ├── ExportImages.tsx │ │ │ ├── ExportXML.test.tsx │ │ │ ├── ExportXML.tsx │ │ │ └── FinishedMyProjectModal.tsx │ │ ├── finishSettings │ │ │ └── FinishSettings.tsx │ │ ├── gridSelector │ │ │ ├── GridSelectorModal.test.tsx │ │ │ └── GridSelectorModal.tsx │ │ ├── import │ │ │ ├── Import.tsx │ │ │ ├── ImportCSV.test.tsx │ │ │ ├── ImportCSV.tsx │ │ │ ├── ImportText.test.tsx │ │ │ ├── ImportText.tsx │ │ │ ├── ImportURL.tsx │ │ │ ├── ImportXML.test.tsx │ │ │ ├── ImportXML.tsx │ │ │ └── __snapshots__ │ │ │ │ ├── ImportCSV.test.tsx.snap │ │ │ │ ├── ImportText.test.tsx.snap │ │ │ │ └── ImportXML.test.tsx.snap │ │ ├── invalidIdentifiers │ │ │ ├── InvalidIdentifiersModal.test.tsx │ │ │ ├── InvalidIdentifiersModal.tsx │ │ │ ├── InvalidIdentifiersStatus.test.tsx │ │ │ ├── InvalidIdentifiersStatus.tsx │ │ │ └── __snapshots__ │ │ │ │ └── InvalidIdentifiersModal.test.tsx.snap │ │ ├── mobile │ │ │ └── MobileStatus.tsx │ │ ├── modals │ │ │ └── Modals.tsx │ │ ├── new │ │ │ ├── New.test.tsx │ │ │ ├── New.tsx │ │ │ └── __snapshots__ │ │ │ │ └── New.test.tsx.snap │ │ ├── project │ │ │ └── ProjectStatus.tsx │ │ ├── search │ │ │ └── SearchStatus.tsx │ │ ├── searchSettings │ │ │ ├── FilterSettings.tsx │ │ │ ├── SearchSettings.test.tsx │ │ │ ├── SearchSettings.tsx │ │ │ ├── SearchTypeSettings.tsx │ │ │ ├── SourceSettings.tsx │ │ │ └── __snapshots__ │ │ │ │ └── SearchSettings.test.tsx.snap │ │ ├── status │ │ │ └── Status.tsx │ │ ├── support │ │ │ ├── SupportBackendModal.tsx │ │ │ └── SupportDeveloperModal.tsx │ │ ├── toasts │ │ │ ├── Toasts.test.tsx │ │ │ └── Toasts.tsx │ │ ├── ui │ │ │ ├── DynamicLogo.test.tsx │ │ │ ├── DynamicLogo.tsx │ │ │ ├── Footer.tsx │ │ │ ├── GenericErrorPage.tsx │ │ │ ├── Layout.tsx │ │ │ ├── Navbar.tsx │ │ │ └── __snapshots__ │ │ │ │ └── DynamicLogo.test.tsx.snap │ │ └── viewSettings │ │ │ └── ViewSettings.tsx │ ├── instrumentation-client.ts │ ├── instrumentation.ts │ ├── mocks │ │ ├── handlers.ts │ │ └── server.ts │ ├── pages │ │ ├── 404.tsx │ │ ├── _app.tsx │ │ ├── _document.tsx │ │ ├── _error.tsx │ │ ├── about.tsx │ │ ├── contributions.tsx │ │ ├── editor.tsx │ │ ├── explore.tsx │ │ ├── index.tsx │ │ └── new.tsx │ ├── store │ │ ├── api.ts │ │ ├── listenerMiddleware.ts │ │ ├── slices │ │ │ ├── backendSlice.ts │ │ │ ├── cardDocumentsSlice.ts │ │ │ ├── cardbackSlice.ts │ │ │ ├── fileDownloadsSlice.ts │ │ │ ├── finishSettingsSlice.ts │ │ │ ├── invalidIdentifiersSlice.ts │ │ │ ├── modalsSlice.ts │ │ │ ├── projectSlice.test.ts │ │ │ ├── projectSlice.ts │ │ │ ├── searchResultsSlice.ts │ │ │ ├── searchSettingsSlice.ts │ │ │ ├── sourceDocumentsSlice.ts │ │ │ ├── toastsSlice.ts │ │ │ └── viewSettingsSlice.ts │ │ └── store.ts │ └── styles │ │ ├── custom.css │ │ └── styles.scss └── tsconfig.json ├── import_sources ├── mypy.ini ├── pyproject.toml ├── readme.md ├── refresh_patreon ├── schemas ├── .eslintrc.js ├── package-lock.json ├── package.json ├── quicktype.ts ├── schemas │ ├── Campaign.json │ ├── Card.json │ ├── CardType.json │ ├── FilterSettings.json │ ├── ImportSite.json │ ├── Language.json │ ├── NewCardsFirstPage.json │ ├── SearchQuery.json │ ├── SearchSettings.json │ ├── SearchTypeSettings.json │ ├── SortBy.json │ ├── Source.json │ ├── SourceContribution.json │ ├── SourceRow.json │ ├── SourceSettings.json │ ├── SourceType.json │ ├── Supporter.json │ ├── SupporterTier.json │ ├── Tag.json │ └── endpoints │ │ ├── CardbacksRequest.json │ │ ├── CardbacksResponse.json │ │ ├── CardsRequest.json │ │ ├── CardsResponse.json │ │ ├── ContributionsResponse.json │ │ ├── DFCPairsResponse.json │ │ ├── EditorSearchRequest.json │ │ ├── EditorSearchResponse.json │ │ ├── ErrorResponse.json │ │ ├── ExploreSearchRequest.json │ │ ├── ExploreSearchResponse.json │ │ ├── ImportSiteDecklistRequest.json │ │ ├── ImportSiteDecklistResponse.json │ │ ├── ImportSitesResponse.json │ │ ├── InfoResponse.json │ │ ├── LanguagesResponse.json │ │ ├── NewCardsFirstPagesResponse.json │ │ ├── NewCardsPageResponse.json │ │ ├── PatreonResponse.json │ │ ├── SampleCardsResponse.json │ │ ├── SearchEngineHealthResponse.json │ │ ├── SourcesResponse.json │ │ └── TagsResponse.json └── tsconfig.json ├── sync_dfcs └── update_database /.github/actions/test-backend/action.yml: -------------------------------------------------------------------------------- 1 | name: Backend tests 2 | description: Test the MPC Autofill Django backend 3 | inputs: 4 | google-drive-api-key: 5 | description: Your Google Drive API key, required for running the database crawler 6 | required: true 7 | moxfield-secret: 8 | description: Your Moxfield API secret, required for pulling data from Moxfield 9 | required: true 10 | runs: 11 | using: composite 12 | steps: 13 | - name: Set up Python 3.9 14 | uses: actions/setup-python@v5 15 | with: 16 | python-version: 3.9 17 | - name: Install Python dependencies 18 | working-directory: MPCAutofill 19 | run: | 20 | python -m pip install --upgrade pip 21 | pip install -r requirements.txt 22 | shell: bash 23 | - name: Write Google Drive API credentials to file 24 | uses: jsdaniell/create-json@v1.2.3 25 | with: 26 | name: "client_secrets.json" 27 | json: ${{ inputs.google-drive-api-key }} 28 | dir: "MPCAutofill/" 29 | - name: Run backend tests 30 | run: | 31 | cd MPCAutofill && pytest . 32 | shell: bash 33 | env: 34 | MOXFIELD_SECRET: ${{ inputs.moxfield-secret }} 35 | -------------------------------------------------------------------------------- /.github/actions/test-desktop-tool/action.yml: -------------------------------------------------------------------------------- 1 | name: Desktop tool tests 2 | description: Test the MPC Autofill CLI / desktop tool 3 | runs: 4 | using: composite 5 | steps: 6 | # not sure atm how to set up brave browser on github actions 7 | - uses: browser-actions/setup-chrome@latest 8 | with: 9 | chrome-version: stable 10 | - uses: browser-actions/setup-edge@latest 11 | with: 12 | edge-version: beta 13 | - name: Fix macOS Chromedriver 14 | if: runner.os == 'macOS' 15 | run: | 16 | rm /usr/local/bin/chromedriver 17 | shell: bash 18 | - name: Set up Python 3.9 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version: 3.9 22 | - name: Install Python dependencies 23 | working-directory: desktop-tool 24 | run: | 25 | python -m pip install --upgrade pip 26 | pip install -r requirements.txt 27 | shell: bash 28 | - name: Write Google Drive API credentials to file 29 | uses: jsdaniell/create-json@v1.2.3 30 | with: 31 | name: "client_secrets.json" 32 | json: ${{ inputs.google-drive-api-key }} 33 | dir: "desktop-tool/" 34 | - name: Run tests 35 | working-directory: desktop-tool 36 | run: pytest . 37 | shell: bash 38 | -------------------------------------------------------------------------------- /.github/actions/test-frontend/action.yml: -------------------------------------------------------------------------------- 1 | name: Frontend tests 2 | description: Test the MPC Autofill static frontend 3 | runs: 4 | using: composite 5 | steps: 6 | - name: Install npm 7 | uses: actions/setup-node@v4 8 | with: 9 | node-version: 18.17 10 | - name: Compile frontend 11 | working-directory: frontend 12 | run: | 13 | npm ci 14 | npm run build 15 | shell: bash 16 | - name: Run frontend tests 17 | working-directory: frontend 18 | run: | 19 | npm run test 20 | shell: bash 21 | -------------------------------------------------------------------------------- /.github/actions/test-pre-commit/action.yml: -------------------------------------------------------------------------------- 1 | name: Formatting and static type checking 2 | description: Validate code styling and type safety with pre-commit hooks 3 | runs: 4 | using: composite 5 | steps: 6 | - name: Set up Python 3.9 7 | uses: actions/setup-python@v5 8 | with: 9 | python-version: 3.9 10 | - name: Install pre-commit 11 | run: pip install pre-commit 12 | shell: bash 13 | - name: Run pre-commit 14 | run: pre-commit run --all-files 15 | shell: bash 16 | -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | # System 2 | 3 | 4 | 5 | - **Operating System (including version)**: 6 | - **Desktop Tool Version**: 7 | - **Browser (including version)**: 8 | 9 | # Affected Components 10 | 11 | 12 | 13 | - [ ] Backend 14 | - [ ] Frontend 15 | - [ ] Desktop Tool 16 | 17 | # Description 18 | 19 | 20 | 21 | 22 | - 23 | 24 | # Steps to Reproduce 25 | 26 | 27 | 28 | 29 | 30 | 31 | - 32 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Provide an overview of your PR here. 4 | 5 | # Checklist 6 | 7 | - [ ] I have installed `pre-commit` and installed the hooks with `pre-commit install` before creating any commits. 8 | - [ ] I have updated any related tests for code I modified or added new tests where appropriate. 9 | - [ ] I have manually tested my changes as follows: 10 | - 11 | - [ ] I have updated any relevant documentation or created new documentation where appropriate. 12 | -------------------------------------------------------------------------------- /.github/workflows/auto-author-assign.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/toshimaru/auto-author-assign 2 | name: Auto Author Assign 3 | on: 4 | pull_request_target: 5 | types: [opened, reopened] 6 | permissions: 7 | pull-requests: write 8 | jobs: 9 | assign-author: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: toshimaru/auto-author-assign@v2.1.1 13 | -------------------------------------------------------------------------------- /.github/workflows/build-desktop-tool.yml: -------------------------------------------------------------------------------- 1 | # credit: https://data-dive.com/multi-os-deployment-in-cloud-using-pyinstaller-and-github-actions 2 | name: Desktop tool build 3 | on: 4 | push: 5 | branches: [master] 6 | workflow_dispatch: 7 | jobs: 8 | build: 9 | name: Build 10 | runs-on: ${{ matrix.os }} 11 | defaults: 12 | run: 13 | working-directory: desktop-tool 14 | strategy: 15 | matrix: 16 | include: 17 | - os: macos-latest 18 | TARGET: macos-arm 19 | - os: macos-13 20 | TARGET: macos-intel 21 | - os: windows-latest 22 | TARGET: windows 23 | - os: ubuntu-latest 24 | TARGET: linux 25 | steps: 26 | - uses: actions/checkout@v4 27 | - uses: browser-actions/setup-chrome@latest 28 | - name: Set up Python 3.9 29 | uses: actions/setup-python@v5 30 | with: 31 | python-version: 3.9 32 | - name: Install dependencies 33 | run: | 34 | python -m pip install --upgrade pip 35 | pip install -r requirements.txt 36 | - name: Install imageio for Nutika .ico conversion 37 | run: | 38 | python -m pip install imageio 39 | - name: Write Google Drive API credentials to file 40 | uses: jsdaniell/create-json@v1.2.3 41 | with: 42 | name: "client_secrets.json" 43 | json: ${{ secrets.GOOGLE_DRIVE_API_KEY }} 44 | dir: "desktop-tool/" 45 | - name: Build with Nuitka for ${{ matrix.TARGET }} 46 | uses: Nuitka/Nuitka-Action@main 47 | with: 48 | nuitka-version: main 49 | working-directory: desktop-tool 50 | script-name: autofill.py 51 | mode: onefile 52 | - name: Upload artifact 53 | uses: actions/upload-artifact@v4 54 | with: 55 | name: ${{ matrix.TARGET }} Build 56 | path: | 57 | desktop-tool/build/*.exe 58 | desktop-tool/build/*.bin 59 | desktop-tool/build/*.app/**/* 60 | -------------------------------------------------------------------------------- /.github/workflows/build-frontend.yml: -------------------------------------------------------------------------------- 1 | name: Frontend build 2 | on: 3 | push: 4 | branches: [frontend-release] 5 | workflow_dispatch: 6 | jobs: 7 | build: 8 | name: Build 9 | runs-on: ubuntu-latest 10 | env: 11 | NEXT_TELEMETRY_DISABLED: 1 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | - name: Install npm 16 | uses: actions/setup-node@v3 17 | with: 18 | node-version: 22.15 19 | - name: Install packages and run tests 20 | working-directory: frontend 21 | run: | 22 | npm ci 23 | npm run test 24 | - name: Build frontend 25 | working-directory: frontend 26 | run: | 27 | npx next build 28 | env: 29 | NEXT_PUBLIC_GA_MEASUREMENT_ID: ${{ secrets.NEXT_PUBLIC_GA_MEASUREMENT_ID }} 30 | NEXT_PUBLIC_IMAGE_BUCKET_URL: ${{ secrets.NEXT_PUBLIC_IMAGE_BUCKET_URL }} 31 | NEXT_PUBLIC_IMAGE_WORKER_URL: ${{ secrets.NEXT_PUBLIC_IMAGE_WORKER_URL }} 32 | - name: Publish frontend to GitHub Pages repo 33 | uses: dmnemec/copy_file_to_another_repo_action@main 34 | env: 35 | API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} 36 | with: 37 | source_file: "frontend/out/." 38 | destination_repo: "mpcautofill/mpcautofill.github.io" 39 | user_email: "chilli.axe@gmail.com" 40 | user_name: "chilli-axe" 41 | -------------------------------------------------------------------------------- /.github/workflows/test-backend.yml: -------------------------------------------------------------------------------- 1 | name: Backend tests 2 | on: 3 | pull_request: 4 | paths: 5 | - "MPCAutofill/**" 6 | workflow_dispatch: 7 | jobs: 8 | test-backend: 9 | name: Backend tests 10 | runs-on: ubuntu-latest 11 | services: 12 | postgres: 13 | image: postgres 14 | env: 15 | POSTGRES_USER: mpcautofill 16 | POSTGRES_PASSWORD: mpcautofill 17 | POSTGRES_DB: mpcautofill 18 | options: >- 19 | --health-cmd pg_isready 20 | --health-interval 10s 21 | --health-timeout 5s 22 | --health-retries 5 23 | ports: 24 | - 5432:5432 25 | steps: 26 | - uses: actions/checkout@v4 27 | - uses: ./.github/actions/test-backend 28 | with: 29 | google-drive-api-key: ${{ secrets.GOOGLE_DRIVE_API_KEY }} 30 | moxfield-secret: ${{ secrets.MOXFIELD_SECRET }} 31 | -------------------------------------------------------------------------------- /.github/workflows/test-desktop-tool.yml: -------------------------------------------------------------------------------- 1 | name: Desktop tool tests 2 | on: 3 | pull_request: 4 | paths: 5 | - "desktop-tool/**" 6 | workflow_dispatch: 7 | jobs: 8 | test-backend: 9 | name: Desktop tool tests 10 | runs-on: ${{ matrix.os }} 11 | strategy: 12 | matrix: 13 | include: 14 | - os: macos-latest 15 | - os: windows-latest 16 | # - os: ubuntu-latest # https://github.com/browser-actions/setup-edge/issues/516 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: ./.github/actions/test-desktop-tool 20 | with: 21 | google-drive-api-key: ${{ secrets.GOOGLE_DRIVE_API_KEY }} 22 | moxfield-secret: ${{ secrets.MOXFIELD_SECRET }} 23 | -------------------------------------------------------------------------------- /.github/workflows/test-frontend.yml: -------------------------------------------------------------------------------- 1 | name: Frontend tests 2 | on: 3 | pull_request: 4 | paths: 5 | - "frontend/**" 6 | workflow_dispatch: 7 | jobs: 8 | test-backend: 9 | name: Frontend tests 10 | runs-on: ubuntu-latest 11 | env: 12 | NEXT_TELEMETRY_DISABLED: 1 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: ./.github/actions/test-frontend 16 | -------------------------------------------------------------------------------- /.github/workflows/test-pre-commit.yml: -------------------------------------------------------------------------------- 1 | name: Formatting and static type checking 2 | on: 3 | push: 4 | branches: ["*"] 5 | workflow_dispatch: 6 | jobs: 7 | test-backend: 8 | name: Formatting and static type checking 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: ./.github/actions/test-pre-commit 13 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | push: 4 | branches: ["master"] 5 | workflow_dispatch: 6 | jobs: 7 | test-backend: 8 | name: Backend tests 9 | runs-on: ubuntu-latest 10 | services: 11 | postgres: 12 | image: postgres 13 | env: 14 | POSTGRES_USER: mpcautofill 15 | POSTGRES_PASSWORD: mpcautofill 16 | POSTGRES_DB: mpcautofill 17 | options: >- 18 | --health-cmd pg_isready 19 | --health-interval 10s 20 | --health-timeout 5s 21 | --health-retries 5 22 | ports: 23 | - 5432:5432 24 | steps: 25 | - uses: actions/checkout@v4 26 | - uses: ./.github/actions/test-backend 27 | with: 28 | google-drive-api-key: ${{ secrets.GOOGLE_DRIVE_API_KEY }} 29 | moxfield-secret: ${{ secrets.MOXFIELD_SECRET }} 30 | test-desktop-tool: 31 | name: Desktop tool tests 32 | runs-on: ${{ matrix.os }} 33 | strategy: 34 | matrix: 35 | include: 36 | - os: macos-latest 37 | - os: windows-latest 38 | # - os: ubuntu-latest # https://github.com/browser-actions/setup-edge/issues/516 39 | steps: 40 | - uses: actions/checkout@v4 41 | - uses: ./.github/actions/test-desktop-tool 42 | with: 43 | google-drive-api-key: ${{ secrets.GOOGLE_DRIVE_API_KEY }} 44 | moxfield-secret: ${{ secrets.MOXFIELD_SECRET }} 45 | test-frontend: 46 | name: Frontend tests 47 | runs-on: ubuntu-latest 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: ./.github/actions/test-frontend 51 | test-pre-commit: 52 | name: Formatting and static type checking 53 | runs-on: ubuntu-latest 54 | steps: 55 | - uses: actions/checkout@v4 56 | - uses: ./.github/actions/test-pre-commit 57 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore all HTML files: 2 | *.html 3 | -------------------------------------------------------------------------------- /.run/Backend - Collect Static.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Backend - Dev Server.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Backend - Import Sources.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Backend - Run Migrations.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Backend - Update DFCs.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Backend - Update Database.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Backend - Worker.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | -------------------------------------------------------------------------------- /.run/Desktop Client - Run Tests.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.run/Desktop Tool - Build Executable.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Desktop Tool - Run with Skip Setup.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Desktop Tool - Run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.run/Dev Server.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.run/Frontend - Dev Server.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |