diff --git a/.github/actions/setup_project/action.yml b/.github/actions/setup_project/action.yml index 0ec83445..720d36bc 100644 --- a/.github/actions/setup_project/action.yml +++ b/.github/actions/setup_project/action.yml @@ -12,7 +12,7 @@ runs: steps: - name: Install apt packages if: ${{ inputs.full == 'true' }} - uses: awalsh128/cache-apt-pkgs-action@v1.4.3 + uses: awalsh128/cache-apt-pkgs-action@v1.6.0 with: packages: gettext version: 1.0 # increment to reset cache @@ -23,26 +23,29 @@ runs: with: redis-version: "7.x" - - name: Install uv - uses: astral-sh/setup-uv@v5 - with: - version: "0.5.14" - enable-cache: true - cache-dependency-glob: "uv.lock" - - name: "Set up Python" - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version-file: ".python-version" - - name: Restore cached virtualenv - uses: actions/cache/restore@v4 + - name: Install uv + uses: astral-sh/setup-uv@v8.1.0 + with: + version: "0.11.8" + enable-cache: false + cache-dependency-glob: "uv.lock" + + - name: Restore cached virtualenv + uses: actions/cache@v5 with: - key: venv-${{ runner.os }}-${{ hashFiles('.python-version') }}-${{ hashFiles('pyproject.toml') }}-${{ env.CACHE_SUFFIX }} path: .venv + key: uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + restore-keys: | + uv-${{ runner.os }}-${{ hashFiles('uv.lock') }} + uv-${{ runner.os }} - name: Install dependencies - run: uv sync + run: uv sync --locked shell: bash - name: Install Xapian @@ -50,15 +53,6 @@ runs: run: uv run ./manage.py install_xapian shell: bash - # compiling xapian accounts for almost the entirety of the virtualenv setup, - # so we save the virtual environment only on workflows where it has been installed - - name: Save cached virtualenv - if: ${{ inputs.full == 'true' }} - uses: actions/cache/save@v4 - with: - key: venv-${{ runner.os }}-${{ hashFiles('.python-version') }}-${{ hashFiles('pyproject.toml') }}-${{ env.CACHE_SUFFIX }} - path: .venv - - name: Compile gettext messages if: ${{ inputs.full == 'true' }} run: uv run ./manage.py compilemessages diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8919d04c..e92bf82e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,8 @@ jobs: name: Launch pre-commits checks (ruff) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: python-version-file: ".python-version" - uses: pre-commit/action@v3.0.1 @@ -35,7 +35,7 @@ jobs: pytest-mark: [not slow] steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - uses: ./.github/actions/setup_project with: full: true @@ -49,7 +49,7 @@ jobs: uv run coverage report uv run coverage html - name: Archive code coverage results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: coverage-report-${{ matrix.pytest-mark }} path: coverage_report diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 8df48378..d46feb8a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -14,7 +14,7 @@ jobs: steps: - name: SSH Remote Commands - uses: appleboy/ssh-action@v1.1.0 + uses: appleboy/ssh-action@v1.2.5 with: # Proxy proxy_host : ${{secrets.PROXY_HOST}} @@ -29,8 +29,6 @@ jobs: username : ${{secrets.USER}} key: ${{secrets.KEY}} - script_stop: true - # See https://github.com/ae-utbm/sith/wiki/GitHub-Actions#deployment-action script: | cd ${{secrets.SITH_PATH}} diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 236917a3..cae93e7b 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -9,10 +9,10 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ./.github/actions/setup_project - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v3 + - uses: actions/cache@v5 with: key: mkdocs-material-${{ env.cache_id }} path: .cache diff --git a/.github/workflows/taiste.yml b/.github/workflows/taiste.yml index 729e051c..9a49c8f3 100644 --- a/.github/workflows/taiste.yml +++ b/.github/workflows/taiste.yml @@ -13,7 +13,7 @@ jobs: steps: - name: SSH Remote Commands - uses: appleboy/ssh-action@v1.1.0 + uses: appleboy/ssh-action@v1.2.5 with: # Proxy proxy_host : ${{secrets.PROXY_HOST}} @@ -28,8 +28,6 @@ jobs: username : ${{secrets.USER}} key: ${{secrets.KEY}} - script_stop: true - # See https://github.com/ae-utbm/sith/wiki/GitHub-Actions#deployment-action script: | cd ${{secrets.SITH_PATH}} diff --git a/club/templates/club/club_detail.jinja b/club/templates/club/club_detail.jinja index 168c4b6c..14a5a384 100644 --- a/club/templates/club/club_detail.jinja +++ b/club/templates/club/club_detail.jinja @@ -26,10 +26,9 @@ {% if club.logo %} {% endif %} +

{{ club.name }}

{% if page_revision %} {{ page_revision|markdown }} - {% else %} -

{{ club.name }}

{% endif %} {% endblock %} diff --git a/com/static/com/css/news-list.scss b/com/static/com/css/news-list.scss index b53ff784..a1dcb966 100644 --- a/com/static/com/css/news-list.scss +++ b/com/static/com/css/news-list.scss @@ -3,6 +3,7 @@ #news { display: flex; + gap: 1em; @media (max-width: 800px) { flex-direction: column; @@ -26,12 +27,14 @@ } h3 { - background: $second-color; - box-shadow: $shadow-color 1px 1px 1px; - padding: 0.4em; + --box-shadow: rgb(60 64 67 / 30%) 0 1px 3px 0, rgb(60 64 67 / 15%) 0 3px 7px 2px; + background: lighten($second-color, 5%); + box-shadow: var(--box-shadow); + padding: .75rem; margin: 0 0 0.5em 0; text-transform: uppercase; font-size: 17px; + border-radius: 10px; &:not(:first-of-type) { margin: 2em 0 1em 0; @@ -39,12 +42,11 @@ .feed { float: right; - color: #f26522; + color: #e25512; } } @media screen and (max-width: $small-devices) { - #left_column, #right_column { flex: 100%; @@ -57,6 +59,7 @@ max-height: 600px; overflow-y: scroll; overflow-x: clip; + margin-top: 1em; #load-more-news-button { text-align: center; @@ -76,15 +79,11 @@ font-size: 70%; margin-bottom: 1em; - h3 { - margin-bottom: 0; - } - #links_content { overflow: auto; box-shadow: $shadow-color 1px 1px 1px; min-height: 20em; - padding-bottom: 1em; + padding: 1em; h4 { margin-left: 5px; @@ -121,6 +120,8 @@ } #birthdays_content { + box-shadow: $shadow-color 1px 1px 1px; + padding: 1em; ul.birthdays_year { margin: 0; list-style-type: none; @@ -135,8 +136,7 @@ } ul { - margin: 0; - margin-left: 1em; + margin: .5em 0 0 1em; list-style-type: square; list-style-position: inside; font-weight: normal; @@ -150,9 +150,13 @@ /* EVENTS TODAY AND NEXT FEW DAYS */ .news_events_group { box-shadow: $shadow-color 1px 1px 1px; - margin-left: 1em; + margin-left: 0; margin-bottom: 0.5em; + @media screen and (max-width: $small-devices) { + margin-left: 3px; + } + .news_events_group_date { display: table-cell; padding: 0.6em; diff --git a/com/templates/com/news_list.jinja b/com/templates/com/news_list.jinja index 2f6dc26e..975fb2ac 100644 --- a/com/templates/com/news_list.jinja +++ b/com/templates/com/news_list.jinja @@ -23,7 +23,7 @@ {% if user.is_authenticated and (user.is_com_admin or user.memberships.board().ongoing().exists()) %} - + {% trans %}Create news{% endtrans %} diff --git a/com/tests/test_notifications.py b/com/tests/test_notifications.py index 8ddbfcb3..fc0e6aee 100644 --- a/com/tests/test_notifications.py +++ b/com/tests/test_notifications.py @@ -7,7 +7,7 @@ from model_bakery import baker from com.models import News, NewsDate from core.baker_recipes import subscriber_user -from core.models import Group, Notification, User +from core.models import Group, Notification, SithFile, User @pytest.mark.django_db @@ -18,6 +18,7 @@ def test_notification_created(): past_news = baker.make(News, is_published=False) baker.make(NewsDate, news=past_news, start_date=now() - timedelta(days=1)) com_admin_group = Group.objects.get(pk=settings.SITH_GROUP_COM_ADMIN_ID) + SithFile.objects.filter(owner__in=com_admin_group.users.all()).delete() com_admin_group.users.all().delete() Notification.objects.all().delete() com_admin = baker.make(User, groups=[com_admin_group]) diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index a326b8ed..22541841 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -622,8 +622,7 @@ class Command(BaseCommand): ) pict.file.name = p.name pict.full_clean() - pict.generate_thumbnails() - pict.save() + pict.generate_thumbnails(save=True) img_skia = Picture.objects.get(name="skia.jpg") img_sli = Picture.objects.get(name="sli.jpg") diff --git a/core/migrations/0050_alter_sithfile_moderator.py b/core/migrations/0050_alter_sithfile_moderator.py new file mode 100644 index 00000000..0b6e9ef1 --- /dev/null +++ b/core/migrations/0050_alter_sithfile_moderator.py @@ -0,0 +1,47 @@ +# Generated by Django 5.2.12 on 2026-05-01 08:59 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models +from django.db.migrations.state import StateApps +from django.db.models import F + + +def set_updated_at(apps: StateApps, schema_editor): + SithFile = apps.get_model("core", "SithFile") + SithFile.objects.update(updated_at=F("date")) + + +class Migration(migrations.Migration): + dependencies = [("core", "0049_user_whitelisted_users")] + + operations = [ + migrations.AlterField( + model_name="sithfile", + name="moderator", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="moderated_files", + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AlterField( + model_name="sithfile", + name="owner", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="owned_files", + to=settings.AUTH_USER_MODEL, + verbose_name="owner", + ), + ), + migrations.AddField( + model_name="sithfile", + name="updated_at", + field=models.DateTimeField(auto_now=True, verbose_name="updated at"), + ), + migrations.RunPython(set_updated_at, reverse_code=migrations.RunPython.noop), + ] diff --git a/core/models.py b/core/models.py index ffbdebfc..208f1937 100644 --- a/core/models.py +++ b/core/models.py @@ -853,7 +853,7 @@ class SithFile(models.Model): User, related_name="owned_files", verbose_name=_("owner"), - on_delete=models.CASCADE, + on_delete=models.PROTECT, ) edit_groups = models.ManyToManyField( Group, related_name="editable_files", verbose_name=_("edit group"), blank=True @@ -865,6 +865,7 @@ class SithFile(models.Model): mime_type = models.CharField(_("mime type"), max_length=30) size = models.IntegerField(_("size"), default=0) date = models.DateTimeField(_("date"), default=timezone.now) + updated_at = models.DateTimeField(_("updated at"), auto_now=True) is_moderated = models.BooleanField(_("is moderated"), default=False) moderator = models.ForeignKey( User, @@ -872,7 +873,7 @@ class SithFile(models.Model): verbose_name=_("owner"), null=True, blank=True, - on_delete=models.CASCADE, + on_delete=models.SET_NULL, ) asked_for_removal = models.BooleanField(_("asked for removal"), default=False) is_in_sas = models.BooleanField( diff --git a/core/static/bundled/core/components/tabs-index.ts b/core/static/bundled/core/components/tabs-index.ts index 7bd85998..260467d5 100644 --- a/core/static/bundled/core/components/tabs-index.ts +++ b/core/static/bundled/core/components/tabs-index.ts @@ -28,7 +28,7 @@ export class Tab extends HTMLElement { return html`