1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-09-18 18:31:04 +00:00

Add ignored articles support

Closes #200
This commit is contained in:
Alban Féron 2020-11-09 17:31:04 +01:00
parent 62ae4a9967
commit cec216684d
No known key found for this signature in database
GPG Key ID: 8CE0313646D16165
4 changed files with 59 additions and 11 deletions

View File

@ -1,5 +1,6 @@
[base]
; A database URI. See the 'schema' folder for schema creation scripts
; A database URI. See the 'schema' folder for schema creation scripts. Note that
; you don't have to run these scripts yourself.
; Default: sqlite:////tmp/supysonic/supysonic.db
;database_uri = sqlite:////var/supysonic/supysonic.db
;database_uri = mysql://supysonic:supysonic@localhost/supysonic
@ -35,6 +36,10 @@ log_level = WARNING
; Enable the administrative web interface. Default: on
;mount_webui = on
; Space separated list of prefixes that should be ignored on index endpoints
; Default: El La Le Las Les Los The
index_ignored_prefixes = El La Le Las Les Los The
[daemon]
; Socket file the daemon will listen on for incoming management commands
; Default: /tmp/supysonic/supysonic.sock

View File

@ -106,6 +106,12 @@ purposes. Defaults to `on`.
Note that setting this off will prevent users from defining a preferred
transcoding format. Defaults to `on`.
`index_ignored_prefixes`: space separated list of prefixes that should be
ignored from artist names when returning their index. Example: if the word _The_
is in this list, artist _The Rolling Stones_ will be listed under the letter _R_.
The match is case insensitive.
Defaults to `El La Le Las Les Los The`.
```ini
[webapp]
; Optional cache directory. Default: /tmp/supysonic
@ -130,6 +136,10 @@ log_level = WARNING
; Enable the administrative web interface. Default: on
;mount_webui = on
; Space separated list of prefixes that should be ignored on index endpoints
; Default: El La Le Las Les Los The
index_ignored_prefixes = El La Le Las Les Los The
```
## `[daemon]` section

View File

@ -5,10 +5,11 @@
#
# Distributed under terms of the GNU AGPLv3 license.
import re
import string
import uuid
from flask import request
from flask import current_app, request
from pony.orm import ObjectNotFound, select, count
from ..db import Folder, Artist, Album, Track
@ -29,6 +30,26 @@ def list_folders():
)
def build_ignored_articles_pattern():
articles = current_app.config["WEBAPP"]["index_ignored_prefixes"]
if articles is None:
return None
articles = articles.split()
if not articles:
return None
return r"^(" + r" |".join(re.escape(a) for a in articles) + r" )"
def ignored_articles_str():
articles = current_app.config["WEBAPP"]["index_ignored_prefixes"]
if articles is None:
return ""
return " ".join(articles.split())
@api.route("/getIndexes.view", methods=["GET", "POST"])
def list_indexes():
musicFolderId = request.values.get("musicFolderId")
@ -49,7 +70,10 @@ def list_indexes():
last_modif = max(map(lambda f: f.last_scan, folders))
if ifModifiedSince is not None and last_modif < ifModifiedSince:
return request.formatter(
"indexes", dict(lastModified=last_modif * 1000, ignoredArticles="")
"indexes",
dict(
lastModified=last_modif * 1000, ignoredArticles=ignored_articles_str()
),
)
# The XSD lies, we don't return artists but a directory structure
@ -60,8 +84,12 @@ def list_indexes():
children += f.tracks.select()[:]
indexes = dict()
pattern = build_ignored_articles_pattern()
for artist in artists:
index = artist.name[0].upper()
name = artist.name
if pattern:
name = re.sub(pattern, "", name, flags=re.I)
index = name[0].upper()
if index in string.digits:
index = "#"
elif index not in string.ascii_letters:
@ -70,19 +98,19 @@ def list_indexes():
if index not in indexes:
indexes[index] = []
indexes[index].append(artist)
indexes[index].append((artist, name))
return request.formatter(
"indexes",
dict(
lastModified=last_modif * 1000,
ignoredArticles="",
ignoredArticles=ignored_articles_str(),
index=[
dict(
name=k,
artist=[
a.as_subsonic_artist(request.user)
for a in sorted(v, key=lambda a: a.name.lower())
for a, _ in sorted(v, key=lambda t: t[1].lower())
],
)
for k, v in sorted(indexes.items())
@ -122,8 +150,12 @@ def list_genres():
def list_artists():
# According to the API page, there are no parameters?
indexes = dict()
pattern = build_ignored_articles_pattern()
for artist in Artist.select():
index = artist.name[0].upper() if artist.name else "?"
name = artist.name or "?"
if pattern:
name = re.sub(pattern, "", name, flags=re.I)
index = name[0].upper()
if index in string.digits:
index = "#"
elif index not in string.ascii_letters:
@ -132,18 +164,18 @@ def list_artists():
if index not in indexes:
indexes[index] = []
indexes[index].append(artist)
indexes[index].append((artist, name))
return request.formatter(
"artists",
dict(
ignoredArticles="",
ignoredArticles=ignored_articles_str(),
index=[
dict(
name=k,
artist=[
a.as_subsonic_artist(request.user)
for a in sorted(v, key=lambda a: a.name.lower())
for a, _ in sorted(v, key=lambda t: t[1].lower())
],
)
for k, v in sorted(indexes.items())

View File

@ -38,6 +38,7 @@ class DefaultConfig(object):
"log_level": "WARNING",
"mount_webui": True,
"mount_api": True,
"index_ignored_prefixes": "El La Le Las Les Los The",
}
DAEMON = {
"socket": r"\\.\pipe\supysonic"