From 7adcf66cff93f19c20e8bd8c0b1a079298940863 Mon Sep 17 00:00:00 2001 From: Evan Babb Date: Tue, 12 Nov 2024 14:09:07 -0800 Subject: [PATCH] add pyproject.toml; add devcontainer for development; bump some packages --- .devcontainer/devcontainer.json | 15 +++ .../docker-compose.yml | 23 ++++- .devcontainer/postCreate.sh | 15 +++ .github/workflows/django.yml | 5 +- .travis.yml | 2 +- Dockerfile | 40 +++++--- pyproject.toml | 95 +++++++++++++++++++ requirements.apt | 1 + requirements/common.txt | 2 +- roundware/__init__.py | 1 + .../0037_asset_file_and_loc_caption.py | 6 +- roundware/rw/models.py | 2 +- roundware/rw/tests/test_models.py | 14 +-- scripts/tests.sh | 2 +- 14 files changed, 188 insertions(+), 35 deletions(-) create mode 100644 .devcontainer/devcontainer.json rename docker-compose.yml => .devcontainer/docker-compose.yml (50%) create mode 100755 .devcontainer/postCreate.sh create mode 100644 pyproject.toml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..fabd0383 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,15 @@ +{ + "name": "[Optional] Your project name here", + "dockerComposeFile": "docker-compose.yml", + "service": "roundware-dev", + "remoteUser": "root", + "runServices": ["roundware-db"], + "shutdownAction": "stopCompose", + "containerEnv": { + "DJANGO_SETTINGS_MODULE": "roundware.settings.testing", + }, + "workspaceFolder": "/code", + "postCreateCommand": [ + "./.devcontainer/postCreate.sh" + ] +} \ No newline at end of file diff --git a/docker-compose.yml b/.devcontainer/docker-compose.yml similarity index 50% rename from docker-compose.yml rename to .devcontainer/docker-compose.yml index aa849fb2..7ea439e9 100644 --- a/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3" services: roundware-db: image: postgis/postgis @@ -8,20 +7,38 @@ services: POSTGRES_PASSWORD: round ports: - "5432" + roundware: - build: "." + build: + context: .. image: roundware:latest ports: - "8888:8888" - command: python3 roundware/manage.py runserver 0.0.0.0:8888 environment: ROUNDWARE_DEBUG: "true" ROUNDWARE_DB_HOST: "roundware-db" ROUNDWARE_DB_NAME: "round" + ROUNDWARE_DB_USER: "round" volumes: - logs:/roundware/logs depends_on: - roundware-db + roundware-dev: + build: + context: .. + image: roundware-dev:latest + ports: + - "8888:8888" + command: python3 -m roundware.manage.py runserver 0.0.0.0:8888 + environment: + ROUNDWARE_DEBUG: "true" + ROUNDWARE_DB_HOST: "roundware-db" + ROUNDWARE_DB_NAME: "round" + volumes: + - logs:/roundware/logs + - ../roundware:/code/roundware + depends_on: + - roundware-db volumes: logs: \ No newline at end of file diff --git a/.devcontainer/postCreate.sh b/.devcontainer/postCreate.sh new file mode 100755 index 00000000..6547820a --- /dev/null +++ b/.devcontainer/postCreate.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# install git in our devcontainer +apt-get update -y +apt-get install -y git +apt-get clean +rm -rf /var/lib/apt/lists/* + +# migrate the database +python -m roundware.manage migrate + +# load fixture data +python -m roundware.manage loaddata default_auth.json +python -m roundware.manage loaddata sample_project.json + diff --git a/.github/workflows/django.yml b/.github/workflows/django.yml index e511b60f..9d383284 100644 --- a/.github/workflows/django.yml +++ b/.github/workflows/django.yml @@ -13,7 +13,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.8] + python-version: [3.12] services: # Label used to access the service container postgres: @@ -41,8 +41,7 @@ jobs: DEBIAN_FRONTEND=noninteractive xargs -a requirements.apt apt-get install -y --fix-missing python3 --version python3 -m pip install --upgrade pip setuptools - python3 -m pip install -r requirements/common.txt - python3 -m pip install -r requirements/dev.txt + python3 -m pip install .[test] echo "PYTHONPATH=$GITHUB_WORKSPACE:$PYTHONPATH" >> $GITHUB_ENV - name: Run Tests diff --git a/.travis.yml b/.travis.yml index 46069e4a..a539e97f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,4 +27,4 @@ before_script: - sudo mkdir /var/www - sudo chmod 777 /var/www - export PYTHONPATH=.:/usr/lib/python2.7/dist-packages/ -script: python roundware/manage.py test --settings=roundware.settings.testing \ No newline at end of file +script: python src/roundware/manage.py test --settings=roundware.settings.testing \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index c3443d63..3abd014d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,31 @@ -FROM ubuntu:20.04 as roundware +FROM ubuntu:24.04 RUN mkdir /code ENV PATH=/code:$PATH ENV PYTHONPATH=/code -WORKDIR /code -RUN apt-get update +WORKDIR /code ADD requirements.apt . -RUN apt-get update -RUN DEBIAN_FRONTEND=noninteractive xargs -a requirements.apt apt-get install -y --fix-missing -RUN python3 -m pip install pip setuptools --upgrade -RUN which python3 && python3 --version -ADD requirements ./requirements -ADD requirements.txt . -ADD scripts ./scripts -ADD roundware ./roundware -RUN python3 -m pip install -r requirements.txt -RUN python3 -m pip install -r requirements/dev.txt -RUN python3 roundware/manage.py collectstatic +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update -y && \ + xargs -a requirements.apt apt-get install -y --fix-missing && \ + apt-get upgrade -y gdal-bin \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +ENV VIRTUAL_ENV=/pythonenv/roundware-venv +RUN mkdir /pythonenv/ +RUN python3 -m venv $VIRTUAL_ENV +ENV PATH="$VIRTUAL_ENV/bin:$PATH" + +RUN python3 -m pip install pip setuptools --upgrade && \ + which python3 \ + && python3 --version + +ADD pyproject.toml . +ADD scripts/ ./scripts +ADD roundware/ ./roundware + +RUN python3 -m pip install . +RUN python3 -m roundware.manage collectstatic -ADD .coveragerc . +ADD .coveragerc . \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..1c52f5e7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,95 @@ +# pyproject.toml for installing instrument-data-collector +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "roundware" +description = "Roundware Server" +license = {text = "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)"} +dynamic = ['version'] +authors = [ + {"name" = "Halsey Burgund", "email" = "halsey@halseyburgund.com"}, + {"name" = "Mike MacHenry"}, + {"name" = "Ben McAllister"}, + {"name" = "Jule Slootbeek"}, + {"name" = "Bryan Wilson"}, + {"name" = "Brad Erickson", "email" = "eosrei@gmail.com" }, + {"name" = "Evan Babb", "email" = "11@probabble.com"}, +] + +maintainers = [ + {"name" = "Halsey Burgund", "email" = "halsey@halseyburgund.com"}, + {"name" = "Evan Babb", "email" = "11@probabble.com"}, +] + +requires-python = ">=3.11" + +dependencies = [ + "Django==3.0", + # Creates REST APIs + "djangorestframework", + # locks down access to api endpoints + "django-dry-rest-permissions", + # Used for DRF filtering + "django-filter<2.3", + # Used in roundware/rw/admin.py, roundware/rw/forms.py, roundware/rw/views, and more. + "django-guardian==2.2.0", + # Used by roundware/api1/commands.py + "psutil==3.4.2", + # Used by roundware/rw/fields.py + # django-validated-file==2.0.1 + "python-magic==0.4.8", + # Used in roundware/rw/views.py + "django-braces==1.14.0", + # Loaded in roundware/urls.py + # django-adminplus==0.2.1 + # Used in roundware/rw/forms.py + "django-crispy-forms==1.9.1", + # Used in roundware/rw/widgets.py + "django-floppyforms==1.9.0", + # Used in roundware/rw/views.py: + "django-extra-views==0.13.0", + # Used in roundware/rw/fields.py and roundware/rw/widgets.py + "django-sortedm2m==3.1.1", + # Required for RDF Date parsing + "python-dateutil==2.2", + # Used in roundwared/icecast2.py + "requests<2.5", + # Used in admin, including Batch Tag Add + "django-formset-js==0.4.0", + # database adapter for PostgreSQL + "psycopg2", + # geographic distance calculator utilities + "geopy", + # cors support to remove php layer + "django-cors-headers==3.3.0", + # fiona is a useful tool for processing geographic files (ETL) + "fiona", + # geographic extensions for djangorestframework-gis + "djangorestframework-gis<=0.16", + # leaflet map utilities for django admin + "django-leaflet", + # Bootstrap admin theme for Django 1.9 + # https://github.com/roundware/django-admin-bootstrapped/zipball/3.0.0 + # audio conversions + "ffmpeg-python==0.2.0" +] + +[project.optional-dependencies] +dev = [ + "ipython", +] +test = [ + "coverage", + "webtest", + "django-webtest", + "model_bakery", + "mock", +] + +[tool.setuptools.dynamic] +version = { attr = "roundware.__version__"} + +[tool.setuptools.packages.find] +where = ["."] \ No newline at end of file diff --git a/requirements.apt b/requirements.apt index a2c11ff5..ad1d6905 100644 --- a/requirements.apt +++ b/requirements.apt @@ -9,3 +9,4 @@ pacpl python3 python3-dev python3-pip +python3-venv \ No newline at end of file diff --git a/requirements/common.txt b/requirements/common.txt index 2b04861a..d65ab2cf 100644 --- a/requirements/common.txt +++ b/requirements/common.txt @@ -21,7 +21,7 @@ django-floppyforms==1.9.0 # Used in roundware/rw/views.py: django-extra-views==0.13.0 # Used in roundware/rw/fields.py and roundware/rw/widgets.py -django-sortedm2m==0.8.1 +django-sortedm2m==3.1.1 # Required for RDF Date parsing python-dateutil==2.2 # Used in roundwared/icecast2.py diff --git a/roundware/__init__.py b/roundware/__init__.py index e69de29b..abeeedbf 100644 --- a/roundware/__init__.py +++ b/roundware/__init__.py @@ -0,0 +1 @@ +__version__ = '0.4.0' diff --git a/roundware/rw/migrations/0037_asset_file_and_loc_caption.py b/roundware/rw/migrations/0037_asset_file_and_loc_caption.py index b1fafe31..8ae2d0d1 100644 --- a/roundware/rw/migrations/0037_asset_file_and_loc_caption.py +++ b/roundware/rw/migrations/0037_asset_file_and_loc_caption.py @@ -4,7 +4,7 @@ import django.core.files.storage from django.db import migrations -import rw.fields +import roundware.rw.fields class Migration(migrations.Migration): @@ -17,11 +17,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='asset', name='file', - field=rw.fields.ValidatedFileField(help_text='Upload file', storage=django.core.files.storage.FileSystemStorage(base_url='/rwmedia/', location='/var/www/roundware/rwmedia/'), upload_to='.'), + field=roundware.rw.fields.ValidatedFileField(help_text='Upload file', storage=django.core.files.storage.FileSystemStorage(base_url='/rwmedia/', location='/var/www/roundware/rwmedia/'), upload_to='.'), ), migrations.AlterField( model_name='asset', name='loc_caption', - field=rw.fields.ValidatedFileField(help_text='Upload captions', null=True, storage=django.core.files.storage.FileSystemStorage(base_url='/rwmedia/', location='/var/www/roundware/rwmedia/'), upload_to='.'), + field=roundware.rw.fields.ValidatedFileField(help_text='Upload captions', null=True, storage=django.core.files.storage.FileSystemStorage(base_url='/rwmedia/', location='/var/www/roundware/rwmedia/'), upload_to='.'), ), ] diff --git a/roundware/rw/models.py b/roundware/rw/models.py index fbaed8a8..54dea9d1 100644 --- a/roundware/rw/models.py +++ b/roundware/rw/models.py @@ -12,7 +12,7 @@ from django.utils.safestring import mark_safe from django.db import transaction from django.contrib.gis.db import models -from rw.fields import ValidatedFileField +from roundware.rw.fields import ValidatedFileField from django.conf import settings from datetime import datetime from django.db.models.signals import post_save diff --git a/roundware/rw/tests/test_models.py b/roundware/rw/tests/test_models.py index c6e74019..db07ab34 100644 --- a/roundware/rw/tests/test_models.py +++ b/roundware/rw/tests/test_models.py @@ -6,7 +6,7 @@ from roundware.rw import models from roundware.settings import DEFAULT_SESSION_ID -from rw.tests.common import use_locmemcache, RWTestCase +from roundware.rw.tests.common import use_locmemcache, RWTestCase class TestUIGroup(RWTestCase): @@ -14,7 +14,7 @@ class TestUIGroup(RWTestCase): """ exercise UIGroup model class """ def setUp(self): - super(type(self), TestUIGroup).setUp(self) + super().setUp() # make uigroup, makes our tagcategory, uimode, project, # selectionmethod @@ -50,7 +50,7 @@ def test_tag_category_cache_invalidation_post_save(self): class TestProject(RWTestCase): def setUp(self): - super(type(self), TestProject).setUp(self) + super().setUp() self.project = baker.make('rw.Project') self.ui_mode = models.UIGroup.LISTEN @@ -82,7 +82,7 @@ def test_no_tag_cats_returned_wrong_uimode(self): class TestAsset(RWTestCase): def setUp(self): - super(type(self), TestAsset).setUp(self) + super().setUp() self.session1 = baker.make('rw.Session') self.session2 = baker.make('rw.Session') @@ -99,11 +99,11 @@ def setUp(self): asset=self.asset1, type="flag") def test_get_likes(self): - self.assertEquals(2, self.asset1.get_likes()) - self.assertEquals(1, self.asset2.get_likes()) + self.assertEqual(2, self.asset1.get_likes()) + self.assertEqual(1, self.asset2.get_likes()) def test_get_flags(self): - self.assertEquals(1, self.asset1.get_flags()) + self.assertEqual(1, self.asset1.get_flags()) def test_distance(self): distance = self.asset1.distance({'latitude': 0, 'longitude': 0}) diff --git a/scripts/tests.sh b/scripts/tests.sh index 76c4f93d..68eaed26 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -12,7 +12,7 @@ fi # runs Django test_coverage script on rw app and roundware-server tests with appropriate settings cd .. -coverage run --source=roundware roundware/manage.py test --settings=roundware.settings.testing $TESTS +coverage run --source=roundware src/roundware/manage.py test --settings=roundware.settings.testing $TESTS # Only display coverage results on full tests if [ "$TESTS" == "tests" ]; then