Quality filter for content frontent (#1469)

This commit is contained in:
petitminion 2024-07-16 18:58:15 +00:00
parent b50b5cb661
commit b59f71ef0f
6 changed files with 130 additions and 3 deletions

View File

@ -2,6 +2,7 @@ from dynamic_preferences import types
from dynamic_preferences.registries import global_preferences_registry
music = types.Section("music")
quality_filters = types.Section("quality_filters")
@global_preferences_registry.register
@ -76,3 +77,85 @@ class MbSyncTags(types.BooleanPreference):
"the track, artist and album objects."
)
default = False
# quality_filters section. Note that the default False is not applied in the fronted
# (the filter will onlyu be use if set to True)
@global_preferences_registry.register
class BitrateFilter(types.ChoicePreference):
show_in_api = True
section = quality_filters
name = "bitrate_filter"
verbose_name = "Upload Quality Filter"
default = "low"
choices = [
("low", "Allow all audio qualities"),
("medium", "Medium : Do not allow low quality"),
("high", "High : only allow high and very-high audio qualities"),
("very_high", "Very High : only allow very-high audio quality"),
]
help_text = (
"The main page content can be filtered based on audio quality. "
"This will exclude lower quality, higher qualities are never excluded. "
"Quality Table can be found in the docs."
)
field_kwargs = {"choices": choices, "required": False}
@global_preferences_registry.register
class HasMbid(types.BooleanPreference):
show_in_api = True
section = quality_filters
name = "has_mbid"
verbose_name = "Musicbrainz Ids filter"
help_text = "Should we filter out metadata without Musicbrainz Ids ?"
default = False
@global_preferences_registry.register
class Format(types.MultipleChoicePreference):
show_in_api = True
section = quality_filters
name = "format"
verbose_name = "Allowed Audio Format"
default = (["aac", "aif", "aiff", "flac", "mp3", "ogg", "opus"],)
choices = [
("ogg", "ogg"),
("opus", "opus"),
("flac", "flac"),
("aif", "aif"),
("aiff", "aiff"),
("aac", "aac"),
("mp3", "mp3"),
]
help_text = "Witch audio format to allow"
@global_preferences_registry.register
class AlbumArt(types.BooleanPreference):
show_in_api = True
section = quality_filters
name = "has_cover"
verbose_name = "Album art Filter"
help_text = "Only Albums with a cover will be displayed in the home page"
default = False
@global_preferences_registry.register
class Tags(types.BooleanPreference):
show_in_api = True
section = quality_filters
name = "has_tags"
verbose_name = "Tags Filter"
help_text = "Only content with at least one tag will be displayed"
default = False
@global_preferences_registry.register
class ReleaseDate(types.BooleanPreference):
show_in_api = True
section = quality_filters
name = "has_release_date"
verbose_name = "Release date Filter"
help_text = "Only content with a release date will be displayed"
default = False

View File

@ -0,0 +1 @@
Quality filter for content frontend (#1469)

View File

@ -1,6 +1,7 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { ref, computed } from 'vue'
import { useStore } from '~/store'
import axios from 'axios'
@ -20,6 +21,9 @@ withDefaults(defineProps<Props>(), {
scope: 'all'
})
const store = useStore()
const qualityFilters = computed(() => store.getters['instance/qualityFilters'])
const artists = ref([])
const logger = useLogger()
@ -63,7 +67,7 @@ fetchData()
<div class="column">
<track-widget
:url="'history/listenings/'"
:filters="{ scope, ordering: '-creation_date' }"
:filters="{ scope, ordering: '-creation_date', ...qualityFilters}"
:websocket-handlers="['Listen']"
>
<template #title>
@ -95,7 +99,7 @@ fetchData()
<div class="ui section hidden divider" />
<div class="ui stackable one column grid">
<div class="column">
<album-widget :filters="{scope: scope, playable: true, ordering: '-creation_date'}">
<album-widget :filters="{scope: scope, playable: true, ordering: '-creation_date', ...qualityFilters}">
<template #title>
{{ $t('components.library.Home.header.recentlyAdded') }}
</template>

View File

@ -3374,6 +3374,7 @@
"moderation": "Moderation",
"music": "Music",
"playlists": "Playlists",
"qualityFilters": "Explore page quality filters",
"sections": "Sections",
"security": "Security",
"settings": "Instance Settings",

View File

@ -104,6 +104,12 @@ interface ModerationSettings {
signup_approval_enabled: { value: boolean }
signup_form_customization: { value: null }
}
interface QualityFiltersSettings {
[key: string]: any;
bitrate_filter: { value: number }
has_mbid: { value: boolean }
}
interface SubsonicSettings {
enabled: { value: boolean }
@ -117,6 +123,7 @@ interface Settings {
instance: InstanceSettings
users: UsersSettings
moderation: ModerationSettings
quality_filters: QualityFiltersSettings
subsonic: SubsonicSettings
ui: UISettings
}
@ -189,6 +196,10 @@ const store: Module<State, RootState> = {
},
signup_form_customization: { value: null }
},
quality_filters: {
bitrate_filter: { value: 0 },
has_mbid: { value: false }
},
subsonic: {
enabled: {
value: true
@ -233,7 +244,22 @@ const store: Module<State, RootState> = {
},
url: (state) => new URL(state.instanceUrl ?? DEFAULT_INSTANCE_URL),
domain: (_state, getters) => getters.url.hostname,
defaultInstance: () => DEFAULT_INSTANCE_URL
defaultInstance: () => DEFAULT_INSTANCE_URL,
qualityFilters: (state) => {
const qualityFilters = state.settings.quality_filters
const filteredQualityFilters: Record<string, any> = {}
for (const key in qualityFilters) {
if (Object.prototype.hasOwnProperty.call(qualityFilters, key)) {
if (qualityFilters[key].value === false) {
continue
} else {
filteredQualityFilters[key] = qualityFilters[key].value
}
}
}
return filteredQualityFilters
}
},
actions: {
setUrl ({ commit }, url) {

View File

@ -61,6 +61,18 @@ const groups = computed(() => [
{ name: 'music__only_allow_musicbrainz_tagged_files' },
{ name: 'music__sync_musicbrainz_tags' },
{ name: 'music__musicbrainz_genre_update' }
]
},
{
label: t('views.admin.Settings.header.qualityFilters'),
id: 'qualityFilters',
settings: [
{ name: 'quality_filters__has_cover' },
{ name: 'quality_filters__has_tags' },
{ name: 'quality_filters__has_mbid' },
{ name: 'quality_filters__format' },
{ name: 'quality_filters__bitrate_filter' },
{ name: 'quality_filters__has_release_date' }
]
},