diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4ed1673 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,120 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "jazztunes_test" +version = "0.0.1" +dependencies = [ +"asgiref==3.7.2", +"asttokens==2.4.1", +"attrs==23.2.0", +"build==1.1.1", +"certifi==2024.2.2", +"cffi==1.16.0", +"cfgv==3.4.0", +"charset-normalizer==3.3.2", +"cli-helpers==2.3.1", +"click==8.1.7", +"configobj==5.0.8", +"coverage[toml]==7.4.4", +"cryptography==42.0.5", +"decorator==5.1.1", +"defusedxml==0.7.1", +"distlib==0.3.8", +"dj-database-url==2.1.0", +"django==5.0.3", +"django-allauth==0.61.1", +"django-bootstrap5==23.4", +"django-debug-toolbar==4.3.0", +"executing==2.0.1", +"filelock==3.13.1", +"gunicorn==21.2.0", +"identify==2.5.35", +"idna==3.6", +"iniconfig==2.0.0", +"ipdb==0.13.13", +"ipython==8.22.2", +"jedi==0.19.1", +"markdown-it-py==3.0.0", +"matplotlib-inline==0.1.6", +"mdurl==0.1.2", +"nodeenv==1.8.0", +"oauthlib==3.2.2", +"packaging==24.0", +"parso==0.8.3", +"pexpect==4.9.0", +"pgspecial==2.1.1", +"pip-tools==7.4.1", +"platformdirs==4.2.0", +"pluggy==1.4.0", +"pre-commit==3.6.2", +"prompt-toolkit==3.0.43", +"psycopg==3.1.18", +"psycopg2==2.9.9", +"ptyprocess==0.7.0", +"pure-eval==0.2.2", +"pycparser==2.21", +"pygments==2.17.2", +"pyjwt[crypto]==2.8.0", +"pyproject-hooks==1.0.0", +"pytest==8.1.1", +"pytest-cov==4.1.0", +"pytest-django==4.8.0", +"pytest-env==1.1.3", +"python-dateutil==2.9.0.post0", +"python-decouple==3.8", +"python-dotenv==1.0.1", +"python-http-client==3.3.7", +"python3-openid==3.2.0", +"pytzdata==2020.1", +"pyyaml==6.0.1", +"requests==2.31.0", +"requests-oauthlib==1.4.0", +"rich==13.7.1", +"ruff==0.3.3", +"sendgrid==6.11.0", +"sentry-sdk==1.42.0", +"setproctitle==1.3.3", +"shellingham==1.5.4", +"six==1.16.0", +"sqlparse==0.4.4", +"stack-data==0.6.3", +"starkbank-ecdsa==2.2.0", +"tabulate[widechars]==0.9.0", +"traitlets==5.14.2", +"typer==0.9.0", +"typing-extensions==4.10.0", +"url-normalize==1.4.3", +"urllib3==1.26.18", +"virtualenv==20.25.1", +"wcwidth==0.1.9", +"wheel==0.43.0", +"whitenoise==6.6.0" +] +requires-python = ">=3.11" +authors = [ + { name="Jeff Jacobson", email="jeffjacobsonhimself@gmail.com" }, +] +description = "A jazz repertoire management app" +readme = "README.md" +license = {file = "LICENSE"} +keywords = ["jazz", "repertoire", "music", "practice", "standards"] +classifiers = [ + "Development Status :: 4 - Beta", + "Environment :: Web Environment", + "Framework :: Django", + "Intended Audience :: Developers", + "Intended Audience :: End Users/Desktop", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Natural Language :: English", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: JavaScript", + "Programming Language :: Python :: 3.11", + "Topic :: Other/Nonlisted Topic" +] + +[project.urls] +Homepage = "https://github.com/jwjacobson/jazztunes" +Issues = "https://github.com/jwjacobson/jazztunes/issues" \ No newline at end of file diff --git a/test.sql b/test.sql deleted file mode 100644 index f3c40ce..0000000 --- a/test.sql +++ /dev/null @@ -1,6 +0,0 @@ -BEGIN; --- --- Remove field is_contrafact from tune --- -ALTER TABLE "tune_tune" DROP COLUMN "is_contrafact" CASCADE; -COMMIT; diff --git a/tests/test_models.py b/tests/test_models.py index 5fafac4..f840759 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -3,7 +3,8 @@ from tune.models import Tune -def test_tune_field_access(): +@pytest.fixture() +def tune_object(): tune = Tune( title="test title", composer="test composer", @@ -14,7 +15,11 @@ def test_tune_field_access(): meter=4, year=2023, ) + return tune + +def test_tune_field_access(tune_object): + tune = tune_object assert tune.title == "test title" assert tune.composer == "test composer" assert tune.key == "C" diff --git a/tune/admin.py b/tune/admin.py index 97365a0..c77498b 100644 --- a/tune/admin.py +++ b/tune/admin.py @@ -1,3 +1,21 @@ +# jazztunes -- A jazz repertoire management app +# Copyright (C) 2024 Jeff Jacobson +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + from django.contrib import admin from tune.models import Tune, RepertoireTune, Tag @@ -19,4 +37,4 @@ class RepertoireTuneAdmin(admin.ModelAdmin): @admin.register(Tag) class TagAdmin(admin.ModelAdmin): list_display = ["name"] - search_fields = ('name',) \ No newline at end of file + search_fields = ("name",) diff --git a/tune/apps.py b/tune/apps.py index 587640a..0274ff6 100644 --- a/tune/apps.py +++ b/tune/apps.py @@ -1,3 +1,20 @@ +# jazztunes -- A jazz repertoire management app +# Copyright (C) 2024 Jeff Jacobson +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from django.apps import AppConfig diff --git a/tune/forms.py b/tune/forms.py index f9d207c..84955c6 100644 --- a/tune/forms.py +++ b/tune/forms.py @@ -1,3 +1,20 @@ +# jazztunes -- A jazz repertoire management app +# Copyright (C) 2024 Jeff Jacobson +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from django.forms import ModelForm from django import forms from .models import Tune, RepertoireTune diff --git a/tune/models.py b/tune/models.py index 5c62f43..a25a89f 100644 --- a/tune/models.py +++ b/tune/models.py @@ -1,3 +1,20 @@ +# jazztunes -- A jazz repertoire management app +# Copyright (C) 2024 Jeff Jacobson +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from django.db import models from django.contrib.auth import get_user_model diff --git a/tune/signals.py b/tune/signals.py index bdc18a3..f6a9492 100644 --- a/tune/signals.py +++ b/tune/signals.py @@ -1,3 +1,20 @@ +# jazztunes -- A jazz repertoire management app +# Copyright (C) 2024 Jeff Jacobson +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from django.db.models.signals import pre_save from django.dispatch import receiver from django.utils import timezone diff --git a/tune/templates/tune/_another_button.html b/tune/templates/tune/_another_button.html index c019048..8257252 100644 --- a/tune/templates/tune/_another_button.html +++ b/tune/templates/tune/_another_button.html @@ -1,5 +1,5 @@
-
+
{% if selected_tune %}
You should play
diff --git a/tune/templates/tune/play.html b/tune/templates/tune/play.html index c44b86f..dcfe296 100644 --- a/tune/templates/tune/play.html +++ b/tune/templates/tune/play.html @@ -12,9 +12,9 @@
-
-
-
+
+
+
Tune Search
@@ -39,7 +39,7 @@
Tune Search
-
+
{% endblock %} diff --git a/tune/urls.py b/tune/urls.py index d23980b..a468baf 100644 --- a/tune/urls.py +++ b/tune/urls.py @@ -1,3 +1,21 @@ +# jazztunes -- A jazz repertoire management app +# Copyright (C) 2024 Jeff Jacobson +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + from django.urls import path from tune import views diff --git a/tune/views.py b/tune/views.py index 89648c5..32fe14c 100644 --- a/tune/views.py +++ b/tune/views.py @@ -1,3 +1,20 @@ +# jazztunes -- A jazz repertoire management app +# Copyright (C) 2024 Jeff Jacobson +# +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + from random import choice from django.contrib import messages @@ -9,7 +26,6 @@ from django.utils import timezone from django.conf import settings from django.http import HttpResponse -from django.template.loader import render_to_string from .models import Tune, RepertoireTune from .forms import TuneForm, RepertoireTuneForm, SearchForm @@ -60,7 +76,7 @@ def return_search_results(request, search_terms, tunes, search_form, timespan=No if len(search_terms) > Tune.MAX_SEARCH_TERMS: messages.error( request, - f"Your query is too long ({len(search_terms)} terms, maximum of {Tune.MAX_SEARCH_TERMS}). Consider using advanced search for more granularity.", + f"Your query is too long ({len(search_terms)} terms, maximum of {Tune.MAX_SEARCH_TERMS}).", ) return render( request, @@ -214,28 +230,31 @@ def get_random_tune(request): ) search_form = SearchForm(request.POST or None) + # A flatter way to validate the form, rather than indenting everything under it if not search_form.is_valid(): - return HttpResponse("Invalid search", status=400) + # This should never trigger + messages.error(request, "Invalid search") + return render(request, "tune/play.html") search_terms = search_form.cleaned_data["search_term"].split(" ") timespan = search_form.cleaned_data.get("timespan", None) result_dict = return_search_results(request, search_terms, tunes, search_form, timespan) if "error" in result_dict: - return render(request, result_dict["template"], result_dict) + messages.error(request, result_dict["error"]) + return render(request, result_dict["template"]) tunes = result_dict.get("tunes") - if not tunes: - return HttpResponse("No tunes found", status=404) - - selected_tune = choice(tunes) - remaining_rep_tunes_ids = [tune.id for tune in tunes if tune != selected_tune] - request.session["rep_tunes"] = remaining_rep_tunes_ids + if tunes: + selected_tune = choice(tunes) + remaining_rep_tunes_ids = [tune.id for tune in tunes if tune != selected_tune] + request.session["rep_tunes"] = remaining_rep_tunes_ids + else: + selected_tune = None request.session.save() - html = render_to_string("tune/_play_card.html", {"selected_tune": selected_tune}, request) - return HttpResponse(html) + return render(request, "tune/_play_card.html", {"selected_tune": selected_tune}) @login_required