diff --git a/.gitignore b/.gitignore index 066a37d..26abb08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,12 @@ +*.sqlite3 *.pyc +*.pyo +__pycache__ *.DS_Store *.egg* -/dist/ -/.idea -/docs/_build/ -/node_modules/ + +dist/ +docs/_build/ +.idea/ +node_modules/ result -*.sqlite3 diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..3e92a67 --- /dev/null +++ b/Readme.md @@ -0,0 +1,11 @@ +- Update `requirements.nix`: + +```sh +pypi2nix -V python3 -r requirements.txt --default-overrides -E postgresql_11 -E "pkgconfig zlib libjpeg openjpeg libtiff freetype lcms2 libwebp tcl" +``` + +- Generate interpreter: + +```sh +nix build -f requirements.nix interpreter +``` diff --git a/django_mycelium/__init__.py b/django_mycelium/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django_mycelium/asgi.py b/django_mycelium/asgi.py new file mode 100644 index 0000000..dc19ae7 --- /dev/null +++ b/django_mycelium/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for django_mycelium project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_mycelium.settings") + +application = get_asgi_application() diff --git a/django_mycelium/settings.py b/django_mycelium/settings.py new file mode 100644 index 0000000..e1bcaf3 --- /dev/null +++ b/django_mycelium/settings.py @@ -0,0 +1,119 @@ +""" +Django settings for django_mycelium project. + +Generated by 'django-admin startproject' using Django 3.0. + +For more information on this file, see +https://docs.djangoproject.com/en/3.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/3.0/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = "owwylmqm5n@0h0ko((1$+ti7l#6q6hni4x0w^9)dk)5y6_r^c3" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "rest_framework", + "translatable_fields", + "mycelium.apps.MyceliumConfig", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] + +ROOT_URLCONF = "django_mycelium.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [os.path.join(BASE_DIR, "templates")], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ] + }, + } +] + +WSGI_APPLICATION = "django_mycelium.wsgi.application" + + +# Database +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": os.path.join(BASE_DIR, "db.sqlite3"), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator" + }, + {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, + {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, + {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, +] + + +# Internationalization +# https://docs.djangoproject.com/en/3.0/topics/i18n/ + +LANGUAGE_CODE = "en" + +LANGUAGES = (("de", "Deutsch"), ("en", "English")) + +TIME_ZONE = "UTC" + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.0/howto/static-files/ + +STATIC_URL = "/static/" diff --git a/django_mycelium/urls.py b/django_mycelium/urls.py new file mode 100644 index 0000000..105f374 --- /dev/null +++ b/django_mycelium/urls.py @@ -0,0 +1,27 @@ +"""django_mycelium URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/3.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path +from rest_framework.schemas import get_schema_view + +urlpatterns = [ + path("admin/", admin.site.urls), + path( + "openapi", + get_schema_view(title="Mycelium", description="API", version="0.1.0"), + name="openapi-schema", + ), +] diff --git a/django_mycelium/wsgi.py b/django_mycelium/wsgi.py new file mode 100644 index 0000000..5f19dfb --- /dev/null +++ b/django_mycelium/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for django_mycelium project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_mycelium.settings") + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..071de8e --- /dev/null +++ b/manage.py @@ -0,0 +1,21 @@ +#!/nix/store/k5rdcbcwwpvj7l9f1yvd5mfggcfz16kk-python3-3.7.5/bin/python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_mycelium.settings") + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/mycelium/__init__.py b/mycelium/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mycelium/admin.py b/mycelium/admin.py new file mode 100644 index 0000000..f9a50d7 --- /dev/null +++ b/mycelium/admin.py @@ -0,0 +1,60 @@ +from django.contrib import admin + +# Register your models here. +from django import forms +from django.contrib.admin import ModelAdmin +from django.contrib.postgres.forms import JSONField + +from mycelium.models import Species, Ingredient, Substrate, Step, Culture +from translatable_fields.widgets import TranslatableWidget + + +class SpeciesForm(forms.ModelForm): + name = JSONField(widget=TranslatableWidget(widget=forms.TextInput)) + fields = ("name", "scientific_name", "genera", "familia", "ordo", "classis") + + +class SpeciesAdmin(ModelAdmin): + form = SpeciesForm + + +admin.site.register(Species, SpeciesAdmin) + + +class IngredientForm(forms.ModelForm): + name = JSONField(widget=TranslatableWidget(widget=forms.TextInput)) + description = JSONField(widget=TranslatableWidget(widget=forms.TextInput)) + fields = ("name", "description", "image") + + +class IngredientAdmin(ModelAdmin): + form = IngredientForm + + +admin.site.register(Ingredient, IngredientAdmin) + + +class SubstrateForm(forms.ModelForm): + name = JSONField(widget=TranslatableWidget(widget=forms.TextInput)) + fields = ("name",) + + +class SubstrateAdmin(ModelAdmin): + form = SubstrateForm + + +admin.site.register(Substrate, SubstrateAdmin) + + +class StepForm(forms.ModelForm): + name = JSONField(widget=TranslatableWidget(widget=forms.TextInput)) + description = JSONField(widget=TranslatableWidget(widget=forms.TextInput)) + fields = ("name", "description") + + +class StepAdmin(ModelAdmin): + form = StepForm + + +admin.site.register(Step, StepAdmin) +admin.site.register(Culture) diff --git a/mycelium/apps.py b/mycelium/apps.py new file mode 100644 index 0000000..98b2b50 --- /dev/null +++ b/mycelium/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class MyceliumConfig(AppConfig): + name = "mycelium" diff --git a/mycelium/migrations/0001_initial.py b/mycelium/migrations/0001_initial.py new file mode 100644 index 0000000..242fea5 --- /dev/null +++ b/mycelium/migrations/0001_initial.py @@ -0,0 +1,34 @@ +# Generated by Django 3.0 on 2020-02-16 12:47 + +from django.db import migrations, models +import translatable_fields.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Species", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", translatable_fields.models.TranslatableField()), + ("scientific_name", models.CharField(max_length=255)), + ("genera", models.CharField(max_length=255)), + ("familia", models.CharField(max_length=255)), + ("ordo", models.CharField(max_length=255)), + ("classis", models.CharField(max_length=255)), + ], + ) + ] diff --git a/mycelium/migrations/0002_auto_20200216_1349.py b/mycelium/migrations/0002_auto_20200216_1349.py new file mode 100644 index 0000000..4ea5a1f --- /dev/null +++ b/mycelium/migrations/0002_auto_20200216_1349.py @@ -0,0 +1,156 @@ +# Generated by Django 3.0 on 2020-02-16 13:49 + +from django.db import migrations, models +import django.db.models.deletion +import translatable_fields.models + + +class Migration(migrations.Migration): + + dependencies = [("mycelium", "0001_initial")] + + operations = [ + migrations.CreateModel( + name="Culture", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "species", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="mycelium.Species", + ), + ), + ], + ), + migrations.CreateModel( + name="Ingredient", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", translatable_fields.models.TranslatableField()), + ("description", translatable_fields.models.TranslatableField()), + ], + ), + migrations.CreateModel( + name="Step", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", translatable_fields.models.TranslatableField()), + ("description", translatable_fields.models.TranslatableField()), + ], + ), + migrations.CreateModel( + name="Substrate", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", translatable_fields.models.TranslatableField()), + ], + ), + migrations.CreateModel( + name="IngredientInSubstrate", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("amount", models.FloatField()), + ( + "ingredient", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="mycelium.Ingredient", + ), + ), + ( + "substrate", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="mycelium.Substrate", + ), + ), + ], + ), + migrations.CreateModel( + name="CultureStep", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("date", models.DateTimeField()), + ("notes", translatable_fields.models.TranslatableField()), + ( + "culture_id", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="mycelium.Culture", + ), + ), + ( + "step_id", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="mycelium.Step" + ), + ), + ], + ), + migrations.AddField( + model_name="culture", + name="steps", + field=models.ManyToManyField( + through="mycelium.CultureStep", to="mycelium.Step" + ), + ), + migrations.AddField( + model_name="culture", + name="substrate", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="mycelium.Substrate", + ), + ), + ] diff --git a/mycelium/migrations/0003_auto_20200216_1542.py b/mycelium/migrations/0003_auto_20200216_1542.py new file mode 100644 index 0000000..78fd9fa --- /dev/null +++ b/mycelium/migrations/0003_auto_20200216_1542.py @@ -0,0 +1,44 @@ +# Generated by Django 3.0 on 2020-02-16 15:42 + +from django.db import migrations, models +import django.db.models.deletion +import translatable_fields.models + + +class Migration(migrations.Migration): + + dependencies = [("mycelium", "0002_auto_20200216_1349")] + + operations = [ + migrations.CreateModel( + name="CultureType", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", translatable_fields.models.TranslatableField()), + ("description", translatable_fields.models.TranslatableField()), + ("image", models.ImageField(null=True, upload_to="")), + ], + ), + migrations.AddField( + model_name="ingredient", + name="image", + field=models.ImageField(null=True, upload_to=""), + ), + migrations.AddField( + model_name="culture", + name="culture_type", + field=models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="mycelium.CultureType", + ), + ), + ] diff --git a/mycelium/migrations/__init__.py b/mycelium/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mycelium/models.py b/mycelium/models.py new file mode 100644 index 0000000..eb26547 --- /dev/null +++ b/mycelium/models.py @@ -0,0 +1,57 @@ +from django.db import models + +# Create your models here. +from translatable_fields.models import TranslatableField + + +class Species(models.Model): + name = TranslatableField() + + scientific_name = models.CharField(max_length=255) + genera = models.CharField(max_length=255) + familia = models.CharField(max_length=255) + ordo = models.CharField(max_length=255) + classis = models.CharField(max_length=255) + + +class Ingredient(models.Model): + name = TranslatableField() + description = TranslatableField() + image = models.ImageField(null=True) + + +class Substrate(models.Model): + name = TranslatableField() + + +class IngredientInSubstrate(models.Model): + amount = models.FloatField() + substrate = models.ForeignKey(Substrate, on_delete=models.CASCADE) + ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE) + + +class Step(models.Model): + name = TranslatableField() + description = TranslatableField() + + +class CultureType(models.Model): + name = TranslatableField() + description = TranslatableField() + image = models.ImageField(null=True) + + +class Culture(models.Model): + substrate = models.ForeignKey(Substrate, null=True, on_delete=models.SET_NULL) + species = models.ForeignKey(Species, null=True, on_delete=models.SET_NULL) + culture_type = models.ForeignKey(CultureType, null=True, on_delete=models.SET_NULL) + steps = models.ManyToManyField( + Step, through="CultureStep", through_fields=("culture_id", "step_id") + ) + + +class CultureStep(models.Model): + culture_id = models.ForeignKey(Culture, on_delete=models.CASCADE) + step_id = models.ForeignKey(Step, on_delete=models.CASCADE) + date = models.DateTimeField() + notes = TranslatableField() diff --git a/mycelium/tests.py b/mycelium/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/mycelium/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/mycelium/views.py b/mycelium/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/mycelium/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/requirements.nix b/requirements.nix new file mode 100644 index 0000000..baafea5 --- /dev/null +++ b/requirements.nix @@ -0,0 +1,294 @@ +# generated using pypi2nix tool (version: 2.0.4) +# See more at: https://github.com/nix-community/pypi2nix +# +# COMMAND: +# pypi2nix -V python3 -r requirements.txt --default-overrides -E postgresql_11 -E 'pkgconfig zlib libjpeg openjpeg libtiff freetype lcms2 libwebp tcl' +# + +{ pkgs ? import {}, + overrides ? ({ pkgs, python }: self: super: {}) +}: + +let + + inherit (pkgs) makeWrapper; + inherit (pkgs.stdenv.lib) fix' extends inNixShell; + + pythonPackages = + import "${toString pkgs.path}/pkgs/top-level/python-packages.nix" { + inherit pkgs; + inherit (pkgs) stdenv; + python = pkgs.python3; + }; + + commonBuildInputs = with pkgs; [ postgresql_11 pkgconfig zlib libjpeg openjpeg libtiff freetype lcms2 libwebp tcl ]; + commonDoCheck = false; + + withPackages = pkgs': + let + pkgs = builtins.removeAttrs pkgs' ["__unfix__"]; + interpreterWithPackages = selectPkgsFn: pythonPackages.buildPythonPackage { + name = "python3-interpreter"; + buildInputs = [ makeWrapper ] ++ (selectPkgsFn pkgs); + buildCommand = '' + mkdir -p $out/bin + ln -s ${pythonPackages.python.interpreter} \ + $out/bin/${pythonPackages.python.executable} + for dep in ${builtins.concatStringsSep " " + (selectPkgsFn pkgs)}; do + if [ -d "$dep/bin" ]; then + for prog in "$dep/bin/"*; do + if [ -x "$prog" ] && [ -f "$prog" ]; then + ln -s $prog $out/bin/`basename $prog` + fi + done + fi + done + for prog in "$out/bin/"*; do + wrapProgram "$prog" --prefix PYTHONPATH : "$PYTHONPATH" + done + pushd $out/bin + ln -s ${pythonPackages.python.executable} python + ln -s ${pythonPackages.python.executable} \ + python3 + popd + ''; + passthru.interpreter = pythonPackages.python; + }; + + interpreter = interpreterWithPackages builtins.attrValues; + in { + __old = pythonPackages; + inherit interpreter; + inherit interpreterWithPackages; + mkDerivation = args: pythonPackages.buildPythonPackage (args // { + nativeBuildInputs = (args.nativeBuildInputs or []) ++ args.buildInputs; + }); + packages = pkgs; + overrideDerivation = drv: f: + pythonPackages.buildPythonPackage ( + drv.drvAttrs // f drv.drvAttrs // { meta = drv.meta; } + ); + withPackages = pkgs'': + withPackages (pkgs // pkgs''); + }; + + python = withPackages {}; + + generated = self: { + "asgiref" = python.mkDerivation { + name = "asgiref-3.2.3"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/80/c4/83a01607f2d10024c172097126264c8e00c6a4827b35d631ece9625e6ba2/asgiref-3.2.3.tar.gz"; + sha256 = "7e06d934a7718bf3975acbf87780ba678957b87c7adc056f13b6215d610695a0"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "http://github.com/django/asgiref/"; + license = licenses.bsdOriginal; + description = "ASGI specs, helper code, and adapters"; + }; + }; + + "django" = python.mkDerivation { + name = "django-3.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/f8/46/b3b8c61f867827fff2305db40659495dcd64fb35c399e75c53f23c113871/Django-3.0.tar.gz"; + sha256 = "d98c9b6e5eed147bc51f47c014ff6826bd1ab50b166956776ee13db5a58804ae"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."asgiref" + self."pytz" + self."sqlparse" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://www.djangoproject.com/"; + license = licenses.bsdOriginal; + description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."; + }; + }; + + "django-filter" = python.mkDerivation { + name = "django-filter-2.2.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/dc/75/af3f0c2682d2603617ee3061b36395a64fb9d70c327bb759de43e643e5b3/django-filter-2.2.0.tar.gz"; + sha256 = "c3deb57f0dd7ff94d7dce52a047516822013e2b441bed472b722a317658cfd14"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."django" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/carltongibson/django-filter/tree/master"; + license = licenses.bsdOriginal; + description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically."; + }; + }; + + "djangorestframework" = python.mkDerivation { + name = "djangorestframework-3.11.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/80/f6/f742b0352d4ade1934fcb2a12f6fd669922415bea3d5d2d6596dc47abe14/djangorestframework-3.11.0.tar.gz"; + sha256 = "e782087823c47a26826ee5b6fa0c542968219263fb3976ec3c31edab23a4001f"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."django" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://www.django-rest-framework.org/"; + license = licenses.bsdOriginal; + description = "Web APIs for Django, made easy."; + }; + }; + + "markdown" = python.mkDerivation { + name = "markdown-3.2.1"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/98/79/ce6984767cb9478e6818bd0994283db55c423d733cc62a88a3ffb8581e11/Markdown-3.2.1.tar.gz"; + sha256 = "90fee683eeabe1a92e149f7ba74e5ccdc81cd397bd6c516d93a8da0ef90b6902"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ + self."setuptools" + ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://Python-Markdown.github.io/"; + license = licenses.bsdOriginal; + description = "Python implementation of Markdown."; + }; + }; + + "pillow" = python.mkDerivation { + name = "pillow-7.0.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/39/47/f28067b187dd664d205f75b07dcc6e0e95703e134008a14814827eebcaab/Pillow-7.0.0.tar.gz"; + sha256 = "4d9ed9a64095e031435af120d3c910148067087541131e82b3e8db302f4c8946"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://python-pillow.org"; + license = "HPND"; + description = "Python Imaging Library (Fork)"; + }; + }; + + "psycopg2" = python.mkDerivation { + name = "psycopg2-2.8.4"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/84/d7/6a93c99b5ba4d4d22daa3928b983cec66df4536ca50b22ce5dcac65e4e71/psycopg2-2.8.4.tar.gz"; + sha256 = "f898e5cc0a662a9e12bde6f931263a1bbd350cfb18e1d5336a12927851825bb6"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "http://initd.org/psycopg/"; + license = licenses.lgpl2; + description = "psycopg2 - Python-PostgreSQL Database Adapter"; + }; + }; + + "pytz" = python.mkDerivation { + name = "pytz-2019.3"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/82/c3/534ddba230bd4fbbd3b7a3d35f3341d014cca213f369a9940925e7e5f691/pytz-2019.3.tar.gz"; + sha256 = "b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "http://pythonhosted.org/pytz"; + license = licenses.mit; + description = "World timezone definitions, modern and historical"; + }; + }; + + "pyyaml" = python.mkDerivation { + name = "pyyaml-5.3"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/3d/d9/ea9816aea31beeadccd03f1f8b625ecf8f645bd66744484d162d84803ce5/PyYAML-5.3.tar.gz"; + sha256 = "e9f45bd5b92c7974e59bcd2dcc8631a6b6cc380a904725fce7bc08872e691615"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/yaml/pyyaml"; + license = licenses.mit; + description = "YAML parser and emitter for Python"; + }; + }; + + "setuptools" = python.mkDerivation { + name = "setuptools-45.2.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/68/75/d1d7b7340b9eb6e0388bf95729e63c410b381eb71fe8875cdfd949d8f9ce/setuptools-45.2.0.zip"; + sha256 = "89c6e6011ec2f6d57d43a3f9296c4ef022c2cbf49bab26b407fe67992ae3397f"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/pypa/setuptools"; + license = licenses.mit; + description = "Easily download, build, install, upgrade, and uninstall Python packages"; + }; + }; + + "sqlparse" = python.mkDerivation { + name = "sqlparse-0.3.0"; + src = pkgs.fetchurl { + url = "https://files.pythonhosted.org/packages/63/c8/229dfd2d18663b375975d953e2bdc06d0eed714f93dcb7732f39e349c438/sqlparse-0.3.0.tar.gz"; + sha256 = "7c3dca29c022744e95b547e867cee89f4fce4373f3549ccd8797d8eb52cdb873"; +}; + doCheck = commonDoCheck; + format = "setuptools"; + buildInputs = commonBuildInputs ++ [ ]; + propagatedBuildInputs = [ ]; + meta = with pkgs.stdenv.lib; { + homepage = "https://github.com/andialbrecht/sqlparse"; + license = licenses.bsdOriginal; + description = "Non-validating SQL parser"; + }; + }; + }; + localOverridesFile = ./requirements_override.nix; + localOverrides = import localOverridesFile { inherit pkgs python; }; + commonOverrides = [ + (let src = pkgs.fetchFromGitHub { owner = "nix-community"; repo = "pypi2nix-overrides"; rev = "fbbcadd9e5fedade659ba2585893d3a8cbba8e56"; sha256 = "1fmqib6j08lswfw0agbgy1hdib3rfmrzx2x5zyzrqbkvc80a734b"; } ; in import "${src}/overrides.nix" { inherit pkgs python; }) + ]; + paramOverrides = [ + (overrides { inherit pkgs python; }) + ]; + allOverrides = + (if (builtins.pathExists localOverridesFile) + then [localOverrides] else [] ) ++ commonOverrides ++ paramOverrides; + +in python.withPackages + (fix' (pkgs.lib.fold + extends + generated + allOverrides + ) + ) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2e3f8eb --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +django==3 +django-filter +djangorestframework +markdown +Pillow +psycopg2 +pyyaml diff --git a/requirements_frozen.txt b/requirements_frozen.txt new file mode 100644 index 0000000..0879ac1 --- /dev/null +++ b/requirements_frozen.txt @@ -0,0 +1,10 @@ +asgiref==3.2.3 +Django==3.0 +django-filter==2.2.0 +djangorestframework==3.11.0 +Markdown==3.2.1 +Pillow==7.0.0 +psycopg2==2.8.4 +pytz==2019.3 +PyYAML==5.3 +sqlparse==0.3.0 diff --git a/requirements_override.nix b/requirements_override.nix new file mode 100644 index 0000000..3b704ef --- /dev/null +++ b/requirements_override.nix @@ -0,0 +1,5 @@ +{ pkgs, python }: + +self: super: { + +} \ No newline at end of file