diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index ca49c296a..cb97fd60f 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -20,17 +20,17 @@ jobs: install: true driver: docker - - name: Notify workflow starting - uses: voxmedia/github-action-slack-notify-build@v1 - continue-on-error: true - if: success() - id: slack - with: - channel_id: ${{ secrets.SLACK_NOTIFICATIONS_CHANNEL_ID }} - status: STARTING - color: warning - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} + #- name: Notify workflow starting + # uses: voxmedia/github-action-slack-notify-build@v1 + # continue-on-error: true + # if: success() + # id: slack + # with: + # channel_id: ${{ secrets.SLACK_NOTIFICATIONS_CHANNEL_ID }} + # status: STARTING + # color: warning + # env: + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} - name: Setup run: bash -c 'mkdir -p ./freesound-data/{packs,uploads,avatars} && echo FS_USER_ID_FROM_ENV=$(id -u) > .env && cp freesound/local_settings.example.py freesound/local_settings.py' @@ -57,25 +57,25 @@ jobs: - name: Run tests run: docker compose -f docker-compose.test.yml run --rm test_runner python manage.py test --noinput --settings=freesound.test_settings - - name: Notify success - uses: voxmedia/github-action-slack-notify-build@v1 - continue-on-error: true - if: success() - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel_id: ${{ secrets.SLACK_NOTIFICATIONS_CHANNEL_ID }} - status: SUCCESS - color: good - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} - - - name: Notify failure - uses: voxmedia/github-action-slack-notify-build@v1 - if: failure() - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel_id: ${{ secrets.SLACK_NOTIFICATIONS_CHANNEL_ID }} - status: FAILED - color: danger - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} + #- name: Notify success + # uses: voxmedia/github-action-slack-notify-build@v1 + # continue-on-error: true + # if: success() + # with: + # message_id: ${{ steps.slack.outputs.message_id }} + # channel_id: ${{ secrets.SLACK_NOTIFICATIONS_CHANNEL_ID }} + # status: SUCCESS + # color: good + # env: + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} + + #- name: Notify failure + # uses: voxmedia/github-action-slack-notify-build@v1 + # if: failure() + # with: + # message_id: ${{ steps.slack.outputs.message_id }} + # channel_id: ${{ secrets.SLACK_NOTIFICATIONS_CHANNEL_ID }} + # status: FAILED + # color: danger + # env: + # SLACK_BOT_TOKEN: ${{ secrets.SLACK_NOTIFICATIONS_BOT_TOKEN }} diff --git a/freesound/settings.py b/freesound/settings.py index 5bc6a9006..6179e949c 100644 --- a/freesound/settings.py +++ b/freesound/settings.py @@ -465,19 +465,19 @@ {'category_code': 'm-sp', 'level': 2, 'name': 'Solo percussion', 'description': 'Music excerpts with solo percussive instruments.'}, {'category_code': 'm-si', 'level': 2, 'name': 'Solo instrument', 'description': 'Music excerpts with only one instrument, excluding percussion.'}, {'category_code': 'm-m', 'level': 2, 'name': 'Multiple instruments', 'description': 'Music excerpts with more than one instrument.'}, - {'category_code': 'm-other', 'level': 2, 'name': 'Other (music)', 'description': 'Music that doesn\'t belong to any of the above categories.'}, + {'category_code': 'm-other', 'level': 2, 'name': 'Other', 'description': 'Music that doesn\'t belong to any of the above categories.'}, {'category_code': 'is', 'level': 1, 'name': 'Instrument samples', 'description': 'Single notes from musical instruments, various versions of the same note, and scales.'}, {'category_code': 'is-p', 'level': 2, 'name': 'Percussion', 'description': 'Instrument samples that are percussive (idiophones or membraphones).'}, {'category_code': 'is-s', 'level': 2, 'name': 'String', 'description': 'Instrument samples that belong to the string instrument family.'}, {'category_code': 'is-w', 'level': 2, 'name': 'Wind', 'description': 'Instrument samples that belong to the wind instrument family (aerophones).'}, {'category_code': 'is-k', 'level': 2, 'name': 'Piano / Keyboard instruments', 'description': 'Instrument samples of piano or other keyboard instruments, not synthesized.'}, {'category_code': 'is-e', 'level': 2, 'name': 'Synths / Electronic', 'description': 'Instrument samples synthesized or produced by electronic means.'}, - {'category_code': 'is-other', 'level': 2, 'name': 'Instrument samples (other)', 'description': 'Instrument samples that don\'t belong to any of the above categories.'}, + {'category_code': 'is-other', 'level': 2, 'name': 'Other', 'description': 'Instrument samples that don\'t belong to any of the above categories.'}, {'category_code': 'sp', 'level': 1, 'name': 'Speech', 'description': 'Sounds where human voice is prominent.'}, {'category_code': 'sp-s', 'level': 2, 'name': 'Solo speech', 'description': 'Recording of a single voice speaking, excluding singing.'}, {'category_code': 'sp-c', 'level': 2, 'name': 'Conversation / Crowd', 'description': 'Several people talking, having a conversation or dialogue.'}, {'category_code': 'sp-p', 'level': 2, 'name': 'Processed / Synthetic', 'description': 'Voice(s) from an indirect source (e.g. radio), processed or synthesized.'}, - {'category_code': 'sp-other', 'level': 2, 'name': 'Other (speech)', 'description': 'Voice-predominant recordings that don\'t belong to any of the above categories.'}, + {'category_code': 'sp-other', 'level': 2, 'name': 'Other', 'description': 'Voice-predominant recordings that don\'t belong to any of the above categories.'}, {'category_code': 'fx', 'level': 1, 'name': 'Sound effects', 'description': 'Isolated sound effects or sound events, each happening one at a time.'}, {'category_code': 'fx-o', 'level': 2, 'name': 'Objects / House appliances', 'description': 'Everyday objects, inside the home or smaller in size.'}, {'category_code': 'fx-v', 'level': 2, 'name': 'Vehicles', 'description': 'Sounds produced from a vehicle.'}, @@ -487,13 +487,13 @@ {'category_code': 'fx-n', 'level': 2, 'name': 'Natural elements and explosions', 'description': 'Sound events occuring by natural processes.'}, {'category_code': 'fx-ex', 'level': 2, 'name': 'Experimental', 'description': 'Experimental sounds or heavily processed audio recordings.'}, {'category_code': 'fx-el', 'level': 2, 'name': 'Electronic / Design', 'description': 'Sound effects that are computer-made or designed for user interfaces or animations.'}, - {'category_code': 'fx-other', 'level': 2, 'name': 'Other (sound effects)', 'description': 'Sound effects that don\'t belong to any of the above categories.'}, + {'category_code': 'fx-other', 'level': 2, 'name': 'Other', 'description': 'Sound effects that don\'t belong to any of the above categories.'}, {'category_code': 'ss', 'level': 1, 'name': 'Soundscapes', 'description': 'Ambiances, field-recordings with multiple events and sound environments.'}, {'category_code': 'ss-n', 'level': 2, 'name': 'Nature', 'description': 'Soundscapes from natural habitats.'}, {'category_code': 'ss-i', 'level': 2, 'name': 'Indoors', 'description': 'Soundscapes from closed or indoor spaces.'}, {'category_code': 'ss-u', 'level': 2, 'name': 'Urban', 'description': 'Soundscapes from cityscapes or outdoor places with human intervention.'}, {'category_code': 'ss-s', 'level': 2, 'name': 'Synthetic / Artificial', 'description': 'Soundscapes that are synthesized or computer-made ambiences.'}, - {'category_code': 'ss-other', 'level': 2, 'name': 'Other (soundscapes)', 'description': 'Soundscapes that don\'t belong to any of the above categories.'}, + {'category_code': 'ss-other', 'level': 2, 'name': 'Other', 'description': 'Soundscapes that don\'t belong to any of the above categories.'}, ] # ------------------------------------------------------------------------------- diff --git a/freesound/static/bw-frontend/src/components/modal.js b/freesound/static/bw-frontend/src/components/modal.js index 4bc2c472d..ddaabb37b 100644 --- a/freesound/static/bw-frontend/src/components/modal.js +++ b/freesound/static/bw-frontend/src/components/modal.js @@ -85,7 +85,10 @@ const bindConfirmationModalElements = (container) => { // Logic to bind default modals -const handleDefaultModal = (modalUrl, modalActivationParam, element) => { +const handleDefaultModal = (modalUrl, modalActivationParam, atPage) => { + if ((atPage !== undefined) && modalUrl.indexOf('&page') == -1){ + modalUrl += '&page=' + atPage; + } handleGenericModal(modalUrl, undefined, undefined, true, true, modalActivationParam); } diff --git a/freesound/static/bw-frontend/src/pages/editDescribeSounds.js b/freesound/static/bw-frontend/src/pages/editDescribeSounds.js index 747313cf3..94922d16d 100644 --- a/freesound/static/bw-frontend/src/pages/editDescribeSounds.js +++ b/freesound/static/bw-frontend/src/pages/editDescribeSounds.js @@ -28,4 +28,6 @@ inputTypeSubmitElements.forEach(button => { } }); }); -}); \ No newline at end of file +}); + +// Move json for BST category field in description form here diff --git a/sounds/forms.py b/sounds/forms.py index 4b3a11f8d..2ed6088c6 100644 --- a/sounds/forms.py +++ b/sounds/forms.py @@ -23,7 +23,7 @@ from captcha.fields import ReCaptchaField from django import forms -from django.core.exceptions import PermissionDenied +from django.core.exceptions import PermissionDenied, ValidationError from django.db.models import Q from django.forms import ModelForm, Textarea, TextInput from django.core.signing import BadSignature, SignatureExpired @@ -247,7 +247,8 @@ class SoundEditAndDescribeForm(forms.Form): widget=forms.TextInput(attrs={'size': 65, 'class': 'inputText'})) bst_category = forms.ChoiceField( choices=Sound.BST_CATEGORY_CHOICES, - required=False + help_text="Choose the most appropriate catgeory and subcatgoery (you can only choose one). This category will be displayed as a filtering option in the Freesound side bar.", + required=True, ) tags = TagField( widget=forms.Textarea(attrs={'cols': 80, 'rows': 3}), @@ -350,6 +351,12 @@ def clean_sources(self): def clean_pack(self): return _pack_form_clean_pack_helper(self.cleaned_data) + + def clean_bst_category(self): + value = self.cleaned_data['bst_category'] + if not '-' in value: + raise ValidationError("Please choose a subcategory.") + return value class SoundCSVDescriptionForm(SoundEditAndDescribeForm): diff --git a/sounds/migrations/0054_alter_sound_bst_category.py b/sounds/migrations/0054_alter_sound_bst_category.py index 0988305d3..3c16b1011 100644 --- a/sounds/migrations/0054_alter_sound_bst_category.py +++ b/sounds/migrations/0054_alter_sound_bst_category.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.23 on 2024-12-23 17:10 +# Generated by Django 3.2.23 on 2025-01-16 15:18 from django.db import migrations, models @@ -13,6 +13,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='sound', name='bst_category', - field=models.CharField(blank=True, choices=[('m', 'Music'), ('m-sp', 'Solo percussion'), ('m-si', 'Solo instrument'), ('m-m', 'Multiple instruments'), ('m-other', 'Other (music)'), ('is', 'Instrument samples'), ('is-p', 'Percussion'), ('is-s', 'String'), ('is-w', 'Wind'), ('is-k', 'Piano / Keyboard instruments'), ('is-e', 'Synths / Electronic'), ('is-other', 'Instrument samples (other)'), ('sp', 'Speech'), ('sp-s', 'Solo speech'), ('sp-c', 'Conversation / Crowd'), ('sp-p', 'Processed / Synthetic'), ('sp-other', 'Other (speech)'), ('fx', 'Sound effects'), ('fx-o', 'Objects / House appliances'), ('fx-v', 'Vehicles'), ('fx-m', 'Other mechanisms, engines, machines'), ('fx-h', 'Human sounds and actions'), ('fx-a', 'Animals'), ('fx-n', 'Natural elements and explosions'), ('fx-ex', 'Experimental'), ('fx-el', 'Electronic / Design'), ('fx-other', 'Other (sound effects)'), ('ss', 'Soundscapes'), ('ss-n', 'Nature'), ('ss-i', 'Indoors'), ('ss-u', 'Urban'), ('ss-s', 'Synthetic / Artificial'), ('ss-other', 'Other (soundscapes)')], default=None, max_length=8, null=True), + field=models.CharField(blank=True, choices=[('m', 'Music'), ('m-sp', 'Solo percussion'), ('m-si', 'Solo instrument'), ('m-m', 'Multiple instruments'), ('m-other', 'Other'), ('is', 'Instrument samples'), ('is-p', 'Percussion'), ('is-s', 'String'), ('is-w', 'Wind'), ('is-k', 'Piano / Keyboard instruments'), ('is-e', 'Synths / Electronic'), ('is-other', 'Other'), ('sp', 'Speech'), ('sp-s', 'Solo speech'), ('sp-c', 'Conversation / Crowd'), ('sp-p', 'Processed / Synthetic'), ('sp-other', 'Other'), ('fx', 'Sound effects'), ('fx-o', 'Objects / House appliances'), ('fx-v', 'Vehicles'), ('fx-m', 'Other mechanisms, engines, machines'), ('fx-h', 'Human sounds and actions'), ('fx-a', 'Animals'), ('fx-n', 'Natural elements and explosions'), ('fx-ex', 'Experimental'), ('fx-el', 'Electronic / Design'), ('fx-other', 'Other'), ('ss', 'Soundscapes'), ('ss-n', 'Nature'), ('ss-i', 'Indoors'), ('ss-u', 'Urban'), ('ss-s', 'Synthetic / Artificial'), ('ss-other', 'Other')], default=None, max_length=8, null=True), ), ] diff --git a/sounds/templatetags/bst_category.py b/sounds/templatetags/bst_category.py new file mode 100644 index 000000000..530ce30a7 --- /dev/null +++ b/sounds/templatetags/bst_category.py @@ -0,0 +1,11 @@ +from django import template + +register = template.Library() + +@register.filter +def get_top_level_bst_category(value): + """ + Extract the top level category from the given value. + The top level category is the part before the '-' in value. + """ + return value.split('-')[0] if '-' in value else value diff --git a/sounds/views.py b/sounds/views.py index d31396dcb..198c8b9bc 100644 --- a/sounds/views.py +++ b/sounds/views.py @@ -663,7 +663,8 @@ def update_edited_sound(sound, data): 'sounds_per_round': forms_per_round, 'last_latlong': request.user.profile.get_last_latlong(), 'total_sounds_to_describe': len_original_describe_edit_sounds, - 'next': request.GET.get('next', '') + 'next': request.GET.get('next', ''), + 'bst_taxonomy': settings.BROAD_SOUND_TAXONOMY } if request.method == "POST" and all_forms_validated_ok: diff --git a/templates/molecules/bst_category_form_field.html b/templates/molecules/bst_category_form_field.html new file mode 100644 index 000000000..b9ca50975 --- /dev/null +++ b/templates/molecules/bst_category_form_field.html @@ -0,0 +1,124 @@ +{% load bst_category %} + +
+ + {{ form.bst_category.errors }} +
+ {{ form.bst_category.as_hidden }} + +
+ {% for value, label in form.fields.bst_category.choices %} + {% if "-" not in value %} + + {% endif %} + {% endfor %} +
+ + +
+ {{ form.bst_category.help_text|safe }} +
+
+ + diff --git a/templates/sounds/edit_and_describe.html b/templates/sounds/edit_and_describe.html index 07c95b044..be4a9c534 100644 --- a/templates/sounds/edit_and_describe.html +++ b/templates/sounds/edit_and_describe.html @@ -71,9 +71,7 @@
Basic information
{{ form.name }}
- {{ form.bst_category.errors }} - {{ form.bst_category.label_tag }} - {{ form.bst_category }} + {% include "molecules/bst_category_form_field.html" %}
{% include "molecules/tags_form_field.html" %}