Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
svfusion
funkwhale
Commits
20eaa5e6
Verified
Commit
20eaa5e6
authored
Dec 16, 2017
by
Eliot Berriot
Browse files
Merge branch 'release/0.2.5'
parents
142a8050
5ac9d261
Changes
58
Hide whitespace changes
Inline
Side-by-side
.gitlab-ci.yml
View file @
20eaa5e6
...
...
@@ -13,14 +13,22 @@ stages:
test_api
:
stage
:
test
image
:
funkwhale/funkwhale:base
variables
:
PIP_CACHE_DIR
:
"
$CI_PROJECT_DIR/pip-cache"
DATABASE_URL
:
"
sqlite://"
before_script
:
-
python3 -m venv --copies virtualenv
-
source virtualenv/bin/activate
-
cd api
-
pip install -r requirements/base.txt
-
pip install -r requirements/local.txt
-
pip install -r requirements/test.txt
script
:
-
pytest
variables
:
DATABASE_URL
:
"
sqlite://"
cache
:
key
:
"
$CI_JOB_NAME-$CI_COMMIT_REF_NAME"
paths
:
-
"
$CI_PROJECT_DIR/pip-cache"
tags
:
-
docker
...
...
CHANGELOG
View file @
20eaa5e6
...
...
@@ -2,10 +2,30 @@ Changelog
=========
0.2.
5
(
u
nreleased)
0.2.
6
(
U
nreleased)
------------------
0.2.5 (2017-12-15)
------------------
Features:
- Import: can now specify search template when querying import sources (#45)
- Login form: now redirect to previous page after login (#2)
- 404: a decent 404 template, at least (#48)
Bugfixes:
- Player: better handling of errors when fetching the audio file (#46)
- Csrf: default CSRF_TRUSTED_ORIGINS to ALLOWED_HOSTS to avoid Csrf issues on admin (#49)
Tech:
- Django 2 compatibility, lot of packages upgrades (#47)
0.2.4 (2017-12-14)
------------------
...
...
api/Dockerfile
View file @
20eaa5e6
...
...
@@ -8,7 +8,9 @@ COPY ./requirements.apt /requirements.apt
RUN
apt-get update
-qq
&&
grep
"^[^#;]"
requirements.apt | xargs apt-get
install
-y
COPY
./requirements /requirements
COPY
./requirements/base.txt /requirements
RUN
pip
install
-r
/requirements/base.txt
COPY
./requirements/production.txt /requirements
RUN
pip
install
-r
/requirements/production.txt
COPY
. /app
...
...
api/config/api_urls.py
View file @
20eaa5e6
...
...
@@ -25,22 +25,32 @@ v1_patterns = router.urls
v1_patterns
+=
[
url
(
r
'^providers/'
,
include
(
'funkwhale_api.providers.urls'
,
namespace
=
'providers'
)),
include
(
(
'funkwhale_api.providers.urls'
,
'providers'
),
namespace
=
'providers'
)),
url
(
r
'^favorites/'
,
include
(
'funkwhale_api.favorites.urls'
,
namespace
=
'favorites'
)),
include
(
(
'funkwhale_api.favorites.urls'
,
'favorites'
),
namespace
=
'favorites'
)),
url
(
r
'^search$'
,
views
.
Search
.
as_view
(),
name
=
'search'
),
url
(
r
'^radios/'
,
include
(
'funkwhale_api.radios.urls'
,
namespace
=
'radios'
)),
include
(
(
'funkwhale_api.radios.urls'
,
'radios'
),
namespace
=
'radios'
)),
url
(
r
'^history/'
,
include
(
'funkwhale_api.history.urls'
,
namespace
=
'history'
)),
include
(
(
'funkwhale_api.history.urls'
,
'history'
),
namespace
=
'history'
)),
url
(
r
'^users/'
,
include
(
'funkwhale_api.users.api_urls'
,
namespace
=
'users'
)),
include
(
(
'funkwhale_api.users.api_urls'
,
'users'
),
namespace
=
'users'
)),
url
(
r
'^token/'
,
jwt_views
.
obtain_jwt_token
),
url
(
r
'^token/refresh/'
,
jwt_views
.
refresh_jwt_token
),
]
urlpatterns
=
[
url
(
r
'^v1/'
,
include
(
v1_patterns
,
namespace
=
'v1'
))
url
(
r
'^v1/'
,
include
(
(
v1_patterns
,
'v1'
),
namespace
=
'v1'
))
]
api/config/settings/common.py
View file @
20eaa5e6
...
...
@@ -75,7 +75,7 @@ INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
# MIDDLEWARE CONFIGURATION
# ------------------------------------------------------------------------------
MIDDLEWARE
_CLASSES
=
(
MIDDLEWARE
=
(
# Make sure djangosecure.middleware.SecurityMiddleware is listed first
'django.contrib.sessions.middleware.SessionMiddleware'
,
'funkwhale_api.users.middleware.AnonymousSessionMiddleware'
,
...
...
api/config/settings/local.py
View file @
20eaa5e6
...
...
@@ -31,7 +31,7 @@ EMAIL_BACKEND = env('DJANGO_EMAIL_BACKEND',
# django-debug-toolbar
# ------------------------------------------------------------------------------
MIDDLEWARE
_CLASSES
+=
(
'debug_toolbar.middleware.DebugToolbarMiddleware'
,)
MIDDLEWARE
+=
(
'debug_toolbar.middleware.DebugToolbarMiddleware'
,)
# INTERNAL_IPS = ('127.0.0.1', '10.0.2.2',)
...
...
api/config/settings/production.py
View file @
20eaa5e6
...
...
@@ -36,7 +36,7 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
#
#
# # Make sure djangosecure.middleware.SecurityMiddleware is listed first
# MIDDLEWARE
_CLASSES
= SECURITY_MIDDLEWARE + MIDDLEWARE
_CLASSES
# MIDDLEWARE = SECURITY_MIDDLEWARE + MIDDLEWARE
#
# # set this to 60 seconds and then to 518400 when you can prove it works
# SECURE_HSTS_SECONDS = 60
...
...
@@ -55,6 +55,8 @@ SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Hosts/domain names that are valid for this site
# See https://docs.djangoproject.com/en/1.6/ref/settings/#allowed-hosts
ALLOWED_HOSTS
=
env
.
list
(
'DJANGO_ALLOWED_HOSTS'
)
CSRF_TRUSTED_ORIGINS
=
ALLOWED_HOSTS
# END SITE CONFIGURATION
INSTALLED_APPS
+=
(
"gunicorn"
,
)
...
...
api/config/settings/test.py
View file @
20eaa5e6
...
...
@@ -22,8 +22,8 @@ CACHES = {
'LOCATION'
:
''
}
}
INSTALLED_APPS
+=
(
'kombu.transport.django'
,)
BROKER_URL
=
'
django
://'
BROKER_URL
=
'
memory
://'
# TESTING
# ------------------------------------------------------------------------------
...
...
api/config/urls.py
View file @
20eaa5e6
...
...
@@ -10,9 +10,9 @@ from django.views import defaults as default_views
urlpatterns
=
[
# Django Admin, use {% url 'admin:index' %}
url
(
settings
.
ADMIN_URL
,
include
(
admin
.
site
.
urls
)
)
,
url
(
settings
.
ADMIN_URL
,
admin
.
site
.
urls
),
url
(
r
'^api/'
,
include
(
"config.api_urls"
,
namespace
=
"api"
)),
url
(
r
'^api/'
,
include
(
(
"config.api_urls"
,
'api'
),
namespace
=
"api"
)),
url
(
r
'^api/auth/'
,
include
(
'rest_auth.urls'
)),
url
(
r
'^api/auth/registration/'
,
include
(
'funkwhale_api.users.rest_auth_urls'
)),
url
(
r
'^accounts/'
,
include
(
'allauth.urls'
)),
...
...
api/funkwhale_api/__init__.py
View file @
20eaa5e6
# -*- coding: utf-8 -*-
__version__
=
'0.2.
4
'
__version__
=
'0.2.
5
'
__version_info__
=
tuple
([
int
(
num
)
if
num
.
isdigit
()
else
num
for
num
in
__version__
.
replace
(
'-'
,
'.'
,
1
).
split
(
'.'
)])
api/funkwhale_api/common/permissions.py
View file @
20eaa5e6
...
...
@@ -7,5 +7,5 @@ class ConditionalAuthentication(BasePermission):
def
has_permission
(
self
,
request
,
view
):
if
settings
.
API_AUTHENTICATION_REQUIRED
:
return
request
.
user
and
request
.
user
.
is_authenticated
()
return
request
.
user
and
request
.
user
.
is_authenticated
return
True
api/funkwhale_api/contrib/sites/migrations/0001_initial.py
View file @
20eaa5e6
...
...
@@ -25,7 +25,7 @@ class Migration(migrations.Migration):
'ordering'
:
(
'domain'
,),
},
managers
=
[
(
b
'objects'
,
django
.
contrib
.
sites
.
models
.
SiteManager
()),
(
'objects'
,
django
.
contrib
.
sites
.
models
.
SiteManager
()),
],
),
]
api/funkwhale_api/favorites/migrations/0001_initial.py
View file @
20eaa5e6
...
...
@@ -19,8 +19,8 @@ class Migration(migrations.Migration):
fields
=
[
(
'id'
,
models
.
AutoField
(
serialize
=
False
,
auto_created
=
True
,
verbose_name
=
'ID'
,
primary_key
=
True
)),
(
'creation_date'
,
models
.
DateTimeField
(
default
=
django
.
utils
.
timezone
.
now
)),
(
'track'
,
models
.
ForeignKey
(
related_name
=
'track_favorites'
,
to
=
'music.Track'
)),
(
'user'
,
models
.
ForeignKey
(
related_name
=
'track_favorites'
,
to
=
settings
.
AUTH_USER_MODEL
)),
(
'track'
,
models
.
ForeignKey
(
related_name
=
'track_favorites'
,
to
=
'music.Track'
,
on_delete
=
models
.
CASCADE
)),
(
'user'
,
models
.
ForeignKey
(
related_name
=
'track_favorites'
,
to
=
settings
.
AUTH_USER_MODEL
,
on_delete
=
models
.
CASCADE
)),
],
options
=
{
'ordering'
:
(
'-creation_date'
,),
...
...
api/funkwhale_api/favorites/models.py
View file @
20eaa5e6
...
...
@@ -5,8 +5,10 @@ from funkwhale_api.music.models import Track
class
TrackFavorite
(
models
.
Model
):
creation_date
=
models
.
DateTimeField
(
default
=
timezone
.
now
)
user
=
models
.
ForeignKey
(
'users.User'
,
related_name
=
'track_favorites'
)
track
=
models
.
ForeignKey
(
Track
,
related_name
=
'track_favorites'
)
user
=
models
.
ForeignKey
(
'users.User'
,
related_name
=
'track_favorites'
,
on_delete
=
models
.
CASCADE
)
track
=
models
.
ForeignKey
(
Track
,
related_name
=
'track_favorites'
,
on_delete
=
models
.
CASCADE
)
class
Meta
:
unique_together
=
(
'track'
,
'user'
)
...
...
api/funkwhale_api/favorites/tests/test_favorites.py
View file @
20eaa5e6
import
json
from
test_plus.test
import
TestCase
from
django.
core.urlresolver
s
import
reverse
from
django.
url
s
import
reverse
from
funkwhale_api.music.models
import
Track
,
Artist
from
funkwhale_api.favorites.models
import
TrackFavorite
...
...
api/funkwhale_api/history/migrations/0001_initial.py
View file @
20eaa5e6
...
...
@@ -20,8 +20,8 @@ class Migration(migrations.Migration):
(
'id'
,
models
.
AutoField
(
verbose_name
=
'ID'
,
primary_key
=
True
,
serialize
=
False
,
auto_created
=
True
)),
(
'end_date'
,
models
.
DateTimeField
(
null
=
True
,
blank
=
True
,
default
=
django
.
utils
.
timezone
.
now
)),
(
'session_key'
,
models
.
CharField
(
null
=
True
,
blank
=
True
,
max_length
=
100
)),
(
'track'
,
models
.
ForeignKey
(
related_name
=
'listenings'
,
to
=
'music.Track'
)),
(
'user'
,
models
.
ForeignKey
(
blank
=
True
,
null
=
True
,
related_name
=
'listenings'
,
to
=
settings
.
AUTH_USER_MODEL
)),
(
'track'
,
models
.
ForeignKey
(
related_name
=
'listenings'
,
to
=
'music.Track'
,
on_delete
=
models
.
CASCADE
)),
(
'user'
,
models
.
ForeignKey
(
blank
=
True
,
null
=
True
,
related_name
=
'listenings'
,
to
=
settings
.
AUTH_USER_MODEL
,
on_delete
=
models
.
CASCADE
)),
],
options
=
{
'ordering'
:
(
'-end_date'
,),
...
...
api/funkwhale_api/history/models.py
View file @
20eaa5e6
...
...
@@ -7,8 +7,14 @@ from funkwhale_api.music.models import Track
class
Listening
(
models
.
Model
):
end_date
=
models
.
DateTimeField
(
default
=
timezone
.
now
,
null
=
True
,
blank
=
True
)
track
=
models
.
ForeignKey
(
Track
,
related_name
=
"listenings"
)
user
=
models
.
ForeignKey
(
'users.User'
,
related_name
=
"listenings"
,
null
=
True
,
blank
=
True
)
track
=
models
.
ForeignKey
(
Track
,
related_name
=
"listenings"
,
on_delete
=
models
.
CASCADE
)
user
=
models
.
ForeignKey
(
'users.User'
,
related_name
=
"listenings"
,
null
=
True
,
blank
=
True
,
on_delete
=
models
.
CASCADE
)
session_key
=
models
.
CharField
(
max_length
=
100
,
null
=
True
,
blank
=
True
)
class
Meta
:
...
...
api/funkwhale_api/history/tests/factories.py
0 → 100644
View file @
20eaa5e6
import
factory
from
funkwhale_api.music.tests
import
factories
from
funkwhale_api.users.tests.factories
import
UserFactory
class
ListeningFactory
(
factory
.
django
.
DjangoModelFactory
):
user
=
factory
.
SubFactory
(
UserFactory
)
track
=
factory
.
SubFactory
(
factories
.
TrackFactory
)
class
Meta
:
model
=
'history.Listening'
api/funkwhale_api/history/tests/test_history.py
View file @
20eaa5e6
import
random
import
json
from
test_plus.test
import
TestCase
from
django.
core.urlresolver
s
import
reverse
from
django.
url
s
import
reverse
from
django.core.exceptions
import
ValidationError
from
django.utils
import
timezone
from
model_mommy
import
momm
y
from
funkwhale_api.music.tests.factories
import
TrackFactor
y
from
funkwhale_api.users.models
import
User
from
funkwhale_api.history
import
models
class
TestHistory
(
TestCase
):
def
setUp
(
self
):
...
...
@@ -17,12 +18,12 @@ class TestHistory(TestCase):
self
.
user
=
User
.
objects
.
create_user
(
username
=
'test'
,
email
=
'test@test.com'
,
password
=
'test'
)
def
test_can_create_listening
(
self
):
track
=
mommy
.
make
(
'music.Track'
)
track
=
TrackFactory
(
)
now
=
timezone
.
now
()
l
=
models
.
Listening
.
objects
.
create
(
user
=
self
.
user
,
track
=
track
)
def
test_anonymous_user_can_create_listening_via_api
(
self
):
track
=
mommy
.
make
(
'music.Track'
)
track
=
TrackFactory
(
)
url
=
self
.
reverse
(
'api:v1:history:listenings-list'
)
response
=
self
.
client
.
post
(
url
,
{
'track'
:
track
.
pk
,
...
...
@@ -34,7 +35,7 @@ class TestHistory(TestCase):
self
.
assertIsNotNone
(
listening
.
session_key
)
def
test_logged_in_user_can_create_listening_via_api
(
self
):
track
=
mommy
.
make
(
'music.Track'
)
track
=
TrackFactory
(
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
'test'
)
...
...
api/funkwhale_api/history/views.py
View file @
20eaa5e6
...
...
@@ -22,14 +22,14 @@ class ListeningViewSet(mixins.CreateModelMixin,
def
get_queryset
(
self
):
queryset
=
super
().
get_queryset
()
if
self
.
request
.
user
.
is_authenticated
()
:
if
self
.
request
.
user
.
is_authenticated
:
return
queryset
.
filter
(
user
=
self
.
request
.
user
)
else
:
return
queryset
.
filter
(
session_key
=
self
.
request
.
session
.
session_key
)
def
get_serializer_context
(
self
):
context
=
super
().
get_serializer_context
()
if
self
.
request
.
user
.
is_authenticated
()
:
if
self
.
request
.
user
.
is_authenticated
:
context
[
'user'
]
=
self
.
request
.
user
else
:
context
[
'session_key'
]
=
self
.
request
.
session
.
session_key
...
...
Prev
1
2
3
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment