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:
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
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")
......
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
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)
......
......@@ -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),
......
......@@ -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
......
......@@ -11,9 +11,6 @@ Production Configurations
"""
from __future__ import absolute_import, unicode_literals
from django.utils import six
from .common import * # noqa
# SECRET CONFIGURATION
......
......@@ -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 = [
......
......@@ -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
......
......@@ -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):
......
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
......
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
......
from channels.generic.websocket import JsonWebsocketConsumer
from funkwhale_api.common import channels
......
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"),
......
......@@ -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>")
......
import operator
from django.conf import settings
from django.http import Http404
from rest_framework.permissions import BasePermission
from funkwhale_api.common import preferences
......
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
......
from . import django_permissions_to_user_permissions
from . import test
......@@ -2,10 +2,10 @@
Convert django permissions to user permissions in the database,
following the work done in #152.
"""
from django.contrib.auth.models import Permission
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 = {
"dynamic_preferences.change_globalpreferencemodel": "settings",
......
......@@ -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]:
......
import requests
from django.conf import settings
import funkwhale_api
......
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
......
from .downloader import download
__all__ = ["download"]
import os
import json
from urllib.parse import quote_plus
import youtube_dl
from django.conf import settings
import glob
def download(
......
from funkwhale_api.common import channels
from funkwhale_api.activity import record
from funkwhale_api.common import channels
from . import serializers
......
import factory
from funkwhale_api.factories import registry
from funkwhale_api.music.factories import TrackFactory
from funkwhale_api.users.factories import UserFactory
......
from django.conf import settings
from django.db import models
from django.utils import timezone
......
from django.conf import settings
from rest_framework import serializers
......
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")
......
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(
......
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)
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",
......
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):
......
from django.forms import widgets
from dynamic_preferences import types
from dynamic_preferences.registries import global_preferences_registry
......
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")
......
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>.*)\"")
......
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