Merge branch '297-linting' into 'develop'

Resolve "Add some linting for Python code"

Closes #297

See merge request funkwhale/funkwhale!242
This commit is contained in:
Eliot Berriot 2018-06-10 10:50:35 +00:00
commit 2b0f7f6db3
181 changed files with 427 additions and 821 deletions

View File

@ -3,13 +3,39 @@ variables:
IMAGE: $IMAGE_NAME:$CI_COMMIT_REF_NAME
IMAGE_LATEST: $IMAGE_NAME:latest
PIP_CACHE_DIR: "$CI_PROJECT_DIR/pip-cache"
PYTHONDONTWRITEBYTECODE: "true"
stages:
- lint
- test
- build
- deploy
black:
image: python:3.6
stage: lint
variables:
GIT_STRATEGY: fetch
before_script:
- pip install black
script:
- black --check --diff api/
flake8:
image: python:3.6
stage: lint
variables:
GIT_STRATEGY: fetch
before_script:
- pip install flake8
script:
- flake8 -v api
cache:
key: "$CI_PROJECT_ID__flake8_pip_cache"
paths:
- "$PIP_CACHE_DIR"
test_api:
services:
- postgres:9.4
@ -108,7 +134,7 @@ pages:
tags:
- docker
docker_develop:
docker_release:
stage: deploy
before_script:
- docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD
@ -119,8 +145,9 @@ docker_develop:
- docker push $IMAGE
only:
- develop@funkwhale/funkwhale
- tags@funkwhale/funkwhale
tags:
- dind
- docker-build
build_api:
# Simply publish a zip containing api/ directory
@ -135,19 +162,3 @@ build_api:
- tags@funkwhale/funkwhale
- master@funkwhale/funkwhale
- develop@funkwhale/funkwhale
docker_release:
stage: deploy
before_script:
- docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD
- cp -r front/dist api/frontend
- cd api
script:
- docker build -t $IMAGE -t $IMAGE_LATEST .
- docker push $IMAGE
- docker push $IMAGE_LATEST
only:
- tags@funkwhale/funkwhale
tags:
- dind

View File

@ -1,15 +1,13 @@
from django.conf.urls import include, url
from dynamic_preferences.api.viewsets import GlobalPreferencesViewSet
from rest_framework import routers
from rest_framework.urlpatterns import format_suffix_patterns
from django.conf.urls import include, url
from rest_framework_jwt import views as jwt_views
from funkwhale_api.activity import views as activity_views
from funkwhale_api.instance import views as instance_views
from funkwhale_api.music import views
from funkwhale_api.playlists import views as playlists_views
from funkwhale_api.subsonic.views import SubsonicViewSet
from rest_framework_jwt import views as jwt_views
from dynamic_preferences.api.viewsets import GlobalPreferencesViewSet
from dynamic_preferences.users.viewsets import UserPreferencesViewSet
router = routers.SimpleRouter()
router.register(r"settings", GlobalPreferencesViewSet, base_name="settings")

View File

@ -1,8 +1,9 @@
import django
import os
import django
from .routing import application # noqa
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
django.setup()
from .routing import application

View File

@ -1,12 +1,9 @@
from django.conf.urls import url
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.conf.urls import url
from funkwhale_api.common.auth import TokenAuthMiddleware
from funkwhale_api.instance import consumers
application = ProtocolTypeRouter(
{
# Empty for now (http->django views is added by default)

View File

@ -10,8 +10,9 @@ https://docs.djangoproject.com/en/dev/ref/settings/
"""
from __future__ import absolute_import, unicode_literals
from urllib.parse import urlsplit
import os
import datetime
from urllib.parse import urlparse, urlsplit
import environ
from celery.schedules import crontab
@ -21,7 +22,6 @@ ROOT_DIR = environ.Path(__file__) - 3 # (/a/b/myfile.py - 3 = /)
APPS_DIR = ROOT_DIR.path("funkwhale_api")
env = environ.Env()
try:
env.read_env(ROOT_DIR.file(".env"))
except FileNotFoundError:
@ -315,7 +315,6 @@ CACHE_DEFAULT = "redis://127.0.0.1:6379/0"
CACHES = {"default": env.cache_url("CACHE_URL", default=CACHE_DEFAULT)}
CACHES["default"]["BACKEND"] = "django_redis.cache.RedisCache"
from urllib.parse import urlparse
cache_url = urlparse(CACHES["default"]["LOCATION"])
CHANNEL_LAYERS = {
@ -332,12 +331,12 @@ CACHES["default"]["OPTIONS"] = {
}
########## CELERY
# CELERY
INSTALLED_APPS += ("funkwhale_api.taskapp.celery.CeleryConfig",)
CELERY_BROKER_URL = env(
"CELERY_BROKER_URL", default=env("CACHE_URL", default=CACHE_DEFAULT)
)
########## END CELERY
# END CELERY
# Location of root django.contrib.admin URL, use {% url 'admin:index' %}
# Your common stuff: Below this line define 3rd party library settings
@ -351,8 +350,6 @@ CELERYBEAT_SCHEDULE = {
}
}
import datetime
JWT_AUTH = {
"JWT_ALLOW_REFRESH": True,
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=7),

View File

@ -10,6 +10,7 @@ Local settings
from .common import * # noqa
# DEBUG
# ------------------------------------------------------------------------------
DEBUG = env.bool("DJANGO_DEBUG", default=True)
@ -49,10 +50,10 @@ INSTALLED_APPS += ("debug_toolbar",)
# ------------------------------------------------------------------------------
TEST_RUNNER = "django.test.runner.DiscoverRunner"
########## CELERY
# CELERY
# In development, all tasks will be executed locally by blocking until the task returns
CELERY_TASK_ALWAYS_EAGER = False
########## END CELERY
# END CELERY
# Your local stuff: Below this line define 3rd party library settings

View File

@ -11,9 +11,6 @@ Production Configurations
"""
from __future__ import absolute_import, unicode_literals
from django.utils import six
from .common import * # noqa
# SECRET CONFIGURATION

View File

@ -5,7 +5,6 @@ from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.views.generic import TemplateView
from django.views import defaults as default_views
urlpatterns = [

View File

@ -15,11 +15,9 @@ framework.
"""
import os
from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
# if running multiple sites in the same mod_wsgi process. To fix this, use
# mod_wsgi daemon mode with each site in its own daemon process, or use

View File

@ -4,8 +4,7 @@ from rest_framework.response import Response
from funkwhale_api.common.permissions import ConditionalAuthentication
from funkwhale_api.favorites.models import TrackFavorite
from . import serializers
from . import utils
from . import serializers, utils
class ActivityViewSet(viewsets.GenericViewSet):

View File

@ -1,12 +1,7 @@
from urllib.parse import parse_qs
import jwt
from django.contrib.auth.models import AnonymousUser
from django.utils.encoding import smart_text
from rest_framework import exceptions
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from funkwhale_api.users.models import User

View File

@ -1,6 +1,5 @@
from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _
from rest_framework import exceptions
from rest_framework_jwt import authentication
from rest_framework_jwt.settings import api_settings

View File

@ -1,4 +1,5 @@
from channels.generic.websocket import JsonWebsocketConsumer
from funkwhale_api.common import channels

View File

@ -1,10 +1,8 @@
import django_filters
from django.db import models
from funkwhale_api.music import utils
PRIVACY_LEVEL_CHOICES = [
("me", "Only me"),
("followers", "Me and my followers"),

View File

@ -41,7 +41,6 @@ class Command(BaseCommand):
script["entrypoint"](self, **options)
def show_help(self):
indentation = 4
self.stdout.write("")
self.stdout.write("Available scripts:")
self.stdout.write("Launch with: python manage.py <script_name>")

View File

@ -1,8 +1,6 @@
import operator
from django.conf import settings
from django.http import Http404
from rest_framework.permissions import BasePermission
from funkwhale_api.common import preferences

View File

@ -1,8 +1,6 @@
from django.conf import settings
from django import forms
from dynamic_preferences import serializers
from dynamic_preferences import types
from django.conf import settings
from dynamic_preferences import serializers, types
from dynamic_preferences.registries import global_preferences_registry

View File

@ -1,2 +0,0 @@
from . import django_permissions_to_user_permissions
from . import test

View File

@ -2,10 +2,10 @@
Convert django permissions to user permissions in the database,
following the work done in #152.
"""
from django.db.models import Q
from funkwhale_api.users import models
from django.contrib.auth.models import Permission
from django.db.models import Q
from funkwhale_api.users import models
mapping = {
"dynamic_preferences.change_globalpreferencemodel": "settings",

View File

@ -40,7 +40,6 @@ class ActionSerializer(serializers.Serializer):
return value
def validate_objects(self, value):
qs = None
if value == "all":
return self.queryset.all().order_by("id")
if type(value) in [list, tuple]:

View File

@ -1,5 +1,4 @@
import requests
from django.conf import settings
import funkwhale_api

View File

@ -1,6 +1,6 @@
from urllib.parse import urlencode, parse_qs, urlsplit, urlunsplit
import os
import shutil
from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
from django.db import transaction

View File

@ -1,2 +1,3 @@
from .downloader import download
__all__ = ["download"]

View File

@ -1,9 +1,7 @@
import os
import json
from urllib.parse import quote_plus
import youtube_dl
from django.conf import settings
import glob
def download(

View File

@ -1,5 +1,5 @@
from funkwhale_api.common import channels
from funkwhale_api.activity import record
from funkwhale_api.common import channels
from . import serializers

View File

@ -1,7 +1,6 @@
import factory
from funkwhale_api.factories import registry
from funkwhale_api.music.factories import TrackFactory
from funkwhale_api.users.factories import UserFactory

View File

@ -1,4 +1,3 @@
from django.conf import settings
from django.db import models
from django.utils import timezone

View File

@ -1,4 +1,3 @@
from django.conf import settings
from rest_framework import serializers

View File

@ -1,8 +1,7 @@
from django.conf.urls import include, url
from . import views
from rest_framework import routers
from . import views
router = routers.SimpleRouter()
router.register(r"tracks", views.TrackFavoriteViewSet, "tracks")

View File

@ -1,15 +1,12 @@
from rest_framework import generics, mixins, viewsets
from rest_framework import status
from rest_framework.response import Response
from rest_framework import pagination
from rest_framework import mixins, status, viewsets
from rest_framework.decorators import list_route
from rest_framework.response import Response
from funkwhale_api.activity import record
from funkwhale_api.music.models import Track
from funkwhale_api.common.permissions import ConditionalAuthentication
from funkwhale_api.music.models import Track
from . import models
from . import serializers
from . import models, serializers
class TrackFavoriteViewSet(

View File

@ -1,6 +1,3 @@
from . import serializers
from . import tasks
ACTIVITY_TYPES = [
"Accept",
"Add",
@ -52,9 +49,13 @@ OBJECT_TYPES = [
def deliver(activity, on_behalf_of, to=[]):
from . import tasks
return tasks.send.delay(activity=activity, actor_id=on_behalf_of.pk, to=to)
def accept_follow(follow):
from . import serializers
serializer = serializers.AcceptFollowSerializer(follow)
return deliver(serializer.data, to=[follow.actor.url], on_behalf_of=follow.target)

View File

@ -1,29 +1,19 @@
import datetime
import logging
import uuid
import xml
from django.conf import settings
from django.db import transaction
from django.urls import reverse
from django.utils import timezone
from rest_framework.exceptions import PermissionDenied
from dynamic_preferences.registries import global_preferences_registry
from funkwhale_api.common import preferences
from funkwhale_api.common import session
from funkwhale_api.common import preferences, session
from funkwhale_api.common import utils as funkwhale_utils
from funkwhale_api.music import models as music_models
from funkwhale_api.music import tasks as music_tasks
from . import activity
from . import keys
from . import models
from . import serializers
from . import signing
from . import utils
from . import activity, keys, models, serializers, signing, utils
logger = logging.getLogger(__name__)
@ -45,7 +35,7 @@ def get_actor_data(actor_url):
response.raise_for_status()
try:
return response.json()
except:
except Exception:
raise ValueError("Invalid actor payload: {}".format(response.text))
@ -155,7 +145,6 @@ class SystemActor(object):
return handler(data, actor)
def handle_follow(self, ac, sender):
system_actor = self.get_actor_instance()
serializer = serializers.FollowSerializer(
data=ac, context={"follow_actor": sender}
)
@ -325,7 +314,6 @@ class TestActor(SystemActor):
reply_url = "https://{}/activities/note/{}".format(
settings.FEDERATION_HOSTNAME, now.timestamp()
)
reply_content = "{} Pong!".format(sender.mention_username)
reply_activity = {
"@context": [
"https://www.w3.org/ns/activitystreams",

View File

@ -1,16 +1,8 @@
import cryptography
from django.contrib.auth.models import AnonymousUser
from rest_framework import authentication, exceptions
from rest_framework import authentication
from rest_framework import exceptions
from . import actors
from . import keys
from . import models
from . import serializers
from . import signing
from . import utils
from . import actors, keys, signing, utils
class SignatureAuthentication(authentication.BaseAuthentication):

View File

@ -1,4 +1,3 @@
from django.forms import widgets
from dynamic_preferences import types
from dynamic_preferences.registries import global_preferences_registry

View File

@ -1,16 +1,14 @@
import uuid
import factory
import requests
import requests_http_signature
import uuid
from django.utils import timezone
from django.conf import settings
from django.utils import timezone
from funkwhale_api.factories import registry
from . import keys
from . import models
from . import keys, models
registry.register(keys.get_key_pair, name="federation.KeyPair")

View File

@ -1,11 +1,9 @@
from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend as crypto_default_backend
import re
import urllib.parse
from . import exceptions
from cryptography.hazmat.backends import default_backend as crypto_default_backend
from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
KEY_ID_REGEX = re.compile(r"keyId=\"(?P<id>.*)\"")

View File

@ -1,15 +1,11 @@
import json
import requests
import requests
from django.conf import settings
from funkwhale_api.common import session
from . import actors
from . import models
from . import serializers
from . import signing
from . import webfinger
from . import actors, models, serializers, signing, webfinger
def scan_from_account_name(account_name):
@ -28,13 +24,6 @@ def scan_from_account_name(account_name):
except serializers.ValidationError:
return {"webfinger": {"errors": ["Invalid account string"]}}
system_library = actors.SYSTEM_ACTORS["library"].get_actor_instance()
library = (
models.Library.objects.filter(
actor__domain=domain, actor__preferred_username=username
)
.select_related("actor")
.first()
)
data["local"] = {"following": False, "awaiting_approval": False}
try:
follow = models.Follow.objects.get(

View File

@ -1,6 +1,6 @@
import os
import uuid
import tempfile
import uuid
from django.conf import settings
from django.contrib.postgres.fields import JSONField

View File

@ -1,8 +1,8 @@
from django.conf import settings
from rest_framework.permissions import BasePermission
from funkwhale_api.common import preferences
from . import actors

View File

@ -1,23 +1,16 @@
import logging
import urllib.parse
from django.urls import reverse
from django.conf import settings
from django.core.paginator import Paginator
from django.db import transaction
from rest_framework import serializers
from dynamic_preferences.registries import global_preferences_registry
from funkwhale_api.common import utils as funkwhale_utils
from funkwhale_api.common import serializers as common_serializers
from funkwhale_api.common import utils as funkwhale_utils
from funkwhale_api.music import models as music_models
from funkwhale_api.music import tasks as music_tasks
from . import activity
from . import filters
from . import models
from . import utils
from . import activity, filters, models, utils
AP_CONTEXT = [
"https://www.w3.org/ns/activitystreams",
@ -341,7 +334,7 @@ class FollowSerializer(serializers.Serializer):
return models.Follow.objects.get_or_create(
actor=self.validated_data["actor"],
target=self.validated_data["object"],
**kwargs,
**kwargs, # noqa
)[0]
def to_representation(self, instance):
@ -352,7 +345,6 @@ class FollowSerializer(serializers.Serializer):
"object": instance.target.url,
"type": "Follow",
}
return ret
class APIFollowSerializer(serializers.ModelSerializer):
@ -687,7 +679,7 @@ class AudioSerializer(serializers.Serializer):
def validate_url(self, v):
try:
url = v["href"]
v["href"]
except (KeyError, TypeError):
raise serializers.ValidationError("Missing href")

View File

@ -1,9 +1,9 @@
import logging
import requests
import requests_http_signature
from . import exceptions
from . import utils
from . import exceptions, utils
logger = logging.getLogger(__name__)
@ -47,7 +47,7 @@ def verify_django(django_request, public_key):
v = request.headers[h]
if v:
request.headers[h] = str(v)
prepared_request = request.prepare()
request.prepare()
return verify(request, public_key)

View File

@ -6,19 +6,15 @@ import os
from django.conf import settings
from django.db.models import Q
from django.utils import timezone
from requests.exceptions import RequestException
from dynamic_preferences.registries import global_preferences_registry
from requests.exceptions import RequestException
from funkwhale_api.common import session
from funkwhale_api.history.models import Listening
from funkwhale_api.taskapp import celery
from . import actors
from . import library as lb
from . import models
from . import signing
from . import models, signing
logger = logging.getLogger(__name__)

View File

@ -1,6 +1,6 @@
from django.conf.urls import include, url
from rest_framework import routers
from . import views
router = routers.SimpleRouter(trailing_slash=False)

View File

@ -1,35 +1,28 @@
from django import forms
from django.conf import settings
from django.core import paginator
from django.db import transaction
from django.http import HttpResponse
from django.http import HttpResponse, Http404
from django.urls import reverse
from rest_framework import mixins
from rest_framework import permissions as rest_permissions
from rest_framework import response
from rest_framework import views
from rest_framework import viewsets
from rest_framework.decorators import list_route, detail_route
from rest_framework.serializers import ValidationError
from rest_framework import mixins, response, viewsets
from rest_framework.decorators import detail_route, list_route
from funkwhale_api.common import preferences
from funkwhale_api.common import utils as funkwhale_utils
from funkwhale_api.music import models as music_models
from funkwhale_api.users.permissions import HasUserPermission
from . import activity
from . import actors
from . import authentication
from . import filters
from . import library
from . import models
from . import permissions
from . import renderers
from . import serializers
from . import tasks
from . import utils
from . import webfinger
from . import (
actors,
authentication,
filters,
library,
models,
permissions,
renderers,
serializers,
tasks,
utils,
webfinger,
)
class FederationMixin(object):
@ -64,7 +57,7 @@ class InstanceActorViewSet(FederationMixin, viewsets.GenericViewSet):
handler = getattr(system_actor, "{}_inbox".format(request.method.lower()))
try:
data = handler(request.data, actor=request.actor)
handler(request.data, actor=request.actor)
except NotImplementedError:
return response.Response(status=405)
return response.Response({}, status=200)
@ -74,7 +67,7 @@ class InstanceActorViewSet(FederationMixin, viewsets.GenericViewSet):
system_actor = self.get_object()
handler = getattr(system_actor, "{}_outbox".format(request.method.lower()))
try:
data = handler(request.data, actor=request.actor)
handler(request.data, actor=request.actor)
except NotImplementedError:
return response.Response(status=405)
return response.Response({}, status=200)
@ -151,7 +144,7 @@ class MusicFilesViewSet(FederationMixin, viewsets.GenericViewSet):
else:
try:
page_number = int(page)
except:
except Exception:
return response.Response({"page": ["Invalid page number"]}, status=400)
p = paginator.Paginator(
qs, preferences.get("federation__collection_page_size")
@ -249,7 +242,7 @@ class LibraryViewSet(
def create(self, request, *args, **kwargs):
serializer = serializers.APILibraryCreateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
library = serializer.save()
serializer.save()
return response.Response(serializer.data, status=201)

View File

@ -1,12 +1,9 @@
from django import forms
from django.conf import settings
from django.urls import reverse
from funkwhale_api.common import session
from . import actors
from . import utils
from . import serializers
from . import actors, serializers
VALID_RESOURCE_TYPES = ["acct"]

View File

@ -1,5 +1,5 @@
from funkwhale_api.common import channels
from funkwhale_api.activity import record
from funkwhale_api.common import channels
from . import serializers

View File

@ -1,6 +1,5 @@
from django.utils import timezone
from django.db import models
from django.core.exceptions import ValidationError
from django.utils import timezone
from funkwhale_api.music.models import Track

View File

@ -1,8 +1,7 @@
from django.conf.urls import include, url
from . import views
from rest_framework import routers
from . import views
router = routers.SimpleRouter()
router.register(r"listenings", views.ListeningViewSet, "listenings")

View File

@ -1,14 +1,8 @@
from rest_framework import generics, mixins, viewsets
from rest_framework import permissions
from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import detail_route
from rest_framework import mixins, permissions, viewsets
from funkwhale_api.activity import record
from funkwhale_api.common.permissions import ConditionalAuthentication
from . import models
from . import serializers
from . import models, serializers
class ListeningViewSet(

View File

@ -1,5 +1,4 @@
from django.forms import widgets
from dynamic_preferences import types
from dynamic_preferences.registries import global_preferences_registry

View File

@ -5,14 +5,12 @@ from funkwhale_api.common import preferences
from . import stats
store = memoize.djangocache.Cache("default")
memo = memoize.Memoizer(store, namespace="instance:stats")
def get():
share_stats = preferences.get("instance__nodeinfo_stats_enabled")
private = preferences.get("instance__nodeinfo_private")
data = {
"version": "2.0",
"software": {"name": "funkwhale", "version": funkwhale_api.__version__},

View File

@ -1,16 +1,13 @@
from rest_framework import views
from rest_framework.response import Response
from dynamic_preferences.api import serializers
from dynamic_preferences.api import viewsets as preferences_viewsets
from dynamic_preferences.registries import global_preferences_registry
from rest_framework import views
from rest_framework.response import Response
from funkwhale_api.common import preferences
from funkwhale_api.users.permissions import HasUserPermission
from . import nodeinfo
from . import stats
NODEINFO_2_CONTENT_TYPE = "application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8" # noqa

View File

@ -1,4 +1,3 @@
from django.db.models import Count
from django_filters import rest_framework as filters

View File

@ -1,8 +1,8 @@
from django.conf.urls import include, url
from . import views
from rest_framework import routers
from . import views
library_router = routers.SimpleRouter()
library_router.register(r"track-files", views.ManageTrackFileViewSet, "track-files")

View File

@ -1,13 +1,10 @@
from rest_framework import mixins
from rest_framework import response
from rest_framework import viewsets
from rest_framework import mixins, response, viewsets
from rest_framework.decorators import list_route
from funkwhale_api.music import models as music_models
from funkwhale_api.users.permissions import HasUserPermission
from . import filters
from . import serializers
from . import filters, serializers
class ManageTrackFileViewSet(

View File

@ -1,7 +1,8 @@
import factory
import os
from funkwhale_api.factories import registry, ManyToManyFromList
import factory
from funkwhale_api.factories import ManyToManyFromList, registry
from funkwhale_api.federation.factories import LibraryTrackFactory
from funkwhale_api.users.factories import UserFactory

View File

@ -3,7 +3,6 @@ Populates the database with fake data
"""
import random
from funkwhale_api.music import models
from funkwhale_api.music import factories

View File

@ -1,8 +1,8 @@
from django.db.models import Count
from django_filters import rest_framework as filters
from funkwhale_api.common import fields
from . import models

View File

@ -1,5 +1,5 @@
import urllib.request
import html.parser
from bs4 import BeautifulSoup

View File

@ -1,10 +1,7 @@
import cacheops
import os
from django.core.management.base import BaseCommand
from django.db import transaction
from django.db.models import Q
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from funkwhale_api.music import models, utils
@ -70,8 +67,7 @@ class Command(BaseCommand):
try:
audio_file = tf.get_audio_file()
if audio_file:
with audio_file as f:
data = utils.get_audio_file_data(audio_file)
data = utils.get_audio_file_data(audio_file)
tf.bitrate = data["bitrate"]
tf.duration = data["length"]
tf.save(update_fields=["duration", "bitrate"])

View File

@ -1,6 +1,6 @@
from django import forms
import arrow
import mutagen
from django import forms
NODEFAULT = object()

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.db import migrations
import taggit.managers

View File

@ -3,7 +3,6 @@ from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
import versatileimagefield.fields
class Migration(migrations.Migration):

View File

@ -2,7 +2,6 @@
from __future__ import unicode_literals
from django.db import migrations, models
import versatileimagefield.fields
class Migration(migrations.Migration):

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
from django.db import migrations, models
from funkwhale_api.common.utils import rename_file
def rename_files(apps, schema_editor):

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.db import migrations
import versatileimagefield.fields

View File

@ -1,9 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
from django.db import migrations, models
from funkwhale_api.common.utils import rename_file
from django.db import migrations
def bind_jobs(apps, schema_editor):

View File

@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
from django.db import migrations, models
from django.db import migrations
from funkwhale_api.music.utils import guess_mimetype

View File

@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
from django.db import migrations, models
from django.db import migrations
def populate_status(apps, schema_editor):

View File

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import uuid
from django.db import migrations, models

View File

@ -1,30 +1,26 @@
import os
import io
import arrow
import datetime
import tempfile
import os
import shutil
import markdown
import tempfile
import uuid
import arrow
import markdown
from django.conf import settings
from django.db import models
from django.core.files.base import ContentFile
from django.core.files import File
from django.core.files.base import ContentFile
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.urls import reverse
from django.utils import timezone
from taggit.managers import TaggableManager
from versatileimagefield.fields import VersatileImageField
from funkwhale_api import downloader
from funkwhale_api import musicbrainz
from funkwhale_api import downloader, musicbrainz
from funkwhale_api.federation import utils as federation_utils
from . import importers
from . import metadata
from . import utils
from . import importers, metadata, utils
class APIModelMixin(models.Model):
@ -71,7 +67,7 @@ class APIModelMixin(models.Model):
try:
cleaned_key, cleaned_value = mapping.from_musicbrainz(key, value)
cleaned_data[cleaned_key] = cleaned_value
except KeyError as e:
except KeyError:
pass
return cleaned_data
@ -138,9 +134,7 @@ def import_tracks(instance, cleaned_data, raw_data):
track_cleaned_data = Track.clean_musicbrainz_data(track_data["recording"])
track_cleaned_data["album"] = instance
track_cleaned_data["position"] = int(track_data["position"])
track = importers.load(
Track, track_cleaned_data, track_data, Track.import_hooks
)
importers.load(Track, track_cleaned_data, track_data, Track.import_hooks)
class AlbumQuerySet(models.QuerySet):
@ -265,13 +259,13 @@ class Work(APIModelMixin):
import_hooks = [import_lyrics, link_recordings]
def fetch_lyrics(self):
l = self.lyrics.first()
if l:
return l
lyric = self.lyrics.first()
if lyric:
return lyric
data = self.api.get(self.mbid, includes=["url-rels"])["work"]
l = import_lyrics(self, {}, data)
lyric = import_lyrics(self, {}, data)
return l
return lyric
class Lyrics(models.Model):
@ -612,7 +606,7 @@ def update_request_status(sender, instance, created, **kwargs):
if not instance.import_request:
return
if not created and not "status" in update_fields:
if not created and "status" not in update_fields:
return
r_status = instance.import_request.status

View File

@ -1,10 +1,8 @@
from django.conf import settings
from rest_framework.permissions import BasePermission
from funkwhale_api.common import preferences
from funkwhale_api.federation import actors
from funkwhale_api.federation import models
from funkwhale_api.federation import actors, models
class Listen(BasePermission):

View File

@ -1,16 +1,11 @@
from django.db import transaction
from django.db.models import Q
from rest_framework import serializers
from taggit.models import Tag
from funkwhale_api.activity import serializers as activity_serializers
from funkwhale_api.federation import utils as federation_utils
from funkwhale_api.federation.models import LibraryTrack
from funkwhale_api.federation.serializers import AP_CONTEXT
from funkwhale_api.users.serializers import UserBasicSerializer
from . import models
from . import tasks
from . import models, tasks
class ArtistAlbumSerializer(serializers.ModelSerializer):

View File

@ -1,22 +1,19 @@
import logging
import os
from django.conf import settings
from django.core.files.base import ContentFile
from musicbrainzngs import ResponseError
from funkwhale_api.common import preferences
from funkwhale_api.federation import activity
from funkwhale_api.federation import actors
from funkwhale_api.federation import models as federation_models
from funkwhale_api.federation import activity, actors
from funkwhale_api.federation import serializers as federation_serializers
from funkwhale_api.taskapp import celery
from funkwhale_api.providers.acoustid import get_acoustid_client
from funkwhale_api.providers.audiofile import tasks as audiofile_tasks
from funkwhale_api.taskapp import celery
from django.conf import settings
from . import models
from . import lyrics as lyrics_utils
from . import models
from . import utils as music_utils
logger = logging.getLogger(__name__)
@ -259,7 +256,7 @@ def import_job_run(self, import_job, replace=False, use_acoustid=False):
if not settings.DEBUG:
try:
self.retry(exc=exc, countdown=30, max_retries=3)
except:
except Exception:
mark_errored(exc)
raise
mark_errored(exc)

View File

@ -1,8 +1,8 @@
import magic
import mimetypes
import mutagen
import re
import magic
import mutagen
from django.db.models import Q

View File

@ -1,46 +1,32 @@
import ffmpeg
import os
import json
import logging
import subprocess
import unicodedata
import urllib
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from django.db import models, transaction
from django.db.models.functions import Length
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.db.models import Count
from django.http import StreamingHttpResponse
from django.urls import reverse
from django.db.models.functions import Length
from django.utils import timezone
from django.utils.decorators import method_decorator
from rest_framework import viewsets, views, mixins
from musicbrainzngs import ResponseError
from rest_framework import mixins
from rest_framework import settings as rest_settings
from rest_framework import views, viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from rest_framework import settings as rest_settings
from rest_framework import permissions
from musicbrainzngs import ResponseError
from taggit.models import Tag
from funkwhale_api.common import utils as funkwhale_utils
from funkwhale_api.common.permissions import ConditionalAuthentication
from funkwhale_api.users.permissions import HasUserPermission
from taggit.models import Tag
from funkwhale_api.federation import actors
from funkwhale_api.federation.authentication import SignatureAuthentication
from funkwhale_api.federation.models import LibraryTrack
from funkwhale_api.musicbrainz import api
from funkwhale_api.requests.models import ImportRequest
from funkwhale_api.users.permissions import HasUserPermission
from . import filters
from . import importers
from . import models
from . import filters, importers, models
from . import permissions as music_permissions
from . import serializers
from . import tasks
from . import utils
from . import serializers, tasks, utils
logger = logging.getLogger(__name__)
@ -471,9 +457,7 @@ class SubmitViewSet(viewsets.ViewSet):
import_request = self.get_import_request(data)
artist_data = api.artists.get(id=data["artistId"])["artist"]
cleaned_data = models.Artist.clean_musicbrainz_data(artist_data)
artist = importers.load(
models.Artist, cleaned_data, artist_data, import_hooks=[]
)
importers.load(models.Artist, cleaned_data, artist_data, import_hooks=[])
import_data = []
batch = None

View File

@ -1 +1,3 @@
from .client import api
__all__ = ["api"]

View File

@ -1,7 +1,7 @@
import musicbrainzngs
import memoize.djangocache
import musicbrainzngs
from django.conf import settings
from funkwhale_api import __version__
_api = musicbrainzngs

View File

@ -1,4 +1,4 @@
from django.conf.urls import include, url
from django.conf.urls import url
from rest_framework import routers
from . import views

View File

@ -1,12 +1,10 @@
from rest_framework import viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.decorators import list_route
import musicbrainzngs
from rest_framework.response import Response
from rest_framework.views import APIView
from funkwhale_api.common.permissions import ConditionalAuthentication
from .client import api

View File

@ -1,12 +1,8 @@
from django.conf import settings
from django.db import models
from django.db import transaction
from django.db import models, transaction
from django.utils import timezone
from rest_framework import exceptions
from funkwhale_api.common import fields
from funkwhale_api.common import preferences
from funkwhale_api.common import fields, preferences
class PlaylistQuerySet(models.QuerySet):

View File

@ -1,12 +1,11 @@
from django.conf import settings
from django.db import transaction
from rest_framework import serializers
from taggit.models import Tag
from funkwhale_api.common import preferences
from funkwhale_api.music.models import Track
from funkwhale_api.music.serializers import TrackSerializer
from funkwhale_api.users.serializers import UserBasicSerializer
from . import models

View File

@ -1,20 +1,13 @@
from django.db.models import Count
from django.db import transaction
from rest_framework import exceptions
from rest_framework import generics, mixins, viewsets
from rest_framework import status
from django.db.models import Count
from rest_framework import exceptions, mixins, viewsets
from rest_framework.decorators import detail_route
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from funkwhale_api.common import permissions
from funkwhale_api.common import fields
from funkwhale_api.music.models import Track
from funkwhale_api.common import fields, permissions
from . import filters
from . import models
from . import serializers
from . import filters, models, serializers
class PlaylistViewSet(

View File

@ -1,7 +1,6 @@
from django import forms
from dynamic_preferences.types import StringPreference, Section
from dynamic_preferences.registries import global_preferences_registry
from dynamic_preferences.types import Section, StringPreference
acoustid = Section("providers_acoustid")

View File

@ -5,8 +5,7 @@ from django.conf import settings
from django.core.files import File
from django.core.management.base import BaseCommand, CommandError
from funkwhale_api.music import models
from funkwhale_api.music import tasks
from funkwhale_api.music import models, tasks
from funkwhale_api.users.models import User
@ -178,7 +177,6 @@ class Command(BaseCommand):
async = options["async"]
import_handler = tasks.import_job_run.delay if async else tasks.import_job_run
batch = user.imports.create(source="shell")
total = len(paths)
errors = []
for i, path in list(enumerate(paths)):
try:

View File

@ -1,12 +1,6 @@
import acoustid
import os
import datetime
from django.core.files import File
from django.db import transaction
from funkwhale_api.taskapp import celery
from funkwhale_api.providers.acoustid import get_acoustid_client
from funkwhale_api.music import models, metadata
from funkwhale_api.music import metadata, models
@transaction.atomic
@ -49,33 +43,3 @@ def import_track_data_from_path(path):
defaults={"title": data.get("title"), "position": position},
)[0]
return track
def import_metadata_with_musicbrainz(path):
pass
@celery.app.task(name="audiofile.from_path")
def from_path(path):
acoustid_track_id = None
try:
client = get_acoustid_client()
result = client.get_best_match(path)
acoustid_track_id = result["id"]
except acoustid.WebServiceError:
track = import_track_data_from_path(path)
except (TypeError, KeyError):
track = import_metadata_without_musicbrainz(path)
else:
track, created = models.Track.get_or_create_from_api(
mbid=result["recordings"][0]["id"]
)
if track.files.count() > 0:
raise ValueError("File already exists for track {}".format(track.pk))
track_file = models.TrackFile(track=track, acoustid_track_id=acoustid_track_id)
track_file.audio_file.save(os.path.basename(path), File(open(path, "rb")))
track_file.save()
return track_file

View File

@ -1,5 +1,4 @@
from django.conf.urls import include, url
from funkwhale_api.music import views
urlpatterns = [
url(

View File

@ -1,9 +1,6 @@
import threading
from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.tools import argparser
from dynamic_preferences.registries import global_preferences_registry as registry
YOUTUBE_API_SERVICE_NAME = "youtube"

View File

@ -1,7 +1,6 @@
from django import forms
from dynamic_preferences.types import StringPreference, Section
from dynamic_preferences.registries import global_preferences_registry
from dynamic_preferences.types import Section, StringPreference
youtube = Section("providers_youtube")

View File

@ -1,6 +1,6 @@
from django.conf.urls import include, url
from .views import APISearch, APISearchs
from django.conf.urls import url
from .views import APISearch, APISearchs
urlpatterns = [
url(r"^search/$", APISearch.as_view(), name="search"),

View File

@ -1,5 +1,6 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.views import APIView
from funkwhale_api.common.permissions import ConditionalAuthentication
from .client import client

View File

@ -1 +0,0 @@
from .registries import registry

View File

@ -24,7 +24,7 @@ class RadioSessionFactory(factory.django.DjangoModelFactory):
@registry.register(name="radios.CustomRadioSession")
class RadioSessionFactory(factory.django.DjangoModelFactory):
class CustomRadioSessionFactory(factory.django.DjangoModelFactory):
user = factory.SubFactory(UserFactory)
radio_type = "custom"
custom_radio = factory.SubFactory(

View File

@ -1,13 +1,11 @@
import collections
import persisting_theory
from django.core.exceptions import ValidationError
from django.db.models import Q
from django.urls import reverse_lazy
import persisting_theory
from funkwhale_api.music import models
from funkwhale_api.taskapp.celery import require_instance
class RadioFilterRegistry(persisting_theory.Registry):
@ -177,7 +175,6 @@ class TagFilter(RadioFilter):
"type": "list",
"subtype": "string",
"autocomplete": reverse_lazy("api:v1:tags-list"),
"autocomplete_qs": "",
"autocomplete_fields": {
"remoteValues": "results",
"name": "name",

View File

@ -1,10 +1,9 @@
from django.db import models
from django.utils import timezone
from django.core.exceptions import ValidationError
from django.contrib.postgres.fields import JSONField
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import JSONField
from django.core.serializers.json import DjangoJSONEncoder
from django.db import models
from django.utils import timezone
from funkwhale_api.music.models import Track
@ -77,7 +76,6 @@ class RadioSession(models.Model):
@property
def radio(self):
from .registries import registry
from . import radios
return registry[self.radio_type](session=self)

View File

@ -1,13 +1,14 @@
import random
from rest_framework import serializers
from django.db.models import Count
from django.core.exceptions import ValidationError
from taggit.models import Tag
from funkwhale_api.users.models import User
from funkwhale_api.music.models import Track, Artist
from . import filters
from . import models
from django.core.exceptions import ValidationError
from django.db.models import Count
from rest_framework import serializers
from taggit.models import Tag
from funkwhale_api.music.models import Artist, Track
from funkwhale_api.users.models import User
from . import filters, models
from .registries import registry
@ -147,7 +148,7 @@ class TagRadio(RelatedObjectRadio):
def get_queryset(self, **kwargs):
qs = super().get_queryset(**kwargs)
return Track.objects.filter(tags__in=[self.session.related_object])
return qs.filter(tags__in=[self.session.related_object])
@registry.register(name="artist")

View File

@ -3,8 +3,7 @@ from rest_framework import serializers
from funkwhale_api.music.serializers import TrackSerializer
from funkwhale_api.users.serializers import UserBasicSerializer
from . import filters
from . import models
from . import filters, models
from .radios import registry

View File

@ -1,8 +1,7 @@
from django.conf.urls import include, url
from . import views
from rest_framework import routers
from . import views
router = routers.SimpleRouter()
router.register(r"sessions", views.RadioSessionViewSet, "sessions")
router.register(r"radios", views.RadioViewSet, "radios")

View File

@ -1,19 +1,12 @@
from django.db.models import Q
from django.http import Http404
from rest_framework import generics, mixins, viewsets
from rest_framework import permissions
from rest_framework import status
from rest_framework.response import Response
from rest_framework import mixins, permissions, status, viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from funkwhale_api.music.serializers import TrackSerializer
from funkwhale_api.common.permissions import ConditionalAuthentication
from . import models
from . import filters
from . import filtersets
from . import serializers
from . import filters, filtersets, models, serializers
class RadioViewSet(
@ -108,7 +101,7 @@ class RadioSessionTrackViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet)
assert request.user == session.user
except AssertionError:
return Response(status=status.HTTP_403_FORBIDDEN)
track = session.radio.pick()
session.radio.pick()
session_track = session.session_tracks.all().latest("id")
# self.perform_create(serializer)
# dirty override here, since we use a different serializer for creation and detail

View File

@ -1,8 +1,7 @@
from django.conf.urls import include, url
from . import views
from rest_framework import routers
from . import views
router = routers.SimpleRouter()
router.register(r"import-requests", views.ImportRequestViewSet, "import-requests")

Some files were not shown because too many files have changed in this diff Show More