kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
Merge branch 'master' into develop
commit
2fefe14963
|
@ -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:
|
||||||
|
|
|
@ -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")
|
||||||
)
|
)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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"]()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Ensure tracks linked to skipped upload can be pruned (#1011)
|
|
@ -0,0 +1 @@
|
||||||
|
Added safeguard to ensure local uploads are never purged from cache (#1086)
|
|
@ -0,0 +1 @@
|
||||||
|
Fix playlist modal only listing 50 first playlists (#1087)
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue