Drop python 3.8 and 3.9, support python 3.13

merge-requests/2823/head
petitminion 2025-01-13 21:47:18 +00:00
rodzic 75c4b3a7ff
commit 78856cc32a
9 zmienionych plików z 1426 dodań i 1369 usunięć

Wyświetl plik

@ -232,7 +232,7 @@ test_api:
image: $CI_REGISTRY/funkwhale/ci/python-funkwhale-api:$PYTHON_VERSION
parallel:
matrix:
- PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11", "3.12"]
- PYTHON_VERSION: ["3.10", "3.11", "3.12", "3.13"]
services:
- name: postgres:15-alpine
command:
@ -540,8 +540,8 @@ package:
artifacts: true
- job: build_front
artifacts: true
# - job: build_tauri
# artifacts: true
# - job: build_tauri
# artifacts: true
rules:
- if: $CI_COMMIT_BRANCH =~ /(stable|develop)/

Wyświetl plik

@ -1,4 +1,4 @@
FROM alpine:3.19 AS requirements
FROM alpine:3.21 AS requirements
RUN set -eux; \
apk add --no-cache \
@ -12,7 +12,7 @@ RUN set -eux; \
poetry export --without-hashes --extras typesense > requirements.txt; \
poetry export --without-hashes --with dev > dev-requirements.txt;
FROM alpine:3.19 AS builder
FROM alpine:3.21 AS builder
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
@ -37,11 +37,11 @@ RUN set -eux; \
openssl-dev \
postgresql-dev \
zlib-dev \
py3-cryptography=41.0.7-r0 \
py3-lxml=4.9.3-r1 \
py3-pillow=10.3.0-r0 \
py3-psycopg2=2.9.9-r0 \
py3-watchfiles=0.19.0-r1 \
py3-cryptography \
py3-lxml \
py3-pillow \
py3-psycopg2 \
py3-watchfiles \
python3-dev
# Create virtual env
@ -61,11 +61,11 @@ RUN --mount=type=cache,target=~/.cache/pip; \
# to install the deps using pip.
grep -Ev 'cryptography|lxml|pillow|psycopg2|watchfiles' /requirements.txt \
| pip3 install -r /dev/stdin \
cryptography==41.0.7 \
lxml==4.9.3 \
pillow==10.2.0 \
psycopg2==2.9.9 \
watchfiles==0.19.0
cryptography \
lxml \
pillow \
psycopg2 \
watchfiles
ARG install_dev_deps=0
RUN --mount=type=cache,target=~/.cache/pip; \
@ -73,14 +73,14 @@ RUN --mount=type=cache,target=~/.cache/pip; \
if [ "$install_dev_deps" = "1" ] ; then \
grep -Ev 'cryptography|lxml|pillow|psycopg2|watchfiles' /dev-requirements.txt \
| pip3 install -r /dev/stdin \
cryptography==41.0.7 \
lxml==4.9.3 \
pillow==10.2.0 \
psycopg2==2.9.9 \
watchfiles==0.19.0; \
cryptography \
lxml \
pillow \
psycopg2 \
watchfiles; \
fi
FROM alpine:3.19 AS production
FROM alpine:3.21 AS production
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
@ -97,11 +97,11 @@ RUN set -eux; \
libpq \
libxml2 \
libxslt \
py3-cryptography=41.0.7-r0 \
py3-lxml=4.9.3-r1 \
py3-pillow=10.3.0-r0 \
py3-psycopg2=2.9.9-r0 \
py3-watchfiles=0.19.0-r1 \
py3-cryptography \
py3-lxml \
py3-pillow \
py3-psycopg2 \
py3-watchfiles \
python3 \
tzdata

Wyświetl plik

@ -7,7 +7,6 @@ import urllib.parse
import uuid
import arrow
import pydub
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.postgres.indexes import GinIndex
@ -939,6 +938,12 @@ class Upload(models.Model):
if self.source and self.source.startswith("file://"):
return open(self.source.replace("file://", "", 1), "rb")
def get_audio_file_path(self):
if self.audio_file:
return self.audio_file.path
if self.source and self.source.startswith("file://"):
return self.source.replace("file://", "", 1)
def get_audio_data(self):
audio_file = self.get_audio_file()
if not audio_file:
@ -952,14 +957,6 @@ class Upload(models.Model):
"size": self.get_file_size(),
}
def get_audio_segment(self):
input = self.get_audio_file()
if not input:
return
audio = pydub.AudioSegment.from_file(input)
return audio
def get_quality(self):
extension_to_mimetypes = utils.get_extension_to_mimetype_dict()
@ -1083,8 +1080,8 @@ class Upload(models.Model):
)
version.audio_file.save(new_name, f)
utils.transcode_audio(
audio=self.get_audio_segment(),
output=version.audio_file,
audio_file_path=self.get_audio_file_path(),
output_path=version.audio_file.path,
output_format=utils.MIMETYPE_TO_EXTENSION[mimetype],
bitrate=str(bitrate),
)

Wyświetl plik

@ -4,10 +4,10 @@ import pathlib
import magic
import mutagen
import pydub
from django.conf import settings
from django.core.cache import cache
from django.db.models import F
from ffmpeg import FFmpeg
from funkwhale_api.common import throttling
from funkwhale_api.common.search import get_fts_query # noqa
@ -114,15 +114,10 @@ def get_actor_from_request(request):
return actor
def transcode_file(input, output, input_format=None, output_format="mp3", **kwargs):
with input.open("rb"):
audio = pydub.AudioSegment.from_file(input, format=input_format)
return transcode_audio(audio, output, output_format, **kwargs)
def transcode_audio(audio, output, output_format, **kwargs):
with output.open("wb"):
return audio.export(output, format=output_format, **kwargs)
def transcode_audio(audio_file_path, output_path, output_format="mp3", **kwargs):
FFmpeg().input(audio_file_path).output(
output_path, format=output_format, **kwargs
).option("y").execute()
def increment_downloads_count(upload, user, wsgi_request):

2676
api/poetry.lock wygenerowano

Plik diff jest za duży Load Diff

Wyświetl plik

@ -25,7 +25,7 @@ exclude = ["tests"]
funkwhale-manage = 'funkwhale_api.main:main'
[tool.poetry.dependencies]
python = "^3.8,<3.13"
python = "^3.10,<3.14"
# Django
dj-rest-auth = "5.0.2"
@ -46,7 +46,7 @@ djangorestframework = "==3.14.0"
drf-spectacular = "==0.26.5"
markdown = "==3.4.4"
persisting-theory = "==1.0"
psycopg2-binary = "==2.9.9"
psycopg2-binary = "==2.9.10"
redis = "==5.0.1"
# Django LDAP
@ -73,12 +73,12 @@ bleach = "==6.1.0"
boto3 = "==1.26.161"
click = "==8.1.7"
cryptography = "==41.0.7"
feedparser = "==6.0.10"
feedparser = "==6.0.11"
python-ffmpeg = "==2.0.12"
liblistenbrainz = "==0.5.5"
musicbrainzngs = "==0.7.1"
mutagen = "==1.46.0"
pillow = "==10.2.0"
pydub = "==0.25.1"
pillow = "==11.1.0"
pyld = "==2.0.3"
python-magic = "==0.4.27"
requests = "==2.31.0"

Wyświetl plik

@ -1,6 +1,5 @@
import os
import pathlib
import tempfile
import pytest
@ -114,25 +113,6 @@ def test_get_dirs_and_files(path, expected, tmpdir):
assert utils.browse_dir(root_path, path) == expected
@pytest.mark.parametrize(
"name, expected",
[
("sample.flac", {"bitrate": 128000, "length": 0}),
("test.mp3", {"bitrate": 16000, "length": 268}),
("test.ogg", {"bitrate": 128000, "length": 1}),
("test.opus", {"bitrate": 128000, "length": 1}),
],
)
def test_transcode_file(name, expected):
path = pathlib.Path(os.path.join(DATA_DIR, name))
with tempfile.NamedTemporaryFile() as dest:
utils.transcode_file(path, pathlib.Path(dest.name))
with open(dest.name, "rb") as f:
result = {k: round(v) for k, v in utils.get_audio_file_data(f).items()}
assert result == expected
def test_custom_s3_domain(factories, settings):
"""See #2220"""
settings.AWS_S3_CUSTOM_DOMAIN = "my.custom.domain.tld"

Wyświetl plik

@ -621,8 +621,6 @@ def test_listen_transcode_in_place(
source="file://" + os.path.join(DATA_DIR, "test.ogg"),
)
assert upload.get_audio_segment()
url = reverse("api:v1:listen-detail", kwargs={"uuid": upload.track.uuid})
handle_serve = mocker.spy(views, "handle_serve")
response = logged_in_api_client.get(url, {"to": "mp3"})

Wyświetl plik

@ -0,0 +1 @@
Drop python 3.8 and 3.9 (#2282)