Commit 2b0f7f6d authored by Agate's avatar Agate 💬

Merge branch '297-linting' into 'develop'

Resolve "Add some linting for Python code"

Closes #297

See merge request funkwhale/funkwhale!242
parents e953468e 7f5e9d64
...@@ -3,13 +3,39 @@ variables: ...@@ -3,13 +3,39 @@ variables:
IMAGE: $IMAGE_NAME:$CI_COMMIT_REF_NAME IMAGE: $IMAGE_NAME:$CI_COMMIT_REF_NAME
IMAGE_LATEST: $IMAGE_NAME:latest IMAGE_LATEST: $IMAGE_NAME:latest
PIP_CACHE_DIR: "$CI_PROJECT_DIR/pip-cache" PIP_CACHE_DIR: "$CI_PROJECT_DIR/pip-cache"
PYTHONDONTWRITEBYTECODE: "true"
stages: stages:
- lint
- test - test
- build - build
- deploy - 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: test_api:
services: services:
- postgres:9.4 - postgres:9.4
...@@ -108,7 +134,7 @@ pages: ...@@ -108,7 +134,7 @@ pages:
tags: tags:
- docker - docker
docker_develop: docker_release:
stage: deploy stage: deploy
before_script: before_script:
- docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD - docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD
...@@ -119,8 +145,9 @@ docker_develop: ...@@ -119,8 +145,9 @@ docker_develop:
- docker push $IMAGE - docker push $IMAGE
only: only:
- develop@funkwhale/funkwhale - develop@funkwhale/funkwhale
- tags@funkwhale/funkwhale
tags: tags:
- dind - docker-build
build_api: build_api:
# Simply publish a zip containing api/ directory # Simply publish a zip containing api/ directory
...@@ -135,19 +162,3 @@ build_api: ...@@ -135,19 +162,3 @@ build_api:
- tags@funkwhale/funkwhale - tags@funkwhale/funkwhale
- master@funkwhale/funkwhale - master@funkwhale/funkwhale
- develop@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
from django.conf.urls import include, url
from dynamic_preferences.api.viewsets import GlobalPreferencesViewSet
from rest_framework import routers from rest_framework import routers
from rest_framework.urlpatterns import format_suffix_patterns 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.activity import views as activity_views
from funkwhale_api.instance import views as instance_views
from funkwhale_api.music import views from funkwhale_api.music import views
from funkwhale_api.playlists import views as playlists_views from funkwhale_api.playlists import views as playlists_views
from funkwhale_api.subsonic.views import SubsonicViewSet 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 = routers.SimpleRouter()
router.register(r"settings", GlobalPreferencesViewSet, base_name="settings") router.register(r"settings", GlobalPreferencesViewSet, base_name="settings")
......
import django
import os import os
import django
from .routing import application # noqa
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
django.setup() django.setup()
from .routing import application
from django.conf.urls import url
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter from channels.routing import ProtocolTypeRouter, URLRouter
from django.conf.urls import url
from funkwhale_api.common.auth import TokenAuthMiddleware from funkwhale_api.common.auth import TokenAuthMiddleware
from funkwhale_api.instance import consumers from funkwhale_api.instance import consumers
application = ProtocolTypeRouter( application = ProtocolTypeRouter(
{ {
# Empty for now (http->django views is added by default) # Empty for now (http->django views is added by default)
......
...@@ -10,8 +10,9 @@ https://docs.djangoproject.com/en/dev/ref/settings/ ...@@ -10,8 +10,9 @@ https://docs.djangoproject.com/en/dev/ref/settings/
""" """
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from urllib.parse import urlsplit import datetime
import os from urllib.parse import urlparse, urlsplit
import environ import environ
from celery.schedules import crontab from celery.schedules import crontab
...@@ -21,7 +22,6 @@ ROOT_DIR = environ.Path(__file__) - 3 # (/a/b/myfile.py - 3 = /) ...@@ -21,7 +22,6 @@ ROOT_DIR = environ.Path(__file__) - 3 # (/a/b/myfile.py - 3 = /)
APPS_DIR = ROOT_DIR.path("funkwhale_api") APPS_DIR = ROOT_DIR.path("funkwhale_api")
env = environ.Env() env = environ.Env()
try: try:
env.read_env(ROOT_DIR.file(".env")) env.read_env(ROOT_DIR.file(".env"))
except FileNotFoundError: except FileNotFoundError:
...@@ -315,7 +315,6 @@ CACHE_DEFAULT = "redis://127.0.0.1:6379/0" ...@@ -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": env.cache_url("CACHE_URL", default=CACHE_DEFAULT)}
CACHES["default"]["BACKEND"] = "django_redis.cache.RedisCache" CACHES["default"]["BACKEND"] = "django_redis.cache.RedisCache"
from urllib.parse import urlparse
cache_url = urlparse(CACHES["default"]["LOCATION"]) cache_url = urlparse(CACHES["default"]["LOCATION"])
CHANNEL_LAYERS = { CHANNEL_LAYERS = {
...@@ -332,12 +331,12 @@ CACHES["default"]["OPTIONS"] = { ...@@ -332,12 +331,12 @@ CACHES["default"]["OPTIONS"] = {
} }
########## CELERY # CELERY
INSTALLED_APPS += ("funkwhale_api.taskapp.celery.CeleryConfig",) INSTALLED_APPS += ("funkwhale_api.taskapp.celery.CeleryConfig",)
CELERY_BROKER_URL = env( CELERY_BROKER_URL = env(
"CELERY_BROKER_URL", default=env("CACHE_URL", default=CACHE_DEFAULT) "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' %} # Location of root django.contrib.admin URL, use {% url 'admin:index' %}
# Your common stuff: Below this line define 3rd party library settings # Your common stuff: Below this line define 3rd party library settings
...@@ -351,8 +350,6 @@ CELERYBEAT_SCHEDULE = { ...@@ -351,8 +350,6 @@ CELERYBEAT_SCHEDULE = {
} }
} }
import datetime
JWT_AUTH = { JWT_AUTH = {
"JWT_ALLOW_REFRESH": True, "JWT_ALLOW_REFRESH": True,
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=7), "JWT_EXPIRATION_DELTA": datetime.timedelta(days=7),
......
...@@ -10,6 +10,7 @@ Local settings ...@@ -10,6 +10,7 @@ Local settings
from .common import * # noqa from .common import * # noqa
# DEBUG # DEBUG
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
DEBUG = env.bool("DJANGO_DEBUG", default=True) DEBUG = env.bool("DJANGO_DEBUG", default=True)
...@@ -49,10 +50,10 @@ INSTALLED_APPS += ("debug_toolbar",) ...@@ -49,10 +50,10 @@ INSTALLED_APPS += ("debug_toolbar",)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
TEST_RUNNER = "django.test.runner.DiscoverRunner" TEST_RUNNER = "django.test.runner.DiscoverRunner"
########## CELERY # CELERY
# In development, all tasks will be executed locally by blocking until the task returns # In development, all tasks will be executed locally by blocking until the task returns
CELERY_TASK_ALWAYS_EAGER = False CELERY_TASK_ALWAYS_EAGER = False
########## END CELERY # END CELERY
# Your local stuff: Below this line define 3rd party library settings # Your local stuff: Below this line define 3rd party library settings
......
...@@ -11,9 +11,6 @@ Production Configurations ...@@ -11,9 +11,6 @@ Production Configurations
""" """
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django.utils import six
from .common import * # noqa from .common import * # noqa
# SECRET CONFIGURATION # SECRET CONFIGURATION
......
...@@ -5,7 +5,6 @@ from django.conf import settings ...@@ -5,7 +5,6 @@ from django.conf import settings
from django.conf.urls import include, url from django.conf.urls import include, url
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.views.generic import TemplateView
from django.views import defaults as default_views from django.views import defaults as default_views
urlpatterns = [ urlpatterns = [
......
...@@ -15,11 +15,9 @@ framework. ...@@ -15,11 +15,9 @@ framework.
""" """
import os import os
from django.core.wsgi import get_wsgi_application from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise from whitenoise.django import DjangoWhiteNoise
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks # 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 # 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 # mod_wsgi daemon mode with each site in its own daemon process, or use
......
...@@ -4,8 +4,7 @@ from rest_framework.response import Response ...@@ -4,8 +4,7 @@ from rest_framework.response import Response
from funkwhale_api.common.permissions import ConditionalAuthentication from funkwhale_api.common.permissions import ConditionalAuthentication
from funkwhale_api.favorites.models import TrackFavorite from funkwhale_api.favorites.models import TrackFavorite
from . import serializers from . import serializers, utils
from . import utils
class ActivityViewSet(viewsets.GenericViewSet): class ActivityViewSet(viewsets.GenericViewSet):
......
from urllib.parse import parse_qs from urllib.parse import parse_qs
import jwt
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.utils.encoding import smart_text
from rest_framework import exceptions from rest_framework import exceptions
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication
from funkwhale_api.users.models import User from funkwhale_api.users.models import User
......
from django.utils.encoding import smart_text from django.utils.encoding import smart_text
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from rest_framework import exceptions from rest_framework import exceptions
from rest_framework_jwt import authentication from rest_framework_jwt import authentication
from rest_framework_jwt.settings import api_settings from rest_framework_jwt.settings import api_settings
......
from channels.generic.websocket import JsonWebsocketConsumer from channels.generic.websocket import JsonWebsocketConsumer
from funkwhale_api.common import channels from funkwhale_api.common import channels
......
import django_filters import django_filters
from django.db import models from django.db import models
from funkwhale_api.music import utils from funkwhale_api.music import utils
PRIVACY_LEVEL_CHOICES = [ PRIVACY_LEVEL_CHOICES = [
("me", "Only me"), ("me", "Only me"),
("followers", "Me and my followers"), ("followers", "Me and my followers"),
......
...@@ -41,7 +41,6 @@ class Command(BaseCommand): ...@@ -41,7 +41,6 @@ class Command(BaseCommand):
script["entrypoint"](self, **options) script["entrypoint"](self, **options)
def show_help(self): def show_help(self):
indentation = 4
self.stdout.write("") self.stdout.write("")
self.stdout.write("Available scripts:") self.stdout.write("Available scripts:")
self.stdout.write("Launch with: python manage.py <script_name>") self.stdout.write("Launch with: python manage.py <script_name>")
......
import operator import operator
from django.conf import settings
from django.http import Http404 from django.http import Http404
from rest_framework.permissions import BasePermission from rest_framework.permissions import BasePermission
from funkwhale_api.common import preferences from funkwhale_api.common import preferences
......
from django.conf import settings
from django import forms from django import forms
from django.conf import settings
from dynamic_preferences import serializers from dynamic_preferences import serializers, types
from dynamic_preferences import types
from dynamic_preferences.registries import global_preferences_registry from dynamic_preferences.registries import global_preferences_registry
......
from . import django_permissions_to_user_permissions
from . import test
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
Convert django permissions to user permissions in the database, Convert django permissions to user permissions in the database,
following the work done in #152. following the work done in #152.
""" """
from django.contrib.auth.models import Permission
from django.db.models import Q from django.db.models import Q
from funkwhale_api.users import models
from django.contrib.auth.models import Permission from funkwhale_api.users import models
mapping = { mapping = {
"dynamic_preferences.change_globalpreferencemodel": "settings", "dynamic_preferences.change_globalpreferencemodel": "settings",
......
...@@ -40,7 +40,6 @@ class ActionSerializer(serializers.Serializer): ...@@ -40,7 +40,6 @@ class ActionSerializer(serializers.Serializer):
return value return value
def validate_objects(self, value): def validate_objects(self, value):
qs = None
if value == "all": if value == "all":
return self.queryset.all().order_by("id") return self.queryset.all().order_by("id")
if type(value) in [list, tuple]: if type(value) in [list, tuple]:
......
import requests import requests
from django.conf import settings from django.conf import settings
import funkwhale_api import funkwhale_api
......
from urllib.parse import urlencode, parse_qs, urlsplit, urlunsplit
import os import os
import shutil import shutil
from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
from django.db import transaction from django.db import transaction
......
from .downloader import download from .downloader import download
__all__ = ["download"]
import os import os
import json
from urllib.parse import quote_plus
import youtube_dl import youtube_dl
from django.conf import settings from django.conf import settings
import glob
def download( def download(
......
from funkwhale_api.common import channels
from funkwhale_api.activity import record from funkwhale_api.activity import record
from funkwhale_api.common import channels
from . import serializers from . import serializers
......
import factory import factory
from funkwhale_api.factories import registry from funkwhale_api.factories import registry
from funkwhale_api.music.factories import TrackFactory from funkwhale_api.music.factories import TrackFactory
from funkwhale_api.users.factories import UserFactory from funkwhale_api.users.factories import UserFactory
......
from django.conf import settings
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
......
from django.conf import settings
from rest_framework import serializers from rest_framework import serializers
......
from django.conf.urls import include, url
from . import views
from rest_framework import routers from rest_framework import routers
from . import views
router = routers.SimpleRouter() router = routers.SimpleRouter()
router.register(r"tracks", views.TrackFavoriteViewSet, "tracks") router.register(r"tracks", views.TrackFavoriteViewSet, "tracks")
......
from rest_framework import generics, mixins, viewsets from rest_framework import mixins, status, viewsets
from rest_framework import status
from rest_framework.response import Response
from rest_framework import pagination
from rest_framework.decorators import list_route from rest_framework.decorators import list_route
from rest_framework.response import Response
from funkwhale_api.activity import record from funkwhale_api.activity import record
from funkwhale_api.music.models import Track
from funkwhale_api.common.permissions import ConditionalAuthentication from funkwhale_api.common.permissions import ConditionalAuthentication
from funkwhale_api.music.models import Track
from . import models from . import models, serializers
from . import serializers
class TrackFavoriteViewSet( class TrackFavoriteViewSet(
......
from . import serializers
from . import tasks
ACTIVITY_TYPES = [ ACTIVITY_TYPES = [
"Accept", "Accept",
"Add", "Add",
...@@ -52,9 +49,13 @@ OBJECT_TYPES = [ ...@@ -52,9 +49,13 @@ OBJECT_TYPES = [
def deliver(activity, on_behalf_of, to=[]): def deliver(activity, on_behalf_of, to=[]):
from . import tasks
return tasks.send.delay(activity=activity, actor_id=on_behalf_of.pk, to=to) return tasks.send.delay(activity=activity, actor_id=on_behalf_of.pk, to=to)
def accept_follow(follow): def accept_follow(follow):
from . import serializers
serializer = serializers.AcceptFollowSerializer(follow) serializer = serializers.AcceptFollowSerializer(follow)
return deliver(serializer.data, to=[follow.actor.url], on_behalf_of=follow.target) return deliver(serializer.data, to=[follow.actor.url], on_behalf_of=follow.target)
import datetime import datetime
import logging import logging
import uuid
import xml import xml
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django.urls import reverse