Merge branch 'master' into develop

merge-requests/1094/merge
Agate 2020-05-07 14:25:10 +02:00
commit 2fefe14963
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 6B501DFD73514E14
11 zmienionych plików z 57 dodań i 12 usunięć

Wyświetl plik

@ -224,7 +224,7 @@ docker_release:
before_script: before_script:
- docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD - docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD
- cp -r front/dist api/frontend - cp -r front/dist api/frontend
- (if [ "$CI_COMMIT_REF_NAME" == "develop" ]; then ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8); fi); - (if [ "$CI_COMMIT_REF_NAME" == "develop" ] || [ "$CI_COMMIT_REF_NAME" == "master" ]; then ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8); fi);
script: script:
- if [[ ! -z "$CI_COMMIT_TAG" ]]; then (./docs/get-releases-json.py | scripts/is-docker-latest.py $CI_COMMIT_TAG -) && export DOCKER_LATEST_TAG="-t $IMAGE_LATEST" || export DOCKER_LATEST_TAG=; fi - if [[ ! -z "$CI_COMMIT_TAG" ]]; then (./docs/get-releases-json.py | scripts/is-docker-latest.py $CI_COMMIT_TAG -) && export DOCKER_LATEST_TAG="-t $IMAGE_LATEST" || export DOCKER_LATEST_TAG=; fi
- cd api - cd api
@ -233,6 +233,7 @@ docker_release:
- if [[ ! -z "$DOCKER_LATEST_TAG" ]]; then docker push $IMAGE_LATEST; fi - if [[ ! -z "$DOCKER_LATEST_TAG" ]]; then docker push $IMAGE_LATEST; fi
only: only:
- develop@funkwhale/funkwhale - develop@funkwhale/funkwhale
- master@funkwhale/funkwhale
- tags@funkwhale/funkwhale - tags@funkwhale/funkwhale
tags: tags:
- docker-build - docker-build
@ -246,7 +247,7 @@ docker_all_in_one_release:
BUILD_PATH: all_in_one BUILD_PATH: all_in_one
before_script: before_script:
- docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD - docker login -u $DOCKER_LOGIN -p $DOCKER_PASSWORD
- (if [ "$CI_COMMIT_REF_NAME" == "develop" ]; then ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8); fi); - (if [ "$CI_COMMIT_REF_NAME" == "develop" ] || [ "$CI_COMMIT_REF_NAME" == "master" ]; then ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8); fi);
script: script:
- if [[ ! -z "$CI_COMMIT_TAG" ]]; then (./docs/get-releases-json.py | scripts/is-docker-latest.py $CI_COMMIT_TAG -) && export DOCKER_LATEST_TAG="-t $ALL_IN_ONE_IMAGE_LATEST" || export DOCKER_LATEST_TAG=; fi - if [[ ! -z "$CI_COMMIT_TAG" ]]; then (./docs/get-releases-json.py | scripts/is-docker-latest.py $CI_COMMIT_TAG -) && export DOCKER_LATEST_TAG="-t $ALL_IN_ONE_IMAGE_LATEST" || export DOCKER_LATEST_TAG=; fi
- wget $ALL_IN_ONE_ARTIFACT_URL -O all_in_one.zip - wget $ALL_IN_ONE_ARTIFACT_URL -O all_in_one.zip
@ -261,6 +262,7 @@ docker_all_in_one_release:
- if [[ ! -z "$DOCKER_LATEST_TAG" ]]; then docker push $ALL_IN_ONE_IMAGE_LATEST; fi - if [[ ! -z "$DOCKER_LATEST_TAG" ]]; then docker push $ALL_IN_ONE_IMAGE_LATEST; fi
only: only:
- develop@funkwhale/funkwhale - develop@funkwhale/funkwhale
- master@funkwhale/funkwhale
- tags@funkwhale/funkwhale - tags@funkwhale/funkwhale
tags: tags:
- docker-build - docker-build
@ -275,7 +277,7 @@ build_api:
- api - api
script: script:
- rm -rf api/tests - rm -rf api/tests
- (if [ "$CI_COMMIT_REF_NAME" == "develop" ]; then ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8); fi); - (if [ "$CI_COMMIT_REF_NAME" == "develop" ] || [ "$CI_COMMIT_REF_NAME" == "master" ]; then ./scripts/set-api-build-metadata.sh $(echo $CI_COMMIT_SHA | cut -c 1-8); fi);
- chmod -R 750 api - chmod -R 750 api
- echo Done! - echo Done!
only: only:

Wyświetl plik

@ -50,6 +50,7 @@ def clean_music_cache():
) )
.local(False) .local(False)
.exclude(audio_file="") .exclude(audio_file="")
.filter(Q(source__startswith="http://") | Q(source__startswith="https://"))
.only("audio_file", "id") .only("audio_file", "id")
.order_by("id") .order_by("id")
) )

Wyświetl plik

@ -817,9 +817,15 @@ def get_prunable_tracks(
Returns a list of tracks with no associated uploads, Returns a list of tracks with no associated uploads,
excluding the one that were listened/favorited/included in playlists. excluding the one that were listened/favorited/included in playlists.
""" """
purgeable_tracks_with_upload = (
models.Upload.objects.exclude(track=None)
.filter(import_status="skipped")
.values("track")
)
queryset = models.Track.objects.all() queryset = models.Track.objects.all()
queryset = queryset.filter(uploads__isnull=True) queryset = queryset.filter(
Q(uploads__isnull=True) | Q(pk__in=purgeable_tracks_with_upload)
)
if exclude_favorites: if exclude_favorites:
queryset = queryset.filter(track_favorites__isnull=True) queryset = queryset.filter(track_favorites__isnull=True)
if exclude_playlists: if exclude_playlists:

Wyświetl plik

@ -16,20 +16,28 @@ def test_clean_federation_music_cache_if_no_listen(preferences, factories):
preferences["federation__music_cache_duration"] = 60 preferences["federation__music_cache_duration"] = 60
remote_library = factories["music.Library"]() remote_library = factories["music.Library"]()
upload1 = factories["music.Upload"]( upload1 = factories["music.Upload"](
library=remote_library, accessed_date=timezone.now() library=remote_library,
accessed_date=timezone.now(),
source="https://upload1.mp3",
) )
upload2 = factories["music.Upload"]( upload2 = factories["music.Upload"](
library=remote_library, library=remote_library,
accessed_date=timezone.now() - datetime.timedelta(minutes=61), accessed_date=timezone.now() - datetime.timedelta(minutes=61),
source="https://upload2.mp3",
)
upload3 = factories["music.Upload"](
library=remote_library, accessed_date=None, source="http://upload3.mp3"
) )
upload3 = factories["music.Upload"](library=remote_library, accessed_date=None)
# local upload, should not be cleaned # local upload, should not be cleaned
upload4 = factories["music.Upload"](library__actor__local=True, accessed_date=None) upload4 = factories["music.Upload"](library__actor__local=True, accessed_date=None)
# non-http source , not cleaned
upload5 = factories["music.Upload"](accessed_date=None, source="noop")
path1 = upload1.audio_file_path path1 = upload1.audio_file_path
path2 = upload2.audio_file_path path2 = upload2.audio_file_path
path3 = upload3.audio_file_path path3 = upload3.audio_file_path
path4 = upload4.audio_file_path path4 = upload4.audio_file_path
path5 = upload5.audio_file_path
tasks.clean_music_cache() tasks.clean_music_cache()
@ -37,15 +45,18 @@ def test_clean_federation_music_cache_if_no_listen(preferences, factories):
upload2.refresh_from_db() upload2.refresh_from_db()
upload3.refresh_from_db() upload3.refresh_from_db()
upload4.refresh_from_db() upload4.refresh_from_db()
upload5.refresh_from_db()
assert bool(upload1.audio_file) is True assert bool(upload1.audio_file) is True
assert bool(upload2.audio_file) is False assert bool(upload2.audio_file) is False
assert bool(upload3.audio_file) is False assert bool(upload3.audio_file) is False
assert bool(upload4.audio_file) is True assert bool(upload4.audio_file) is True
assert bool(upload5.audio_file) is True
assert os.path.exists(path1) is True assert os.path.exists(path1) is True
assert os.path.exists(path2) is False assert os.path.exists(path2) is False
assert os.path.exists(path3) is False assert os.path.exists(path3) is False
assert os.path.exists(path4) is True assert os.path.exists(path4) is True
assert os.path.exists(path5) is True
def test_clean_federation_music_cache_orphaned(settings, preferences, factories): def test_clean_federation_music_cache_orphaned(settings, preferences, factories):

Wyświetl plik

@ -867,6 +867,8 @@ def test_clean_transcoding_cache(preferences, now, factories):
def test_get_prunable_tracks(factories): def test_get_prunable_tracks(factories):
prunable_track = factories["music.Track"]() prunable_track = factories["music.Track"]()
# track is still prunable if it has a skipped upload linked to it
factories["music.Upload"](import_status="skipped", track=prunable_track)
# non prunable tracks # non prunable tracks
factories["music.Upload"]() factories["music.Upload"]()
factories["favorites.TrackFavorite"]() factories["favorites.TrackFavorite"]()

Wyświetl plik

@ -0,0 +1 @@
Ensure tracks linked to skipped upload can be pruned (#1011)

Wyświetl plik

@ -0,0 +1 @@
Added safeguard to ensure local uploads are never purged from cache (#1086)

Wyświetl plik

@ -0,0 +1 @@
Fix playlist modal only listing 50 first playlists (#1087)

Wyświetl plik

@ -38,7 +38,8 @@ FUNKWHALE_API_PORT=5000
# more concurrent requests, but also leads to higher CPU/Memory usage # more concurrent requests, but also leads to higher CPU/Memory usage
FUNKWHALE_WEB_WORKERS=1 FUNKWHALE_WEB_WORKERS=1
# Replace this by the definitive, public domain you will use for # Replace this by the definitive, public domain you will use for
# your instance # your instance. It cannot be changed after initial deployment
# without breaking your instance.
FUNKWHALE_HOSTNAME=yourdomain.funkwhale FUNKWHALE_HOSTNAME=yourdomain.funkwhale
FUNKWHALE_PROTOCOL=https FUNKWHALE_PROTOCOL=https

Wyświetl plik

@ -1,6 +1,19 @@
Installation Installation
============= =============
Requirements
------------
Regardless of your chosen installation method, the following requirements must be met in order to successfully deploy Funkwhale:
- **A dedicated domain or subdomain**: it is not possible to deploy Funkwhale on a subdirectory of an existing domain.
- **Access to ports 80 and/or 443**: if you cannot serve the Funkwhale web app and API on these ports, federation will not work
.. note::
Because of the federated nature of Funkwhale, **we strongly recommend you not to change the Funkwhale domain after initial deployment**, as it is likely to break
your installation.
Available installation methods Available installation methods
------------------------------- -------------------------------

Wyświetl plik

@ -25,14 +25,20 @@ export default {
} }
}, },
actions: { actions: {
fetchOwn ({commit, rootState}) { async fetchOwn ({commit, rootState}) {
let userId = rootState.auth.profile.id let userId = rootState.auth.profile.id
if (!userId) { if (!userId) {
return return
} }
return axios.get('playlists/', {params: {user: userId}}).then((response) => { let playlists = []
commit('playlists', response.data.results) let url = 'playlists/'
}) while (url != null) {
let response = await axios.get(url, {params: {user: userId}})
playlists = [...playlists, ...response.data.results]
url = response.data.next
}
commit('playlists', playlists)
} }
} }
} }