From 9322aef98ed52e1f80cbc2d5926c0f117bb0eab7 Mon Sep 17 00:00:00 2001 From: Uday Vidyadharan Date: Sun, 28 Jul 2024 23:26:13 -0400 Subject: [PATCH] First Commit --- .devcontainer/Dockerfile | 5 + .devcontainer/devcontainer.json | 17 + .github/workflows/artifact-management.yaml | 17 + .github/workflows/link-check.yaml | 36 ++ .github/workflows/pull-request.yaml | 130 +++++++ .gitignore | 169 ++++++++ .readthedocs.yaml | 28 ++ .vscode/extensions.json | 8 + .vscode/settings.json | 5 + .vscode/tasks.json | 78 ++++ LICENSE | 29 ++ README.md | 5 + dependencies | 4 + docs/Makefile | 54 +++ docs/requirements.txt | 11 + docs/scripts/convertWebp.py | 8 + docs/scripts/convert_md_to_rst.py | 8 + docs/scripts/imagesizechecker.py | 98 +++++ docs/source/_static/RTX.png | Bin 0 -> 45609 bytes docs/source/_static/css/ftc-rtd.css | 147 +++++++ docs/source/_static/css/ftc-rtl.css | 75 ++++ docs/source/_static/js/api-docs-redirect.js | 24 ++ .../_static/js/external-links-new-tab.js | 4 + docs/source/_static/js/fix-rtd-menu-ios.js | 1 + docs/source/_static/js/version-2014.js | 22 ++ docs/source/assets/FIRSTTech_iconHorz_RGB.png | Bin 0 -> 35841 bytes .../assets/FIRSTTech_iconHorz_RGB_reverse.png | Bin 0 -> 74199 bytes .../FIRST_IN SHOW_Logo_Horizontal_RGB-01.png | Bin 0 -> 175887 bytes docs/source/assets/FIRSTicon_RGB_withTM.ico | Bin 0 -> 16958 bytes docs/source/assets/FTC_Center_Stage_Title.pdf | Bin 0 -> 230123 bytes docs/source/assets/Latex_Footer_FTC.png | Bin 0 -> 11607 bytes docs/source/assets/Latex_Logo_FTC.png | Bin 0 -> 32483 bytes docs/source/conf.py | 351 +++++++++++++++++ docs/source/ftc_ml/faq/faq.rst | 95 +++++ docs/source/ftc_ml/images/image1.png | Bin 0 -> 13697 bytes docs/source/ftc_ml/images/image10.png | Bin 0 -> 119933 bytes docs/source/ftc_ml/images/image14.png | Bin 0 -> 86184 bytes docs/source/ftc_ml/images/image16.png | Bin 0 -> 141511 bytes docs/source/ftc_ml/images/image17.png | Bin 0 -> 421071 bytes docs/source/ftc_ml/images/image2.png | Bin 0 -> 193082 bytes docs/source/ftc_ml/images/image3.png | Bin 0 -> 75351 bytes docs/source/ftc_ml/images/image4.png | Bin 0 -> 28828 bytes docs/source/ftc_ml/images/image9.png | Bin 0 -> 145411 bytes docs/source/ftc_ml/implement/index.rst | 16 + docs/source/ftc_ml/index.rst | 55 +++ docs/source/ftc_ml/intro/intro.rst | 39 ++ .../ftc_ml/logging_on/images/image2.jpg | Bin 0 -> 45037 bytes .../ftc_ml/logging_on/images/image3.png | Bin 0 -> 36356 bytes .../ftc_ml/logging_on/images/image4.png | Bin 0 -> 25379 bytes docs/source/ftc_ml/logging_on/logging-on.rst | 162 ++++++++ .../cancel_training/cancel-training.rst | 12 + .../cancel_training/images/image18.png | Bin 0 -> 50777 bytes .../cont-training-models.rst | 29 ++ .../cont_training_models/images/image15.png | Bin 0 -> 37617 bytes .../create_videos/create-videos.rst | 25 ++ .../deleting_model/deleting-model.rst | 25 ++ .../deleting_model/images/image19.png | Bin 0 -> 39736 bytes .../deleting_model/images/image20.png | Bin 0 -> 18277 bytes .../downloading_model/downloading-model.rst | 11 + .../downloading_model/images/image21.png | Bin 0 -> 41296 bytes docs/source/ftc_ml/managing_tool/index.rst | 24 ++ .../managing_tool/labeling/images/fig6.png | Bin 0 -> 157158 bytes .../managing_tool/labeling/images/image7.jpg | Bin 0 -> 83272 bytes .../managing_tool/labeling/labeling.rst | 117 ++++++ .../model_metrics/images/image16.png | Bin 0 -> 95626 bytes .../model_metrics/images/image17.jpg | Bin 0 -> 95707 bytes .../model_metrics/model-metrics.rst | 173 +++++++++ .../managing_tool/overview/images/image5.jpg | Bin 0 -> 30408 bytes .../managing_tool/overview/overview.rst | 115 ++++++ .../produce_dataset/images/image10.png | Bin 0 -> 111829 bytes .../produce_dataset/images/image9.png | Bin 0 -> 102744 bytes .../produce_dataset/produce-dataset.rst | 57 +++ .../training_models/images/image14.jpg | Bin 0 -> 41497 bytes .../training_models/training-models.rst | 131 +++++++ .../upload_videos/images/image6.png | Bin 0 -> 89759 bytes .../upload_videos/upload-videos.rst | 35 ++ .../optimize_videos/optimize-videos.rst | 193 ++++++++++ docs/source/index.rst | 14 + docs/source/todo.rst | 6 + docs/source/tos/tos.rst | 360 ++++++++++++++++++ docs/source/usage.txt | 25 ++ 81 files changed, 3053 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .github/workflows/artifact-management.yaml create mode 100644 .github/workflows/link-check.yaml create mode 100644 .github/workflows/pull-request.yaml create mode 100644 .gitignore create mode 100644 .readthedocs.yaml create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 LICENSE create mode 100644 README.md create mode 100644 dependencies create mode 100644 docs/Makefile create mode 100644 docs/requirements.txt create mode 100644 docs/scripts/convertWebp.py create mode 100644 docs/scripts/convert_md_to_rst.py create mode 100644 docs/scripts/imagesizechecker.py create mode 100644 docs/source/_static/RTX.png create mode 100644 docs/source/_static/css/ftc-rtd.css create mode 100644 docs/source/_static/css/ftc-rtl.css create mode 100644 docs/source/_static/js/api-docs-redirect.js create mode 100644 docs/source/_static/js/external-links-new-tab.js create mode 100644 docs/source/_static/js/fix-rtd-menu-ios.js create mode 100644 docs/source/_static/js/version-2014.js create mode 100644 docs/source/assets/FIRSTTech_iconHorz_RGB.png create mode 100644 docs/source/assets/FIRSTTech_iconHorz_RGB_reverse.png create mode 100644 docs/source/assets/FIRST_IN SHOW_Logo_Horizontal_RGB-01.png create mode 100644 docs/source/assets/FIRSTicon_RGB_withTM.ico create mode 100644 docs/source/assets/FTC_Center_Stage_Title.pdf create mode 100644 docs/source/assets/Latex_Footer_FTC.png create mode 100644 docs/source/assets/Latex_Logo_FTC.png create mode 100644 docs/source/conf.py create mode 100644 docs/source/ftc_ml/faq/faq.rst create mode 100644 docs/source/ftc_ml/images/image1.png create mode 100644 docs/source/ftc_ml/images/image10.png create mode 100644 docs/source/ftc_ml/images/image14.png create mode 100644 docs/source/ftc_ml/images/image16.png create mode 100644 docs/source/ftc_ml/images/image17.png create mode 100644 docs/source/ftc_ml/images/image2.png create mode 100644 docs/source/ftc_ml/images/image3.png create mode 100644 docs/source/ftc_ml/images/image4.png create mode 100644 docs/source/ftc_ml/images/image9.png create mode 100644 docs/source/ftc_ml/implement/index.rst create mode 100644 docs/source/ftc_ml/index.rst create mode 100644 docs/source/ftc_ml/intro/intro.rst create mode 100644 docs/source/ftc_ml/logging_on/images/image2.jpg create mode 100644 docs/source/ftc_ml/logging_on/images/image3.png create mode 100644 docs/source/ftc_ml/logging_on/images/image4.png create mode 100644 docs/source/ftc_ml/logging_on/logging-on.rst create mode 100644 docs/source/ftc_ml/managing_tool/cancel_training/cancel-training.rst create mode 100644 docs/source/ftc_ml/managing_tool/cancel_training/images/image18.png create mode 100644 docs/source/ftc_ml/managing_tool/cont_training_models/cont-training-models.rst create mode 100644 docs/source/ftc_ml/managing_tool/cont_training_models/images/image15.png create mode 100644 docs/source/ftc_ml/managing_tool/create_videos/create-videos.rst create mode 100644 docs/source/ftc_ml/managing_tool/deleting_model/deleting-model.rst create mode 100644 docs/source/ftc_ml/managing_tool/deleting_model/images/image19.png create mode 100644 docs/source/ftc_ml/managing_tool/deleting_model/images/image20.png create mode 100644 docs/source/ftc_ml/managing_tool/downloading_model/downloading-model.rst create mode 100644 docs/source/ftc_ml/managing_tool/downloading_model/images/image21.png create mode 100644 docs/source/ftc_ml/managing_tool/index.rst create mode 100644 docs/source/ftc_ml/managing_tool/labeling/images/fig6.png create mode 100644 docs/source/ftc_ml/managing_tool/labeling/images/image7.jpg create mode 100644 docs/source/ftc_ml/managing_tool/labeling/labeling.rst create mode 100644 docs/source/ftc_ml/managing_tool/model_metrics/images/image16.png create mode 100644 docs/source/ftc_ml/managing_tool/model_metrics/images/image17.jpg create mode 100644 docs/source/ftc_ml/managing_tool/model_metrics/model-metrics.rst create mode 100644 docs/source/ftc_ml/managing_tool/overview/images/image5.jpg create mode 100644 docs/source/ftc_ml/managing_tool/overview/overview.rst create mode 100644 docs/source/ftc_ml/managing_tool/produce_dataset/images/image10.png create mode 100644 docs/source/ftc_ml/managing_tool/produce_dataset/images/image9.png create mode 100644 docs/source/ftc_ml/managing_tool/produce_dataset/produce-dataset.rst create mode 100644 docs/source/ftc_ml/managing_tool/training_models/images/image14.jpg create mode 100644 docs/source/ftc_ml/managing_tool/training_models/training-models.rst create mode 100644 docs/source/ftc_ml/managing_tool/upload_videos/images/image6.png create mode 100644 docs/source/ftc_ml/managing_tool/upload_videos/upload-videos.rst create mode 100644 docs/source/ftc_ml/optimize_videos/optimize-videos.rst create mode 100644 docs/source/index.rst create mode 100644 docs/source/todo.rst create mode 100644 docs/source/tos/tos.rst create mode 100644 docs/source/usage.txt diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..07dd334 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,5 @@ +FROM python:3.9.18-bullseye +WORKDIR /app +COPY . . +RUN apt-get update && apt-get install -y texlive-latex-recommended texlive-fonts-recommended texlive-latex-extra latexmk texlive-lang-greek texlive-luatex texlive-xetex texlive-fonts-extra dvipng librsvg2-bin git fonts-roboto +RUN pip install -r docs/requirements.txt diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..50245d4 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,17 @@ +{ + "name": "Dockerfile", + "build": { + "context": "..", + "dockerfile": "Dockerfile" + }, + "customizations": { + "vscode": { + "extensions": [ + "lextudio.restructuredtext", + "lextudio.restructuredtext-pack", + "trond-snekvik.simple-rst", + "ms-python.python" + ] + } + } +} diff --git a/.github/workflows/artifact-management.yaml b/.github/workflows/artifact-management.yaml new file mode 100644 index 0000000..e2e92f7 --- /dev/null +++ b/.github/workflows/artifact-management.yaml @@ -0,0 +1,17 @@ +name: "Artifact Management" + +on: + workflow_dispatch: + schedule: + - cron: '15 8 1 * *' + +jobs: + delete-artifacts: + runs-on: ubuntu-latest + steps: + - uses: dscabsa/purge-artifacts-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + expire-in: 7days + + diff --git a/.github/workflows/link-check.yaml b/.github/workflows/link-check.yaml new file mode 100644 index 0000000..bde0d5c --- /dev/null +++ b/.github/workflows/link-check.yaml @@ -0,0 +1,36 @@ +name: "Link Check" + +on: + workflow_dispatch: + schedule: + - cron: '0 */12 * * *' + +jobs: + link-check: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Python Setup + uses: actions/setup-python@v4 + with: + python-version: 3.9 + cache: 'pip' + + - name: Python Install Dependencies + run: pip install -r docs/requirements.txt + + - name: link-check + run: make -C docs/ linkcheck SPHINXOPTS="-W --keep-going -n -q" + + - name: Arhive Log + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + env: + PR_NUMBER: ${{ github.event.number }} + ID: ${{ github.run_attempt }} + with: + name: LINKCHECK-${{ env.PR_NUMBER }}-${{ env.ID }} + path: docs/build/linkcheck/output.txt + retention-days: 7 diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml new file mode 100644 index 0000000..d2b27ef --- /dev/null +++ b/.github/workflows/pull-request.yaml @@ -0,0 +1,130 @@ +name: "Pull Request Docs Check" + +on: +- pull_request + +jobs: + build-pdf: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Refresh Packages + run: sudo apt-fast -y update + + - name: Install Dependencies + run: xargs -a dependencies sudo apt-fast install -y + + - name: Python Setup + uses: actions/setup-python@v4 + with: + python-version: 3.9 + cache: 'pip' + + - name: Python Install Dependencies + run: pip install -r docs/requirements.txt + + - name: Build PDF + env: + SPHINXOPTS: "-D html_context.commit=${{ github.sha }} -D version=latest -A display_github=true -A github_user=${{ github.repository_owner }} -A github_repo=${{ github.event.repository.name }} -A github_version=${{ github.ref_name }} -A conf_py_path=/docs/source/" + run: make -C docs/ latexpdf + + - name: Archive PDF + env: + PR_NUMBER: ${{ github.event.number }} + ID: ${{ github.run_attempt }} + uses: actions/upload-artifact@v3 + with: + name: FTCDOCS-PDF + path: | + docs/build/latex/*.pdf + FTCDOCS-PR-${{ env.PR_NUMBER }}-${{ env.ID }} + if-no-files-found: error + + build-html: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Refresh Packages + run: sudo apt-fast -y update + + - name: Python Setup + uses: actions/setup-python@v4 + with: + python-version: 3.9 + cache: 'pip' + + - name: Python Install Dependencies + run: pip install -r docs/requirements.txt + + - name: Build Site + env: + SPHINXOPTS: "-D html_context.commit=${{ github.sha }} -D version=latest -A display_github=true -A github_user=${{ github.repository_owner }} -A github_repo=${{ github.event.repository.name }} -A github_version=${{ github.ref_name }} -A conf_py_path=/docs/source/" + run: make -C docs/ html + + - name: Archive Site + uses: actions/upload-artifact@v3 + with: + name: FTCDOCS-HTML + path: 'docs/build/html' + if-no-files-found: error + + spelling-check: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - uses: reviewdog/action-misspell@v1 + with: + locale: "US" + reporter: "github-check" + + link-check: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Python Setup + uses: actions/setup-python@v4 + with: + python-version: 3.9 + cache: 'pip' + + - name: Python Install Dependencies + run: pip install -r docs/requirements.txt + + - name: link-check + run: make -C docs/ linkcheck SPHINXOPTS="-W --keep-going -n -q" + + - name: Archive Log + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + env: + PR_NUMBER: ${{ github.event.number }} + ID: ${{ github.run_attempt }} + with: + name: LINKCHECK + path: docs/build/linkcheck/output.txt + retention-days: 7 + + image-check: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Python Setup + uses: actions/setup-python@v4 + with: + python-version: 3.9 + + - name: Python Install Dependencies + run: pip install -r docs/requirements.txt + + - name: image-check + run: make -C docs/ imagecheck diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7022de9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,169 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/python,jupyternotebooks +# Edit at https://www.toptal.com/developers/gitignore?templates=python,jupyternotebooks + +### JupyterNotebooks ### +# gitignore template for Jupyter Notebooks +# website: http://jupyter.org/ + +.ipynb_checkpoints +*/.ipynb_checkpoints/* + +# IPython +profile_default/ +ipython_config.py + +# Remove previous ipynb_checkpoints +# git rm -r .ipynb_checkpoints/ + +### VIM +*.swp +*.swo + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook + +# IPython + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# End of https://www.toptal.com/developers/gitignore/api/python,jupyternotebooks + +# PyCharm project settings +.idea/ +.idea/workspace.xml +.idea/ftcdocs.iml +.idea/misc.xml +.idea/misc.xml +.idea/workspace.xml +.idea/ftcdocs.iml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..3d06039 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,28 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/source/conf.py + +# Build documentation with MkDocs +#mkdocs: +# configuration: mkdocs.yml + +# Optionally build your docs in additional formats such as PDF +formats: + - pdf + +# Optionally set the version of Python and requirements required to build your docs +build: + os: "ubuntu-22.04" + tools: + python: "3.9" + +python: + install: + - requirements: docs/requirements.txt diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c0b3e03 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "lextudio.restructuredtext", + "lextudio.restructuredtext-pack", + "trond-snekvik.simple-rst", + "ms-python.python" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..423fa3e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "makefile.makefilePath": "docs/", + "iis.configDir": "", + "esbonio.sphinx.confDir": "" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a619751 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,78 @@ +{ + "tasks": [ + { + "type": "shell", + "label": "make-setup", + "command": "make", + "options": { + "cwd": "${workspaceFolder}/docs" + }, + "args": [ + "setup" + ], + "group": { + "kind": "build", + }, + "problemMatcher": [] + }, + { + "type": "shell", + "label": "make-html", + "command": "make", + "options": { + "cwd": "${workspaceFolder}/docs" + }, + "args": [ + "html" + ], + "group": { + "kind": "build", + }, + "problemMatcher": [] + }, + { + "type": "shell", + "label": "make-latexpdf", + "command": "make", + "options": { + "cwd": "${workspaceFolder}/docs" + }, + "args": [ + "latexpdf" + ], + "group": { + "kind": "build", + }, + "problemMatcher": [] + }, + { + "type": "shell", + "label": "make-autobuild", + "command": "make", + "options": { + "cwd": "${workspaceFolder}/docs" + }, + "args": [ + "autobuild" + ], + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "shell", + "label": "make-clean", + "command": "make", + "options": { + "cwd": "${workspaceFolder}/docs" + }, + "args": [ + "clean" + ], + "problemMatcher": [] + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3dbba66 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2022, FIRST Tech Challenge +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a09e2f9 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +*FIRST* Tech Challenge Documentation Archive +============================================ + +This is the archive for the FIRST Tech Challenge Documentation +Archive which can be found [here](https://github.com/FIRST-Tech-Challenge/ftcdocs) diff --git a/dependencies b/dependencies new file mode 100644 index 0000000..82dbd8b --- /dev/null +++ b/dependencies @@ -0,0 +1,4 @@ +texlive-xetex +latexmk +jq +fonts-roboto \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..28f4bf4 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,54 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +SIZECHECKER = python3 -m scripts.imagesizechecker +CONFEXCLUDE = --exclude-file source/conf.py +SIZEMAX = 500 + +AUTOBUILD = sphinx-autobuild +HTMLBUILDDIR = build/html +LATEXBUILDDIR = build/latex/ +BOOKLETSBUILDDIR = build/booklets + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +setup: + python -m pip install -r requirements.txt + +autobuild: + @$(AUTOBUILD) $(SOURCEDIR) $(HTMLBUILDDIR) --port=7350 + +--move-booklets: + mkdir -p $(BOOKLETSBUILDDIR) + cp $(addsuffix .pdf, $(basename $(wildcard $(LATEXBUILDDIR)*.tex))) $(BOOKLETSBUILDDIR) + +--generate-booklets: + BOOKLETS_BUILD="true" $(SPHINXBUILD) -M latexpdf $(SOURCEDIR) $(BUILDDIR) $(SPHINXOPTS) $(O) + +booklets: --generate-booklets --move-booklets + +local-full: + DOCS_BUILD="true" $(SPHINXBUILD) -b html $(SOURCEDIR) $(HTMLBUILDDIR) $(SPHINXOPTS) $(O) + @$(SPHINXBUILD) -M latexpdf $(SOURCEDIR) $(BUILDDIR) $(SPHINXOPTS) $(O) + cp $(LATEXBUILDDIR)*.pdf $(HTMLBUILDDIR) + +imagecheck: + @$(SIZECHECKER) $(SOURCEDIR) $(SIZEMAX) $(CONFEXCLUDE) $(O) + +.PHONY: help autobuild Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..4b06570 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,11 @@ +Sphinx==5.0.0 +sphinx-autobuild==2024.2.4 +make==0.1.6.post2 +git+https://github.com/FIRST-Tech-Challenge/ftcdocs-helper@main#subdirectory=sphinx_rtd_dark_mode_v2 +git+https://github.com/FIRST-Tech-Challenge/ftcdocs-helper@main#subdirectory=javasphinx +sphinx_design==0.2.0 +git+https://github.com/FIRST-Tech-Challenge/ftcdocs-helper@main#subdirectory=googleanalytics +git+https://github.com/FIRST-Tech-Challenge/ftcdocs-helper@main#subdirectory=cookiebanner +sphinx-sitemap==2.3.0 +python-git-info==0.8.3 +sphinxcontrib-mermaid==0.9.2 diff --git a/docs/scripts/convertWebp.py b/docs/scripts/convertWebp.py new file mode 100644 index 0000000..c91aca7 --- /dev/null +++ b/docs/scripts/convertWebp.py @@ -0,0 +1,8 @@ +import glob +import os +from PIL import Image + +for image in glob.glob("**/*.webp", recursive = True): + im1 = Image.open(image) + im1.save(image.replace(".jpeg", ".png"), "PNG") + os.remove(image) diff --git a/docs/scripts/convert_md_to_rst.py b/docs/scripts/convert_md_to_rst.py new file mode 100644 index 0000000..65b8625 --- /dev/null +++ b/docs/scripts/convert_md_to_rst.py @@ -0,0 +1,8 @@ +import glob +import os +from tqdm import tqdm + +for markdown in (pbar := tqdm(glob.glob("**/*.md", recursive = True))): + pbar.set_postfix_str(f"Converting {markdown}") + filename = markdown.replace(".md", ".rst") + os.system(f'pandoc --to=rst --output=\"{filename}\" \"{markdown}\"') diff --git a/docs/scripts/imagesizechecker.py b/docs/scripts/imagesizechecker.py new file mode 100644 index 0000000..3f884b1 --- /dev/null +++ b/docs/scripts/imagesizechecker.py @@ -0,0 +1,98 @@ +# Credit to WPI Lib - FRC Docs +# Source: https://github.com/wpilibsuite/frc-docs/blob/stable/scripts/imagesizechecker.py +# License: http://creativecommons.org/licenses/by/4.0/ + +import os +import argparse +import importlib + +IMAGE_FORMATS = (".png", ".jpg", ".jpeg", ".svg") +KILOBYTE_SIZE = 1000 + + +def clean_module_path(path): + return ( + (path[: -len(".py")] if path.endswith(".py") else path) + .replace("/", ".") + .replace("\\", ".") + ) + + +def verify_image_size(file, max_size, excluded_files): + if file.path.lower().endswith(IMAGE_FORMATS) and not file.path.replace( + "\\", "/" + ).endswith(tuple(excluded_files)): + file_size = file.stat().st_size + + if not file_size <= max_size: + print( + "FILE SIZE IS TOO LARGE File Size: {} Path: {}".format( + file_size, file.path + ) + ) + return False + + return True + + +def iterate_image_sizes(path, max_size, excluded_files): + oversized_count = 0 + for entry in os.scandir(path): + if entry.is_file(): + if not verify_image_size(entry, max_size, excluded_files): + oversized_count += 1 + elif entry.is_dir(): + oversized_count += iterate_image_sizes(entry.path, max_size, excluded_files) + return oversized_count + + +def main(): + arg_parser = argparse.ArgumentParser( + description="verifies image file size is valid" + ) + arg_parser.add_argument("path", type=str, help="the path to scan in") + arg_parser.add_argument( + "max-size", type=int, help="the max size of a file in kilobytes" + ) + arg_parser.add_argument( + "--exclude-file", + "-e", + type=str, + default=None, + help="python file containing IMAGE_SIZE_EXCLUSIONS list", + ) + + args = vars(arg_parser.parse_args()) + + print("Running SizeCheck") + print("Specified Size: {}KB".format(args["max-size"])) + print("Scan Directory: {}".format(args["path"])) + + # Gets excluded files from conf.py + exclude_file = args["exclude_file"] + if exclude_file is not None: + excluded_files = list( + importlib.import_module( + clean_module_path(exclude_file) + ).IMAGE_SIZE_EXCLUSIONS + ) + print("Exclusion Config: {}".format(exclude_file)) + else: + excluded_files = list() + + # Check how many images are too big + oversized_count = iterate_image_sizes( + args["path"], args["max-size"] * KILOBYTE_SIZE, excluded_files + ) + + if oversized_count == 0: + print("\nNo files bigger than {}KB have been found.".format(args["max-size"])) + else: + print( + "\n{} files are bigger than {}KB.".format(oversized_count, args["max-size"]) + ) + exit(1) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/docs/source/_static/RTX.png b/docs/source/_static/RTX.png new file mode 100644 index 0000000000000000000000000000000000000000..d811a985dc22443eb6595df47a63a9898139e59f GIT binary patch literal 45609 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 UYJ+CRQTTYQ`b-7+&?4mj07a8R*8l(j literal 0 HcmV?d00001 diff --git a/docs/source/_static/css/ftc-rtd.css b/docs/source/_static/css/ftc-rtd.css new file mode 100644 index 0000000..c7ab5bc --- /dev/null +++ b/docs/source/_static/css/ftc-rtd.css @@ -0,0 +1,147 @@ +#link-bar a:visited { + color: #FFF; +} + +#link-bar li { + float: left; + padding: 15px; +} + +html[data-theme='dark'] .card, .btn-block { + background-color: #333; +} + +.center {text-align: center;} + +.color-strip { + height: 10px; + margin :0; + padding: 0; + position: relative; + width: 100%; + z-index: 999; + display: table; +} + +.color-strip .fblue { + background: #009cd7; +} + +.color-strip .forange { + background: #f57e25; +} + +.color-strip .fred { + background: #ed1c24; +} + +.color-strip div { + height: 100%; + display: table-cell; +} + +.rst-versions { + width: 320px; +} + +.header-bar { + background: #003974; + min-height: 60px; +} + +.link-bar-container { + margin-left: 320px; +} + +.wy-nav-content { + background: #fcfcfc; +} + +/* Tweaks to make sidebar scroll look pretty */ +.wy-side-scroll { + width: auto; + overflow-y: auto; + margin-top: 10px; +} + +.wy-nav-side { + width: 320px; + padding-bottom: 3em; +} + +.wy-nav-content { + max-width: 1000px; +} + +.wy-nav-content-wrap { + margin-left: 320px; +} + +.wy-nav-content-wrap{ + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#003974',endColorstr='#003974',GradientType=1); + background:#003974; + background:-moz-linear-gradient(left,#6cc2c9,#003974); + background:-webkit-gradient(linear,left top,right top,color-stop(50%,#6cc2c9),color-stop(100%,#003974)); + background:-webkit-linear-gradient(left,#6cc2c9,#003974); + background:-o-linear-gradient(left,#6cc2c9,#003974); + background:-ms-linear-gradient(left,#6cc2c9,#003974); + background:linear-gradient(to right,#6cc2c9,#003974) +} + +html[data-theme='dark'] .wy-nav-content-wrap{ + background:#141414; +} + +.wy-nav-side,.wy-side-nav-search,.wy-nav-top { + background: #003974; +} + +/* Hide color bar on mobile */ +@media screen and (max-width: 768px) { + .header-bar { + display: none; + } + + .wy-nav-content-wrap { + margin-left: 0px; + } + + .wy-nav-side { + width: 300px; + } + + .wy-nav-side.shift { + max-width: 320px; + } + + /* Fix sidebar adjust */ + .rst-versions { + width: 85%; + max-width: 320px; + } +} + +/* Handle landscape */ +@media screen and (min-width: 377px) { + .wy-nav-content-wrap.shift { + left: 320px; + } +} +/* Fix table padding https://github.com/readthedocs/sphinx_rtd_theme/issues/117 */ +@media screen and (min-width: 768px) { + .wy-table-responsive table td, .wy-table-responsive table th { + white-space: normal !important; + } +} + +div.ethical-sidebar, div.ethical-footer { + position: absolute; + left: -99999px; +} + +/* ===================================== */ +/* ====== START SPHINX TABS CSS ======== */ + +.sphinx-tab img { + margin-bottom: 24px; +} diff --git a/docs/source/_static/css/ftc-rtl.css b/docs/source/_static/css/ftc-rtl.css new file mode 100644 index 0000000..c236752 --- /dev/null +++ b/docs/source/_static/css/ftc-rtl.css @@ -0,0 +1,75 @@ +@import url('https://fonts.googleapis.com/css2?family=Heebo&display=swap'); + +body, .rst-content .toctree-wrapper > p.caption, h1, h2, h3, h4, h5, h6, legend { + font-family: 'Heebo', sans-serif; +} +body { + direction: rtl; +} +.fa:before { + transform: scale(-1, 1); +} +.rst-content div[class^=highlight] pre, .highlighttable { + direction: ltr; +} +.rst-content code, .rst-content tt { + direction: ltr; + unicode-bidi: bidi-override; +} + +.link-bar-container { + margin-right: 320px; + margin-left: 0; +} +#link-bar li, .wy-nav-top i { + float: right; +} + +.wy-nav-side, .rst-versions { + right: 0; + left: unset; +} +.wy-nav-content-wrap { + margin-right: 320px; + margin-left: 0; +} +@media screen and (max-width: 768px) { + .wy-nav-side, .rst-versions { + right: -300px; + } + .wy-nav-content-wrap { + margin-right: 0; + } + .wy-nav-side.shift, .rst-versions.shift { + right: 0; + left: unset; + } + .wy-nav-content-wrap.shift { + right: 85%; + left: unset; + } +} + +.rst-content .admonition-title:before { + margin-right: 0; + margin-left: 4px; +} +.wy-breadcrumbs li.wy-breadcrumbs-aside { + float: left; +} +.float-right { + float: left; +} +.float-left { + float: right; +} +.rst-versions .rst-current-version { + text-align: left; +} +.rst-versions .rst-current-version .fa-book, .rst-versions .rst-current-version .icon-book { + float: right; +} +.rst-other-versions { + text-align: right; +} + diff --git a/docs/source/_static/js/api-docs-redirect.js b/docs/source/_static/js/api-docs-redirect.js new file mode 100644 index 0000000..3f8351a --- /dev/null +++ b/docs/source/_static/js/api-docs-redirect.js @@ -0,0 +1,24 @@ +function resolveApiDocsLink(url) { + "use strict"; + + if (!window.hasOwnProperty("docsAccessInfo")) { // Cache Docs Access Info + const match = window.location.href.match(/.*wpilib(?\/|\\)[0-9]{4}\kdocumentation\k/); + const onlineDocsUrl = "https://first.wpi.edu/wpilib/allwpilib/docs/release/"; + + window.docsAccessInfo = {}; + window.docsAccessInfo.isLocal = Boolean(match); + [window.docsAccessInfo.urlBase, window.docsAccessInfo.urlSep] = match || [onlineDocsUrl, "/"]; + window.docsAccessInfo.pathOffset = onlineDocsUrl.length; + } + + return window.docsAccessInfo.urlBase + url.substring(window.docsAccessInfo.pathOffset); +} + +document.addEventListener('DOMContentLoaded', function() { + "use strict"; + for (let link of document.links) { + if (link.href.startsWith("https://first.wpi.edu/wpilib/allwpilib/docs/release/")) { + link.href = resolveApiDocsLink(link.href) + } + } +}, false); diff --git a/docs/source/_static/js/external-links-new-tab.js b/docs/source/_static/js/external-links-new-tab.js new file mode 100644 index 0000000..627818d --- /dev/null +++ b/docs/source/_static/js/external-links-new-tab.js @@ -0,0 +1,4 @@ +$(document).ready(function () { + $('a.external').attr('target', '_blank'); + $('a.external').attr('rel', 'noopener'); +}); diff --git a/docs/source/_static/js/fix-rtd-menu-ios.js b/docs/source/_static/js/fix-rtd-menu-ios.js new file mode 100644 index 0000000..78fff9e --- /dev/null +++ b/docs/source/_static/js/fix-rtd-menu-ios.js @@ -0,0 +1 @@ +window.dataLayer = window.dataLayer || []; diff --git a/docs/source/_static/js/version-2014.js b/docs/source/_static/js/version-2014.js new file mode 100644 index 0000000..13119b9 --- /dev/null +++ b/docs/source/_static/js/version-2014.js @@ -0,0 +1,22 @@ +$lazy = async function (selector) { + let $this = []; + + while (!$this.length) { + await new Promise((resolve) => setTimeout(resolve, 500)); + $this = $(selector); + } + + return $this; +}; + +document.addEventListener( + "DOMContentLoaded", + async function () { + (await $lazy(".rst-other-versions .injected dt:contains('Versions')")) + .parent() + .append( + `
2014
` + ); + }, + false +); diff --git a/docs/source/assets/FIRSTTech_iconHorz_RGB.png b/docs/source/assets/FIRSTTech_iconHorz_RGB.png new file mode 100644 index 0000000000000000000000000000000000000000..c81787f6f0f0c30acc537d03fabd2683483e512f GIT binary patch literal 35841 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