Umstellung auf natural sort

Hallo,

in use natural sort by freddy36 · Pull Request #296 · biologist79/ESPuino · GitHub wird die Sortierung von Dateien in Ordnern (Sowohl bei der Playlist Erzeugung, als auch im Web-Datei-Explorer) von einem einfachen strcmp() auf eine natürliche Sortierung umgebaut.
Aktuell müssen bei der Benennung der Dateien ggf. führende 0en genutzt werden, um die vermutlich gewünschte Sortierung zu erhalten.
Mit der Änderung würden Zahlen entsprechend Ihres für Menschen offensichtlichen Wertes sortiert.

Zur Verdeutlichung des Unterschiedes hier ein Beispiel:

standard strcmp() sort natural sort
Example title (Part 1).mp3 Example title (Part 1).mp3
Example title (Part 10).mp3 Example title (Part 2).mp3
Example title (Part 11).mp3 Example title (Part 3).mp3
Example title (Part 12).mp3 Example title (Part 4).mp3
Example title (Part 13).mp3 Example title (Part 5).mp3
Example title (Part 14).mp3 Example title (Part 6).mp3
Example title (Part 15).mp3 Example title (Part 7).mp3
Example title (Part 16).mp3 Example title (Part 8).mp3
Example title (Part 17).mp3 Example title (Part 9).mp3
Example title (Part 18).mp3 Example title (Part 10).mp3
Example title (Part 19).mp3 Example title (Part 11).mp3
Example title (Part 2).mp3 Example title (Part 12).mp3
Example title (Part 20).mp3 Example title (Part 13).mp3
Example title (Part 21).mp3 Example title (Part 14).mp3
Example title (Part 22).mp3 Example title (Part 15).mp3
Example title (Part 23).mp3 Example title (Part 16).mp3
Example title (Part 24).mp3 Example title (Part 17).mp3
Example title (Part 25).mp3 Example title (Part 18).mp3
Example title (Part 26).mp3 Example title (Part 19).mp3
Example title (Part 27).mp3 Example title (Part 20).mp3
Example title (Part 28).mp3 Example title (Part 21).mp3
Example title (Part 29).mp3 Example title (Part 22).mp3
Example title (Part 3).mp3 Example title (Part 23).mp3
Example title (Part 30).mp3 Example title (Part 24).mp3
Example title (Part 31).mp3 Example title (Part 25).mp3
Example title (Part 32).mp3 Example title (Part 26).mp3
Example title (Part 33).mp3 Example title (Part 27).mp3
Example title (Part 34).mp3 Example title (Part 28).mp3
Example title (Part 35).mp3 Example title (Part 29).mp3
Example title (Part 36).mp3 Example title (Part 30).mp3
Example title (Part 37).mp3 Example title (Part 31).mp3
Example title (Part 38).mp3 Example title (Part 32).mp3
Example title (Part 39).mp3 Example title (Part 33).mp3
Example title (Part 4).mp3 Example title (Part 34).mp3
Example title (Part 5).mp3 Example title (Part 35).mp3
Example title (Part 6).mp3 Example title (Part 36).mp3
Example title (Part 7).mp3 Example title (Part 37).mp3
Example title (Part 8).mp3 Example title (Part 38).mp3
Example title (Part 9).mp3 Example title (Part 39).mp3

Verwendet wird dieser Algorithmus/Bibliothek:

Der PR führ bei mir zu einer 464 Bytes größeren Firmware. Davon entfällt aber etwas mehr als die Hälfte auf den Kommentar in der management.html, was sich durch entsprechende Minification der Datei leicht wieder einsparen lassen würde.

Zusätzlicher HEAP Speicher wird nicht benötigt, der zusätzlich benötigte Stack Speicher dürfte vernachlässigbar sein.

Würde dies bei irgendjemand zu einer unerwarteten Sortierung von Dateien führen)?
Ist eine Konfigurierbarkeit des Features (settings.h oder zur Laufzeit/NVS) gewünscht?

EDIT2:
Umfrage zum bevorzugten Sortieralgorithmus:

  • egal, macht keinen Unterschied für mich
  • string vergleich (aktuell)
  • natürlich - Groß- und Kleinschreibung beachten
  • natürlich - Groß- und Kleinschreibung ignorieren
0 Teilnehmer

Und zur Konfigurierbarkeit:

  • fest im code
  • Konfigurierbar (settings.h)
  • Konfigurierbar (Webinterface)
0 Teilnehmer

Gute Idee, finde ich super.

Gerne per Settings Eintrag, dann kann jeder selber entscheiden und wir machen nix „kaputt“

Warum nicht die .c Datei bei uns aufnehmen? Statt eine Lib Verweis mehr? Das sollte in diesem Fall gut gehen…

So ist klar wo es herkommt, plötzliche Änderungen gibt es durch den fixen commit nicht. Ist mir am Ende des Tages aber egal.

Eine weitere Frage in dem Kontext: Aktuell erfolgt die Sortierung der playlists case-sensitive. Sollen wir es in dem Kontext auch direkt auf case-insensitive umstellen?

Würde dann ein #define PLAYLIST_SORT_FUNCTION strcmp/strnatcmp/strnatcasecmp einführen.

Also wenn wir das einführen als konfigurierbar, dann als Option im Webinterface. Wir reden immer mal wieder davon, dass wir die Komplexität der settings.h reduzieren wollen und welche Optionen man in’s Webinterface verschieben kann. Da fangen wir nicht an und beladen das noch mehr.

das Fass willst du auch noch aufmachen :wink:

Wie man da sieht sind sich nicht mal Windows (links) und Linux/WSL (rechts) da einig…

Ich meine hier gibt es einige Mac User, die sollten dann rechts haben…

Alternativer Vorschlag:
Erstmal fest für alle einführen, wenn jemand wirklich irgendein Namensschema hat was mit natural sort zu einer falschen Reinfolge führt (mir fällt spontan nichts halbwegs sinnvolles ein), bau ich gerne eine Option um es via Webinterface/NVS konfigurierbar zu machen.

Passend zum verwendeten FAT32 würde ich es dann auch case-insensitive machen.

Eija, vielleicht haben ja ein paar Leute eine Meinung dazu.
Für mich selbst ändert das nix - ich benenne Dateien eh immer so, dass mich Sortieralg. nicht „überraschen“ :grimacing:.

2 „Gefällt mir“

Hallo zusammen,

ich fände natural sort + case-insensitive am besten.

Ich finde die Idee mit natural sort gut. Für mich persönlich brauche ich es nicht (benenne meine Dateien auch entsprechend), aber für meinen Bekanntenkreis mit jetzt schon 5 ESPuino’s wäre das sicherlich eine Erleichterung.

Was wir aber definitiv anschauen / ausprobieren müssen ist, wie die Funktion/Library mit UTF-8 im Dateinamen umgeht. Sonst sehe ich keine Hürden.

Meine Stimme für Settings ist, vorerst direkt im Code und einstellbar machen, wenn jemand es braucht (dafür sollte die Änderung aber vorbereitet sein). D.h. gekapselter Code um die Änderung dann einfach durchführen zu können (habe mir die PR aber ehrlich noch nicht genau angeschaut :slight_smile: ). Ist überschaubar :+1:

Haben den initialen Post um zwei Umfragen erweitert, gerne dort mal abstimmen.

1 „Gefällt mir“

Habe es mit diversen Sonderzeichen Probiert, das funktioniert grundsätzlich. Die C Implementierung weis nichts von Unicode (genausowenig wie das aktuelle strcmp).

UTF-8 nutzt für alle Zeichen, welche mehr als 1 Byte benötigen, nur Werte >=128. Das isdigit() auf Bestandteile eines UTF-8 Zeichens anschlägt ist daher ausgeschlossen. Es sollte keine Unterschiede bei der Sortierung zum aktuellen strcmp() geben.

Beim sortieren für den Webinterface-Explorer wird localeCompare() verwendet, das ist entsprechend local/unicode aware und liefert entsprechend eine „korrektere“ natürliche Reinfolge. Dürfte in der Praxis aber nicht relevant sein (würde nur Leute betreffen, welche Unicode Zeichen nutzen um die Reinfolge von Dateien zu bestimmen).

1 „Gefällt mir“

Ich habe mal den PR getestet. Auch wenn ich diese Einstellung niemals verwenden werde finde ich die Umsetzung sehr gelungen. Die Einstellungen wird schlank über das bestehende System an die Weboberfläche übertragen:

Anmerkungen:

  • Nach dem Speichern gehen leider alle Batterieeinstellungen alle auf 0, siehe Foto. Damit wird das Batterie-Checkintervall bei jedem Durchlauf ausgelöst und flutet das Log (Das kann ich noch abfangen).
  • Die Benennung der Sortierungen könnte man noch etwas schöner machen (Habe jetzt keinen besseren Vorschlag), evt. die Default-Einstellung nach oben?

@freddy Insgesamt aber ein guter Wurf! So wie im PR gezeigt können wir viele #Defines durch Einstellung zur Laufzeit ersetzen.

3 „Gefällt mir“

Mein Vorschlag:

  • Standardsortierung
  • Natürlich: Groß- und Kleinschreibung beachten
  • Natürlich: Groß- und Kleinschreibung ignorieren

Und ja, der Standardwert nach oben.

Und oben als Überschrift:
Sortierungsmodus für Dateibrowser

Der Datei Browser ignoriert die Einstellung aktuell noch.
Das Bau ich noch ein.
Primär geht es auch um die Playlist (Abspiele von mehreren Dateien im Ordner).

Mit welchem Browser testest du?
Aufm Desktop mit Chrome kann ich das nicht reproduzieren.
Am code wurde auch nichts geändert.
Mir ist aber auch aufgefallen, das die ganzen Nummer Einstellungen als JSON String an den ESPuino geschickt werden. Eventuell ist das das Problem. Ist aber mindestens ineffizient auf ESPuino Seite. Das wollte ich noch in einem seperaten PR ändern.

Mit welchem Browser testest du?

Das war jetzt MS-Edge. Problem tritt mit aktuellem DEV nicht auf, dort werden die Batterieeinstellungen korrekt gespeichert & angezeigt.

@freddy Dir scheinen versehentlich diese Zeilen rausgefallen zu sein. Wenn die wieder drin sind klappt es auch mit den Batterieeinstellungen:

Ja, sorry ist bei mir lokal schon gefixt, aber wohl vergessen zu pushen

1 „Gefällt mir“

Pull Request ist nun aktualisiert.

localeCompare() wird nicht mehr verwendet, ein case-sensitive + natural compare ist damit nicht ohne größere workarounds möglich.

Habe es ersetzt mit der JavaScript-Version des Algorithmus, der auch im C++ Code genutzt wird.

Beim Ändern des Algorithmus werden die bereits geholten Explorer Einträge nicht automatisch neu sortiert, hoffe das ist eine Limitierung, mit der man leben kann.

2 „Gefällt mir“

Die Funktion ist jetzt mit 20240212-1-DEV eingebaut, Vielen Dank @freddy für die Arbeit!

grafik

2 „Gefällt mir“