- Ordner wie Tags (docs/library.md): folders.js zeichnet die Chip-Reihe, das Blatt „In Ordner …“ (Häkchen, Neuer Ordner) und „Ordner verwalten“ (umbenennen = zusammenlegen, löschen, Reihenfolge). E-Books: `folders` im verschlüsselten Meta, Reihenfolge in verschlüsselten Bibliotheks-Einstellungen (/books/prefs/). Podcasts/Hörbücher: PodcastFeed.folders (Migration 0021, übernimmt `folder`), /podcasts/folders/ (+rename, +delete). Blogs: Reihenfolge (/feeds/folders/order/). - Bibliothek (53-library.js): Kopf mit Suche, Sortierung, Raster/Liste und +; Chips Angefangen · Ungelesen · Gelesen · Ordner; eine „Weiterlesen“-Karte; Mehrfachauswahl (lange drücken). E-Ink und diora Reader beginnen als Liste. - Cover Ende-zu-Ende verschlüsselt (covers.js, /books/<id>/cover/): aus dem E-Book (EPUB-Coverbild, PDF Seite 1), 300 px, mit dem Nutzerschlüssel verschlüsselt, einmal hochgeladen; sparsam im Leerlauf, nie beim Lesen, nie auf E-Ink. - Bücher ohne Cover bekommen eins (gencover.js): Stichwörter aus Titel, Autor, Regal und Ordnern wählen ein Gestaltungskonzept (Konstruktivismus, Geometrie, Psyche, Wellen, Karte, Kosmos, Ornament, Botanik, Berge, Zellen, Raster, Schatten, Typo, sonst Bauhaus); ein Hash aus Titel und Autor Palette, Aufbau und Details – einzigartig, überall gleich, nichts gespeichert. - Hörbücher: Ordner-Chips statt Kacheln, „In Ordner …“ mit mehreren Ordnern. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
980 B
Python
32 lines
980 B
Python
# Generated by Django 6.1 on 2026-10-16 18:21
|
|
|
|
from django.db import migrations, models
|
|
|
|
|
|
def folder_to_folders(apps, schema_editor):
|
|
"""An audiobook's one folder becomes its first (and only) folder in the list."""
|
|
PodcastFeed = apps.get_model('podcasts', 'PodcastFeed')
|
|
for feed in PodcastFeed.objects.exclude(folder=''):
|
|
feed.folders = [feed.folder]
|
|
feed.save(update_fields=['folders'])
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
('podcasts', '0020_audiobook_folder'),
|
|
]
|
|
|
|
operations = [
|
|
migrations.AddField(
|
|
model_name='podcastfeed',
|
|
name='folders',
|
|
field=models.JSONField(blank=True, default=list),
|
|
),
|
|
migrations.AddField(
|
|
model_name='podcastsettings',
|
|
name='folder_order',
|
|
field=models.JSONField(blank=True, default=list),
|
|
),
|
|
migrations.RunPython(folder_to_folders, migrations.RunPython.noop),
|
|
]
|