From 58abfd765a58e2f534ec0b2f0bec5c3867a8d39c Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Sun, 10 Mar 2024 12:57:46 +0100 Subject: [PATCH 01/28] Translate po/com.github.geigi.cozy.pot in es (#897) 100% translated source file: 'po/com.github.geigi.cozy.pot' on 'es'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- po/es.po | 903 ++++++++++++++++++++++--------------------------------- 1 file changed, 365 insertions(+), 538 deletions(-) diff --git a/po/es.po b/po/es.po index a93816b8..f8fce10b 100644 --- a/po/es.po +++ b/po/es.po @@ -7,41 +7,42 @@ # Julian Geywitz , 2019 # elgosz , 2020 # Adolfo Jayme-Barrientos, 2020 -# Jose Luis Tirado , 2021 -# Óscar Fernández Díaz , 2022 +# 3d8f3be0ee8144f79bb8d426275ac860_306eb54 <399766b5ab6702f5e3ef857abef0cf21_951974>, 2022 +# Jose Luis Tirado , 2024 +# Ezequiel Partida, 2024 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: com.github.geigi.cozy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-04 16:30+0100\n" +"POT-Creation-Date: 2024-02-17 20:33+0100\n" "PO-Revision-Date: 2019-09-08 09:31+0000\n" -"Last-Translator: Óscar Fernández Díaz , 2022\n" -"Language-Team: Spanish (https://www.transifex.com/geigi/teams/78138/es/)\n" +"Last-Translator: Ezequiel Partida, 2024\n" +"Language-Team: Spanish (https://app.transifex.com/geigi/teams/78138/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" -#: cozy/application.py:101 +#: cozy/application.py:59 msgid "Audiobooks" msgstr "Audiolibros" -#: cozy/control/offline_cache.py:200 +#: cozy/control/offline_cache.py:197 msgid "Copying" msgstr "Copiando" -#: cozy/media/files.py:69 +#: cozy/media/files.py:67 msgid "Cannot copy: Audiobook directory is read only" msgstr "No se pudo copiar: El directorio de audiolibros es de sólo lectura" -#: cozy/media/files.py:71 +#: cozy/media/files.py:69 msgid "Cannot copy: Disk is full" msgstr "No se pudo copiar: El disco está lleno" -#: cozy/media/files.py:73 cozy/media/files.py:89 +#: cozy/media/files.py:71 cozy/media/files.py:87 msgid "Cannot copy: Permission denied" msgstr "No se pudo copiar: Permiso denegado" @@ -49,16 +50,13 @@ msgstr "No se pudo copiar: Permiso denegado" msgid "Error while importing new files" msgstr "Error al importar nuevos archivos" -#: cozy/model/track.py:38 -msgid "Chapter" -msgstr "Capítulo" - #: cozy/tools.py:92 cozy/tools.py:96 #, python-brace-format msgid "{hours} hour" msgid_plural "{hours} hours" msgstr[0] "{hours} hora" msgstr[1] "{hours} horas" +msgstr[2] "{hours} horas" #: cozy/tools.py:94 cozy/tools.py:98 #, python-brace-format @@ -66,6 +64,7 @@ msgid "{minutes} minute" msgid_plural "{minutes} minutes" msgstr[0] "{minutes} minuto" msgstr[1] "{minutes} minutos" +msgstr[2] "{minutes} minutos" #: cozy/tools.py:100 #, python-brace-format @@ -73,6 +72,7 @@ msgid "{seconds} second" msgid_plural "{seconds} seconds" msgstr[0] "{seconds} segundo" msgstr[1] "{seconds} segundos" +msgstr[2] "{seconds} segundos" #: cozy/tools.py:102 msgid "finished" @@ -101,6 +101,7 @@ msgid "{weeks} week ago" msgid_plural "{weeks} weeks ago" msgstr[0] "Hace {weeks} semana" msgstr[1] "Hace {weeks} semanas" +msgstr[2] "Hace {weeks} semanas" #: cozy/tools.py:136 #, python-brace-format @@ -108,6 +109,7 @@ msgid "{months} month ago" msgid_plural "{months} months ago" msgstr[0] "Hace {months} mes" msgstr[1] "Hace {months} meses" +msgstr[2] "Hace {months} meses" #: cozy/tools.py:138 #, python-brace-format @@ -115,232 +117,289 @@ msgid "{years} year ago" msgid_plural "{years} years ago" msgstr[0] "Hace {years} año" msgstr[1] "Hace {years} años" +msgstr[2] "Hace {years} años" -#: cozy/ui/book_detail_view.py:313 +#: cozy/ui/book_detail_view.py:299 msgid "Downloaded" msgstr "Descargado" -#: cozy/ui/book_detail_view.py:316 data/ui/book_detail.ui:152 +#: cozy/ui/book_detail_view.py:302 data/ui/book_detail.ui:116 msgid "Download" msgstr "Descargar" -#: cozy/ui/chapter_element.py:27 -msgid "Play this part" -msgstr "Reproducir esta sección" +#: cozy/ui/db_migration_failed_view.py:6 +msgid "" +"During an update of the database an error occurred and Cozy will not be able" +" to startup. A backup of the database was created before the update and has " +"been restored now. Until this issue is resolved please use version 0.9.5 of " +"Cozy. You can help resolve this problem by reporting an issue on GitHub." +msgstr "" +"Durante una actualización de la base de datos se produjo un error y Cozy no " +"podrá iniciarse. Una copia de seguridad de la base de datos fué creada antes" +" de la actualización y ha sido restaurada. Hasta que se resuelva este " +"problema, utilice la versión 0.9.5 de Cozy. Puede ayudar a resolver este " +"problema informando un problema en GitHub." + +#: cozy/ui/db_migration_failed_view.py:15 +msgid "Failed to Update Database" +msgstr "No se pudo actualizar la base de datos" + +#: cozy/ui/db_migration_failed_view.py:22 +msgid "Close Cozy" +msgstr "Cerrar Cozy" + +#: cozy/ui/db_migration_failed_view.py:23 +msgid "Receive help on GitHub" +msgstr "Recibir ayuda en GitHub" + +#: cozy/ui/delete_book_view.py:13 +msgid "Delete Audiobook?" +msgstr "Borrar Audiolibro?" -#: cozy/ui/disk_element.py:27 +#: cozy/ui/delete_book_view.py:14 +msgid "The audiobook will be removed from your disk and from Cozy's library." +msgstr "El audiolibro será eliminado de tu disco y de la biblioteca de Cozy." + +#: cozy/ui/delete_book_view.py:21 cozy/ui/file_not_found_dialog.py:26 +msgid "Cancel" +msgstr "Cancelar" + +#: cozy/ui/delete_book_view.py:22 +msgid "Remove Audiobook" +msgstr "Remover Audiolibro" + +#: cozy/ui/disk_element.py:22 msgid "Disc" msgstr "Disco" -#: cozy/ui/file_not_found_dialog.py:56 -msgid "All files" -msgstr "Todos los archivos" +#: cozy/ui/file_not_found_dialog.py:18 +msgid "File not found" +msgstr "Archivo no encontrado" -#: cozy/ui/main_view.py:301 data/ui/main_window.ui:412 -msgid "Set Audiobooks Directory" -msgstr "Establecer carpeta de audiolibros" +#: cozy/ui/file_not_found_dialog.py:19 +msgid "This file could not be found. Do you want to locate it manually?" +msgstr "El archivo no se ha encontrado. ¿Quiere localizarlo manualmente?" -#: cozy/ui/warnings.py:27 cozy/ui/warnings.py:42 +#: cozy/ui/file_not_found_dialog.py:27 +msgid "Locate" +msgstr "Localizar" + +#: cozy/ui/file_not_found_dialog.py:38 +msgid "Locate Missing File" +msgstr "Localizar archivo faltante" + +#: cozy/ui/file_not_found_dialog.py:41 #, python-brace-format -msgid "{storage} is offline." -msgstr "{storage} no está disponible." +msgid "{ext} files" +msgstr "Archivos {ext}" + +#: cozy/ui/file_not_found_dialog.py:44 +msgid "Audio files" +msgstr "Archivos de sonido" + +#: cozy/ui/import_failed_dialog.py:8 +msgid "This can have multiple reasons:" +msgstr "Esto puede tener múltimples razones:" + +#: cozy/ui/import_failed_dialog.py:11 +msgid "The audio format is not supported" +msgstr "El formato de audio no es compatible" -#: cozy/ui/widgets/book_element.py:52 +#: cozy/ui/import_failed_dialog.py:12 +msgid "The path or filename contains non utf-8 characters" +msgstr "La ruta o el nombre del archivo contiene caracteres que no son utf-8" + +#: cozy/ui/import_failed_dialog.py:13 +msgid "The file(s) are no valid audio files" +msgstr "Los archivos no son archivos de audio válidos" + +#: cozy/ui/import_failed_dialog.py:14 +msgid "The file(s) are corrupt" +msgstr "El archivo está corrupto" + +#: cozy/ui/import_failed_dialog.py:28 +msgid "Some files could not be imported" +msgstr "Algunos archivos no pudieron importarse" + +#: cozy/ui/import_failed_dialog.py:35 +msgid "Ok" +msgstr "Aceptar" + +#: cozy/ui/main_view.py:198 +msgid "Patreon Supporters" +msgstr "Patrocinadores de Patreon" + +#: cozy/ui/main_view.py:202 +msgid "m4b chapter support in mutagen" +msgstr "soporte de capítulos m4b en mutágeno" + +#: cozy/ui/main_view.py:206 +msgid "Open Source Projects" +msgstr "Proyectos de código abierto" + +#. Translators: Replace "translator-credits" with your names, one name per +#. line +#: cozy/ui/main_view.py:211 +msgid "translator-credits" +msgstr "créditos-traductor" + +#: cozy/ui/widgets/book_element.py:70 msgid "Mark as read" msgstr "Marcar como leído" -#: cozy/ui/widgets/book_element.py:55 +#: cozy/ui/widgets/book_element.py:73 msgid "Open in file browser" msgstr "Abrir en explorador de archivos" -#: cozy/ui/widgets/book_element.py:58 +#: cozy/ui/widgets/book_element.py:76 msgid "Remove from library" msgstr "Eliminar de la biblioteca" -#: cozy/ui/widgets/error_reporting.py:12 +#: cozy/ui/widgets/book_row.py:25 +msgid "Play this book" +msgstr "Reproducir este libro" + +#: cozy/ui/widgets/error_reporting.py:11 msgid "Disabled" msgstr "Desactivado" -#: cozy/ui/widgets/error_reporting.py:13 +#: cozy/ui/widgets/error_reporting.py:12 msgid "Basic error reporting" msgstr "Informe de errores básico" -#: cozy/ui/widgets/error_reporting.py:14 +#: cozy/ui/widgets/error_reporting.py:13 msgid "Detailed error reporting" msgstr "Informe de errores detallado" -#: cozy/ui/widgets/error_reporting.py:15 data/ui/error_reporting.ui:240 +#: cozy/ui/widgets/error_reporting.py:14 data/ui/error_reporting.ui:162 msgid "Detailed error reporting with import errors" msgstr "Informe de errores detallado con errores de importación" -#: cozy/ui/widgets/error_reporting.py:19 +#: cozy/ui/widgets/error_reporting.py:18 msgid "No error or crash reporting." msgstr "Ningún informe de errores o cierres inesperados." -#: cozy/ui/widgets/error_reporting.py:20 data/ui/error_reporting.ui:259 +#: cozy/ui/widgets/error_reporting.py:19 data/ui/error_reporting.ui:174 msgid "The following information will be sent in case of an error or crash:" msgstr "La siguiente información será enviada en caso de fallo o error:" -#: cozy/ui/widgets/error_reporting.py:25 +#: cozy/ui/widgets/error_reporting.py:24 msgid "Which type of error occurred" msgstr "Que tipo de error se produjo" -#: cozy/ui/widgets/error_reporting.py:26 +#: cozy/ui/widgets/error_reporting.py:25 msgid "Line of code where an error occurred" msgstr "Línea de código donde se origino el error" -#: cozy/ui/widgets/error_reporting.py:27 +#: cozy/ui/widgets/error_reporting.py:26 msgid "Cozy's version" msgstr "Versión de Cozy" -#: cozy/ui/widgets/error_reporting.py:28 +#: cozy/ui/widgets/error_reporting.py:27 msgid "Linux distribution" msgstr "Distribución de Linux" -#: cozy/ui/widgets/error_reporting.py:29 +#: cozy/ui/widgets/error_reporting.py:28 msgid "Desktop environment" -msgstr "Ambiente de escritorio" +msgstr "Entorno de escritorio" -#: cozy/ui/widgets/error_reporting.py:30 +#: cozy/ui/widgets/error_reporting.py:29 msgid "Media type of files that Cozy couldn't import" msgstr "Tipos de archivos de medios que Cozy no pudo importar" -#: cozy/ui/widgets/filter_list_box.py:20 -#: cozy/view_model/library_view_model.py:54 -#: cozy/view_model/library_view_model.py:160 +#: cozy/ui/widgets/filter_list_box.py:18 +#: cozy/view_model/library_view_model.py:45 +#: cozy/view_model/library_view_model.py:135 msgid "All" msgstr "Todos" -#: cozy/ui/widgets/filter_list_box.py:21 +#: cozy/ui/widgets/filter_list_box.py:19 msgid "Display all books" msgstr "Mostrar todos los libros" -#: cozy/ui/widgets/search_results.py:73 -msgid "Jump to author " -msgstr "Ir al autor" - -#: cozy/ui/widgets/search_results.py:76 -msgid "Jump to reader " -msgstr "Ir al lector" - -#: cozy/ui/widgets/search_results.py:100 -msgid "Play this book" -msgstr "Reproducir este libro" +#: cozy/ui/widgets/search_results.py:13 +#, python-brace-format +msgid "Jump to {artist_name}" +msgstr "Saltar a {artist_name}" -#: cozy/ui/widgets/sleep_timer.py:60 data/ui/timer_popover.ui:66 +#: cozy/ui/widgets/sleep_timer.py:57 data/ui/timer_popover.ui:53 msgid "min" msgstr "min" -#: cozy/ui/widgets/sleep_timer.py:65 +#: cozy/ui/widgets/sleep_timer.py:62 msgid "Off" msgstr "Apagado" -#: cozy/ui/widgets/storage_list_box_row.py:70 data/ui/preferences.ui:377 +#: cozy/ui/widgets/storages.py:11 +msgid "Set Audiobooks Directory" +msgstr "Establecer carpeta de audiolibros" + +#: cozy/ui/widgets/storages.py:65 data/ui/storage_locations.ui:18 msgid "External drive" msgstr "Disco externo" -#: cozy/ui/widgets/storage_list_box_row.py:73 +#: cozy/ui/widgets/storages.py:68 msgid "Internal drive" msgstr "Disco interno" -#: cozy/view_model/headerbar_view_model.py:91 +#: cozy/view_model/headerbar_view_model.py:78 msgid "Refreshing audio book collection" msgstr "Refrescando la colección de audiolibros" -#: cozy/view_model/headerbar_view_model.py:100 -#: cozy/view_model/headerbar_view_model.py:116 +#: cozy/view_model/headerbar_view_model.py:87 +#: cozy/view_model/headerbar_view_model.py:103 msgid "Copying new files…" msgstr "Copiando nuevos archivos…" -#: cozy/view_model/headerbar_view_model.py:107 +#: cozy/view_model/headerbar_view_model.py:94 msgid "Changing audio book location…" msgstr "Cambiando ubicación del audiolibro..." -#: data/ui/about.ui:16 -msgid "GitHub" -msgstr "GitHub" - -#: data/ui/album_element.ui:104 +#: data/ui/album_element.ui:47 msgid "Play" msgstr "Reproducir" -#: data/ui/book_detail.ui:219 +#: data/ui/book_detail.ui:149 msgid "Remaining" msgstr "Restante" -#: data/ui/book_detail.ui:274 +#: data/ui/book_detail.ui:195 msgid "Total" msgstr "Total" -#: data/ui/book_detail.ui:290 +#: data/ui/book_detail.ui:208 msgid "Last played" msgstr "Última reproducción" -#: data/ui/book_detail.ui:306 +#: data/ui/book_detail.ui:221 msgid "Published" msgstr "Publicado" -#: data/ui/book_detail.ui:341 +#: data/ui/book_detail.ui:246 msgid "Some or all files of this book cannot be found." msgstr "No se pueden encontrar algunos o todos los archivos de este libro." -#: data/ui/book_detail.ui:364 +#: data/ui/book_detail.ui:259 msgid "unavailable" msgstr "no disponible" -#: data/ui/book_detail.ui:533 +#: data/ui/book_detail.ui:363 msgid "Loading chapters, please wait..." msgstr "Cargando capítulos, por favor espere..." -#: data/ui/book_element.ui:36 +#: data/ui/book_element.ui:10 msgid "Open book overview" msgstr "Abrir la sinopsis del libro" -#: data/ui/db_migration_failed.ui:31 -msgid "Close Cozy" -msgstr "Cerrar Cozy" - -#: data/ui/db_migration_failed.ui:47 -msgid "Receive help on GitHub" -msgstr "Recibir ayuda en GitHub" - -#: data/ui/db_migration_failed.ui:108 -msgid "An error occured while updating the database" -msgstr "Se ha producido un error al actualizar la base de datos" - -#: data/ui/db_migration_failed.ui:129 -msgid "" -"During an update of the database an error occurred and Cozy will not be able to startup.\n" -"A backup of the database was created before the update and has been restored now.\n" -"Until this issue is resolved please use version 0.9.5 of Cozy.\n" -"You can help resolve this problem by reporting an issue on GitHub." -msgstr "" -"Durante una actualización de la base de datos se ha producido un error y Cozy no podrá iniciarse.\n" -"Se creó una copia de seguridad de la base de datos antes de la actualización y se ha restaurado ahora.\n" -"Hasta que se resuelva este problema, por favor utilice la versión 0.9.5 de Cozy.\n" -"Puede ayudar a resolver este problema reportando un problema en GitHub." - -#: data/ui/delete_book_dialog.ui:31 data/ui/file_not_found.ui:19 -msgid "Cancel" -msgstr "Cancelar" - -#: data/ui/delete_book_dialog.ui:45 -msgid "Delete Audiobook" -msgstr "Eliminar audiolibro" - -#: data/ui/delete_book_dialog.ui:105 -msgid "Are you sure you want to delete the selected audiobook?" -msgstr "¿Estás seguro de que quieres eliminar el audiolibro seleccionado?" - -#: data/ui/delete_book_dialog.ui:126 -msgid "The audiobook will be removed from your disk and from Cozy's library." -msgstr "El audiolibro será eliminado de tu disco y de la biblioteca de Cozy." +#: data/ui/chapter_element.ui:5 +msgid "Play this part" +msgstr "Reproducir esta sección" -#: data/ui/error_reporting.ui:29 data/ui/preferences.ui:455 +#: data/ui/error_reporting.ui:24 data/ui/preferences.ui:124 msgid "User feedback" msgstr "Comentarios de usuario" -#: data/ui/error_reporting.ui:98 +#: data/ui/error_reporting.ui:67 msgctxt "Error and crash reporting dialog" msgid "" "You can help improve Cozy by contributing information in case of errors and " @@ -349,7 +408,7 @@ msgstr "" "Puedes ayudar a mejorar Cozy aportando información en caso de fallos y " "errores." -#: data/ui/error_reporting.ui:112 +#: data/ui/error_reporting.ui:75 msgctxt "Error and crash reporting dialog" msgid "" "Contributing this information is optional and completely anonymous. We will " @@ -360,386 +419,304 @@ msgstr "" "recolectaremos información personal, archivos que importaste o ninguna otra " "información que pudiera identificarte." -#: data/ui/error_reporting.ui:127 +#: data/ui/error_reporting.ui:84 msgctxt "Error and crash reporting dialog" msgid "" "Cozy is opensource and the user feedback source code can be inspected here: " msgstr "" "Cozy es código libre, el código y los comentarios de pueden leer aquí:" -#: data/ui/file_not_found.ui:32 -msgid "Locate" -msgstr "Localizar" +#. Translators: Don't touch the markup. Translate the text "Sourcecode on +#. GitHub" only! +#: data/ui/error_reporting.ui:94 +msgid "" +"Sourcecode" +" on GitHub" +msgstr "" +"Código " +"abierto en GitHub" -#: data/ui/file_not_found.ui:86 -msgid "File not found" -msgstr "Archivo no encontrado" +#: data/ui/first_import_button.ui:12 +msgid "Select Folder" +msgstr "Seleccionar Carpeta" -#: data/ui/file_not_found.ui:119 -msgid "This file could not be found. Do you want to locate it manually?" -msgstr "El archivo no se ha encontrado. ¿Quiere localizarlo manualmente?" +#: data/ui/headerbar.ui:17 +msgid "Toggle Filter Sidebar" +msgstr "Alternar el filtro de barra lateral" -#: data/ui/headerbar.ui:56 -msgid "Display background task progress" -msgstr "Mostrar el progreso de la tarea en segundo plano" +#: data/ui/headerbar.ui:22 +msgid "Options" +msgstr "Opciones" -#: data/ui/headerbar.ui:70 +#: data/ui/headerbar.ui:26 +msgid "Open the options popover" +msgstr "Abrir el cuadro de opciones" + +#: data/ui/headerbar.ui:33 msgid "Search your library" msgstr "Buscar en la biblioteca" -#: data/ui/headerbar.ui:80 -msgid "Search menu button" -msgstr "Botón de menú de búsqueda" - -#: data/ui/headerbar.ui:81 +#: data/ui/headerbar.ui:36 msgid "Open the search popover" msgstr "Abrir el cuadro de búsqueda" -#: data/ui/headerbar.ui:96 -msgid "Options" -msgstr "Opciones" +#: data/ui/headerbar.ui:44 +msgid "Display background task progress" +msgstr "Mostrar el progreso de la tarea en segundo plano" -#: data/ui/headerbar.ui:107 -msgid "Options menu button" -msgstr "Botón de menú de opciones" +#: data/ui/headerbar.ui:67 +msgid "Start typing..." +msgstr "Empiece a teclear..." -#: data/ui/headerbar.ui:108 -msgid "Open the options popover" -msgstr "Abrir el cuadro de opciones" +#: data/ui/headerbar.ui:80 +msgid "_Scan Library" +msgstr "Anali_zar biblioteca" -#: data/ui/import_failed.ui:27 -msgid "Ok" -msgstr "Aceptar" +#: data/ui/headerbar.ui:86 +msgid "_Hide unavailable books" +msgstr "_Ocultar libros no disponibles" -#: data/ui/import_failed.ui:81 -msgid "Some files could not be imported" -msgstr "Algunos archivos no pudieron importarse" +#: data/ui/headerbar.ui:92 +msgid "_Preferences" +msgstr "_Preferencias" -#: data/ui/import_failed.ui:134 -msgid "" -"This can have multiple reasons:\n" -"- The audio format is not supported\n" -"- The path or filename contains non utf-8 characters\n" -"- The file(s) are no valid audio files\n" -"- The file(s) are corrupt" -msgstr "" -"Puede deberse a varios motivos:\n" -"• No se admite el formato de audio\n" -"• La ruta o el nombre de archivo contiene caracteres no UTF-8\n" -"• Los archivos de audio no son válidos\n" -"• Los archivos están dañados" +#: data/ui/headerbar.ui:96 +msgid "_About Cozy" +msgstr "_Acerca de Cozy" + +#: data/ui/headerbar.ui:102 +msgid "_Quit" +msgstr "_Salir" + +#: data/ui/main_window.ui:26 +msgid "Drop Audio Books Here to Add Them to Your Library" +msgstr "Suelte aquí los audiolibros para añadirlos a su biblioteca" -#: data/ui/main_window.ui:68 +#: data/ui/main_window.ui:48 +msgid "Library" +msgstr "Biblioteca" + +#: data/ui/main_window.ui:65 msgid "Recent" msgstr "Reciente" -#: data/ui/main_window.ui:90 -msgid "List of authors" -msgstr "Lista de autores" - -#: data/ui/main_window.ui:106 data/ui/main_window.ui:250 -#: data/ui/search_popover.ui:107 +#: data/ui/main_window.ui:77 data/ui/search_page.ui:46 msgid "Author" msgstr "Autor" -#: data/ui/main_window.ui:128 -msgid "List of readers" -msgstr "Lista de lectores" +#: data/ui/main_window.ui:89 +msgid "List of authors" +msgstr "Lista de autores" -#: data/ui/main_window.ui:144 data/ui/search_popover.ui:201 +#: data/ui/main_window.ui:108 data/ui/search_page.ui:59 msgid "Reader" msgstr "Lector" -#: data/ui/main_window.ui:189 +#: data/ui/main_window.ui:120 +msgid "List of readers" +msgstr "Lista de lectores" + +#: data/ui/main_window.ui:172 msgid "List of books" msgstr "Lista de libros" -#: data/ui/main_window.ui:222 -msgid "" -"Start exploring your library by switching to the Author or Reader view." -msgstr "" -"Empiece a explorar su biblioteca cambiando a la vista de Autor o de Lector." +#: data/ui/main_window.ui:194 +msgid "No Recent Books Yet" +msgstr "Aún no hay audiolibros recientes" -#: data/ui/main_window.ui:280 -msgid "Stay tuned while Cozy is preparing your library…" -msgstr "Está atento mientras Cozy prepara tu biblioteca…" +#: data/ui/main_window.ui:195 +msgid "Explore your library by switching to the Author or Reader view" +msgstr "Explore su biblioteca cambiando a la vista Autor o Lector" -#: data/ui/main_window.ui:334 -msgid "Import your Audiobooks" -msgstr "Importe sus audiolibros" - -#: data/ui/main_window.ui:353 -msgid "" -"Cozy automatically imports your audiobooks in one directory - your library" -msgstr "" -"Cozy importa automáticamente sus audiolibros a un directorio: su biblioteca." - -#: data/ui/main_window.ui:385 -msgid "Drag & Drop" -msgstr "Arrastrar y soltar" - -#: data/ui/main_window.ui:387 -msgid "Drag your audiobooks into cozy and they will be automatically imported" -msgstr "Arrastre sus audiolibros a Cozy y se importarán automáticamente." +#: data/ui/media_controller.ui:48 +msgid "Currently playing" +msgstr "Ahora en reproducción" -#: data/ui/main_window.ui:414 -msgid "Load audiobooks from a directory, network drive or an external disk" -msgstr "" -"Cargar audiolibros desde un directorio, una unidad de red o un disco externo" +#: data/ui/media_controller.ui:65 +msgid "Title of currently playing book" +msgstr "Título del libro que se está reproduciendo" -#: data/ui/main_window.ui:417 -msgid "Select" -msgstr "Seleccionar" +#: data/ui/media_controller.ui:82 +msgid "Title of the currently playing part" +msgstr "Título de la sección que se está reproduciendo" -#: data/ui/media_controller.ui:64 data/ui/media_controller.ui:482 -#: data/ui/media_controller_big.ui:189 data/ui/media_controller_small.ui:70 +#: data/ui/media_controller.ui:111 msgid "Rewind" msgstr "Retroceder" -#: data/ui/media_controller.ui:71 data/ui/media_controller.ui:489 -#: data/ui/media_controller_big.ui:197 data/ui/media_controller_small.ui:77 -msgid "Rewind button" -msgstr "Retroceder" - -#: data/ui/media_controller.ui:72 data/ui/media_controller.ui:490 -#: data/ui/media_controller_big.ui:198 data/ui/media_controller_small.ui:78 +#: data/ui/media_controller.ui:116 msgid "Rewind playback" msgstr "Retroceder la reproducción" -#: data/ui/media_controller.ui:89 data/ui/media_controller.ui:507 -#: data/ui/media_controller_big.ui:220 data/ui/media_controller_small.ui:100 +#: data/ui/media_controller.ui:130 msgid "Start playback" msgstr "Reproducir" -#: data/ui/media_controller.ui:96 data/ui/media_controller.ui:514 -#: data/ui/media_controller_big.ui:228 data/ui/media_controller_small.ui:107 -msgid "Play/Pause Button" -msgstr "Botón de reproducción/pausa" - -#: data/ui/media_controller.ui:97 data/ui/media_controller.ui:515 -#: data/ui/media_controller_big.ui:229 data/ui/media_controller_small.ui:108 +#: data/ui/media_controller.ui:135 msgid "Start or pause the playback" msgstr "Iniciar o pausar la reproducción" -#: data/ui/media_controller.ui:113 data/ui/media_controller.ui:531 -#: data/ui/media_controller_big.ui:252 data/ui/media_controller_small.ui:131 +#: data/ui/media_controller.ui:148 msgid "Forward" msgstr "Avanzar" -#: data/ui/media_controller.ui:120 data/ui/media_controller.ui:538 -#: data/ui/media_controller_big.ui:260 data/ui/media_controller_small.ui:138 -msgid "Forward button" -msgstr "Botón de avance" - -#: data/ui/media_controller.ui:121 data/ui/media_controller.ui:539 -#: data/ui/media_controller_big.ui:261 data/ui/media_controller_small.ui:139 +#: data/ui/media_controller.ui:153 msgid "Forward Playback" msgstr "Botón de retroceso" -#: data/ui/media_controller.ui:175 data/ui/media_controller_big.ui:76 -msgid "Currently playing" -msgstr "Ahora en reproducción" - -#: data/ui/media_controller.ui:190 data/ui/media_controller_big.ui:97 -msgid "Booktitle" -msgstr "Título del libro" - -#: data/ui/media_controller.ui:191 data/ui/media_controller_big.ui:98 -msgid "Title of currently playing book" -msgstr "Título del libro que se está reproduciendo" - -#: data/ui/media_controller.ui:217 data/ui/media_controller_big.ui:126 -msgid "Part name" -msgstr "Nombre de la sección" - -#: data/ui/media_controller.ui:218 data/ui/media_controller_big.ui:127 -msgid "Title of the currently playing part" -msgstr "Título de la sección que se está reproduciendo" - -#: data/ui/media_controller.ui:256 data/ui/seek_bar.ui:20 -msgid "Elapsed time" -msgstr "Tiempo transcurrido" - -#: data/ui/media_controller.ui:264 data/ui/seek_bar.ui:28 -msgid "Time elapsed" -msgstr "Tiempo transcurrido" - -#: data/ui/media_controller.ui:265 data/ui/seek_bar.ui:29 -msgid "Elapsed time of current part" -msgstr "Tiempo transcurrido de la sección actual" - -#: data/ui/media_controller.ui:281 data/ui/seek_bar.ui:45 -msgid "Jump to position in current chapter" -msgstr "Saltar a la posición en el capítulo actual" - -#: data/ui/media_controller.ui:290 data/ui/seek_bar.ui:56 -msgid "Position slider" -msgstr "Deslizador de posición" - -#: data/ui/media_controller.ui:291 data/ui/seek_bar.ui:57 -msgid "Position of the current part in seconds" -msgstr "Posición de la sección actual en segundos" - -#: data/ui/media_controller.ui:310 data/ui/seek_bar.ui:76 -msgid "Remaining time" -msgstr "Tiempo restante" - -#: data/ui/media_controller.ui:317 data/ui/seek_bar.ui:83 -msgid "Time remaining" -msgstr "Tiempo restante" - -#: data/ui/media_controller.ui:318 data/ui/seek_bar.ui:84 -msgid "Remaining time of current part" -msgstr "Tiempo restante de la sección actual" - -#: data/ui/media_controller.ui:350 data/ui/media_controller_big.ui:324 +#: data/ui/media_controller.ui:179 msgid "Volume control" msgstr "Control de volumen" -#: data/ui/media_controller.ui:387 data/ui/media_controller.ui:572 -#: data/ui/media_controller_big.ui:367 data/ui/media_controller_small.ui:175 +#: data/ui/media_controller.ui:202 msgid "Playback speed" msgstr "Velocidad de reproducción" -#: data/ui/media_controller.ui:408 data/ui/media_controller_big.ui:394 -msgid "Sleep timer" -msgstr "Temporizador de apagado" - -#: data/ui/media_controller.ui:418 data/ui/media_controller_big.ui:404 -msgid "Timer menu button" -msgstr "Botón de temporizador de apagado" +#: data/ui/media_controller.ui:213 data/ui/preferences.ui:80 +msgid "Sleep Timer" +msgstr "Temporizador para dormir" -#: data/ui/media_controller.ui:419 data/ui/media_controller_big.ui:405 +#: data/ui/media_controller.ui:220 msgid "Open the sleep timer popover" msgstr "Abrir el cuadro del temporizador" -#: data/ui/media_controller_big.ui:53 -msgid "Open book" -msgstr "Abrir libro" - -#: data/ui/preferences.ui:55 +#: data/ui/preferences.ui:27 msgid "General" msgstr "General" -#: data/ui/preferences.ui:60 +#: data/ui/preferences.ui:30 msgid "Appearance" msgstr "Apariencia" -#: data/ui/preferences.ui:83 +#: data/ui/preferences.ui:33 +msgid "Dark Mode" +msgstr "Modo oscuro" + +#: data/ui/preferences.ui:40 msgid "Tags" msgstr "Etiquetas" -#: data/ui/preferences.ui:90 +#: data/ui/preferences.ui:43 +msgid "Swap Author and Reader" +msgstr "Intercambie entre autor y lector" + +#: data/ui/preferences.ui:44 msgid "Activate if author and reader are displayed the wrong way" msgstr "Activar si el autor y el lector se muestran de forma incorrecta" -#: data/ui/preferences.ui:107 +#: data/ui/preferences.ui:51 msgid "Playback" msgstr "Reproducción" -#: data/ui/preferences.ui:114 +#: data/ui/preferences.ui:54 +msgid "Replay" +msgstr "Reproducir" + +#: data/ui/preferences.ui:55 msgid "Rewind 30 seconds of the current book when starting Cozy" msgstr "Rebobinar 30 segundos del libro actual al iniciar Cozy" -#: data/ui/preferences.ui:172 -msgid "Sleep Timer" -msgstr "Temporizador para dormir" +#: data/ui/preferences.ui:60 +msgid "Rewind Duration" +msgstr "Duración de Rebobinado" + +#: data/ui/preferences.ui:69 +msgid "Forward Duration" +msgstr "Duración hacia adelante" + +#: data/ui/preferences.ui:83 +msgid "Fadeout" +msgstr "Desvanecimiento" -#: data/ui/preferences.ui:218 +#: data/ui/preferences.ui:88 +msgid "Fadeout Duration" +msgstr "Duración del Desvanecimiento" + +#: data/ui/preferences.ui:104 msgid "Storage" msgstr "Almacenamiento" -#: data/ui/preferences.ui:223 +#: data/ui/preferences.ui:107 msgid "Artwork" msgstr "Material gráfico" -#: data/ui/preferences.ui:230 +#: data/ui/preferences.ui:110 +msgid "Prefer External Images Over Embedded Cover" +msgstr "Preferir imágenes externas sobre portada incrustada" + +#: data/ui/preferences.ui:111 msgid "Always use images (cover.jpg, *.png, …) when available" msgstr "Use siempre imágenes (cover.jpg, *.png, …) cuando estén disponibles" -#: data/ui/preferences.ui:247 -msgid "Storage locations" -msgstr "Ubicaciones de almacenamiento" - -#: data/ui/preferences.ui:309 -msgid "Add location" -msgstr "Añadir ubicación" - -#: data/ui/preferences.ui:335 -msgid "Remove location" -msgstr "Eliminar ubicación" +#: data/ui/preferences.ui:121 +msgid "Feedback" +msgstr "Comentarios" -#: data/ui/preferences.ui:373 -msgid "Toggle this storage location to be internal/external." -msgstr "Alternar esta ubicación de almacenamiento entre interna y externa." +#: data/ui/search_page.ui:9 +msgid "Search in your library" +msgstr "Buscar en su biblioteca" -#: data/ui/preferences.ui:402 -msgid "Set as default storage location for new audiobooks" -msgstr "" -"Establecer como ubicación de almacenamiento predeterminada para nuevos " -"audiolibros" +#: data/ui/search_page.ui:15 +msgid "No results found" +msgstr "No se encontraron resultados" -#: data/ui/preferences.ui:406 -msgid "Set as default" -msgstr "Establecer como predeterminado" +#: data/ui/search_page.ui:33 +msgid "Book" +msgstr "Libro" -#: data/ui/preferences.ui:450 -msgid "Feedback" -msgstr "Comentarios" +#: data/ui/seek_bar.ui:15 +msgid "Elapsed time" +msgstr "Tiempo transcurrido" -#: data/ui/preferences.ui:460 -msgid "User Feedback" -msgstr "Comentarios de usuario" +#: data/ui/seek_bar.ui:21 +msgid "Elapsed time of current part" +msgstr "Tiempo transcurrido de la sección actual" -#: data/ui/search_popover.ui:24 -msgid "Search" -msgstr "Buscar" +#: data/ui/seek_bar.ui:32 +msgid "Jump to position in current chapter" +msgstr "Saltar a la posición en el capítulo actual" -#: data/ui/search_popover.ui:36 -msgid "Search box" -msgstr "Cuadro de búsqueda" +#: data/ui/seek_bar.ui:39 +msgid "Position of the current part in seconds" +msgstr "Posición de la sección actual en segundos" -#: data/ui/search_popover.ui:37 -msgid "Search your audiobook library" -msgstr "Buscar en su biblioteca de audiolibros" +#: data/ui/seek_bar.ui:48 +msgid "Remaining time" +msgstr "Tiempo restante" -#: data/ui/search_popover.ui:67 -msgid "Which book are you looking for?" -msgstr "¿Qué libro está buscando?" +#: data/ui/seek_bar.ui:53 +msgid "Remaining time of current part" +msgstr "Tiempo restante de la sección actual" -#: data/ui/search_popover.ui:154 -msgid "Book" -msgstr "Libro" +#: data/ui/storage_locations.ui:5 +msgid "Storage locations" +msgstr "Ubicaciones de almacenamiento" -#: data/ui/search_popover.ui:248 -msgid "Part" -msgstr "Sección" +#: data/ui/storage_locations.ui:24 +msgid "Set as default" +msgstr "Establecer como predeterminado" -#: data/ui/search_popover.ui:295 -msgid "Nothing found :(" -msgstr "No se ha encontrado nada :(" +#: data/ui/storage_locations.ui:28 +msgid "Remove" +msgstr "Remover" -#: data/ui/timer_popover.ui:37 +#: data/ui/timer_popover.ui:30 msgid "Timer duration" msgstr "Duración del temporizador" -#: data/ui/timer_popover.ui:49 -msgid "Timer duration slider" -msgstr "Deslizador del tiempo del temporizador" - -#: data/ui/timer_popover.ui:50 +#: data/ui/timer_popover.ui:40 msgid "Set the sleep timer duration in minutes" msgstr "Ajustar el temporizador de apagado en minutos" -#: data/ui/timer_popover.ui:116 +#: data/ui/timer_popover.ui:86 msgid "Stop after current chapter" msgstr "Parar tras el capítulo actual" -#: data/ui/timer_popover.ui:164 +#: data/ui/timer_popover.ui:107 msgid "Enable system power control" msgstr "Activar control de encendido del sistema" -#: data/ui/timer_popover.ui:201 +#: data/ui/timer_popover.ui:125 msgid "" "Type of the action when the timer finishes.\n" "\"shutdown\" will attempt to turn your system off (also known as power off)\n" @@ -749,164 +726,14 @@ msgstr "" "«apagar» intentará apagar el sistema.\n" "«suspender» intentará suspender el sistema (también se conoce como «dormir»)." -#: data/ui/timer_popover.ui:205 -msgid "" -"System power action\n" -"to perform" -msgstr "Acción ha realizar" +#: data/ui/timer_popover.ui:129 +msgid "System power action to perform" +msgstr "Acción de encendido del sistema a realizar" -#: data/ui/timer_popover.ui:221 +#: data/ui/timer_popover.ui:137 msgid "suspend" msgstr "suspender" -#: data/ui/timer_popover.ui:237 +#: data/ui/timer_popover.ui:143 msgid "shutdown" msgstr "apagar" - -#: data/ui/titlebar_menu.ui:7 -msgid "_Scan Library" -msgstr "Anali_zar biblioteca" - -#: data/ui/titlebar_menu.ui:13 -msgid "_Hide unavailable books" -msgstr "_Ocultar libros no disponibles" - -#: data/ui/titlebar_menu.ui:19 -msgid "_Preferences" -msgstr "_Preferencias" - -#: data/ui/titlebar_menu.ui:25 -msgid "_Help" -msgstr "Ay_uda" - -#: data/ui/titlebar_menu.ui:29 -msgid "_About" -msgstr "_Acerca de" - -#: data/ui/titlebar_menu.ui:33 -msgid "_Quit" -msgstr "_Salir" - -#: data/ui/welcome.ui:29 -msgid "Welcome!" -msgstr "¡Bienvenido/a!" - -#: data/ui/welcome.ui:46 -msgid "Add your audiobooks and let's get cozy." -msgstr "Añada sus audiolibros y pongámonos cómodos." - -#: data/ui/whats_new.ui:9 -msgid "Whats new?" -msgstr "¿Novedades?" - -#: data/ui/whats_new.ui:27 -msgid "Continue" -msgstr "Continuación" - -#: data/ui/whats_new_importer.ui:17 data/ui/whats_new_library.ui:17 -#: data/ui/whats_new_m4b.ui:17 data/ui/whats_new_m4b_chapter.ui:17 -msgid "What's new in Cozy" -msgstr "Novedades en Cozy" - -#: data/ui/whats_new_importer.ui:52 -msgid "A completely rewritten and far more reliable media importer." -msgstr "" -"Un importador de archivos completamente re-escrito y mucho más confiable." - -#: data/ui/whats_new_importer.ui:77 -msgid "" -"Did you experience audio files that couldn't be imported? Drag & Drop those " -"files onto Cozy or use the application menu in the titlebar to rescan your " -"audiobook directories!" -msgstr "" -"¿Te encontraste con algún archivo que no pudiste importar? ¡Puedes arrastrar" -" y soltar esos archivos en Cozy o usar el menú de la aplicación en la barra " -"de título para re-escanear tus directorios de audiolibros!" - -#: data/ui/whats_new_importer.ui:92 -msgid "Supported media files currently are mp3, m4a, flac, ogg, opus and wav." -msgstr "" -"Los archivos soportados actualmente son mp3, m4a, flac, ogg, opus y wav." - -#: data/ui/whats_new_importer.ui:107 -msgid "More to come in a later update." -msgstr "Más cosas en una actualización futura" - -#: data/ui/whats_new_library.ui:52 -msgid "An important change in library management" -msgstr "Un cambio importante en la gestión de las bibliotecas" - -#: data/ui/whats_new_library.ui:77 -msgid "" -"Previously every file which was imported in your library but couldn't be " -"found anymore was removed from the library during a scan." -msgstr "" -"Anteriormente, todos los archivos que se importaban en la biblioteca, pero " -"que ya no se podían encontrar, se eliminaban de la biblioteca durante una " -"exploración." - -#: data/ui/whats_new_library.ui:92 -msgid "" -"Now audiobooks are not removed from your library automatically anymore. This" -" prevents accidentally loosing the progress of a audiobook when a file can't" -" be found temporarily." -msgstr "" -"Ahora los audiolibros ya no se eliminan automáticamente de tu biblioteca. " -"Esto evita perder accidentalmente el progreso de un audiolibro cuando un " -"archivo no puede ser encontrado temporalmente." - -#: data/ui/whats_new_library.ui:107 -msgid "" -"To remove an audiobook from the library simply right-click on it and choose " -"the remove from library option." -msgstr "" -"Para eliminar un audiolibro de la biblioteca basta con hacer clic con el " -"botón derecho del ratón sobre él y elegir la opción de eliminar de la " -"biblioteca." - -#: data/ui/whats_new_m4b.ui:52 -msgid "Basic support for m4b audio books." -msgstr "Soporte básico para libros de audio m4b." - -#: data/ui/whats_new_m4b.ui:77 -msgid "" -"Many of you have been waiting for it: Support for m4b audio books! This " -"version features basic support for m4b files without chapter support." -msgstr "" -"Muchos lo han estado esperando: ¡Soporte para los audio libros de m4b! Esta " -"versión tiene soporte básico para archivos m4b sin soporte de capítulos." - -#: data/ui/whats_new_m4b.ui:92 -msgid "" -"Drag & Drop your m4b files onto Cozy or use the application menu in the " -"titlebar to rescan your audiobook directories." -msgstr "" -"Arrastra y suelta tus archivos m4b en Cozy o usa el menú de la aplicación en" -" la barra de título para volver a explorar tus directorios de audiolibros." - -#: data/ui/whats_new_m4b.ui:107 -msgid "Chapter support will follow in a later update. Stay tuned!" -msgstr "" -"El soporte para los capítulos se presentará en una actualización posterior. " -"¡Estén atentos!" - -#: data/ui/whats_new_m4b_chapter.ui:52 -msgid "Chapter support for m4b audio books." -msgstr "Compatibilidad con capítulos de audiolibros m4b." - -#: data/ui/whats_new_m4b_chapter.ui:77 -msgid "This version of Cozy features chapter support for m4b audio books!" -msgstr "" -"¡Esta versión de Cozy incluye soporte de capítulos para audiolibros m4b!" - -#: data/ui/whats_new_m4b_chapter.ui:92 -msgid "" -"If you already have m4b files imported you'll need to start a scan of your " -"library from the app menu." -msgstr "" -"Si ya tiene archivos m4b importados, tendrá que iniciar un análisis de su " -"biblioteca desde el menú de la aplicación." - -#: data/ui/whats_new_m4b_chapter.ui:107 -msgid "The chapters will then be detected." -msgstr "Entonces se detectarán los capítulos." From 6a1ca9715c8db9913baaec7aa26a8778563b408b Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Sun, 10 Mar 2024 12:59:55 +0100 Subject: [PATCH 02/28] Translate po/com.github.geigi.cozy.pot in fr (#893) 100% translated source file: 'po/com.github.geigi.cozy.pot' on 'fr'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- po/fr.po | 908 ++++++++++++++++++++++--------------------------------- 1 file changed, 365 insertions(+), 543 deletions(-) diff --git a/po/fr.po b/po/fr.po index fc5b6552..f6b60d78 100644 --- a/po/fr.po +++ b/po/fr.po @@ -5,44 +5,44 @@ # # Translators: # Charavner Louis , 2020 -# Thibault Martin , 2021 +# Thibault Martin, 2021 # e78dfa95e8487a60e89adc3a5c3879f2, 2021 # Trevor Clokie , 2021 -# Julian Geywitz , 2021 -# Irénée THIRION, 2022 +# Julian Geywitz , 2024 +# renecoty, 2024 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: com.github.geigi.cozy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-04 16:30+0100\n" +"POT-Creation-Date: 2024-02-17 20:33+0100\n" "PO-Revision-Date: 2019-09-08 09:31+0000\n" -"Last-Translator: Irénée THIRION, 2022\n" -"Language-Team: French (https://www.transifex.com/geigi/teams/78138/fr/)\n" +"Last-Translator: renecoty, 2024\n" +"Language-Team: French (https://app.transifex.com/geigi/teams/78138/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Plural-Forms: nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;\n" -#: cozy/application.py:101 +#: cozy/application.py:59 msgid "Audiobooks" msgstr "Livres audio" -#: cozy/control/offline_cache.py:200 +#: cozy/control/offline_cache.py:197 msgid "Copying" msgstr "Copie en cours" -#: cozy/media/files.py:69 +#: cozy/media/files.py:67 msgid "Cannot copy: Audiobook directory is read only" msgstr "Copie impossible : le répertoire Audiobook est en lecture seule" -#: cozy/media/files.py:71 +#: cozy/media/files.py:69 msgid "Cannot copy: Disk is full" msgstr "Copie impossible : stockage plein" -#: cozy/media/files.py:73 cozy/media/files.py:89 +#: cozy/media/files.py:71 cozy/media/files.py:87 msgid "Cannot copy: Permission denied" msgstr "Copie impossible : permission refusée" @@ -50,16 +50,13 @@ msgstr "Copie impossible : permission refusée" msgid "Error while importing new files" msgstr "Erreur dans l'importation de nouveaux fichiers" -#: cozy/model/track.py:38 -msgid "Chapter" -msgstr "Chapitre" - #: cozy/tools.py:92 cozy/tools.py:96 #, python-brace-format msgid "{hours} hour" msgid_plural "{hours} hours" msgstr[0] "{hours} heure" msgstr[1] "{hours} heures" +msgstr[2] "{hours} heures" #: cozy/tools.py:94 cozy/tools.py:98 #, python-brace-format @@ -67,6 +64,7 @@ msgid "{minutes} minute" msgid_plural "{minutes} minutes" msgstr[0] "{minutes} minute" msgstr[1] "{minutes} minutes" +msgstr[2] "{minutes} minutes" #: cozy/tools.py:100 #, python-brace-format @@ -74,6 +72,7 @@ msgid "{seconds} second" msgid_plural "{seconds} seconds" msgstr[0] "{seconds} seconde" msgstr[1] "{seconds} secondes" +msgstr[2] "{seconds} secondes" #: cozy/tools.py:102 msgid "finished" @@ -102,6 +101,7 @@ msgid "{weeks} week ago" msgid_plural "{weeks} weeks ago" msgstr[0] "Il y a {weeks} semaine" msgstr[1] "Il y a {weeks} semaines" +msgstr[2] "Il y a {weeks} semaines" #: cozy/tools.py:136 #, python-brace-format @@ -109,6 +109,7 @@ msgid "{months} month ago" msgid_plural "{months} months ago" msgstr[0] "Il y a {months} mois" msgstr[1] "Il y a {months} mois" +msgstr[2] "Il y a {months} mois" #: cozy/tools.py:138 #, python-brace-format @@ -116,234 +117,291 @@ msgid "{years} year ago" msgid_plural "{years} years ago" msgstr[0] "Il y a {years} an" msgstr[1] "Il y a {years} ans" +msgstr[2] "Il y a {years} ans" -#: cozy/ui/book_detail_view.py:313 +#: cozy/ui/book_detail_view.py:299 msgid "Downloaded" msgstr "Téléchargement terminé" -#: cozy/ui/book_detail_view.py:316 data/ui/book_detail.ui:152 +#: cozy/ui/book_detail_view.py:302 data/ui/book_detail.ui:116 msgid "Download" msgstr "Télécharger" -#: cozy/ui/chapter_element.py:27 -msgid "Play this part" -msgstr "Lire cette partie" +#: cozy/ui/db_migration_failed_view.py:6 +msgid "" +"During an update of the database an error occurred and Cozy will not be able" +" to startup. A backup of the database was created before the update and has " +"been restored now. Until this issue is resolved please use version 0.9.5 of " +"Cozy. You can help resolve this problem by reporting an issue on GitHub." +msgstr "" +"Lors d’une mise à jour de la base de données, une erreur s’est produite et " +"Cozy ne pourra pas démarrer. Une sauvegarde de la base de données a été " +"créée avant la mise à jour et a été restaurée. Jusqu’à ce que ce problème " +"soit résolu, veuillez utiliser la version 0.9.5 de Cozy. Vous pouvez aider à" +" résoudre ce problème en le signalant sur GitHub." + +#: cozy/ui/db_migration_failed_view.py:15 +msgid "Failed to Update Database" +msgstr "Échec de la mise à jour de la base de données" + +#: cozy/ui/db_migration_failed_view.py:22 +msgid "Close Cozy" +msgstr "Fermer Cozy" + +#: cozy/ui/db_migration_failed_view.py:23 +msgid "Receive help on GitHub" +msgstr "Recevoir de l'aide sur GitHub" + +#: cozy/ui/delete_book_view.py:13 +msgid "Delete Audiobook?" +msgstr "Supprimer le livre audio ?" -#: cozy/ui/disk_element.py:27 +#: cozy/ui/delete_book_view.py:14 +msgid "The audiobook will be removed from your disk and from Cozy's library." +msgstr "" +"Le livre audio sera supprimé de votre disque et de la librairie de Cozy." + +#: cozy/ui/delete_book_view.py:21 cozy/ui/file_not_found_dialog.py:26 +msgid "Cancel" +msgstr "Annuler" + +#: cozy/ui/delete_book_view.py:22 +msgid "Remove Audiobook" +msgstr "Supprimer le livre audio" + +#: cozy/ui/disk_element.py:22 msgid "Disc" msgstr "Disque" -#: cozy/ui/file_not_found_dialog.py:56 -msgid "All files" -msgstr "Tous les fichiers" +#: cozy/ui/file_not_found_dialog.py:18 +msgid "File not found" +msgstr "Fichier introuvable" -#: cozy/ui/main_view.py:301 data/ui/main_window.ui:412 -msgid "Set Audiobooks Directory" -msgstr "Définir le répertoire des livres audio" +#: cozy/ui/file_not_found_dialog.py:19 +msgid "This file could not be found. Do you want to locate it manually?" +msgstr "Ce fichier est introuvable. Voulez-vous le rechercher manuellement ?" -#: cozy/ui/warnings.py:27 cozy/ui/warnings.py:42 +#: cozy/ui/file_not_found_dialog.py:27 +msgid "Locate" +msgstr "Voir l’emplacement" + +#: cozy/ui/file_not_found_dialog.py:38 +msgid "Locate Missing File" +msgstr "Localiser le fichier manquant" + +#: cozy/ui/file_not_found_dialog.py:41 #, python-brace-format -msgid "{storage} is offline." -msgstr "{storage} est inaccessible." +msgid "{ext} files" +msgstr "{ext} fichiers" + +#: cozy/ui/file_not_found_dialog.py:44 +msgid "Audio files" +msgstr "Fichiers audio" + +#: cozy/ui/import_failed_dialog.py:8 +msgid "This can have multiple reasons:" +msgstr "Il peut y avoir plusieurs raisons à cela :" + +#: cozy/ui/import_failed_dialog.py:11 +msgid "The audio format is not supported" +msgstr "Le format audio n’est pas pris en charge" + +#: cozy/ui/import_failed_dialog.py:12 +msgid "The path or filename contains non utf-8 characters" +msgstr "Le chemin ou le nom du fichier contient des caractères non UTF-8" + +#: cozy/ui/import_failed_dialog.py:13 +msgid "The file(s) are no valid audio files" +msgstr "Le(s) fichier(s) n’est/ne sont pas un/des fichier(s) audio valide(s)" + +#: cozy/ui/import_failed_dialog.py:14 +msgid "The file(s) are corrupt" +msgstr "Le(s) fichier(s) est/sont corrompu(s)" -#: cozy/ui/widgets/book_element.py:52 +#: cozy/ui/import_failed_dialog.py:28 +msgid "Some files could not be imported" +msgstr "Certains fichiers n’ont pas pu être importés" + +#: cozy/ui/import_failed_dialog.py:35 +msgid "Ok" +msgstr "Ok" + +#: cozy/ui/main_view.py:198 +msgid "Patreon Supporters" +msgstr "Supporters Patreon" + +#: cozy/ui/main_view.py:202 +msgid "m4b chapter support in mutagen" +msgstr "Prise en charge des chapitres m4b dans mutagen" + +#: cozy/ui/main_view.py:206 +msgid "Open Source Projects" +msgstr "Projets open source" + +#. Translators: Replace "translator-credits" with your names, one name per +#. line +#: cozy/ui/main_view.py:211 +msgid "translator-credits" +msgstr "Irénée Thirion" + +#: cozy/ui/widgets/book_element.py:70 msgid "Mark as read" msgstr "Marquer comme lu" -#: cozy/ui/widgets/book_element.py:55 +#: cozy/ui/widgets/book_element.py:73 msgid "Open in file browser" msgstr "Ouvrir dans l’explorateur de fichiers" -#: cozy/ui/widgets/book_element.py:58 +#: cozy/ui/widgets/book_element.py:76 msgid "Remove from library" msgstr "Supprimer" -#: cozy/ui/widgets/error_reporting.py:12 +#: cozy/ui/widgets/book_row.py:25 +msgid "Play this book" +msgstr "Lire ce livre" + +#: cozy/ui/widgets/error_reporting.py:11 msgid "Disabled" msgstr "Désactivé" -#: cozy/ui/widgets/error_reporting.py:13 +#: cozy/ui/widgets/error_reporting.py:12 msgid "Basic error reporting" msgstr "Rapport d’erreurs simple" -#: cozy/ui/widgets/error_reporting.py:14 +#: cozy/ui/widgets/error_reporting.py:13 msgid "Detailed error reporting" msgstr "Rapport d’erreurs détaillé" -#: cozy/ui/widgets/error_reporting.py:15 data/ui/error_reporting.ui:240 +#: cozy/ui/widgets/error_reporting.py:14 data/ui/error_reporting.ui:162 msgid "Detailed error reporting with import errors" msgstr "Rapport d’erreurs détaillé avec erreurs d’import" -#: cozy/ui/widgets/error_reporting.py:19 +#: cozy/ui/widgets/error_reporting.py:18 msgid "No error or crash reporting." msgstr "Pas de rapport d’erreur ou de plantage." -#: cozy/ui/widgets/error_reporting.py:20 data/ui/error_reporting.ui:259 +#: cozy/ui/widgets/error_reporting.py:19 data/ui/error_reporting.ui:174 msgid "The following information will be sent in case of an error or crash:" msgstr "" "Les informations suivantes seront envoyées en cas d’erreur ou de plantage :" -#: cozy/ui/widgets/error_reporting.py:25 +#: cozy/ui/widgets/error_reporting.py:24 msgid "Which type of error occurred" msgstr "Quel type d’erreur est survenu" -#: cozy/ui/widgets/error_reporting.py:26 +#: cozy/ui/widgets/error_reporting.py:25 msgid "Line of code where an error occurred" msgstr "Ligne de code où l’erreur est survenue" -#: cozy/ui/widgets/error_reporting.py:27 +#: cozy/ui/widgets/error_reporting.py:26 msgid "Cozy's version" msgstr "Version de Cozy" -#: cozy/ui/widgets/error_reporting.py:28 +#: cozy/ui/widgets/error_reporting.py:27 msgid "Linux distribution" msgstr "Distribution de Linux" -#: cozy/ui/widgets/error_reporting.py:29 +#: cozy/ui/widgets/error_reporting.py:28 msgid "Desktop environment" msgstr "Environnement de bureau" -#: cozy/ui/widgets/error_reporting.py:30 +#: cozy/ui/widgets/error_reporting.py:29 msgid "Media type of files that Cozy couldn't import" msgstr "Type de fichiers média que Cozy n’a pas pu importer" -#: cozy/ui/widgets/filter_list_box.py:20 -#: cozy/view_model/library_view_model.py:54 -#: cozy/view_model/library_view_model.py:160 +#: cozy/ui/widgets/filter_list_box.py:18 +#: cozy/view_model/library_view_model.py:45 +#: cozy/view_model/library_view_model.py:135 msgid "All" msgstr "Tous" -#: cozy/ui/widgets/filter_list_box.py:21 +#: cozy/ui/widgets/filter_list_box.py:19 msgid "Display all books" msgstr "Afficher tous les livres" -#: cozy/ui/widgets/search_results.py:73 -msgid "Jump to author " -msgstr "Aller à l’auteur" - -#: cozy/ui/widgets/search_results.py:76 -msgid "Jump to reader " -msgstr "Aller au narrateur" - -#: cozy/ui/widgets/search_results.py:100 -msgid "Play this book" -msgstr "Lire ce livre" +#: cozy/ui/widgets/search_results.py:13 +#, python-brace-format +msgid "Jump to {artist_name}" +msgstr "Aller à {artist_name}" -#: cozy/ui/widgets/sleep_timer.py:60 data/ui/timer_popover.ui:66 +#: cozy/ui/widgets/sleep_timer.py:57 data/ui/timer_popover.ui:53 msgid "min" msgstr "min" -#: cozy/ui/widgets/sleep_timer.py:65 +#: cozy/ui/widgets/sleep_timer.py:62 msgid "Off" msgstr "Désactivée" -#: cozy/ui/widgets/storage_list_box_row.py:70 data/ui/preferences.ui:377 +#: cozy/ui/widgets/storages.py:11 +msgid "Set Audiobooks Directory" +msgstr "Définir le répertoire des livres audio" + +#: cozy/ui/widgets/storages.py:65 data/ui/storage_locations.ui:18 msgid "External drive" msgstr "Stockage externe" -#: cozy/ui/widgets/storage_list_box_row.py:73 +#: cozy/ui/widgets/storages.py:68 msgid "Internal drive" msgstr "Stockage interne" -#: cozy/view_model/headerbar_view_model.py:91 +#: cozy/view_model/headerbar_view_model.py:78 msgid "Refreshing audio book collection" msgstr "Rafraîchissement de la collection de livres audio" -#: cozy/view_model/headerbar_view_model.py:100 -#: cozy/view_model/headerbar_view_model.py:116 +#: cozy/view_model/headerbar_view_model.py:87 +#: cozy/view_model/headerbar_view_model.py:103 msgid "Copying new files…" msgstr "Copiant les fichiers..." -#: cozy/view_model/headerbar_view_model.py:107 +#: cozy/view_model/headerbar_view_model.py:94 msgid "Changing audio book location…" msgstr "Modifier l'emplacement des livres audio…" -#: data/ui/about.ui:16 -msgid "GitHub" -msgstr "GitHub" - -#: data/ui/album_element.ui:104 +#: data/ui/album_element.ui:47 msgid "Play" msgstr "Jouer" -#: data/ui/book_detail.ui:219 +#: data/ui/book_detail.ui:149 msgid "Remaining" msgstr "Restant" -#: data/ui/book_detail.ui:274 +#: data/ui/book_detail.ui:195 msgid "Total" msgstr "Total" -#: data/ui/book_detail.ui:290 +#: data/ui/book_detail.ui:208 msgid "Last played" msgstr "Dernière lecture" -#: data/ui/book_detail.ui:306 +#: data/ui/book_detail.ui:221 msgid "Published" msgstr "Publié" -#: data/ui/book_detail.ui:341 +#: data/ui/book_detail.ui:246 msgid "Some or all files of this book cannot be found." msgstr "Tout ou partie des fichiers de ce livre ne peuvent être trouvés." -#: data/ui/book_detail.ui:364 +#: data/ui/book_detail.ui:259 msgid "unavailable" msgstr "indisponible" -#: data/ui/book_detail.ui:533 +#: data/ui/book_detail.ui:363 msgid "Loading chapters, please wait..." msgstr "Chargement des chapitres, merci de patienter..." -#: data/ui/book_element.ui:36 +#: data/ui/book_element.ui:10 msgid "Open book overview" msgstr "Voir le résumé" -#: data/ui/db_migration_failed.ui:31 -msgid "Close Cozy" -msgstr "Fermer Cozy" - -#: data/ui/db_migration_failed.ui:47 -msgid "Receive help on GitHub" -msgstr "Recevoir de l'aide sur GitHub" - -#: data/ui/db_migration_failed.ui:108 -msgid "An error occured while updating the database" -msgstr "Une erreur a eu lieu lors du chargement de la base de données" - -#: data/ui/db_migration_failed.ui:129 -msgid "" -"During an update of the database an error occurred and Cozy will not be able to startup.\n" -"A backup of the database was created before the update and has been restored now.\n" -"Until this issue is resolved please use version 0.9.5 of Cozy.\n" -"You can help resolve this problem by reporting an issue on GitHub." -msgstr "" -"Durant une mise à jour de la base de données une erreur est survenue et Cozy ne sera pas capable de démarrer.\n" -"Une sauvegarde de la base de données a été créée avant la mise à jour et a désormais été restaurée.\n" -"Jusqu'à ce que ce problème soit résolu, merci d'utiliser la version 0.9.5 de Cozy.\n" -"Vous pouvez aider à résoudre ce problème en rapportant l'erreur sur GitHub." - -#: data/ui/delete_book_dialog.ui:31 data/ui/file_not_found.ui:19 -msgid "Cancel" -msgstr "Annuler" - -#: data/ui/delete_book_dialog.ui:45 -msgid "Delete Audiobook" -msgstr "Supprimez ce livre audio" - -#: data/ui/delete_book_dialog.ui:105 -msgid "Are you sure you want to delete the selected audiobook?" -msgstr "Êtes-vous certain que vous voulez supprimer le livre audio choisi ?" - -#: data/ui/delete_book_dialog.ui:126 -msgid "The audiobook will be removed from your disk and from Cozy's library." -msgstr "" -"Le livre audio sera supprimé de votre disque et de la librairie de Cozy." +#: data/ui/chapter_element.ui:5 +msgid "Play this part" +msgstr "Lire cette partie" -#: data/ui/error_reporting.ui:29 data/ui/preferences.ui:455 +#: data/ui/error_reporting.ui:24 data/ui/preferences.ui:124 msgid "User feedback" msgstr "Rapports utilisateur" -#: data/ui/error_reporting.ui:98 +#: data/ui/error_reporting.ui:67 msgctxt "Error and crash reporting dialog" msgid "" "You can help improve Cozy by contributing information in case of errors and " @@ -352,7 +410,7 @@ msgstr "" "Vous pouvez aider à améliorer Cozy en envoyant des rapports d’erreur ou de " "plantage." -#: data/ui/error_reporting.ui:112 +#: data/ui/error_reporting.ui:75 msgctxt "Error and crash reporting dialog" msgid "" "Contributing this information is optional and completely anonymous. We will " @@ -363,7 +421,7 @@ msgstr "" "collectons aucune donnée personnelle, fichier que vous importez ou " "informations permettant de vous identifier." -#: data/ui/error_reporting.ui:127 +#: data/ui/error_reporting.ui:84 msgctxt "Error and crash reporting dialog" msgid "" "Cozy is opensource and the user feedback source code can be inspected here: " @@ -371,380 +429,297 @@ msgstr "" "Cozy est open source, et le code d’envoi de rapports d’erreur peut être " "inspecté ici :" -#: data/ui/file_not_found.ui:32 -msgid "Locate" -msgstr "Voir l’emplacement" +#. Translators: Don't touch the markup. Translate the text "Sourcecode on +#. GitHub" only! +#: data/ui/error_reporting.ui:94 +msgid "" +"Sourcecode" +" on GitHub" +msgstr "" +"Code " +"source sur GitHub" -#: data/ui/file_not_found.ui:86 -msgid "File not found" -msgstr "Fichier introuvable" +#: data/ui/first_import_button.ui:12 +msgid "Select Folder" +msgstr "Sélectionner un dossier" -#: data/ui/file_not_found.ui:119 -msgid "This file could not be found. Do you want to locate it manually?" -msgstr "Ce fichier est introuvable. Voulez-vous le rechercher manuellement ?" +#: data/ui/headerbar.ui:17 +msgid "Toggle Filter Sidebar" +msgstr "Basculer la barre latérale des filtres" -#: data/ui/headerbar.ui:56 -msgid "Display background task progress" -msgstr "Afficher la progression des tâches en arrière-plan" +#: data/ui/headerbar.ui:22 +msgid "Options" +msgstr "Options" -#: data/ui/headerbar.ui:70 +#: data/ui/headerbar.ui:26 +msgid "Open the options popover" +msgstr "Ouvrir les options" + +#: data/ui/headerbar.ui:33 msgid "Search your library" msgstr "Rechercher dans votre bibliothèque" -#: data/ui/headerbar.ui:80 -msgid "Search menu button" -msgstr "Bouton du menu de recherche" - -#: data/ui/headerbar.ui:81 +#: data/ui/headerbar.ui:36 msgid "Open the search popover" msgstr "Ouvrir la boîte de recherche" -#: data/ui/headerbar.ui:96 -msgid "Options" -msgstr "Options" +#: data/ui/headerbar.ui:44 +msgid "Display background task progress" +msgstr "Afficher la progression des tâches en arrière-plan" -#: data/ui/headerbar.ui:107 -msgid "Options menu button" -msgstr "Bouton du menu options" +#: data/ui/headerbar.ui:67 +msgid "Start typing..." +msgstr "Commencez à taper…" -#: data/ui/headerbar.ui:108 -msgid "Open the options popover" -msgstr "Ouvrir les options" +#: data/ui/headerbar.ui:80 +msgid "_Scan Library" +msgstr "_Scanner la bibliothèque" -#: data/ui/import_failed.ui:27 -msgid "Ok" -msgstr "Ok" +#: data/ui/headerbar.ui:86 +msgid "_Hide unavailable books" +msgstr "_Masquer les livres non disponibles" -#: data/ui/import_failed.ui:81 -msgid "Some files could not be imported" -msgstr "Certains fichiers n’ont pas pu être importés" +#: data/ui/headerbar.ui:92 +msgid "_Preferences" +msgstr "_Préférences" -#: data/ui/import_failed.ui:134 -msgid "" -"This can have multiple reasons:\n" -"- The audio format is not supported\n" -"- The path or filename contains non utf-8 characters\n" -"- The file(s) are no valid audio files\n" -"- The file(s) are corrupt" -msgstr "" -"Ceci peut se produire pour diverses raisons :\n" -"- L'encodage audio n’est pas pris en charge\n" -"- Le chemin d’accès contient des caractères non utf-8\n" -"- Il ne s’agit pas de fichier(s) audio valide(s)\n" -"- Il s’agit de fichier(s) corrompu(s)" +#: data/ui/headerbar.ui:96 +msgid "_About Cozy" +msgstr "À _propos de Cozy" + +#: data/ui/headerbar.ui:102 +msgid "_Quit" +msgstr "_Quitter" -#: data/ui/main_window.ui:68 +#: data/ui/main_window.ui:26 +msgid "Drop Audio Books Here to Add Them to Your Library" +msgstr "Déposez des livres audio ici pour les ajou" + +#: data/ui/main_window.ui:48 +msgid "Library" +msgstr "Bibliothèque" + +#: data/ui/main_window.ui:65 msgid "Recent" msgstr "Récent" -#: data/ui/main_window.ui:90 -msgid "List of authors" -msgstr "Liste des auteurs" - -#: data/ui/main_window.ui:106 data/ui/main_window.ui:250 -#: data/ui/search_popover.ui:107 +#: data/ui/main_window.ui:77 data/ui/search_page.ui:46 msgid "Author" msgstr "Auteur" -#: data/ui/main_window.ui:128 -msgid "List of readers" -msgstr "Liste des narrateurs" +#: data/ui/main_window.ui:89 +msgid "List of authors" +msgstr "Liste des auteurs" -#: data/ui/main_window.ui:144 data/ui/search_popover.ui:201 +#: data/ui/main_window.ui:108 data/ui/search_page.ui:59 msgid "Reader" msgstr "Narrateur" -#: data/ui/main_window.ui:189 +#: data/ui/main_window.ui:120 +msgid "List of readers" +msgstr "Liste des narrateurs" + +#: data/ui/main_window.ui:172 msgid "List of books" msgstr "Liste des livres" -#: data/ui/main_window.ui:222 -msgid "" -"Start exploring your library by switching to the Author or Reader view." -msgstr "" -"Commencez à explorer votre librairie en passant à la vue Auteur ou Lecteur." - -#: data/ui/main_window.ui:280 -msgid "Stay tuned while Cozy is preparing your library…" -msgstr "Attendez pendant que Cozy prépare votre bibliothèque..." - -#: data/ui/main_window.ui:334 -msgid "Import your Audiobooks" -msgstr "Importer vos livres audios" - -#: data/ui/main_window.ui:353 -msgid "" -"Cozy automatically imports your audiobooks in one directory - your library" -msgstr "" -"Cozy va automatiquement importer vos livres audios dans un répertoire unique" -" - votre bibliothèque" +#: data/ui/main_window.ui:194 +msgid "No Recent Books Yet" +msgstr "Aucun livre récent pour le moment" -#: data/ui/main_window.ui:385 -msgid "Drag & Drop" -msgstr "Glisser & Déposer" +#: data/ui/main_window.ui:195 +msgid "Explore your library by switching to the Author or Reader view" +msgstr "Parcourez votre bibliothèque en passant à la vue Auteur ou Lecteur" -#: data/ui/main_window.ui:387 -msgid "Drag your audiobooks into cozy and they will be automatically imported" -msgstr "" -"Faites glisser vos livres audio directement dans Cozy pour les importer" +#: data/ui/media_controller.ui:48 +msgid "Currently playing" +msgstr "Lecture en cours" -#: data/ui/main_window.ui:414 -msgid "Load audiobooks from a directory, network drive or an external disk" -msgstr "" -"Charger les livres audio depuis un répertoire, un stockage en ligne ou un " -"disque externe" +#: data/ui/media_controller.ui:65 +msgid "Title of currently playing book" +msgstr "Titre du livre en cours de lecture" -#: data/ui/main_window.ui:417 -msgid "Select" -msgstr "Sélectionner" +#: data/ui/media_controller.ui:82 +msgid "Title of the currently playing part" +msgstr "Titre du chapitre en cours de lecture" -#: data/ui/media_controller.ui:64 data/ui/media_controller.ui:482 -#: data/ui/media_controller_big.ui:189 data/ui/media_controller_small.ui:70 +#: data/ui/media_controller.ui:111 msgid "Rewind" msgstr "Rembobinage" -#: data/ui/media_controller.ui:71 data/ui/media_controller.ui:489 -#: data/ui/media_controller_big.ui:197 data/ui/media_controller_small.ui:77 -msgid "Rewind button" -msgstr "Bouton de rembobinage" - -#: data/ui/media_controller.ui:72 data/ui/media_controller.ui:490 -#: data/ui/media_controller_big.ui:198 data/ui/media_controller_small.ui:78 +#: data/ui/media_controller.ui:116 msgid "Rewind playback" msgstr "Rembobinage de la lecture" -#: data/ui/media_controller.ui:89 data/ui/media_controller.ui:507 -#: data/ui/media_controller_big.ui:220 data/ui/media_controller_small.ui:100 +#: data/ui/media_controller.ui:130 msgid "Start playback" msgstr "Démarrer la lecture" -#: data/ui/media_controller.ui:96 data/ui/media_controller.ui:514 -#: data/ui/media_controller_big.ui:228 data/ui/media_controller_small.ui:107 -msgid "Play/Pause Button" -msgstr "Bouton Marche/Arrêt" - -#: data/ui/media_controller.ui:97 data/ui/media_controller.ui:515 -#: data/ui/media_controller_big.ui:229 data/ui/media_controller_small.ui:108 +#: data/ui/media_controller.ui:135 msgid "Start or pause the playback" msgstr "Démarrer ou interrompre la lecture" -#: data/ui/media_controller.ui:113 data/ui/media_controller.ui:531 -#: data/ui/media_controller_big.ui:252 data/ui/media_controller_small.ui:131 +#: data/ui/media_controller.ui:148 msgid "Forward" msgstr "Avancer" -#: data/ui/media_controller.ui:120 data/ui/media_controller.ui:538 -#: data/ui/media_controller_big.ui:260 data/ui/media_controller_small.ui:138 -msgid "Forward button" -msgstr "Bouton d'avancement" - -#: data/ui/media_controller.ui:121 data/ui/media_controller.ui:539 -#: data/ui/media_controller_big.ui:261 data/ui/media_controller_small.ui:139 +#: data/ui/media_controller.ui:153 msgid "Forward Playback" msgstr "Avancer la lecture" -#: data/ui/media_controller.ui:175 data/ui/media_controller_big.ui:76 -msgid "Currently playing" -msgstr "Lecture en cours" - -#: data/ui/media_controller.ui:190 data/ui/media_controller_big.ui:97 -msgid "Booktitle" -msgstr "Titre" - -#: data/ui/media_controller.ui:191 data/ui/media_controller_big.ui:98 -msgid "Title of currently playing book" -msgstr "Titre du livre en cours de lecture" - -#: data/ui/media_controller.ui:217 data/ui/media_controller_big.ui:126 -msgid "Part name" -msgstr "Nom du chapitre" - -#: data/ui/media_controller.ui:218 data/ui/media_controller_big.ui:127 -msgid "Title of the currently playing part" -msgstr "Titre du chapitre en cours de lecture" - -#: data/ui/media_controller.ui:256 data/ui/seek_bar.ui:20 -msgid "Elapsed time" -msgstr "Temps écoulé" - -#: data/ui/media_controller.ui:264 data/ui/seek_bar.ui:28 -msgid "Time elapsed" -msgstr "Temps écoulé" - -#: data/ui/media_controller.ui:265 data/ui/seek_bar.ui:29 -msgid "Elapsed time of current part" -msgstr "Temps écoulé depuis le début du chapitre" - -#: data/ui/media_controller.ui:281 data/ui/seek_bar.ui:45 -msgid "Jump to position in current chapter" -msgstr "Se déplacer dans le chapitre courant" - -#: data/ui/media_controller.ui:290 data/ui/seek_bar.ui:56 -msgid "Position slider" -msgstr "Indicateur de position" - -#: data/ui/media_controller.ui:291 data/ui/seek_bar.ui:57 -msgid "Position of the current part in seconds" -msgstr "Position dans le chapitre courant en secondes" - -#: data/ui/media_controller.ui:310 data/ui/seek_bar.ui:76 -msgid "Remaining time" -msgstr "Temps restant" - -#: data/ui/media_controller.ui:317 data/ui/seek_bar.ui:83 -msgid "Time remaining" -msgstr "Temps restant" - -#: data/ui/media_controller.ui:318 data/ui/seek_bar.ui:84 -msgid "Remaining time of current part" -msgstr "Temps restant du chapitre actuel" - -#: data/ui/media_controller.ui:350 data/ui/media_controller_big.ui:324 +#: data/ui/media_controller.ui:179 msgid "Volume control" msgstr "Volume" -#: data/ui/media_controller.ui:387 data/ui/media_controller.ui:572 -#: data/ui/media_controller_big.ui:367 data/ui/media_controller_small.ui:175 +#: data/ui/media_controller.ui:202 msgid "Playback speed" msgstr "Vitesse de lecture" -#: data/ui/media_controller.ui:408 data/ui/media_controller_big.ui:394 -msgid "Sleep timer" -msgstr "Minuterie" - -#: data/ui/media_controller.ui:418 data/ui/media_controller_big.ui:404 -msgid "Timer menu button" -msgstr "Bouton du chronomètre" +#: data/ui/media_controller.ui:213 data/ui/preferences.ui:80 +msgid "Sleep Timer" +msgstr "Minuterie de veille" -#: data/ui/media_controller.ui:419 data/ui/media_controller_big.ui:405 +#: data/ui/media_controller.ui:220 msgid "Open the sleep timer popover" msgstr "Ouvrir le chronomètre" -#: data/ui/media_controller_big.ui:53 -msgid "Open book" -msgstr "Ouvrir le livre" - -#: data/ui/preferences.ui:55 +#: data/ui/preferences.ui:27 msgid "General" msgstr "Général" -#: data/ui/preferences.ui:60 +#: data/ui/preferences.ui:30 msgid "Appearance" msgstr "Apparence" -#: data/ui/preferences.ui:83 +#: data/ui/preferences.ui:33 +msgid "Dark Mode" +msgstr "Mode sombre" + +#: data/ui/preferences.ui:40 msgid "Tags" msgstr "Étiquettes" -#: data/ui/preferences.ui:90 +#: data/ui/preferences.ui:43 +msgid "Swap Author and Reader" +msgstr "Échanger Auteur et Lecteur" + +#: data/ui/preferences.ui:44 msgid "Activate if author and reader are displayed the wrong way" msgstr "Activer si l'auteur et le lecteur sont mal affichés" -#: data/ui/preferences.ui:107 +#: data/ui/preferences.ui:51 msgid "Playback" msgstr "Lecture" -#: data/ui/preferences.ui:114 +#: data/ui/preferences.ui:54 +msgid "Replay" +msgstr "Rejouer" + +#: data/ui/preferences.ui:55 msgid "Rewind 30 seconds of the current book when starting Cozy" msgstr "Rembobiner 30 secondes du livre en cours lors du démarrage de Cozy" -#: data/ui/preferences.ui:172 -msgid "Sleep Timer" -msgstr "Minuterie de veille" +#: data/ui/preferences.ui:60 +msgid "Rewind Duration" +msgstr "Durée du rembobinage" + +#: data/ui/preferences.ui:69 +msgid "Forward Duration" +msgstr "Durée de l’avancement" + +#: data/ui/preferences.ui:83 +msgid "Fadeout" +msgstr "Fondu de transition" -#: data/ui/preferences.ui:218 +#: data/ui/preferences.ui:88 +msgid "Fadeout Duration" +msgstr "Durée du fondu enchaîné" + +#: data/ui/preferences.ui:104 msgid "Storage" msgstr "Stockage" -#: data/ui/preferences.ui:223 +#: data/ui/preferences.ui:107 msgid "Artwork" msgstr "Couverture" -#: data/ui/preferences.ui:230 +#: data/ui/preferences.ui:110 +msgid "Prefer External Images Over Embedded Cover" +msgstr "Préférer les images externes à la place de la couverture incluse" + +#: data/ui/preferences.ui:111 msgid "Always use images (cover.jpg, *.png, …) when available" msgstr "Toujours utiliser des images (couverture.jpg, *.png, ...) si possible" -#: data/ui/preferences.ui:247 -msgid "Storage locations" -msgstr "Emplacements de stockage" - -#: data/ui/preferences.ui:309 -msgid "Add location" -msgstr "Ajouter un emplacement" - -#: data/ui/preferences.ui:335 -msgid "Remove location" -msgstr "Retirer l’emplacement" +#: data/ui/preferences.ui:121 +msgid "Feedback" +msgstr "Retours" -#: data/ui/preferences.ui:373 -msgid "Toggle this storage location to be internal/external." -msgstr "Basculer l’état interne/externe pour cet emplacement" +#: data/ui/search_page.ui:9 +msgid "Search in your library" +msgstr "Rechercher dans votre bibliothèque" -#: data/ui/preferences.ui:402 -msgid "Set as default storage location for new audiobooks" -msgstr "Définir comme emplacement par défaut pour les nouveaux livres audio" +#: data/ui/search_page.ui:15 +msgid "No results found" +msgstr "Aucun résultat" -#: data/ui/preferences.ui:406 -msgid "Set as default" -msgstr "Définir par défaut" +#: data/ui/search_page.ui:33 +msgid "Book" +msgstr "Livre" -#: data/ui/preferences.ui:450 -msgid "Feedback" -msgstr "Retours" +#: data/ui/seek_bar.ui:15 +msgid "Elapsed time" +msgstr "Temps écoulé" -#: data/ui/preferences.ui:460 -msgid "User Feedback" -msgstr "Retour Utilisateur" +#: data/ui/seek_bar.ui:21 +msgid "Elapsed time of current part" +msgstr "Temps écoulé depuis le début du chapitre" -#: data/ui/search_popover.ui:24 -msgid "Search" -msgstr "Recherche" +#: data/ui/seek_bar.ui:32 +msgid "Jump to position in current chapter" +msgstr "Se déplacer dans le chapitre courant" -#: data/ui/search_popover.ui:36 -msgid "Search box" -msgstr "Boîte de recherche" +#: data/ui/seek_bar.ui:39 +msgid "Position of the current part in seconds" +msgstr "Position dans le chapitre courant en secondes" -#: data/ui/search_popover.ui:37 -msgid "Search your audiobook library" -msgstr "Recherchez dans votre bibliothèque de livres audio" +#: data/ui/seek_bar.ui:48 +msgid "Remaining time" +msgstr "Temps restant" -#: data/ui/search_popover.ui:67 -msgid "Which book are you looking for?" -msgstr "Quel livre recherchez-vous ?" +#: data/ui/seek_bar.ui:53 +msgid "Remaining time of current part" +msgstr "Temps restant du chapitre actuel" -#: data/ui/search_popover.ui:154 -msgid "Book" -msgstr "Livre" +#: data/ui/storage_locations.ui:5 +msgid "Storage locations" +msgstr "Emplacements de stockage" -#: data/ui/search_popover.ui:248 -msgid "Part" -msgstr "Chapitre" +#: data/ui/storage_locations.ui:24 +msgid "Set as default" +msgstr "Définir par défaut" -#: data/ui/search_popover.ui:295 -msgid "Nothing found :(" -msgstr "Rien n’a été trouvé :(" +#: data/ui/storage_locations.ui:28 +msgid "Remove" +msgstr "Supprimer" -#: data/ui/timer_popover.ui:37 +#: data/ui/timer_popover.ui:30 msgid "Timer duration" msgstr "Durée du décompte" -#: data/ui/timer_popover.ui:49 -msgid "Timer duration slider" -msgstr "Indicateur du décompte" - -#: data/ui/timer_popover.ui:50 +#: data/ui/timer_popover.ui:40 msgid "Set the sleep timer duration in minutes" msgstr "Ajuster la durée du chronomètre" -#: data/ui/timer_popover.ui:116 +#: data/ui/timer_popover.ui:86 msgid "Stop after current chapter" msgstr "Arrêter la lecture à la fin de ce chapitre" -#: data/ui/timer_popover.ui:164 +#: data/ui/timer_popover.ui:107 msgid "Enable system power control" msgstr "Activer la gestion d'énergie" -#: data/ui/timer_popover.ui:201 +#: data/ui/timer_popover.ui:125 msgid "" "Type of the action when the timer finishes.\n" "\"shutdown\" will attempt to turn your system off (also known as power off)\n" @@ -754,167 +729,14 @@ msgstr "" "« éteindre » éteindra votre ordinateur.\n" "« mettre en veille » mettra votre ordinateur en veille" -#: data/ui/timer_popover.ui:205 -msgid "" -"System power action\n" -"to perform" -msgstr "" -"Action d’état du système\n" -"à effectuer" +#: data/ui/timer_popover.ui:129 +msgid "System power action to perform" +msgstr "Action d’alimentation du système à effectuer" -#: data/ui/timer_popover.ui:221 +#: data/ui/timer_popover.ui:137 msgid "suspend" msgstr "mettre en veille" -#: data/ui/timer_popover.ui:237 +#: data/ui/timer_popover.ui:143 msgid "shutdown" msgstr "éteindre" - -#: data/ui/titlebar_menu.ui:7 -msgid "_Scan Library" -msgstr "_Scanner la bibliothèque" - -#: data/ui/titlebar_menu.ui:13 -msgid "_Hide unavailable books" -msgstr "_Masquer les livres non disponibles" - -#: data/ui/titlebar_menu.ui:19 -msgid "_Preferences" -msgstr "_Préférences" - -#: data/ui/titlebar_menu.ui:25 -msgid "_Help" -msgstr "_Aide" - -#: data/ui/titlebar_menu.ui:29 -msgid "_About" -msgstr "_À propos" - -#: data/ui/titlebar_menu.ui:33 -msgid "_Quit" -msgstr "_Quitter" - -#: data/ui/welcome.ui:29 -msgid "Welcome!" -msgstr "Bienvenue !" - -#: data/ui/welcome.ui:46 -msgid "Add your audiobooks and let's get cozy." -msgstr "Ajoutez vos livres audio et soyez cozy." - -#: data/ui/whats_new.ui:9 -msgid "Whats new?" -msgstr "Nouveautés" - -#: data/ui/whats_new.ui:27 -msgid "Continue" -msgstr "Continuer" - -#: data/ui/whats_new_importer.ui:17 data/ui/whats_new_library.ui:17 -#: data/ui/whats_new_m4b.ui:17 data/ui/whats_new_m4b_chapter.ui:17 -msgid "What's new in Cozy" -msgstr "Ce qui est nouveau avec Cozy" - -#: data/ui/whats_new_importer.ui:52 -msgid "A completely rewritten and far more reliable media importer." -msgstr "" -"Un assistant d’importation complètement réécrit et beaucoup plus fiable" - -#: data/ui/whats_new_importer.ui:77 -msgid "" -"Did you experience audio files that couldn't be imported? Drag & Drop those " -"files onto Cozy or use the application menu in the titlebar to rescan your " -"audiobook directories!" -msgstr "" -"Avez-vous fait face à des fichiers qui ne pouvaient pas être importés ? " -"Glissez & déposez ces fichiers sur Cozy ou utilisez le menu dans la barre " -"d’en-tête pour scanner à nouveau vos répertoires de livres audio !" - -#: data/ui/whats_new_importer.ui:92 -msgid "Supported media files currently are mp3, m4a, flac, ogg, opus and wav." -msgstr "" -"Les fichiers média pris en charge actuellement son mp3, m4a, flac, off, opus" -" et wav." - -#: data/ui/whats_new_importer.ui:107 -msgid "More to come in a later update." -msgstr "Plus de nouveautés dans une prochaine mises à jour." - -#: data/ui/whats_new_library.ui:52 -msgid "An important change in library management" -msgstr "Un changement important au management des bibliothèques" - -#: data/ui/whats_new_library.ui:77 -msgid "" -"Previously every file which was imported in your library but couldn't be " -"found anymore was removed from the library during a scan." -msgstr "" -"Auparavant, tous les fichiers dans votre bibliothèque qui Cozy ne peut pas " -"trouver étaient supprimés de votre bibliothèque pendant les scans." - -#: data/ui/whats_new_library.ui:92 -msgid "" -"Now audiobooks are not removed from your library automatically anymore. This" -" prevents accidentally loosing the progress of a audiobook when a file can't" -" be found temporarily." -msgstr "" -"Désormais les livres audio ne sont plus supprimés automatiquement de votre " -"librairie. Cela évite de perdre accidentellement la progression d'un livre " -"audio quand un fichier ne peut pas être trouvé temporairement." - -#: data/ui/whats_new_library.ui:107 -msgid "" -"To remove an audiobook from the library simply right-click on it and choose " -"the remove from library option." -msgstr "" -"Pour supprimer un livre audio de votre bibliothèque, faites un clic droit " -"sur le livre et choisissez l'option de le supprimer de votre bibliothèque." - -#: data/ui/whats_new_m4b.ui:52 -msgid "Basic support for m4b audio books." -msgstr "Prise en charge élémentaire des livres audio m4b." - -#: data/ui/whats_new_m4b.ui:77 -msgid "" -"Many of you have been waiting for it: Support for m4b audio books! This " -"version features basic support for m4b files without chapter support." -msgstr "" -"Beaucoup d’entre vous l’attendaient : la prise en charge des livres audio " -"m4b ! Cette version introduit la prise en charge élémentaire des fichiers " -"m4b sans prise en charge du chapitrage." - -#: data/ui/whats_new_m4b.ui:92 -msgid "" -"Drag & Drop your m4b files onto Cozy or use the application menu in the " -"titlebar to rescan your audiobook directories." -msgstr "" -"Glissez et déposez vos fichiers m4b sur Cozy, ou utilisez le menu dans la " -"barre d’en-tête pour scanner à nouveau vos répertoires de livres audio." - -#: data/ui/whats_new_m4b.ui:107 -msgid "Chapter support will follow in a later update. Stay tuned!" -msgstr "" -"La prise en charge du chapitrage sera pour une prochaine mise à jour. Gardez" -" un œil sur les mises à jour !" - -#: data/ui/whats_new_m4b_chapter.ui:52 -msgid "Chapter support for m4b audio books." -msgstr "Prise en charge des chapitres pour les livres audio m4b." - -#: data/ui/whats_new_m4b_chapter.ui:77 -msgid "This version of Cozy features chapter support for m4b audio books!" -msgstr "" -"Cette version de Cozy apporte une prise en charge des chapitres pour les " -"livres audio m4b !" - -#: data/ui/whats_new_m4b_chapter.ui:92 -msgid "" -"If you already have m4b files imported you'll need to start a scan of your " -"library from the app menu." -msgstr "" -"Si vous avez déjà des fichiers m4b importés vous aurez besoin de démarrer un" -" scan de votre librairie depuis le menu de l'application. " - -#: data/ui/whats_new_m4b_chapter.ui:107 -msgid "The chapters will then be detected." -msgstr "Les chapitres seront alors détectés." From 557520e29525540eb15aba3726f29bc28f3593a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Sun, 10 Mar 2024 13:19:42 +0100 Subject: [PATCH 03/28] Fixup missing translator credits from newly translated po files (#898) --- po/de.po | 2 +- po/es.po | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/po/de.po b/po/de.po index 2ab508a2..e5f73d1a 100644 --- a/po/de.po +++ b/po/de.po @@ -231,7 +231,7 @@ msgstr "Open Source Projekte" #. line #: cozy/ui/main_view.py:211 msgid "translator-credits" -msgstr "translator-credits" +msgstr "Julian Geywitz" #: cozy/ui/widgets/book_element.py:70 msgid "Mark as read" diff --git a/po/es.po b/po/es.po index f8fce10b..5ac4858c 100644 --- a/po/es.po +++ b/po/es.po @@ -241,7 +241,10 @@ msgstr "Proyectos de código abierto" #. line #: cozy/ui/main_view.py:211 msgid "translator-credits" -msgstr "créditos-traductor" +msgstr "" +"Adolfo Jayme-Barrientos\n" +"Jose Luis Tirado\n" +"Ezequiel Partida" #: cozy/ui/widgets/book_element.py:70 msgid "Mark as read" From bc231bfa096fc79debf0d689038cc8ba71447be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Thu, 14 Mar 2024 14:43:17 +0100 Subject: [PATCH 04/28] Switch to Blueprint (#896) Now we no longer have to write XML files by hand, yay! --- .gitignore | 2 + com.github.geigi.cozy.json | 12 + cozy/application.py | 11 +- cozy/ui/about_window.py | 57 ++++ cozy/ui/book_detail_view.py | 2 +- cozy/ui/chapter_element.py | 2 +- cozy/ui/headerbar.py | 2 +- cozy/ui/main_view.py | 124 ++----- cozy/ui/media_controller.py | 19 +- cozy/ui/preferences_view.py | 95 ------ cozy/ui/preferences_window.py | 61 ++++ cozy/ui/search_view.py | 2 +- cozy/ui/widgets/album_element.py | 2 +- cozy/ui/widgets/book_element.py | 2 +- cozy/ui/widgets/error_reporting.py | 2 +- cozy/ui/widgets/first_import_button.py | 2 +- cozy/ui/widgets/playback_speed_popover.py | 2 +- cozy/ui/widgets/progress_popover.py | 2 +- cozy/ui/widgets/seek_bar.py | 2 +- cozy/ui/widgets/sleep_timer.py | 2 +- cozy/ui/widgets/storages.py | 4 +- data/gresource.xml | 22 +- data/meson.build | 13 +- data/{ui => }/style.css | 0 data/ui/album_element.blp | 62 ++++ data/ui/album_element.ui | 73 ---- data/ui/book_detail.blp | 356 ++++++++++++++++++++ data/ui/book_detail.ui | 387 ---------------------- data/ui/book_element.blp | 53 +++ data/ui/book_element.ui | 55 --- data/ui/chapter_element.blp | 64 ++++ data/ui/chapter_element.ui | 72 ---- data/ui/error_reporting.blp | 174 ++++++++++ data/ui/error_reporting.ui | 194 ----------- data/ui/first_import_button.blp | 23 ++ data/ui/first_import_button.ui | 26 -- data/ui/gresource.xml | 23 -- data/ui/headerbar.blp | 107 ++++++ data/ui/headerbar.ui | 107 ------ data/ui/main_window.blp | 253 ++++++++++++++ data/ui/main_window.ui | 291 ---------------- data/ui/media_controller.blp | 223 +++++++++++++ data/ui/media_controller.ui | 232 ------------- data/ui/meson.build | 31 +- data/ui/playback_speed_popover.blp | 33 ++ data/ui/playback_speed_popover.ui | 39 --- data/ui/preferences.blp | 114 +++++++ data/ui/preferences.ui | 131 -------- data/ui/progress_popover.blp | 28 ++ data/ui/progress_popover.ui | 35 -- data/ui/search_page.blp | 63 ++++ data/ui/search_page.ui | 79 ----- data/ui/seek_bar.blp | 63 ++++ data/ui/seek_bar.ui | 63 ---- data/ui/storage_locations.blp | 35 ++ data/ui/storage_locations.ui | 34 -- data/ui/storage_row.blp | 33 ++ data/ui/storage_row.ui | 32 -- data/ui/timer_popover.blp | 135 ++++++++ data/ui/timer_popover.ui | 154 --------- main.py | 2 +- po/POTFILES | 38 +-- pyproject.toml | 2 + 63 files changed, 2085 insertions(+), 2278 deletions(-) create mode 100644 cozy/ui/about_window.py delete mode 100644 cozy/ui/preferences_view.py create mode 100644 cozy/ui/preferences_window.py rename data/{ui => }/style.css (100%) create mode 100644 data/ui/album_element.blp delete mode 100644 data/ui/album_element.ui create mode 100644 data/ui/book_detail.blp delete mode 100644 data/ui/book_detail.ui create mode 100644 data/ui/book_element.blp delete mode 100644 data/ui/book_element.ui create mode 100644 data/ui/chapter_element.blp delete mode 100644 data/ui/chapter_element.ui create mode 100644 data/ui/error_reporting.blp delete mode 100644 data/ui/error_reporting.ui create mode 100644 data/ui/first_import_button.blp delete mode 100644 data/ui/first_import_button.ui delete mode 100644 data/ui/gresource.xml create mode 100644 data/ui/headerbar.blp delete mode 100644 data/ui/headerbar.ui create mode 100644 data/ui/main_window.blp delete mode 100644 data/ui/main_window.ui create mode 100644 data/ui/media_controller.blp delete mode 100644 data/ui/media_controller.ui create mode 100644 data/ui/playback_speed_popover.blp delete mode 100644 data/ui/playback_speed_popover.ui create mode 100644 data/ui/preferences.blp delete mode 100644 data/ui/preferences.ui create mode 100644 data/ui/progress_popover.blp delete mode 100644 data/ui/progress_popover.ui create mode 100644 data/ui/search_page.blp delete mode 100644 data/ui/search_page.ui create mode 100644 data/ui/seek_bar.blp delete mode 100644 data/ui/seek_bar.ui create mode 100644 data/ui/storage_locations.blp delete mode 100644 data/ui/storage_locations.ui create mode 100644 data/ui/storage_row.blp delete mode 100644 data/ui/storage_row.ui create mode 100644 data/ui/timer_popover.blp delete mode 100644 data/ui/timer_popover.ui diff --git a/.gitignore b/.gitignore index 89aa95db..ceb3efcb 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,8 @@ debian/debhelper-build-stamp debian/files peewee/ venv/ +env/ +blueprint-compiler/ .pytest_cache diff --git a/com.github.geigi.cozy.json b/com.github.geigi.cozy.json index 5d9ec935..b9202a58 100644 --- a/com.github.geigi.cozy.json +++ b/com.github.geigi.cozy.json @@ -111,6 +111,18 @@ } ] }, + { + "name": "blueprint-compiler", + "buildsystem": "meson", + "cleanup": [ "*" ], + "sources": [ + { + "type": "git", + "url": "https://gitlab.gnome.org/jwestman/blueprint-compiler.git", + "tag": "v0.10.0" + } + ] + }, { "name": "cozy", "buildsystem": "meson", diff --git a/cozy/application.py b/cozy/application.py index 89e1fda9..4c8dfab1 100644 --- a/cozy/application.py +++ b/cozy/application.py @@ -42,7 +42,7 @@ def do_startup(self): log.info("Starting up cozy %s", __version__) log.info("libadwaita version: %s", Adw._version) - self.ui = CozyUI(self.pkgdatadir, self, __version__) + self.ui = CozyUI(self, __version__) Adw.Application.do_startup(self) init_db() self.ui.startup() @@ -56,10 +56,9 @@ def do_activate(self): if Settings.get().first_start: Settings.update(first_start=False).execute() - path = os.path.join(Path.home(), _("Audiobooks")) - Storage.create(path=path, default=True) - - os.makedirs(path, exist_ok=True) + audiobooks_path = Path.home() / _("Audiobooks") + audiobooks_path.mkdir(exist_ok=True) + Storage.create(path=str(audiobooks_path), default=True) self.add_window(self.ui.window) @@ -82,7 +81,7 @@ def handle_exception(self, _): def quit(self): self.app_controller.quit() - super(Application, self).quit() + super().quit() @staticmethod def init_custom_widgets(): diff --git a/cozy/ui/about_window.py b/cozy/ui/about_window.py new file mode 100644 index 00000000..00acf0cd --- /dev/null +++ b/cozy/ui/about_window.py @@ -0,0 +1,57 @@ +from collections import defaultdict + +from gi.repository import Adw, Gio, Gtk + + +class AboutWindow: + def __init__(self, version: str) -> None: + self._window = Adw.AboutWindow.new_from_appdata( + "/com/github/geigi/cozy/appdata/com.github.geigi.cozy.appdata.xml", + release_notes_version=version, + ) + + contributors = self.get_contributors() + self._window.set_developers(sorted(contributors["code"])) + self._window.set_designers(sorted(contributors["design"])) + self._window.set_artists(sorted(contributors["icon"])) + + self._window.set_license_type(Gtk.License.GPL_3_0) + + # Translators: Replace "translator-credits" with your names, one name per line + self._window.set_translator_credits(_("translator-credits")) + + self.set_extra_credits() + + def get_contributors(self) -> list[str]: + authors_file = Gio.resources_lookup_data( + "/com/github/geigi/cozy/appdata/authors.list", Gio.ResourceLookupFlags.NONE + ) + + current_section = "" + result = defaultdict(list) + for line in authors_file.get_data().decode().splitlines(): + if line.startswith("#"): + current_section = line[1:].strip().lower() + elif line.startswith("-"): + result[current_section].append(line[1:].strip()) + + return result + + def set_extra_credits(self) -> None: + self._window.add_acknowledgement_section( + _("Patreon Supporters"), + ["Fred Warren", "Gabriel", "Hu Mann", "Josiah", "Oleksii Kriukov"], + ) + self._window.add_acknowledgement_section(_("m4b chapter support in mutagen"), ("mweinelt",)) + self._window.add_acknowledgement_section( + _("Open Source Projects"), + ("Lollypop music player https://gitlab.gnome.org/World/lollypop",), + ) + + self._window.add_legal_section( + "python-inject", "© 2010 Ivan Korobkov", Gtk.License.APACHE_2_0 + ) + + def present(self, parent: Adw.ApplicationWindow) -> None: + self._window.set_transient_for(parent) + self._window.present() diff --git a/cozy/ui/book_detail_view.py b/cozy/ui/book_detail_view.py index 3a25271c..48c9a3df 100644 --- a/cozy/ui/book_detail_view.py +++ b/cozy/ui/book_detail_view.py @@ -22,7 +22,7 @@ ALBUM_ART_SIZE = 256 -@Gtk.Template.from_resource('/com/github/geigi/cozy/book_detail.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/book_detail.ui') class BookDetailView(Gtk.Box): __gtype_name__ = 'BookDetail' diff --git a/cozy/ui/chapter_element.py b/cozy/ui/chapter_element.py index 10f20aae..ff75af4b 100644 --- a/cozy/ui/chapter_element.py +++ b/cozy/ui/chapter_element.py @@ -4,7 +4,7 @@ from cozy.model.chapter import Chapter -@Gtk.Template.from_resource('/com/github/geigi/cozy/chapter_element.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/chapter_element.ui') class ChapterElement(Gtk.Box): __gtype_name__ = "ChapterElement" diff --git a/cozy/ui/headerbar.py b/cozy/ui/headerbar.py index 48c8efa2..fbca9e70 100644 --- a/cozy/ui/headerbar.py +++ b/cozy/ui/headerbar.py @@ -15,7 +15,7 @@ log = logging.getLogger("Headerbar") -@Gtk.Template.from_resource("/com/github/geigi/cozy/headerbar.ui") +@Gtk.Template.from_resource("/com/github/geigi/cozy/ui/headerbar.ui") class Headerbar(Gtk.Box): __gtype_name__ = "Headerbar" diff --git a/cozy/ui/main_view.py b/cozy/ui/main_view.py index a7f67808..c113e1b3 100644 --- a/cozy/ui/main_view.py +++ b/cozy/ui/main_view.py @@ -21,7 +21,8 @@ from cozy.view_model.storages_view_model import StoragesViewModel from cozy.open_view import OpenView from cozy.ui.library_view import LibraryView -from cozy.ui.preferences_view import PreferencesView +from cozy.ui.about_window import AboutWindow +from cozy.ui.preferences_window import PreferencesWindow from cozy.ui.widgets.first_import_button import FirstImportButton @@ -29,12 +30,8 @@ class CozyUI(EventSender, metaclass=Singleton): - """ - CozyUI is the main ui class. - """ - # Is currently an dialog open? - is_initialized = False - __inhibit_cookie = None + """CozyUI is the main ui class""" + fs_monitor = inject.attr(fs_monitor.FilesystemMonitor) application_settings = inject.attr(ApplicationSettings) _importer: Importer = inject.attr(Importer) @@ -43,14 +40,13 @@ class CozyUI(EventSender, metaclass=Singleton): _player: Player = inject.attr(Player) _storages_view_model: StoragesViewModel = inject.attr(StoragesViewModel) - def __init__(self, pkgdatadir, app, version): + _library_view: LibraryView + + def __init__(self, app, version): super().__init__() - self.pkgdir = pkgdatadir self.app = app self.version = version - self._library_view: LibraryView = None - def activate(self, library_view: LibraryView): self.__init_window() self.__init_actions() @@ -61,24 +57,9 @@ def activate(self, library_view: LibraryView): self.auto_import() self.check_for_tracks() - self.is_initialized = True - def startup(self): - self.__init_resources() - - def __init_resources(self): - """ - Initialize all resources like gresource and glade windows. - """ - - self.appdata_resource = Gio.resource_load( - os.path.join(self.pkgdir, 'com.github.geigi.cozy.appdata.gresource')) - Gio.Resource._register(self.appdata_resource) - - self.window_builder = Gtk.Builder.new_from_resource( - "/com/github/geigi/cozy/main_window.ui") - - self.window: Gtk.Window = self.window_builder.get_object("app_window") + self.window_builder = Gtk.Builder.new_from_resource("/com/github/geigi/cozy/ui/main_window.ui") + self.window: Adw.ApplicationWindow = self.window_builder.get_object("app_window") def __init_window(self): """ @@ -112,15 +93,9 @@ def __init_actions(self): """ Init all app actions. """ - - about_action = Gio.SimpleAction.new("about", None) - about_action.connect("activate", self.about) - self.app.add_action(about_action) - self.app.set_accels_for_action("app.about", ["F1"]) - - self.create_action("about", self.about) + self.create_action("about", self.show_about_window, ["F1"]) + self.create_action("prefs", self.show_preferences_window, ["comma"]) self.create_action("quit", self.quit, ["q", "w"]) - self.create_action("prefs", self.show_prefs, ["comma"]) self.scan_action = self.create_action("scan", self.scan) self.play_pause_action = self.create_action("play_pause", self.play_pause, ["space"]) @@ -130,6 +105,16 @@ def __init_actions(self): self.hide_offline_action.connect("change-state", self.__on_hide_offline) self.app.add_action(self.hide_offline_action) + def __init_components(self): + path = self._settings.default_location.path if self._settings.storage_locations else None + self.import_button = FirstImportButton(self._set_audiobook_path, path) + self.get_object("welcome_status_page").set_child(self.import_button) + + if not self._player.loaded_book: + self.block_ui_buttons(True) + + self._importer.add_listener(self._on_importer_event) + def create_action( self, name: str, @@ -145,16 +130,6 @@ def create_action( return action - def __init_components(self): - path = self._settings.default_location.path if self._settings.storage_locations else None - self.import_button = FirstImportButton(self._set_audiobook_path, path) - self.get_object("welcome_status_page").set_child(self.import_button) - - if not self._player.loaded_book: - self.block_ui_buttons(True) - - self._importer.add_listener(self._on_importer_event) - def get_object(self, name): return self.window_builder.get_object(name) @@ -165,60 +140,11 @@ def quit(self, action, parameter): self.on_close(None) self.app.quit() - def _get_contributors(self): - authors_file = self.appdata_resource.lookup_data("/com/github/geigi/cozy/authors", Gio.ResourceLookupFlags.NONE) - - current_section = "" - result = defaultdict(list) - for line in authors_file.get_data().decode().splitlines(): - if line.startswith("#"): - current_section = line[1:].strip().lower() - elif line.startswith("-"): - result[current_section].append(line[1:].strip()) - - return result - - def about(self, *junk): - """ - Show about window. - """ - about = Adw.AboutWindow.new_from_appdata( - "/com/github/geigi/cozy/com.github.geigi.cozy.appdata.xml", - release_notes_version=self.version, - ) - - contributors = self._get_contributors() - about.set_developers(sorted(contributors["code"])) - about.set_designers(sorted(contributors["design"])) - about.set_artists(sorted(contributors["icon"])) - - about.set_license_type(Gtk.License.GPL_3_0) - - about.add_acknowledgement_section( - _("Patreon Supporters"), - ["Fred Warren", "Gabriel", "Hu Mann", "Josiah", "Oleksii Kriukov"] - ) - about.add_acknowledgement_section( - _("m4b chapter support in mutagen"), - ("mweinelt",), - ) - about.add_acknowledgement_section( - _("Open Source Projects"), - ("Lollypop music player https://gitlab.gnome.org/World/lollypop",), - ) - - # Translators: Replace "translator-credits" with your names, one name per line - about.set_translator_credits(_("translator-credits")) - about.add_legal_section("python-inject", "© 2010 Ivan Korobkov", Gtk.License.APACHE_2_0) + def show_about_window(self, *_): + AboutWindow(self.version).present(self.window) - about.set_transient_for(self.window) - about.present() - - def show_prefs(self, *_): - """ - Show preferences window. - """ - PreferencesView().present() + def show_preferences_window(self, *_): + PreferencesWindow().present(self.window) def play_pause(self, *_): self._player.play_pause() diff --git a/cozy/ui/media_controller.py b/cozy/ui/media_controller.py index ae0c64b6..15100bce 100644 --- a/cozy/ui/media_controller.py +++ b/cozy/ui/media_controller.py @@ -17,7 +17,7 @@ COVER_SIZE = 46 -@Gtk.Template.from_resource('/com/github/geigi/cozy/media_controller.ui') +@Gtk.Template.from_resource("/com/github/geigi/cozy/ui/media_controller.ui") class MediaController(Adw.BreakpointBin): __gtype_name__ = "MediaController" @@ -50,7 +50,18 @@ def __init__(self, main_window_builder: Gtk.Builder): self.playback_speed_button.set_popover(PlaybackSpeedPopover()) self.timer_button.set_popover(self.sleep_timer) - self._playback_control_view_model: PlaybackControlViewModel = inject.instance(PlaybackControlViewModel) + self.volume_button.set_icons( + [ + "audio-volume-muted-symbolic", + "audio-volume-high-symbolic", + "audio-volume-low-symbolic", + "audio-volume-medium-symbolic", + ] + ) + + self._playback_control_view_model: PlaybackControlViewModel = inject.instance( + PlaybackControlViewModel + ) self._artwork_cache: ArtworkCache = inject.instance(ArtworkCache) self._connect_view_model() self._connect_widgets() @@ -85,7 +96,9 @@ def _connect_widgets(self): self.cover_img.set_cursor(Gdk.Cursor.new_from_name("pointer")) def _set_cover_image(self, book: Book): - paintable = self._artwork_cache.get_cover_paintable(book, self.get_scale_factor(), COVER_SIZE) + paintable = self._artwork_cache.get_cover_paintable( + book, self.get_scale_factor(), COVER_SIZE + ) if paintable: self.cover_img.set_from_paintable(paintable) else: diff --git a/cozy/ui/preferences_view.py b/cozy/ui/preferences_view.py deleted file mode 100644 index decca8ff..00000000 --- a/cozy/ui/preferences_view.py +++ /dev/null @@ -1,95 +0,0 @@ -from typing import Any -from gi.repository import Adw, Gio, Gtk - -from cozy.ext import inject -from cozy.ui.widgets.error_reporting import ErrorReporting - -from cozy.ui.widgets.storages import StorageLocations -from cozy.view_model.settings_view_model import SettingsViewModel - - -@Gtk.Template.from_resource("/com/github/geigi/cozy/preferences.ui") -class PreferencesView(Adw.PreferencesWindow): - __gtype_name__ = "PreferencesWindow" - - _glib_settings: Gio.Settings = inject.attr(Gio.Settings) - _view_model: SettingsViewModel = inject.attr(SettingsViewModel) - - storages_page: Adw.PreferencesPage = Gtk.Template.Child() - user_feedback_preference_group: Adw.PreferencesGroup = Gtk.Template.Child() - - dark_mode_switch: Adw.SwitchRow = Gtk.Template.Child() - swap_author_reader_switch: Adw.SwitchRow = Gtk.Template.Child() - replay_switch: Adw.SwitchRow = Gtk.Template.Child() - sleep_timer_fadeout_switch: Adw.SwitchRow = Gtk.Template.Child() - artwork_prefer_external_switch: Adw.SwitchRow = Gtk.Template.Child() - - rewind_duration_adjustment: Gtk.Adjustment = Gtk.Template.Child() - forward_duration_adjustment: Gtk.Adjustment = Gtk.Template.Child() - fadeout_duration_adjustment: Gtk.Adjustment = Gtk.Template.Child() - - def __init__(self, **kwargs: Any) -> None: - main_window = inject.instance("MainWindow") - super().__init__(transient_for=main_window.window, **kwargs) - - error_reporting = ErrorReporting() - error_reporting.show_header(False) - self.user_feedback_preference_group.add(error_reporting) - - self.storage_locations_view = StorageLocations() - self.storages_page.add(self.storage_locations_view) - - self._view_model.bind_to("lock_ui", self._on_lock_ui_changed) - self._bind_settings() - - def _bind_settings(self) -> None: - self._glib_settings.bind( - "dark-mode", self.dark_mode_switch, "active", Gio.SettingsBindFlags.DEFAULT - ) - - self._glib_settings.bind( - "swap-author-reader", - self.swap_author_reader_switch, - "active", - Gio.SettingsBindFlags.DEFAULT, - ) - - self._glib_settings.bind( - "replay", self.replay_switch, "active", Gio.SettingsBindFlags.DEFAULT - ) - self._glib_settings.bind( - "rewind-duration", - self.rewind_duration_adjustment, - "value", - Gio.SettingsBindFlags.DEFAULT, - ) - self._glib_settings.bind( - "forward-duration", - self.forward_duration_adjustment, - "value", - Gio.SettingsBindFlags.DEFAULT, - ) - - self._glib_settings.bind( - "sleep-timer-fadeout", - self.sleep_timer_fadeout_switch, - "enable-expansion", - Gio.SettingsBindFlags.DEFAULT, - ) - - self._glib_settings.bind( - "sleep-timer-fadeout-duration", - self.fadeout_duration_adjustment, - "value", - Gio.SettingsBindFlags.DEFAULT, - ) - - self._glib_settings.bind( - "prefer-external-cover", - self.artwork_prefer_external_switch, - "active", - Gio.SettingsBindFlags.DEFAULT, - ) - - def _on_lock_ui_changed(self) -> None: - self.storage_locations_view.set_sensitive(not self._view_model.lock_ui) diff --git a/cozy/ui/preferences_window.py b/cozy/ui/preferences_window.py new file mode 100644 index 00000000..0ad0e95c --- /dev/null +++ b/cozy/ui/preferences_window.py @@ -0,0 +1,61 @@ +from gi.repository import Adw, Gio, Gtk + +from cozy.ext import inject +from cozy.ui.widgets.error_reporting import ErrorReporting +from cozy.ui.widgets.storages import StorageLocations +from cozy.view_model.settings_view_model import SettingsViewModel + + +@Gtk.Template.from_resource("/com/github/geigi/cozy/ui/preferences.ui") +class PreferencesWindow(Adw.PreferencesWindow): + __gtype_name__ = "PreferencesWindow" + + _glib_settings: Gio.Settings = inject.attr(Gio.Settings) + _view_model: SettingsViewModel = inject.attr(SettingsViewModel) + + storages_page: Adw.PreferencesPage = Gtk.Template.Child() + user_feedback_preference_group: Adw.PreferencesGroup = Gtk.Template.Child() + + dark_mode_switch: Adw.SwitchRow = Gtk.Template.Child() + swap_author_reader_switch: Adw.SwitchRow = Gtk.Template.Child() + replay_switch: Adw.SwitchRow = Gtk.Template.Child() + sleep_timer_fadeout_switch: Adw.SwitchRow = Gtk.Template.Child() + artwork_prefer_external_switch: Adw.SwitchRow = Gtk.Template.Child() + + rewind_duration_adjustment: Gtk.Adjustment = Gtk.Template.Child() + forward_duration_adjustment: Gtk.Adjustment = Gtk.Template.Child() + fadeout_duration_adjustment: Gtk.Adjustment = Gtk.Template.Child() + + def __init__(self) -> None: + super().__init__() + + error_reporting = ErrorReporting() + error_reporting.show_header(False) + self.user_feedback_preference_group.add(error_reporting) + + self.storage_locations_view = StorageLocations() + self.storages_page.add(self.storage_locations_view) + + self._view_model.bind_to("lock_ui", self._on_lock_ui_changed) + self._bind_settings() + + def _bind_settings(self) -> None: + bind_settings = lambda setting, widget, propetry: self._glib_settings.bind( + setting, widget, propetry, Gio.SettingsBindFlags.DEFAULT + ) + + bind_settings("dark-mode", self.dark_mode_switch, "active") + bind_settings("swap-author-reader", self.swap_author_reader_switch, "active") + bind_settings("replay", self.replay_switch, "active") + bind_settings("rewind-duration", self.rewind_duration_adjustment, "value") + bind_settings("forward-duration", self.forward_duration_adjustment, "value") + bind_settings("sleep-timer-fadeout", self.sleep_timer_fadeout_switch, "enable-expansion") + bind_settings("sleep-timer-fadeout-duration", self.fadeout_duration_adjustment, "value") + bind_settings("prefer-external-cover", self.artwork_prefer_external_switch, "active") + + def _on_lock_ui_changed(self) -> None: + self.storage_locations_view.set_sensitive(not self._view_model.lock_ui) + + def present(self, parent: Adw.ApplicationWindow) -> None: + self.set_transient_for(parent) + super().present() diff --git a/cozy/ui/search_view.py b/cozy/ui/search_view.py index c83d2b4a..99ec3b31 100644 --- a/cozy/ui/search_view.py +++ b/cozy/ui/search_view.py @@ -11,7 +11,7 @@ from cozy.view_model.search_view_model import SearchViewModel -@Gtk.Template.from_resource("/com/github/geigi/cozy/search_page.ui") +@Gtk.Template.from_resource("/com/github/geigi/cozy/ui/search_page.ui") class SearchView(Adw.Bin): __gtype_name__ = "SearchView" diff --git a/cozy/ui/widgets/album_element.py b/cozy/ui/widgets/album_element.py index 11a84a1d..790d08d6 100644 --- a/cozy/ui/widgets/album_element.py +++ b/cozy/ui/widgets/album_element.py @@ -16,7 +16,7 @@ log = logging.getLogger("album_element") -@Gtk.Template.from_resource('/com/github/geigi/cozy/album_element.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/album_element.ui') class AlbumElement(Gtk.Box): __gtype_name__ = "AlbumElement" diff --git a/cozy/ui/widgets/book_element.py b/cozy/ui/widgets/book_element.py index 8bb61fe5..efeb965a 100644 --- a/cozy/ui/widgets/book_element.py +++ b/cozy/ui/widgets/book_element.py @@ -4,7 +4,7 @@ from cozy.ui.widgets.album_element import AlbumElement -@Gtk.Template.from_resource('/com/github/geigi/cozy/book_element.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/book_element.ui') class BookElement(Gtk.FlowBoxChild): __gtype_name__ = "BookElement" diff --git a/cozy/ui/widgets/error_reporting.py b/cozy/ui/widgets/error_reporting.py index 36103270..a5c0887b 100644 --- a/cozy/ui/widgets/error_reporting.py +++ b/cozy/ui/widgets/error_reporting.py @@ -30,7 +30,7 @@ } -@Gtk.Template.from_resource('/com/github/geigi/cozy/error_reporting.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/error_reporting.ui') class ErrorReporting(Gtk.Box): __gtype_name__ = 'ErrorReporting' diff --git a/cozy/ui/widgets/first_import_button.py b/cozy/ui/widgets/first_import_button.py index a72c9f45..f4271d3f 100644 --- a/cozy/ui/widgets/first_import_button.py +++ b/cozy/ui/widgets/first_import_button.py @@ -5,7 +5,7 @@ from typing import Callable -@Gtk.Template.from_resource('/com/github/geigi/cozy/first_import_button.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/first_import_button.ui') class FirstImportButton(Gtk.Button): __gtype_name__ = "FirstImportButton" diff --git a/cozy/ui/widgets/playback_speed_popover.py b/cozy/ui/widgets/playback_speed_popover.py index 18c9266b..6478e8ca 100644 --- a/cozy/ui/widgets/playback_speed_popover.py +++ b/cozy/ui/widgets/playback_speed_popover.py @@ -4,7 +4,7 @@ from gi.repository import Gtk -@Gtk.Template.from_resource('/com/github/geigi/cozy/playback_speed_popover.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/playback_speed_popover.ui') class PlaybackSpeedPopover(Gtk.Popover): __gtype_name__ = "PlaybackSpeedPopover" diff --git a/cozy/ui/widgets/progress_popover.py b/cozy/ui/widgets/progress_popover.py index 8c5fe889..c50d219c 100644 --- a/cozy/ui/widgets/progress_popover.py +++ b/cozy/ui/widgets/progress_popover.py @@ -1,7 +1,7 @@ from gi.repository import Gtk -@Gtk.Template.from_resource('/com/github/geigi/cozy/progress_popover.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/progress_popover.ui') class ProgressPopover(Gtk.Popover): __gtype_name__ = 'ProgressPopover' diff --git a/cozy/ui/widgets/seek_bar.py b/cozy/ui/widgets/seek_bar.py index ffadb331..9c058086 100644 --- a/cozy/ui/widgets/seek_bar.py +++ b/cozy/ui/widgets/seek_bar.py @@ -3,7 +3,7 @@ from cozy.control.string_representation import seconds_to_str -@Gtk.Template.from_resource('/com/github/geigi/cozy/seek_bar.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/seek_bar.ui') class SeekBar(Gtk.Box): __gtype_name__ = "SeekBar" diff --git a/cozy/ui/widgets/sleep_timer.py b/cozy/ui/widgets/sleep_timer.py index 6d396db1..b7bad85a 100644 --- a/cozy/ui/widgets/sleep_timer.py +++ b/cozy/ui/widgets/sleep_timer.py @@ -4,7 +4,7 @@ from gi.repository import Gtk -@Gtk.Template.from_resource('/com/github/geigi/cozy/timer_popover.ui') +@Gtk.Template.from_resource('/com/github/geigi/cozy/ui/timer_popover.ui') class SleepTimer(Gtk.Popover): __gtype_name__ = "SleepTimer" diff --git a/cozy/ui/widgets/storages.py b/cozy/ui/widgets/storages.py index f20726dd..a6366929 100644 --- a/cozy/ui/widgets/storages.py +++ b/cozy/ui/widgets/storages.py @@ -25,7 +25,7 @@ def finish_callback(dialog, result): location_chooser.select_folder(inject.instance("MainWindow").window, None, finish_callback) -@Gtk.Template.from_resource("/com/github/geigi/cozy/storage_row.ui") +@Gtk.Template.from_resource("/com/github/geigi/cozy/ui/storage_row.ui") class StorageRow(Adw.ActionRow): __gtype_name__ = "StorageRow" @@ -81,7 +81,7 @@ def _set_default_icon(self) -> None: GObject.signal_new("menu-opened", StorageRow, GObject.SIGNAL_RUN_LAST, GObject.TYPE_PYOBJECT, ()) -@Gtk.Template.from_resource("/com/github/geigi/cozy/storage_locations.ui") +@Gtk.Template.from_resource("/com/github/geigi/cozy/ui/storage_locations.ui") class StorageLocations(Adw.PreferencesGroup): __gtype_name__ = "StorageLocations" diff --git a/data/gresource.xml b/data/gresource.xml index 79834c56..ed745904 100644 --- a/data/gresource.xml +++ b/data/gresource.xml @@ -1,8 +1,28 @@ + style.css + ui/album_element.ui + ui/book_detail.ui + ui/book_element.ui + ui/chapter_element.ui + ui/error_reporting.ui + ui/first_import_button.ui + ui/headerbar.ui + ui/main_window.ui + ui/media_controller.ui + ui/playback_speed_popover.ui + ui/preferences.ui + ui/progress_popover.ui + ui/search_page.ui + ui/seek_bar.ui + ui/storage_locations.ui + ui/storage_row.ui + ui/timer_popover.ui + + + ../AUTHORS.md com.github.geigi.cozy.appdata.xml - ../AUTHORS.md diff --git a/data/meson.build b/data/meson.build index d6e010a5..8d002ba1 100644 --- a/data/meson.build +++ b/data/meson.build @@ -2,14 +2,15 @@ subdir('ui') subdir('icons') gnome.compile_resources( - meson.project_name() + '.appdata', - 'gresource.xml', - gresource_bundle: true, - install_dir: DATA_DIR, - install: true, + meson.project_name(), + 'gresource.xml', + dependencies: blueprints, + gresource_bundle: true, + source_dir: meson.current_build_dir(), + install_dir: DATA_DIR, + install: true, ) - install_data( meson.project_name() + '.gschema.xml', install_dir: join_paths(get_option('datadir'), 'glib-2.0', 'schemas') diff --git a/data/ui/style.css b/data/style.css similarity index 100% rename from data/ui/style.css rename to data/style.css diff --git a/data/ui/album_element.blp b/data/ui/album_element.blp new file mode 100644 index 00000000..fea55dc5 --- /dev/null +++ b/data/ui/album_element.blp @@ -0,0 +1,62 @@ +using Gtk 4.0; + +template $AlbumElement: Box { + orientation: vertical; + + Overlay { + child: Overlay { + child: Image album_art_image {}; + + [overlay] + Revealer album_art_overlay_revealer { + transition-type: crossfade; + transition-duration: 200; + + child: DrawingArea album_art_drawing_area {}; + } + }; + + [overlay] + Revealer play_button_revealer { + name: 'play_button_revealer'; + halign: end; + valign: end; + hexpand: false; + vexpand: false; + transition-type: crossfade; + transition-duration: 200; + + child: Overlay { + halign: end; + valign: end; + margin-end: 10; + margin-bottom: 10; + + child: Button play_button { + width-request: 40; + height-request: 40; + focusable: true; + focus-on-click: false; + tooltip-text: _('Play'); + halign: center; + valign: center; + icon-name: 'media-playback-start-symbolic'; + + styles [ + "circular", + "book_play_button", + ] + }; + + [overlay] + DrawingArea progress_drawing_area { + can-target: false; + width-request: 40; + height-request: 40; + halign: center; + valign: center; + } + }; + } + } +} diff --git a/data/ui/album_element.ui b/data/ui/album_element.ui deleted file mode 100644 index 5ed94ea6..00000000 --- a/data/ui/album_element.ui +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/data/ui/book_detail.blp b/data/ui/book_detail.blp new file mode 100644 index 00000000..43ae11f1 --- /dev/null +++ b/data/ui/book_detail.blp @@ -0,0 +1,356 @@ +using Gtk 4.0; +using Adw 1; + +template $BookDetail: Box { + Box { + orientation: vertical; + + ScrolledWindow { + focusable: true; + valign: center; + vexpand: true; + hscrollbar-policy: never; + propagate-natural-width: true; + propagate-natural-height: true; + + child: Viewport { + child: FlowBox main_flow_box { + valign: center; + margin-start: 12; + margin-end: 12; + margin-top: 12; + margin-bottom: 12; + hexpand: true; + vexpand: true; + column-spacing: 12; + row-spacing: 12; + min-children-per-line: 1; + max-children-per-line: 2; + selection-mode: none; + + FlowBoxChild { + halign: center; + valign: start; + + child: Adw.Clamp { + maximum-size: 250; + tightening-threshold: 250; + + Box { + orientation: vertical; + spacing: 6; + + Box album_art_container { + halign: center; + margin-bottom: 18; + width-request: 256; + height-request: 256; + + Picture album_art { + styles [ + "book_detail_art", + ] + } + + styles [ + "card", + ] + } + + Label book_label { + halign: start; + valign: end; + label: 'Book name'; + wrap: true; + wrap-mode: word_char; + ellipsize: end; + max-width-chars: 25; + lines: 4; + xalign: 0; + + styles [ + "title-1", + "bold", + ] + } + + Label author_label { + halign: start; + valign: start; + margin-bottom: 6; + label: 'Book author'; + wrap: true; + wrap-mode: word_char; + ellipsize: end; + max-width-chars: 30; + lines: 2; + xalign: 0; + + styles [ + "title-3", + "dim-label", + ] + } + + Box { + halign: center; + valign: center; + margin-bottom: 12; + spacing: 5; + + Box download_box { + halign: end; + valign: center; + + Image download_image { + icon-name: 'download-symbolic'; + } + + Label download_label { + margin-start: 5; + margin-end: 4; + label: _('Download'); + } + } + + Switch download_switch { + focusable: true; + halign: start; + valign: center; + } + } + + ProgressBar book_progress_bar { + width-request: 250; + halign: center; + valign: start; + show-text: true; + margin-bottom: 18; + } + + Grid { + margin-bottom: 18; + hexpand: true; + row-spacing: 4; + column-spacing: 20; + + Label remaining_text { + halign: start; + hexpand: true; + label: _('Remaining'); + + styles [ + "dim-label", + ] + + layout { + column: '0'; + row: '3'; + } + } + + Label remaining_label { + hexpand: true; + label: 'label'; + xalign: 0; + + layout { + column: '1'; + row: '3'; + } + } + + Label total_label { + hexpand: true; + label: 'label'; + xalign: 0; + + layout { + column: '1'; + row: '2'; + } + } + + Label last_played_label { + hexpand: true; + label: 'label'; + xalign: 0; + + layout { + column: '1'; + row: '1'; + } + } + + Label { + halign: start; + label: _('Total'); + + styles [ + "dim-label", + ] + + layout { + column: '0'; + row: '2'; + } + } + + Label { + halign: start; + label: _('Last played'); + + styles [ + "dim-label", + ] + + layout { + column: '0'; + row: '1'; + } + } + + Label published_text { + halign: start; + label: _('Published'); + + styles [ + "dim-label", + ] + + layout { + column: '0'; + row: '0'; + } + } + + Label published_label { + hexpand: true; + label: 'label'; + xalign: 0; + + layout { + column: '1'; + row: '0'; + } + } + } + + Box unavailable_box { + tooltip-text: _('Some or all files of this book cannot be found.'); + halign: center; + spacing: 4; + + Image { + icon-name: 'info-symbolic'; + + styles [ + "unavailable_image", + ] + } + + Label { + label: _('unavailable'); + + styles [ + "unavailable_label", + ] + } + + styles [ + "unavailable_box", + ] + } + + Box { + margin-top: 20; + orientation: vertical; + + Button play_book_button { + focusable: true; + receives-default: true; + halign: center; + icon-name: 'media-playback-start-symbolic'; + + styles [ + "suggested-action", + "pill", + ] + } + } + } + }; + } + + FlowBoxChild { + hexpand: true; + vexpand: true; + + child: Adw.Clamp { + maximum-size: 500; + tightening-threshold: 350; + + Stack chapters_stack { + StackPage { + name: 'chapters_wrapper'; + title: 'page0'; + + child: ScrolledWindow book_overview_scroller { + focusable: true; + hexpand: true; + vexpand: true; + hscrollbar-policy: never; + vscrollbar-policy: never; + propagate-natural-width: true; + propagate-natural-height: true; + + child: Viewport track_list_container { + child: Box chapter_box { + valign: start; + margin-start: 8; + margin-end: 8; + margin-top: 8; + margin-bottom: 8; + orientation: vertical; + spacing: 4; + }; + + styles [ + "no_frame", + ] + }; + + styles [ + "no_frame", + ] + }; + } + + StackPage { + name: 'chapters_loader'; + title: 'chapters'; + + child: Box { + halign: center; + valign: start; + margin-top: 8; + + Spinner { + halign: center; + hexpand: true; + } + + Label chapters_loading_text { + halign: center; + label: _('Loading chapters, please wait...'); + } + }; + } + } + }; + } + }; + }; + } + } +} diff --git a/data/ui/book_detail.ui b/data/ui/book_detail.ui deleted file mode 100644 index df9a7838..00000000 --- a/data/ui/book_detail.ui +++ /dev/null @@ -1,387 +0,0 @@ - - - - - - - diff --git a/data/ui/book_element.blp b/data/ui/book_element.blp new file mode 100644 index 00000000..a8090ec0 --- /dev/null +++ b/data/ui/book_element.blp @@ -0,0 +1,53 @@ +using Gtk 4.0; + +template $BookElement: FlowBoxChild { + height-request: 150; + width-request: 150; + + child: Box container_box { + focusable: true; + tooltip-text: _('Open book overview'); + orientation: vertical; + spacing: 1; + valign: start; + + Label name_label { + halign: start; + valign: end; + margin-top: 15; + hexpand: false; + vexpand: false; + wrap: true; + ellipsize: end; + max-width-chars: 20; + xalign: 0; + yalign: 0; + + styles [ + "heading", + ] + } + + Label author_label { + halign: start; + valign: end; + hexpand: false; + vexpand: false; + wrap: true; + ellipsize: end; + max-width-chars: 30; + xalign: 0; + yalign: 0; + + styles [ + "dim-label", + "caption", + ] + } + + styles [ + "card", + "book_card", + ] + }; +} diff --git a/data/ui/book_element.ui b/data/ui/book_element.ui deleted file mode 100644 index ad157685..00000000 --- a/data/ui/book_element.ui +++ /dev/null @@ -1,55 +0,0 @@ - - - - - diff --git a/data/ui/chapter_element.blp b/data/ui/chapter_element.blp new file mode 100644 index 00000000..a3017374 --- /dev/null +++ b/data/ui/chapter_element.blp @@ -0,0 +1,64 @@ +using Gtk 4.0; + +template $ChapterElement: Box { + tooltip-text: _('Play this part'); + + Box { + margin-start: 12; + margin-end: 12; + margin-top: 6; + margin-bottom: 6; + spacing: 5; + + Stack icon_stack { + StackPage { + name: 'number'; + + child: Label number_label { + halign: start; + width-chars: 3; + xalign: 0; + yalign: 0; + + styles [ + "dim-label", + ] + }; + } + + StackPage { + name: 'play_icon'; + + child: Image play_icon { + halign: start; + valign: center; + icon-name: 'media-playback-start-symbolic'; + pixel-size: 12; + }; + } + } + + Label title_label { + hexpand: true; + ellipsize: end; + max-width-chars: 50; + xalign: 0; + yalign: 0; + + styles [ + "semi-bold", + ] + } + + Label duration_label { + halign: end; + justify: right; + xalign: 0; + yalign: 0; + } + } + + styles [ + "chapter_element", + ] +} diff --git a/data/ui/chapter_element.ui b/data/ui/chapter_element.ui deleted file mode 100644 index 21137c26..00000000 --- a/data/ui/chapter_element.ui +++ /dev/null @@ -1,72 +0,0 @@ - - - - - diff --git a/data/ui/error_reporting.blp b/data/ui/error_reporting.blp new file mode 100644 index 00000000..8eaac02b --- /dev/null +++ b/data/ui/error_reporting.blp @@ -0,0 +1,174 @@ +using Gtk 4.0; + +Adjustment verbose_adjustment { + lower: 1; + upper: 5; + value: 3; + step-increment: 1; + page-increment: 1; + page-size: 1; +} + +template $ErrorReporting: Box { + orientation: vertical; + spacing: 10; + + styles [ + "card", + ] + + Box header_box { + halign: center; + spacing: 15; + + Label { + label: _('User feedback'); + wrap: true; + + styles [ + "title-3", + ] + } + + Image { + pixel-size: 32; + icon-name: 'book-alert-symbolic'; + } + } + + ListBox { + selection-mode: none; + activate-on-single-click: false; + + styles [ + "transparent_bg", + ] + + ListBoxRow { + activatable: false; + selectable: false; + + child: Box { + margin-start: 10; + margin-end: 10; + margin-top: 10; + margin-bottom: 10; + orientation: vertical; + spacing: 10; + + Box { + valign: center; + orientation: vertical; + spacing: 10; + + Label { + halign: start; + valign: center; + label: C_('Error and crash reporting dialog', 'You can help improve Cozy by contributing information in case of errors and crashes. '); + wrap: true; + xalign: 0; + } + + Label { + valign: center; + label: C_('Error and crash reporting dialog', 'Contributing this information is optional and completely anonymous. We will never collect personal data, files you import or any information that could identify you.'); + wrap: true; + xalign: 0; + } + + Label { + valign: center; + halign: start; + label: C_('Error and crash reporting dialog', 'Cozy is opensource and the user feedback source code can be inspected here: '); + wrap: true; + xalign: 0; + } + } + + Label { + label: _('Sourcecode on GitHub'); + use-markup: true; + } + }; + } + + ListBoxRow { + activatable: false; + selectable: false; + + child: Separator { + margin-start: 5; + margin-end: 5; + }; + } + + ListBoxRow { + activatable: false; + selectable: false; + + child: Scale verbose_scale { + focusable: true; + margin-start: 20; + margin-end: 20; + margin-top: 10; + margin-bottom: 10; + adjustment: verbose_adjustment; + restrict-to-fill-level: false; + fill-level: 0; + round-digits: 0; + }; + } + + ListBoxRow { + activatable: false; + selectable: false; + + child: Separator { + margin-start: 5; + margin-end: 5; + }; + } + + ListBoxRow { + activatable: false; + selectable: false; + + child: Box { + halign: start; + valign: center; + margin-start: 10; + margin-end: 10; + margin-top: 10; + margin-bottom: 10; + orientation: vertical; + spacing: 10; + + Label level_label { + halign: start; + label: _('Detailed error reporting with import errors'); + wrap: true; + xalign: 0; + + styles [ + "heading", + ] + } + + Label description_label { + halign: start; + valign: start; + label: _('The following information will be sent in case of an error or crash:'); + wrap: true; + xalign: 0; + } + + Label details_label { + vexpand: true; + halign: start; + valign: start; + wrap: true; + } + }; + } + } +} diff --git a/data/ui/error_reporting.ui b/data/ui/error_reporting.ui deleted file mode 100644 index 53900433..00000000 --- a/data/ui/error_reporting.ui +++ /dev/null @@ -1,194 +0,0 @@ - - - - - 1 - 5 - 3 - 1 - 1 - 1 - - - diff --git a/data/ui/first_import_button.blp b/data/ui/first_import_button.blp new file mode 100644 index 00000000..00fd60b4 --- /dev/null +++ b/data/ui/first_import_button.blp @@ -0,0 +1,23 @@ +using Gtk 4.0; +using Adw 1; + +template $FirstImportButton: Button { + halign: center; + + Stack stack { + hhomogeneous: false; + + Adw.ButtonContent label { + halign: center; + label: _('Select Folder'); + icon-name: 'folder-open-symbolic'; + } + + Spinner spinner {} + } + + styles [ + "suggested-action", + "pill", + ] +} diff --git a/data/ui/first_import_button.ui b/data/ui/first_import_button.ui deleted file mode 100644 index ff26a8b3..00000000 --- a/data/ui/first_import_button.ui +++ /dev/null @@ -1,26 +0,0 @@ - - - - - diff --git a/data/ui/gresource.xml b/data/ui/gresource.xml deleted file mode 100644 index b8098433..00000000 --- a/data/ui/gresource.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - style.css - album_element.ui - book_detail.ui - book_element.ui - chapter_element.ui - error_reporting.ui - first_import_button.ui - headerbar.ui - main_window.ui - media_controller.ui - playback_speed_popover.ui - preferences.ui - progress_popover.ui - search_page.ui - seek_bar.ui - storage_locations.ui - storage_row.ui - timer_popover.ui - - diff --git a/data/ui/headerbar.blp b/data/ui/headerbar.blp new file mode 100644 index 00000000..7f71b50b --- /dev/null +++ b/data/ui/headerbar.blp @@ -0,0 +1,107 @@ +using Gtk 4.0; +using Adw 1; + +template $Headerbar: Box { + orientation: vertical; + + Adw.HeaderBar headerbar { + [title] + Adw.ViewSwitcher view_switcher { + policy: wide; + } + + [start] + ToggleButton show_sidebar_button { + visible: false; + icon-name: 'sidebar-show-symbolic'; + tooltip-text: _('Toggle Filter Sidebar'); + } + + [end] + MenuButton menu_button { + tooltip-text: _('Options'); + menu-model: primary_menu; + icon-name: 'open-menu-symbolic'; + + accessibility { + label: _('Open the options popover'); + } + } + + [end] + ToggleButton search_button { + name: 'Search toggle button'; + tooltip-text: _('Search your library'); + icon-name: 'loupe-large-symbolic'; + + accessibility { + label: _('Open the search popover'); + } + } + + [end] + MenuButton progress_menu_button { + visible: false; + can-focus: true; + tooltip-text: _('Display background task progress'); + + Spinner progress_spinner {} + + styles [ + "flat", + ] + } + } + + SearchBar search_bar { + search-mode-enabled: bind search_button.active bidirectional; + + Adw.Clamp { + margin-start: 6; + margin-end: 6; + margin-bottom: 6; + maximum-size: 450; + + SearchEntry search_entry { + search-delay: 100; + placeholder-text: _('Start typing...'); + hexpand: true; + } + } + } +} + +menu primary_menu { + section { + item { + action: 'app.scan'; + label: _('_Scan Library'); + } + } + + section { + item { + action: 'app.hide_offline'; + label: _('_Hide unavailable books'); + } + } + + section { + item { + action: 'app.prefs'; + label: _('_Preferences'); + } + + item { + action: 'app.about'; + label: _('_About Cozy'); + } + } + + section { + item { + action: 'app.quit'; + label: _('_Quit'); + } + } +} diff --git a/data/ui/headerbar.ui b/data/ui/headerbar.ui deleted file mode 100644 index 38b87863..00000000 --- a/data/ui/headerbar.ui +++ /dev/null @@ -1,107 +0,0 @@ - - - - - -
- - app.scan - _Scan Library - -
-
- - app.hide_offline - _Hide unavailable books - -
-
- - app.prefs - _Preferences - - - app.about - _About Cozy - -
-
- - app.quit - _Quit - -
-
-
- diff --git a/data/ui/main_window.blp b/data/ui/main_window.blp new file mode 100644 index 00000000..77f34eed --- /dev/null +++ b/data/ui/main_window.blp @@ -0,0 +1,253 @@ +using Gtk 4.0; +using Adw 1; + +Adw.ApplicationWindow app_window { + name: 'main_window'; + title: 'Cozy'; + icon-name: 'com.github.geigi.cozy'; + width-request: 360; + height-request: 294; + + Adw.Breakpoint { + condition ("max-width: 500sp") + + setters { + mobile_view_switcher.reveal: true; + } + } + + content: Overlay { + [overlay] + Revealer drop_revealer { + transition-type: crossfade; + reveal-child: false; + can-target: false; + + Adw.StatusPage { + icon-name: 'library-symbolic'; + title: _('Drop Audio Books Here to Add Them to Your Library'); + + styles [ + "drag-overlay-status-page", + ] + } + } + + Adw.ToastOverlay toast_overlay { + Stack main_stack { + StackPage { + name: 'main'; + + child: Adw.ToolbarView { + bottom-bar-style: raised; + + content: Adw.NavigationView navigation_view { + Adw.NavigationPage { + title: _('Library'); + tag: 'main'; + + Adw.ToolbarView header_container { + content: Stack library_stack { + transition-type: crossfade; + + Adw.OverlaySplitView split_view { + show-sidebar: false; + collapsed: true; + + sidebar: Adw.ViewStack sort_stack { + vexpand: true; + + Adw.ViewStackPage { + name: 'recent'; + title: _('Recent'); + icon-name: 'recent-symbolic'; + + child: Label { + label: 'Empty'; + }; + } + + Adw.ViewStackPage { + name: 'author'; + title: _('Author'); + icon-name: 'person-symbolic'; + + child: ScrolledWindow sort_author_scroller { + focusable: true; + hscrollbar-policy: never; + has-frame: true; + + child: Viewport sort_author_viewport { + $FilterListBox author_box { + accessibility { + label: _('List of authors'); + } + + styles [ + "navigation-sidebar", + ] + } + }; + + styles [ + "no_frame", + ] + }; + } + + Adw.ViewStackPage { + name: 'reader'; + title: _('Reader'); + icon-name: 'microphone2-symbolic'; + + child: ScrolledWindow sort_reader_scroller { + focusable: true; + hscrollbar-policy: never; + has-frame: true; + + child: Viewport sort_reader_viewport { + $FilterListBox reader_box { + accessibility { + label: _('List of readers'); + } + + styles [ + "navigation-sidebar", + ] + } + }; + + styles [ + "no_frame", + ] + }; + } + }; + + content: Stack book_stack { + hexpand: true; + hhomogeneous: false; + vhomogeneous: false; + interpolate-size: true; + + StackPage { + name: 'books'; + + child: ScrolledWindow book_scroller { + focusable: true; + hexpand: true; + hscrollbar-policy: never; + has-frame: true; + + child: Viewport books_viewport { + vscroll-policy: natural; + hscroll-policy: minimum; + + child: FlowBox book_box { + margin-top: 18; + margin-bottom: 18; + margin-start: 18; + margin-end: 18; + hexpand: true; + valign: start; + homogeneous: true; + column-spacing: 18; + row-spacing: 18; + min-children-per-line: 1; + max-children-per-line: 10; + selection-mode: none; + + accessibility { + label: _('List of books'); + } + + styles [ + "book_box", + ] + }; + }; + + styles [ + "no_frame", + ] + }; + } + + StackPage { + name: 'no_recent'; + + child: Adw.StatusPage { + icon-name: 'library-symbolic'; + title: _('No Recent Books Yet'); + description: _('Explore your library by switching to the Author or Reader view'); + }; + } + + styles [ + "main_stack", + ] + }; + } + }; + } + } + + Adw.NavigationPage { + title: 'Book title'; + tag: 'book_overview'; + + child: Adw.ToolbarView book_details_container {}; + } + }; + + [bottom] + Box { + orientation: vertical; + + Revealer media_control_box {} + + Adw.ViewSwitcherBar mobile_view_switcher { + reveal: false; + hexpand: true; + } + } + }; + } + + StackPage { + name: 'import'; + + child: Adw.ToolbarView { + [top] + Adw.HeaderBar { + show-title: false; + } + + content: Adw.StatusPage { + icon-name: 'com.github.geigi.cozy'; + title: 'Importing'; + description: 'Stay tuned while Cozy is preparing your library…'; + }; + }; + } + + StackPage { + name: 'welcome'; + + child: Adw.ToolbarView { + [top] + Adw.HeaderBar { + show-title: false; + } + + content: Adw.StatusPage welcome_status_page { + icon-name: 'com.github.geigi.cozy'; + title: 'Let\'s get cozy'; + description: 'Select a Folder, or Drag Audiobooks Here to Add Them to Your Library'; + }; + }; + } + } + } + }; +} diff --git a/data/ui/main_window.ui b/data/ui/main_window.ui deleted file mode 100644 index e0418da7..00000000 --- a/data/ui/main_window.ui +++ /dev/null @@ -1,291 +0,0 @@ - - - - - main_window - Cozy - com.github.geigi.cozy - 360 - 294 - - - max-width: 550sp - true - - - - - - - crossfade - false - false - - - library-symbolic - Drop Audio Books Here to Add Them to Your Library - - - - - - - - - - - - main - - - raised - - - - - Library - main - - - - - crossfade - - - false - true - - - true - - - recent - Recent - recent-symbolic - - - Empty - - - - - - - author - Author - person-symbolic - - - true - never - true - - - - - - List of authors - - - - - - - - - - - - - - reader - Reader - microphone2-symbolic - - - true - never - true - - - - - - List of readers - - - - - - - - - - - - - - - - true - false - false - true - - - books - - - true - true - never - true - - - natural - minimum - - - 18 - 18 - 18 - 18 - true - start - true - 18 - 18 - 1 - 10 - none - - List of books - - - - - - - - - - - - - - no_recent - - - library-symbolic - No Recent Books Yet - Explore your library by switching to the Author or Reader view - - - - - - - - - - - - - - - - - - Book title - book_overview - - - - - - - - - - vertical - - - - - - false - true - - - - - - - - - - - import - - - - - false - - - - - com.github.geigi.cozy - Importing - Stay tuned while Cozy is preparing your library… - - - - - - - - - welcome - - - - - false - - - - - com.github.geigi.cozy - Let's get cozy - Select a Folder, or Drag Audiobooks Here to Add Them to Your Library - - - - - - - - - - - - - - diff --git a/data/ui/media_controller.blp b/data/ui/media_controller.blp new file mode 100644 index 00000000..c1ef2a58 --- /dev/null +++ b/data/ui/media_controller.blp @@ -0,0 +1,223 @@ +using Gtk 4.0; +using Adw 1; + +template $MediaController: Adw.BreakpointBin { + hexpand: true; + width-request: 350; + height-request: 52; + + Adw.Breakpoint { + condition ("max-width: 750sp") + + setters { + seek_bar_container.visible: false; + volume_button.visible: false; + separator.visible: false; + center_box.hexpand: false; + } + } + + Adw.Breakpoint { + condition ("max-width: 550sp") + + setters { + title_box.visible: false; + seek_bar_container.visible: false; + volume_button.visible: false; + timer_button.visible: false; + separator.visible: false; + center_box.hexpand: false; + } + } + + child: CenterBox { + [start] + Box mini_player { + valign: center; + hexpand: false; + spacing: 12; + + Box book_info_box { + spacing: 12; + height-request: 0; + + Image cover_img { + pixel-size: 52; + icon-name: 'end'; + } + + Box title_box { + hexpand: true; + tooltip-text: _('Currently playing'); + valign: center; + orientation: vertical; + spacing: 2; + + Label title_label { + halign: start; + valign: center; + ellipsize: end; + width-chars: 15; + single-line-mode: true; + max-width-chars: 20; + xalign: 0; + + accessibility { + label: _('Title of currently playing book'); + } + + styles [ + "heading", + ] + } + + Label subtitle_label { + halign: start; + valign: center; + ellipsize: end; + width-chars: 15; + single-line-mode: true; + max-width-chars: 20; + xalign: 0; + + accessibility { + label: _('Title of the currently playing part'); + } + } + } + + Separator separator { + orientation: vertical; + } + } + } + + [center] + Box center_box { + hexpand: true; + margin-start: 12; + margin-end: 12; + spacing: 12; + + Box control_box { + valign: center; + spacing: 6; + + Button prev_button { + focusable: true; + receives-default: true; + tooltip-text: _('Rewind'); + halign: center; + valign: center; + icon-name: 'object-rotate-left-symbolic'; + + accessibility { + label: _('Rewind playback'); + } + + styles [ + "flat", + "circular", + ] + } + + Button play_button { + width-request: 42; + height-request: 42; + focusable: true; + receives-default: true; + tooltip-text: _('Start playback'); + halign: center; + valign: center; + icon-name: 'media-playback-start-symbolic'; + + accessibility { + label: _('Start or pause the playback'); + } + + styles [ + "opaque", + "play_button", + "circular", + ] + } + + Button next_button { + focusable: true; + receives-default: true; + tooltip-text: _('Forward'); + halign: center; + valign: center; + icon-name: 'object-rotate-right-symbolic'; + + accessibility { + label: _('Forward Playback'); + } + + styles [ + "flat", + "circular", + ] + } + } + + Box seek_bar_container { + hexpand: true; + } + } + + [end] + Box tools_box { + halign: center; + valign: center; + margin-start: 12; + margin-end: 12; + spacing: 3; + + ScaleButton volume_button { + tooltip-text: _('Volume control'); + + adjustment: Adjustment { + lower: 0; + upper: 1; + value: 1; + step-increment: 0.1; + page-increment: 0.2; + }; + + styles [ + "flat", + ] + } + + MenuButton playback_speed_button { + focusable: true; + receives-default: true; + tooltip-text: _('Playback speed'); + icon-name: 'playback-speed-symbolic'; + + styles [ + "flat", + ] + } + + MenuButton timer_button { + focusable: true; + receives-default: true; + tooltip-text: _('Sleep Timer'); + + Image timer_image { + icon-name: 'bed-symbolic'; + } + + accessibility { + label: _('Open the sleep timer popover'); + } + + styles [ + "flat", + ] + } + } + }; +} diff --git a/data/ui/media_controller.ui b/data/ui/media_controller.ui deleted file mode 100644 index ebb3f3a8..00000000 --- a/data/ui/media_controller.ui +++ /dev/null @@ -1,232 +0,0 @@ - - - - - diff --git a/data/ui/meson.build b/data/ui/meson.build index c9087642..62d2ee72 100644 --- a/data/ui/meson.build +++ b/data/ui/meson.build @@ -1,9 +1,26 @@ -message('Compiling resources') +message('Compiling blueprints') -gnome.compile_resources( - meson.project_name() + '.ui', - 'gresource.xml', - gresource_bundle: true, - install_dir: DATA_DIR, - install: true + +blueprints = custom_target('blueprints', + input: files( + 'album_element.blp', + 'book_detail.blp', + 'book_element.blp', + 'chapter_element.blp', + 'error_reporting.blp', + 'first_import_button.blp', + 'headerbar.blp', + 'main_window.blp', + 'media_controller.blp', + 'playback_speed_popover.blp', + 'preferences.blp', + 'progress_popover.blp', + 'search_page.blp', + 'seek_bar.blp', + 'storage_locations.blp', + 'storage_row.blp', + 'timer_popover.blp', + ), + output: '.', + command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'], ) diff --git a/data/ui/playback_speed_popover.blp b/data/ui/playback_speed_popover.blp new file mode 100644 index 00000000..a2be5ce2 --- /dev/null +++ b/data/ui/playback_speed_popover.blp @@ -0,0 +1,33 @@ +using Gtk 4.0; + +Adjustment speed_value { + lower: 0.5; + upper: 3.5; + value: 1; + step-increment: 0.05; + page-increment: 0.1; +} + +template $PlaybackSpeedPopover: Popover { + width-request: 300; + + child: Box { + Scale playback_speed_scale { + hexpand: true; + focusable: true; + margin-start: 6; + margin-end: 6; + margin-top: 6; + margin-bottom: 6; + adjustment: speed_value; + fill-level: 5; + round-digits: 1; + } + + Label playback_speed_label { + margin-end: 12; + label: '1.0 x'; + use-markup: true; + } + }; +} diff --git a/data/ui/playback_speed_popover.ui b/data/ui/playback_speed_popover.ui deleted file mode 100644 index 7965dee5..00000000 --- a/data/ui/playback_speed_popover.ui +++ /dev/null @@ -1,39 +0,0 @@ - - - - - 0.5 - 3.5 - 1 - 0.05 - 0.1 - - - - diff --git a/data/ui/preferences.blp b/data/ui/preferences.blp new file mode 100644 index 00000000..71947c06 --- /dev/null +++ b/data/ui/preferences.blp @@ -0,0 +1,114 @@ +using Gtk 4.0; +using Adw 1; + +Adjustment fadeout_duration_adjustment { + upper: 120; + value: 15; + step-increment: 5; + page-increment: 10; +} + +Adjustment forward_duration_adjustment { + lower: 5; + upper: 120; + step-increment: 5; + page-increment: 10; +} + +Adjustment rewind_duration_adjustment { + lower: 5; + upper: 120; + value: 15; + step-increment: 5; + page-increment: 10; +} + +template $PreferencesWindow: Adw.PreferencesWindow { + Adw.PreferencesPage { + icon-name: 'settings-symbolic'; + title: _('General'); + + Adw.PreferencesGroup { + title: _('Appearance'); + + Adw.SwitchRow dark_mode_switch { + title: _('Dark Mode'); + } + } + + Adw.PreferencesGroup { + title: _('Tags'); + + Adw.SwitchRow swap_author_reader_switch { + title: _('Swap Author and Reader'); + subtitle: _('Activate if author and reader are displayed the wrong way'); + } + } + + Adw.PreferencesGroup { + title: _('Playback'); + + Adw.SwitchRow replay_switch { + title: _('Replay'); + subtitle: _('Rewind 30 seconds of the current book when starting Cozy'); + } + + Adw.SpinRow rewind_duration_spin_button { + title: _('Rewind Duration'); + focusable: true; + adjustment: rewind_duration_adjustment; + snap-to-ticks: true; + numeric: true; + } + + Adw.SpinRow forward_duration_spin_button { + title: _('Forward Duration'); + focusable: true; + adjustment: forward_duration_adjustment; + snap-to-ticks: true; + numeric: true; + } + } + + Adw.PreferencesGroup { + title: _('Sleep Timer'); + + Adw.ExpanderRow sleep_timer_fadeout_switch { + title: _('Fadeout'); + expanded: true; + show-enable-switch: true; + + Adw.SpinRow { + title: _('Fadeout Duration'); + focusable: true; + adjustment: fadeout_duration_adjustment; + snap-to-ticks: true; + numeric: true; + } + } + } + } + + Adw.PreferencesPage storages_page { + icon-name: 'harddisk-symbolic'; + title: _('Storage'); + + Adw.PreferencesGroup { + title: _('Artwork'); + + Adw.SwitchRow artwork_prefer_external_switch { + title: _('Prefer External Images Over Embedded Cover'); + subtitle: _('Always use images (cover.jpg, *.png, …) when available'); + } + } + } + + Adw.PreferencesPage { + icon-name: 'papyrus-vertical-symbolic'; + title: _('Feedback'); + + Adw.PreferencesGroup user_feedback_preference_group { + title: _('User feedback'); + } + } +} diff --git a/data/ui/preferences.ui b/data/ui/preferences.ui deleted file mode 100644 index fa684640..00000000 --- a/data/ui/preferences.ui +++ /dev/null @@ -1,131 +0,0 @@ - - - - - 120 - 15 - 5 - 10 - - - 5 - 120 - 5 - 10 - - - 5 - 120 - 15 - 5 - 10 - - - - diff --git a/data/ui/progress_popover.blp b/data/ui/progress_popover.blp new file mode 100644 index 00000000..6e453e16 --- /dev/null +++ b/data/ui/progress_popover.blp @@ -0,0 +1,28 @@ +using Gtk 4.0; +using Adw 1; + +template $ProgressPopover: Popover { + Adw.Clamp { + margin-start: 15; + margin-end: 15; + margin-top: 15; + margin-bottom: 15; + maximum-size: 300; + tightening-threshold: 250; + + Box { + orientation: vertical; + spacing: 10; + + Label progress_label { + ellipsize: end; + xalign: 0; + } + + ProgressBar progress_bar { + fraction: 0.5; + text: 'dfsg'; + } + } + } +} diff --git a/data/ui/progress_popover.ui b/data/ui/progress_popover.ui deleted file mode 100644 index e0838bdb..00000000 --- a/data/ui/progress_popover.ui +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - diff --git a/data/ui/search_page.blp b/data/ui/search_page.blp new file mode 100644 index 00000000..d32e2c41 --- /dev/null +++ b/data/ui/search_page.blp @@ -0,0 +1,63 @@ +using Gtk 4.0; +using Adw 1; + +template $SearchView: Adw.Bin { + Stack stack { + Adw.StatusPage start_searching_page { + title: _('Search in your library'); + icon-name: 'library-symbolic'; + } + + Adw.StatusPage nothing_found_page { + title: _('No results found'); + icon-name: 'edit-find-symbolic'; + } + + ScrolledWindow search_scroller { + Adw.Clamp { + margin-start: 18; + margin-end: 18; + margin-top: 18; + margin-bottom: 18; + + Box { + orientation: vertical; + spacing: 24; + + Adw.PreferencesGroup book_result_box { + title: _('Book'); + visible: false; + + ListBox book_result_list { + styles [ + "boxed-list", + ] + } + } + + Adw.PreferencesGroup author_result_box { + title: _('Author'); + visible: false; + + ListBox author_result_list { + styles [ + "boxed-list", + ] + } + } + + Adw.PreferencesGroup reader_result_box { + title: _('Reader'); + visible: false; + + ListBox reader_result_list { + styles [ + "boxed-list", + ] + } + } + } + } + } + } +} diff --git a/data/ui/search_page.ui b/data/ui/search_page.ui deleted file mode 100644 index ec3ff64f..00000000 --- a/data/ui/search_page.ui +++ /dev/null @@ -1,79 +0,0 @@ - - - - - diff --git a/data/ui/seek_bar.blp b/data/ui/seek_bar.blp new file mode 100644 index 00000000..9b43833a --- /dev/null +++ b/data/ui/seek_bar.blp @@ -0,0 +1,63 @@ +using Gtk 4.0; + +Adjustment seek_bar_adjustment { + upper: 100; + step-increment: 1; + page-increment: 15; +} + +template $SeekBar: Box { + valign: center; + hexpand: true; + spacing: 5; + + Label current_label { + tooltip-text: _('Elapsed time'); + halign: end; + valign: center; + label: '--:--'; + single-line-mode: true; + + accessibility { + label: _('Elapsed time of current part'); + } + + styles [ + "numeric", + ] + } + + Scale progress_scale { + width-request: 150; + focusable: true; + tooltip-text: _('Jump to position in current chapter'); + valign: center; + hexpand: true; + adjustment: seek_bar_adjustment; + restrict-to-fill-level: false; + fill-level: 0; + + accessibility { + label: _('Position of the current part in seconds'); + } + } + + Box remaining_event_box { + valign: center; + + Label remaining_label { + tooltip-text: _('Remaining time'); + halign: start; + label: '--:--'; + single-line-mode: true; + + accessibility { + label: _('Remaining time of current part'); + } + + styles [ + "numeric", + ] + } + } +} diff --git a/data/ui/seek_bar.ui b/data/ui/seek_bar.ui deleted file mode 100644 index 2b91b6d2..00000000 --- a/data/ui/seek_bar.ui +++ /dev/null @@ -1,63 +0,0 @@ - - - - - 100 - 1 - 15 - - - diff --git a/data/ui/storage_locations.blp b/data/ui/storage_locations.blp new file mode 100644 index 00000000..c463b3be --- /dev/null +++ b/data/ui/storage_locations.blp @@ -0,0 +1,35 @@ +using Gtk 4.0; +using Adw 1; + +template $StorageLocations: Adw.PreferencesGroup { + title: _('Storage locations'); + + ListBox storage_locations_list { + margin-bottom: 18; + + styles [ + "boxed-list", + ] + } +} + +menu storage_menu { + section { + item { + label: _('External drive'); + action: 'storage.mark-external'; + } + } + + section { + item { + label: _('Set as default'); + action: 'storage.make-default'; + } + + item { + label: _('Remove'); + action: 'storage.remove'; + } + } +} diff --git a/data/ui/storage_locations.ui b/data/ui/storage_locations.ui deleted file mode 100644 index afb6dce7..00000000 --- a/data/ui/storage_locations.ui +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -
- - External drive - storage.mark-external - -
-
- - Set as default - storage.make-default - - - Remove - storage.remove - -
-
-
- diff --git a/data/ui/storage_row.blp b/data/ui/storage_row.blp new file mode 100644 index 00000000..f029706a --- /dev/null +++ b/data/ui/storage_row.blp @@ -0,0 +1,33 @@ +using Gtk 4.0; +using Adw 1; + +template $StorageRow: Adw.ActionRow { + selectable: false; + activatable: true; + + [prefix] + Image icon {} + + [suffix] + Image default_icon { + visible: false; + margin-start: 6; + margin-end: 6; + icon-name: 'emblem-default-symbolic'; + + styles [ + "accent", + ] + } + + [suffix] + MenuButton menu_button { + icon-name: 'view-more-symbolic'; + valign: center; + halign: center; + + styles [ + "flat", + ] + } +} diff --git a/data/ui/storage_row.ui b/data/ui/storage_row.ui deleted file mode 100644 index 0669bcf9..00000000 --- a/data/ui/storage_row.ui +++ /dev/null @@ -1,32 +0,0 @@ - - - - - diff --git a/data/ui/timer_popover.blp b/data/ui/timer_popover.blp new file mode 100644 index 00000000..07cd347a --- /dev/null +++ b/data/ui/timer_popover.blp @@ -0,0 +1,135 @@ +using Gtk 4.0; + +EntryBuffer timer_buffer { + text: '0'; + max-length: 10; +} + +Adjustment timer_value { + upper: 120; + step-increment: 1; + page-increment: 5; +} + +template $SleepTimer: Popover { + width-request: 180; + + child: Box { + width-request: 270; + margin-start: 10; + margin-end: 10; + margin-top: 15; + margin-bottom: 20; + orientation: vertical; + spacing: 10; + + Grid timer_grid { + Scale timer_scale { + width-request: 205; + focusable: true; + tooltip-text: _('Timer duration'); + halign: start; + margin-end: 10; + adjustment: timer_value; + restrict-to-fill-level: true; + fill-level: 120; + round-digits: 5; + digits: 0; + value-pos: right; + + accessibility { + label: _('Set the sleep timer duration in minutes'); + } + + layout { + column: '0'; + row: '0'; + } + } + + Label min_label { + halign: end; + valign: center; + margin-start: 6; + label: _('min'); + + layout { + column: '2'; + row: '0'; + } + } + + Box { + width-request: 25; + valign: center; + orientation: vertical; + + Label timer_label { + halign: end; + valign: center; + } + + layout { + column: '1'; + row: '0'; + } + } + } + + Box { + Label { + hexpand: true; + halign: start; + margin-end: 10; + label: _('Stop after current chapter'); + } + + Switch chapter_switch { + focusable: true; + halign: end; + valign: center; + } + } + + Separator {} + + Box { + Label { + hexpand: true; + halign: start; + label: _('Enable system power control'); + } + + Switch power_control_switch { + focusable: true; + halign: end; + valign: center; + } + } + + Box power_control_options { + sensitive: false; + + Label { + hexpand: true; + tooltip-markup: _('Type of the action when the timer finishes.\n"shutdown" will attempt to turn your system off (also known as power off)\n"suspend" will attempt to suspend your system (also known as sleep).'); + halign: start; + label: _('System power action to perform'); + } + + Box { + orientation: vertical; + + CheckButton system_suspend_radiob { + label: _('suspend'); + active: true; + } + + CheckButton system_shutdown_radiob { + label: _('shutdown'); + group: system_suspend_radiob; + } + } + } + }; +} diff --git a/data/ui/timer_popover.ui b/data/ui/timer_popover.ui deleted file mode 100644 index 65661a58..00000000 --- a/data/ui/timer_popover.ui +++ /dev/null @@ -1,154 +0,0 @@ - - - - - 0 - 10 - - - 120 - 1 - 5 - - - diff --git a/main.py b/main.py index 00afe960..0eb3cf4a 100755 --- a/main.py +++ b/main.py @@ -52,7 +52,7 @@ # gresource must be registered before importing any Gtk.Template annotated classes -resource = Gio.Resource.load(os.path.join(pkgdatadir, 'com.github.geigi.cozy.ui.gresource')) +resource = Gio.Resource.load(os.path.join(pkgdatadir, 'com.github.geigi.cozy.gresource')) resource._register() old_except_hook = None diff --git a/po/POTFILES b/po/POTFILES index 0c080d9c..28be621d 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -12,8 +12,8 @@ cozy/ui/delete_book_view.py cozy/ui/disk_element.py cozy/ui/file_not_found_dialog.py cozy/ui/import_failed_dialog.py -cozy/ui/preferences_view.py cozy/ui/main_view.py +cozy/ui/preferences_view.py cozy/ui/widgets/book_element.py cozy/ui/widgets/book_row.py cozy/ui/widgets/error_reporting.py @@ -23,21 +23,21 @@ cozy/ui/widgets/sleep_timer.py cozy/ui/widgets/storages.py cozy/view_model/headerbar_view_model.py cozy/view_model/library_view_model.py -data/ui/album_element.ui -data/ui/book_detail.ui -data/ui/book_element.ui -data/ui/chapter_element.ui -data/ui/error_reporting.ui -data/ui/first_import_button.ui -data/ui/headerbar.ui -data/ui/main_window.ui -data/ui/media_controller.ui -data/ui/playback_speed_popover.ui -data/ui/preferences.ui -data/ui/progress_popover.ui -data/ui/search_page.ui -data/ui/seek_bar.ui -data/ui/storage_locations.ui -data/ui/storage_row.ui -data/ui/timer_popover.ui -main.py \ No newline at end of file +data/ui/album_element.blp +data/ui/book_detail.blp +data/ui/book_element.blp +data/ui/chapter_element.blp +data/ui/error_reporting.blp +data/ui/first_import_button.blp +data/ui/headerbar.blp +data/ui/main_window.blp +data/ui/media_controller.blp +data/ui/playback_speed_popover.blp +data/ui/preferences.blp +data/ui/progress_popover.blp +data/ui/search_page.blp +data/ui/seek_bar.blp +data/ui/storage_locations.blp +data/ui/storage_row.blp +data/ui/timer_popover.blp +main.py diff --git a/pyproject.toml b/pyproject.toml index 10591275..9e634c5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,4 +11,6 @@ multi_line_output = 3 line-length = 100 builtins = ["_"] output-format = "github" + +[tool.ruff.lint] extend-select = ["B", "SIM", "PIE", "C4", "INT", "LOG"] From 1dedfed3b727aa6b6ab90b4dbaf16b1433798381 Mon Sep 17 00:00:00 2001 From: rdbende Date: Fri, 1 Mar 2024 14:37:29 +0100 Subject: [PATCH 05/28] Update branding colors, as I realized, the current ones look horrible IRL (cherry picked from commit 8acef861edda12f6cf41d3708141f20b98ce0828) --- data/com.github.geigi.cozy.appdata.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/com.github.geigi.cozy.appdata.xml b/data/com.github.geigi.cozy.appdata.xml index 5fe44179..36bd6657 100644 --- a/data/com.github.geigi.cozy.appdata.xml +++ b/data/com.github.geigi.cozy.appdata.xml @@ -238,8 +238,8 @@ 360 - #ffa348 - #ffa348 + #ffbe6f + #39314e 2 From 0387ed4de686fdffd42e24f51241cf7ae77beec9 Mon Sep 17 00:00:00 2001 From: rdbende Date: Sun, 3 Mar 2024 17:05:31 +0100 Subject: [PATCH 06/28] Change purple to washed-out orange --- data/com.github.geigi.cozy.appdata.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/com.github.geigi.cozy.appdata.xml b/data/com.github.geigi.cozy.appdata.xml index 36bd6657..a9a79399 100644 --- a/data/com.github.geigi.cozy.appdata.xml +++ b/data/com.github.geigi.cozy.appdata.xml @@ -239,7 +239,7 @@ #ffbe6f - #39314e + #6a451f 2 From 06c75bed26489028b999c185f18c160769c64f23 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:05:51 +0000 Subject: [PATCH 07/28] Translate po/extra/extra.pot in ru 100% translated source file: 'po/extra/extra.pot' on 'ru'. --- po/extra/ru.po | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/po/extra/ru.po b/po/extra/ru.po index 852705eb..51fa92da 100644 --- a/po/extra/ru.po +++ b/po/extra/ru.po @@ -5,9 +5,10 @@ # # Translators: # Camellan , 2019 -# Dellon Zerus , 2020 +# a06b2f09006889fdcfe2748d6de9ffe6_1cb4257 <3c4467a30d3a7f297ca7238adcadbf50_945653>, 2020 # Julian Geywitz , 2021 # Victor, 2022 +# Dmitry Petruk, 2024 # #, fuzzy msgid "" @@ -16,7 +17,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-16 15:04+0100\n" "PO-Revision-Date: 2019-09-08 09:39+0000\n" -"Last-Translator: Victor, 2022\n" +"Last-Translator: Dmitry Petruk, 2024\n" "Language-Team: Russian (https://app.transifex.com/geigi/teams/78138/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -42,7 +43,7 @@ msgstr "Слушайте аудиокниги" #: data/com.github.geigi.cozy.appdata.xml:17 msgid "Do you like audio books? Then lets get cozy!" -msgstr "Тебе нравятся аудиокниги? Тогда устраивайся поудобнее!" +msgstr "Любите аудиокниги? Тогда устраивайтесь поудобнее!" #: data/com.github.geigi.cozy.appdata.xml:18 msgid "Cozy is a audio book player. Here are some of the features:" From a4a2c0f0d6f35704b52505e00e0c7e7a0eb694fe Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:09:55 +0000 Subject: [PATCH 08/28] Translate po/extra/extra.pot in ru 100% translated source file: 'po/extra/extra.pot' on 'ru'. --- po/extra/ru.po | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/po/extra/ru.po b/po/extra/ru.po index 51fa92da..54ce2030 100644 --- a/po/extra/ru.po +++ b/po/extra/ru.po @@ -51,8 +51,7 @@ msgstr "Cozy — плеер для аудиокниг. Вот некоторые #: data/com.github.geigi.cozy.appdata.xml:20 msgid "Import all your audio books into Cozy to browse them comfortably" -msgstr "" -"Импортируйте все свои аудиокниги в Cosy, чтобы обозревать их с комфортом" +msgstr "Импортируйте все свои аудиокниги в Cozy для комфортного прослушивания" #: data/com.github.geigi.cozy.appdata.xml:21 msgid "" From 141c08b0aaead07cf67b6a9644b8e1b066c4a1b8 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:11:39 +0000 Subject: [PATCH 09/28] Translate po/extra/extra.pot in ru 100% translated source file: 'po/extra/extra.pot' on 'ru'. --- po/extra/ru.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/po/extra/ru.po b/po/extra/ru.po index 54ce2030..cbb8697f 100644 --- a/po/extra/ru.po +++ b/po/extra/ru.po @@ -58,8 +58,8 @@ msgid "" "Listen to your DRM free mp3, m4b, m4a (aac, ALAC, …), flac, ogg and wav " "audio books" msgstr "" -"Слушайте ваши бесплатные mp3, m4a (aac, ALAC, ...), flac, ogg и wav аудио " -"книги" +"Слушайте свои аудиокниги без DRM в форматах mp3, m4a (aac, ALAC, …), flac, " +"ogg и wav" #: data/com.github.geigi.cozy.appdata.xml:22 msgid "Remembers your playback position" From c94803e98061d4aa0379aeb733875efb9ef9106d Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:13:42 +0000 Subject: [PATCH 10/28] Translate po/extra/extra.pot in ru 100% translated source file: 'po/extra/extra.pot' on 'ru'. --- po/extra/ru.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/extra/ru.po b/po/extra/ru.po index cbb8697f..ef12741f 100644 --- a/po/extra/ru.po +++ b/po/extra/ru.po @@ -63,7 +63,7 @@ msgstr "" #: data/com.github.geigi.cozy.appdata.xml:22 msgid "Remembers your playback position" -msgstr "Запоминает позицию воспроизведения" +msgstr "Запоминает, где вы остановились" #: data/com.github.geigi.cozy.appdata.xml:23 msgid "Sleep timer" From b28003762de96abd42e978f88f5169a467c77a2d Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:20:04 +0000 Subject: [PATCH 11/28] Translate po/extra/extra.pot in ru 100% translated source file: 'po/extra/extra.pot' on 'ru'. --- po/extra/ru.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/extra/ru.po b/po/extra/ru.po index ef12741f..6ac171c3 100644 --- a/po/extra/ru.po +++ b/po/extra/ru.po @@ -93,7 +93,7 @@ msgstr "" #: data/com.github.geigi.cozy.appdata.xml:28 msgid "Drag and Drop to import new audio books" -msgstr "Для импорта новых аудиокниг просто перетащите книги в окно программы" +msgstr "Для импорта новых аудиокниг просто перетяните их в окно программы" #: data/com.github.geigi.cozy.appdata.xml:29 msgid "Sort your audio books by author, reader and name" From 954915eeaea10568b5855c4ec095179521968c14 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 20:22:59 +0000 Subject: [PATCH 12/28] Translate po/extra/extra.pot in ru 100% translated source file: 'po/extra/extra.pot' on 'ru'. --- po/extra/ru.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/extra/ru.po b/po/extra/ru.po index 6ac171c3..8d99a92b 100644 --- a/po/extra/ru.po +++ b/po/extra/ru.po @@ -97,4 +97,4 @@ msgstr "Для импорта новых аудиокниг просто пер #: data/com.github.geigi.cozy.appdata.xml:29 msgid "Sort your audio books by author, reader and name" -msgstr "Сортируйте ваши аудиокниги по автору, диктору и имени" +msgstr "Сортируйте свои аудиокниги по автору, чтецу и названию" From d4226f9d299aabdad3cb7d0f964dfa433abc1e3e Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 13:58:28 +0100 Subject: [PATCH 13/28] Translate po/com.github.geigi.cozy.pot in ru (#901) 100% translated source file: 'po/com.github.geigi.cozy.pot' on 'ru'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- po/ru.po | 967 ++++++++++++++++++++++--------------------------------- 1 file changed, 393 insertions(+), 574 deletions(-) diff --git a/po/ru.po b/po/ru.po index fd4e5c00..22e660a3 100644 --- a/po/ru.po +++ b/po/ru.po @@ -4,33 +4,32 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Lapunov Yegor , 2020 -# Nikolai Oplachko , 2020 # Caarmi, 2021 -# Dellon Zerus , 2021 +# a06b2f09006889fdcfe2748d6de9ffe6_1cb4257 <3c4467a30d3a7f297ca7238adcadbf50_945653>, 2021 # Jan Lyakhovsky , 2021 -# Julian Geywitz , 2021 # Camellan , 2021 # h h , 2021 # Aleksey Aleksey , 2021 -# Виктор, 2022 +# Victor, 2022 +# Julian Geywitz , 2024 +# Dmitry Petruk, 2024 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: com.github.geigi.cozy\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-09 20:31+0200\n" +"POT-Creation-Date: 2024-02-17 20:33+0100\n" "PO-Revision-Date: 2019-09-08 09:31+0000\n" -"Last-Translator: Виктор, 2022\n" -"Language-Team: Russian (https://www.transifex.com/geigi/teams/78138/ru/)\n" +"Last-Translator: Dmitry Petruk, 2024\n" +"Language-Team: Russian (https://app.transifex.com/geigi/teams/78138/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" "Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" -#: cozy/application.py:106 +#: cozy/application.py:59 msgid "Audiobooks" msgstr "Аудиокниги" @@ -38,16 +37,16 @@ msgstr "Аудиокниги" msgid "Copying" msgstr "Копирование" -#: cozy/media/files.py:69 +#: cozy/media/files.py:67 msgid "Cannot copy: Audiobook directory is read only" msgstr "" "Не удалось скопировать: папка с аудиокнигами доступна только для чтения" -#: cozy/media/files.py:71 +#: cozy/media/files.py:69 msgid "Cannot copy: Disk is full" -msgstr "Не удалось скопировать: диск переполнен" +msgstr "Не удалось скопировать: диск заполнен" -#: cozy/media/files.py:73 cozy/media/files.py:89 +#: cozy/media/files.py:71 cozy/media/files.py:87 msgid "Cannot copy: Permission denied" msgstr "Не удалось скопировать: в доступе отказано" @@ -55,36 +54,32 @@ msgstr "Не удалось скопировать: в доступе отказ msgid "Error while importing new files" msgstr "Ошибка при импортировании новых файлов" -#: cozy/model/track.py:38 -msgid "Chapter" -msgstr "Глава" - #: cozy/tools.py:92 cozy/tools.py:96 #, python-brace-format msgid "{hours} hour" msgid_plural "{hours} hours" msgstr[0] "{hours} час" -msgstr[1] "{hours} часов" +msgstr[1] "{hours} часа" msgstr[2] "{hours} часов" -msgstr[3] "{hours} часов" +msgstr[3] "{hours} часа" #: cozy/tools.py:94 cozy/tools.py:98 #, python-brace-format msgid "{minutes} minute" msgid_plural "{minutes} minutes" msgstr[0] "{minutes} минута" -msgstr[1] "{minutes} минут" +msgstr[1] "{minutes} минуты" msgstr[2] "{minutes} минут" -msgstr[3] "{minutes} минут" +msgstr[3] "{minutes} минуты" #: cozy/tools.py:100 #, python-brace-format msgid "{seconds} second" msgid_plural "{seconds} seconds" msgstr[0] "{seconds} секунда" -msgstr[1] "{seconds} секунд" +msgstr[1] "{seconds} секунды" msgstr[2] "{seconds} секунд" -msgstr[3] "{seconds} секунд" +msgstr[3] "{seconds} секунды" #: cozy/tools.py:102 msgid "finished" @@ -105,25 +100,25 @@ msgstr "вчера" #: cozy/tools.py:132 #, python-format msgid "%s days ago" -msgstr "%s дней(я) назад" +msgstr "%s д. назад" #: cozy/tools.py:134 #, python-brace-format msgid "{weeks} week ago" msgid_plural "{weeks} weeks ago" -msgstr[0] "{weeks} неделя назад" +msgstr[0] "{weeks} неделю назад" msgstr[1] "{weeks} недели назад" msgstr[2] "{weeks} недель назад" -msgstr[3] "{weeks} недель назад" +msgstr[3] "{weeks} недели назад" #: cozy/tools.py:136 #, python-brace-format msgid "{months} month ago" msgid_plural "{months} months ago" msgstr[0] "{months} месяц назад" -msgstr[1] "{months} месяцев назад" +msgstr[1] "{months} месяца назад" msgstr[2] "{months} месяцев назад" -msgstr[3] "{months} месяцев назад" +msgstr[3] "{months} месяца назад" #: cozy/tools.py:138 #, python-brace-format @@ -132,252 +127,307 @@ msgid_plural "{years} years ago" msgstr[0] "{years} год назад" msgstr[1] "{years} года назад" msgstr[2] "{years} лет назад" -msgstr[3] "{years} лет назад" +msgstr[3] "{years} года назад" -#: cozy/ui/book_detail_view.py:313 +#: cozy/ui/book_detail_view.py:299 msgid "Downloaded" -msgstr "Загружено" +msgstr "Скачано" -#: cozy/ui/book_detail_view.py:316 data/ui/book_detail.ui:152 +#: cozy/ui/book_detail_view.py:302 data/ui/book_detail.ui:116 msgid "Download" -msgstr "Загрузить" +msgstr "Скачать" -#: cozy/ui/chapter_element.py:27 -msgid "Play this part" -msgstr "Слушать эту часть" +#: cozy/ui/db_migration_failed_view.py:6 +msgid "" +"During an update of the database an error occurred and Cozy will not be able" +" to startup. A backup of the database was created before the update and has " +"been restored now. Until this issue is resolved please use version 0.9.5 of " +"Cozy. You can help resolve this problem by reporting an issue on GitHub." +msgstr "" +"Во время обновления базы данных произошла ошибка, и Cozy не сможет " +"запуститься. Сейчас восстановлена резервная копия базы данных, которая была " +"создана перед обновлением. Пока эта проблема не будет решена, пожалуйста, " +"используйте версию Cozy 0.9.5. Вы можете помочь решить эту проблему, сообщив" +" о ней на GitHub." + +#: cozy/ui/db_migration_failed_view.py:15 +msgid "Failed to Update Database" +msgstr "Не удалось обновить базу данных" -#: cozy/ui/disk_element.py:27 +#: cozy/ui/db_migration_failed_view.py:22 +msgid "Close Cozy" +msgstr "Закрыть Cozy" + +#: cozy/ui/db_migration_failed_view.py:23 +msgid "Receive help on GitHub" +msgstr "Получить помощь на GitHub" + +#: cozy/ui/delete_book_view.py:13 +msgid "Delete Audiobook?" +msgstr "Удалить аудиокнигу?" + +#: cozy/ui/delete_book_view.py:14 +msgid "The audiobook will be removed from your disk and from Cozy's library." +msgstr "Аудиокнига будет удалена с вашего диска и из библиотеки Cozy." + +#: cozy/ui/delete_book_view.py:21 cozy/ui/file_not_found_dialog.py:26 +msgid "Cancel" +msgstr "Отмена" + +#: cozy/ui/delete_book_view.py:22 +msgid "Remove Audiobook" +msgstr "Удалить аудиокнигу" + +#: cozy/ui/disk_element.py:22 msgid "Disc" msgstr "Диск" -#: cozy/ui/file_not_found_dialog.py:56 -msgid "All files" -msgstr "Все файлы" +#: cozy/ui/file_not_found_dialog.py:18 +msgid "File not found" +msgstr "Файл не найден" -#: cozy/ui/main_view.py:301 data/ui/main_window.ui:412 -msgid "Set Audiobooks Directory" -msgstr "Указать каталог аудиокниг" +#: cozy/ui/file_not_found_dialog.py:19 +msgid "This file could not be found. Do you want to locate it manually?" +msgstr "Файл не найден. Вы хотите найти его самостоятельно?" + +#: cozy/ui/file_not_found_dialog.py:27 +msgid "Locate" +msgstr "Расположение" + +#: cozy/ui/file_not_found_dialog.py:38 +msgid "Locate Missing File" +msgstr "Найти недостающий файл" -#: cozy/ui/warnings.py:27 cozy/ui/warnings.py:42 +#: cozy/ui/file_not_found_dialog.py:41 #, python-brace-format -msgid "{storage} is offline." -msgstr "{storage} в автономном режиме." +msgid "{ext} files" +msgstr "Файлы: {ext}" + +#: cozy/ui/file_not_found_dialog.py:44 +msgid "Audio files" +msgstr "Аудиофайлы" + +#: cozy/ui/import_failed_dialog.py:8 +msgid "This can have multiple reasons:" +msgstr "У этого может быть несколько причин:" + +#: cozy/ui/import_failed_dialog.py:11 +msgid "The audio format is not supported" +msgstr "Аудиоформат не поддерживается" + +#: cozy/ui/import_failed_dialog.py:12 +msgid "The path or filename contains non utf-8 characters" +msgstr "Путь или название файла содержат символы не в utf-8" -#: cozy/ui/widgets/book_element.py:52 +#: cozy/ui/import_failed_dialog.py:13 +msgid "The file(s) are no valid audio files" +msgstr "Файлы не являются корректными аудиофайлами" + +#: cozy/ui/import_failed_dialog.py:14 +msgid "The file(s) are corrupt" +msgstr "Файлы повреждены" + +#: cozy/ui/import_failed_dialog.py:28 +msgid "Some files could not be imported" +msgstr "Некоторые файлы не могут быть импортированы" + +#: cozy/ui/import_failed_dialog.py:35 +msgid "Ok" +msgstr "Ок" + +#: cozy/ui/main_view.py:198 +msgid "Patreon Supporters" +msgstr "Поддержали нас на Patreon" + +#: cozy/ui/main_view.py:202 +msgid "m4b chapter support in mutagen" +msgstr "Поддержка глав m4b в mutagen" + +#: cozy/ui/main_view.py:206 +msgid "Open Source Projects" +msgstr "Проекты с открытым исходным кодом" + +#. Translators: Replace "translator-credits" with your names, one name per +#. line +#: cozy/ui/main_view.py:211 +msgid "translator-credits" +msgstr "Dmitry Petruk" + +#: cozy/ui/widgets/book_element.py:70 msgid "Mark as read" msgstr "Отметить как прочитанное" -#: cozy/ui/widgets/book_element.py:55 +#: cozy/ui/widgets/book_element.py:73 msgid "Open in file browser" msgstr "Открыть в файловом менеджере" -#: cozy/ui/widgets/book_element.py:58 +#: cozy/ui/widgets/book_element.py:76 msgid "Remove from library" msgstr "Удалить из библиотеки" -#: cozy/ui/widgets/error_reporting.py:12 +#: cozy/ui/widgets/book_row.py:25 +msgid "Play this book" +msgstr "Слушать эту аудиокнигу" + +#: cozy/ui/widgets/error_reporting.py:11 msgid "Disabled" msgstr "Отключено" -#: cozy/ui/widgets/error_reporting.py:13 +#: cozy/ui/widgets/error_reporting.py:12 msgid "Basic error reporting" -msgstr "Докладывать об основных ошибках" +msgstr "Сообщать об основных ошибках" -#: cozy/ui/widgets/error_reporting.py:14 +#: cozy/ui/widgets/error_reporting.py:13 msgid "Detailed error reporting" -msgstr "Детально докладывать об ошибках" +msgstr "Подробно сообщать об ошибках" -#: cozy/ui/widgets/error_reporting.py:15 data/ui/error_reporting.ui:240 +#: cozy/ui/widgets/error_reporting.py:14 data/ui/error_reporting.ui:162 msgid "Detailed error reporting with import errors" -msgstr "Детально докладывать об ошибках, включая ошибки во время импортации" +msgstr "Подробно сообщать об ошибках, включая ошибки импорта" -#: cozy/ui/widgets/error_reporting.py:19 +#: cozy/ui/widgets/error_reporting.py:18 msgid "No error or crash reporting." -msgstr "Не докладывать об ошибках и сбоях." +msgstr "Не сообщать об ошибках и сбоях." -#: cozy/ui/widgets/error_reporting.py:20 data/ui/error_reporting.ui:259 +#: cozy/ui/widgets/error_reporting.py:19 data/ui/error_reporting.ui:174 msgid "The following information will be sent in case of an error or crash:" msgstr "Данная информация будет отправлена в случае сбоя или ошибки:" -#: cozy/ui/widgets/error_reporting.py:25 +#: cozy/ui/widgets/error_reporting.py:24 msgid "Which type of error occurred" msgstr "Вид произошедшей ошибки" -#: cozy/ui/widgets/error_reporting.py:26 +#: cozy/ui/widgets/error_reporting.py:25 msgid "Line of code where an error occurred" -msgstr "Линия на которой произошла ошибка" +msgstr "Строка кода, на которой появилась ошибка" -#: cozy/ui/widgets/error_reporting.py:27 +#: cozy/ui/widgets/error_reporting.py:26 msgid "Cozy's version" msgstr "Версия Cozy" -#: cozy/ui/widgets/error_reporting.py:28 +#: cozy/ui/widgets/error_reporting.py:27 msgid "Linux distribution" msgstr "Дистрибутив Linux" -#: cozy/ui/widgets/error_reporting.py:29 +#: cozy/ui/widgets/error_reporting.py:28 msgid "Desktop environment" msgstr "Среда рабочего стола" -#: cozy/ui/widgets/error_reporting.py:30 +#: cozy/ui/widgets/error_reporting.py:29 msgid "Media type of files that Cozy couldn't import" msgstr "Формат файлов, которые Cozy не смог импортировать" -#: cozy/ui/widgets/filter_list_box.py:20 -#: cozy/view_model/library_view_model.py:54 -#: cozy/view_model/library_view_model.py:160 +#: cozy/ui/widgets/filter_list_box.py:18 +#: cozy/view_model/library_view_model.py:45 +#: cozy/view_model/library_view_model.py:135 msgid "All" msgstr "Все" -#: cozy/ui/widgets/filter_list_box.py:21 +#: cozy/ui/widgets/filter_list_box.py:19 msgid "Display all books" msgstr "Отобразить все книги" -#: cozy/ui/widgets/search_results.py:73 -msgid "Jump to author " -msgstr "Перейти к автору " - -#: cozy/ui/widgets/search_results.py:76 -msgid "Jump to reader " -msgstr "Перейти к диктору " - -#: cozy/ui/widgets/search_results.py:100 -msgid "Play this book" -msgstr "Слушать эту аудиокнигу" +#: cozy/ui/widgets/search_results.py:13 +#, python-brace-format +msgid "Jump to {artist_name}" +msgstr "Перейти к {artist_name}" -#: cozy/ui/widgets/sleep_timer.py:60 data/ui/timer_popover.ui:66 +#: cozy/ui/widgets/sleep_timer.py:57 data/ui/timer_popover.ui:53 msgid "min" msgstr "мин" -#: cozy/ui/widgets/sleep_timer.py:65 +#: cozy/ui/widgets/sleep_timer.py:62 msgid "Off" msgstr "Отключено" -#: cozy/ui/widgets/storage_list_box_row.py:70 data/ui/preferences.ui:380 +#: cozy/ui/widgets/storages.py:11 +msgid "Set Audiobooks Directory" +msgstr "Указать каталог аудиокниг" + +#: cozy/ui/widgets/storages.py:65 data/ui/storage_locations.ui:18 msgid "External drive" msgstr "Внешний диск" -#: cozy/ui/widgets/storage_list_box_row.py:73 +#: cozy/ui/widgets/storages.py:68 msgid "Internal drive" -msgstr "Внутрення память" +msgstr "Внутренняя память" -#: cozy/view_model/headerbar_view_model.py:91 +#: cozy/view_model/headerbar_view_model.py:78 msgid "Refreshing audio book collection" msgstr "Обновление коллекции аудиокниг" -#: cozy/view_model/headerbar_view_model.py:100 -#: cozy/view_model/headerbar_view_model.py:116 +#: cozy/view_model/headerbar_view_model.py:87 +#: cozy/view_model/headerbar_view_model.py:103 msgid "Copying new files…" msgstr "Копирование новых файлов…" -#: cozy/view_model/headerbar_view_model.py:107 +#: cozy/view_model/headerbar_view_model.py:94 msgid "Changing audio book location…" msgstr "Изменение каталога аудиокниг…" -#: data/ui/about.ui:16 -msgid "GitHub" -msgstr "GitHub" - -#: data/ui/album_element.ui:104 +#: data/ui/album_element.ui:47 msgid "Play" msgstr "Воспроизвести" -#: data/ui/book_detail.ui:219 +#: data/ui/book_detail.ui:149 msgid "Remaining" -msgstr "Оставшиеся" +msgstr "Осталось" -#: data/ui/book_detail.ui:274 +#: data/ui/book_detail.ui:195 msgid "Total" -msgstr "Общие" +msgstr "Всего" -#: data/ui/book_detail.ui:290 +#: data/ui/book_detail.ui:208 msgid "Last played" msgstr "Последний раз воспроизводилось" -#: data/ui/book_detail.ui:306 +#: data/ui/book_detail.ui:221 msgid "Published" msgstr "Опубликовано" -#: data/ui/book_detail.ui:341 +#: data/ui/book_detail.ui:246 msgid "Some or all files of this book cannot be found." -msgstr "Не удалось найти один или из более файлов этой книги." +msgstr "Не удалось найти некоторые или все файлы этой книги." -#: data/ui/book_detail.ui:364 +#: data/ui/book_detail.ui:259 msgid "unavailable" -msgstr "не доступно" +msgstr "недоступно" -#: data/ui/book_detail.ui:533 +#: data/ui/book_detail.ui:363 msgid "Loading chapters, please wait..." -msgstr "Загрузка глав, пожалуйста, подождите..." +msgstr "Загрузка глав. Пожалуйста, подождите…" -#: data/ui/book_element.ui:36 +#: data/ui/book_element.ui:10 msgid "Open book overview" msgstr "Открыть обзор книги" -#: data/ui/db_migration_failed.ui:31 -msgid "Close Cozy" -msgstr "Закрыть Cozy" - -#: data/ui/db_migration_failed.ui:47 -msgid "Receive help on GitHub" -msgstr "Получить помощь на GitHub" - -#: data/ui/db_migration_failed.ui:108 -msgid "An error occured while updating the database" -msgstr "Произошла ошибка во время обновления базы данных" - -#: data/ui/db_migration_failed.ui:129 -msgid "" -"During an update of the database an error occurred and Cozy will not be able to startup.\n" -"A backup of the database was created before the update and has been restored now.\n" -"Until this issue is resolved please use version 0.9.5 of Cozy.\n" -"You can help resolve this problem by reporting an issue on GitHub." -msgstr "" -"Во время обновления базы данных произошла ошибка, и Cozy не сможет запуститься.\n" -"Перед обновлением была создана резервная копия базы данных и сейчас она восстановлена.\n" -"Пока эта проблема не будет решена, используйте версию Cozy 0.9.5.\n" -"Вы можете помочь решить эту проблему, сообщив о проблеме на GitHub." - -#: data/ui/delete_book_dialog.ui:31 data/ui/file_not_found.ui:19 -msgid "Cancel" -msgstr "Отмена" - -#: data/ui/delete_book_dialog.ui:45 -msgid "Delete Audiobook" -msgstr "Удалить аудиокнигу" - -#: data/ui/delete_book_dialog.ui:105 -msgid "Are you sure you want to delete the selected audiobook?" -msgstr "Вы уверены что хотите удалить выбраную аудиокнигу?" - -#: data/ui/delete_book_dialog.ui:126 -msgid "The audiobook will be removed from your disk and from Cozy's library." -msgstr "Аудиокнига будет удалена с вашего диска и из библиотеки Cozy." +#: data/ui/chapter_element.ui:5 +msgid "Play this part" +msgstr "Слушать эту часть" -#: data/ui/error_reporting.ui:29 data/ui/preferences.ui:458 +#: data/ui/error_reporting.ui:24 data/ui/preferences.ui:124 msgid "User feedback" -msgstr "Пользовательские отзывы" +msgstr "Обратная связь пользователей" -#: data/ui/error_reporting.ui:98 +#: data/ui/error_reporting.ui:67 msgctxt "Error and crash reporting dialog" msgid "" "You can help improve Cozy by contributing information in case of errors and " "crashes. " -msgstr "" -"Вы можете помочь Cozy, отправляя информацию в случае ошибок или сбоев." +msgstr "Вы можете помочь Cozy, отправляя отчёты об ошибка или сбоях." -#: data/ui/error_reporting.ui:112 +#: data/ui/error_reporting.ui:75 msgctxt "Error and crash reporting dialog" msgid "" "Contributing this information is optional and completely anonymous. We will " "never collect personal data, files you import or any information that could " "identify you." msgstr "" -"Отправление этой информации необязательно, и совершенно анонимно. Мы не " -"никогда не используем информацию о вас, о ваших файлах, или о ваших личных " -"данных." +"Отправление этой информации необязательно и совершенно анонимно. Мы никогда " +"не собираем ваши личные данные, импротируемые файлы или любую информацию о " +"вас." -#: data/ui/error_reporting.ui:127 +#: data/ui/error_reporting.ui:84 msgctxt "Error and crash reporting dialog" msgid "" "Cozy is opensource and the user feedback source code can be inspected here: " @@ -385,380 +435,298 @@ msgstr "" "Cozy является программой с открытым исходным кодом, а отзывы пользователей " "можно найти здесь: " -#: data/ui/file_not_found.ui:32 -msgid "Locate" -msgstr "Расположение" +#. Translators: Don't touch the markup. Translate the text "Sourcecode on +#. GitHub" only! +#: data/ui/error_reporting.ui:94 +msgid "" +"Sourcecode" +" on GitHub" +msgstr "" +"Исходный " +"код на GitHub" -#: data/ui/file_not_found.ui:86 -msgid "File not found" -msgstr "Файл не найден" +#: data/ui/first_import_button.ui:12 +msgid "Select Folder" +msgstr "Выбрать папку" -#: data/ui/file_not_found.ui:119 -msgid "This file could not be found. Do you want to locate it manually?" -msgstr "Файл не найден. Вы хотите найти его самостоятельно?" +#: data/ui/headerbar.ui:17 +msgid "Toggle Filter Sidebar" +msgstr "Переключить боковую панель фильтра" -#: data/ui/headerbar.ui:56 -msgid "Display background task progress" -msgstr "Отображение выполнения фоновой задачи" +#: data/ui/headerbar.ui:22 +msgid "Options" +msgstr "Настройки" -#: data/ui/headerbar.ui:70 -msgid "Search your library" -msgstr "Поиск в вашей аудиобиблиотеке" +#: data/ui/headerbar.ui:26 +msgid "Open the options popover" +msgstr "Открыть окно настроек" -#: data/ui/headerbar.ui:80 -msgid "Search menu button" -msgstr "Кнопка меню поиска" +#: data/ui/headerbar.ui:33 +msgid "Search your library" +msgstr "Поиск в аудиобиблиотеке" -#: data/ui/headerbar.ui:81 +#: data/ui/headerbar.ui:36 msgid "Open the search popover" msgstr "Откройте поисковый запрос" -#: data/ui/headerbar.ui:96 -msgid "Options" -msgstr "Настройки" +#: data/ui/headerbar.ui:44 +msgid "Display background task progress" +msgstr "Отображать выполнение фоновой задачи" -#: data/ui/headerbar.ui:107 -msgid "Options menu button" -msgstr "Кнопка меню настроек" +#: data/ui/headerbar.ui:67 +msgid "Start typing..." +msgstr "Начните вводить…" -#: data/ui/headerbar.ui:108 -msgid "Open the options popover" -msgstr "Открыть окно настроек" +#: data/ui/headerbar.ui:80 +msgid "_Scan Library" +msgstr "_Сканировать библиотеку" -#: data/ui/import_failed.ui:27 -msgid "Ok" -msgstr "Да" +#: data/ui/headerbar.ui:86 +msgid "_Hide unavailable books" +msgstr "_Скрыть недоступные книги" -#: data/ui/import_failed.ui:81 -msgid "Some files could not be imported" -msgstr "Некоторые файлы не могут быть импортированы" +#: data/ui/headerbar.ui:92 +msgid "_Preferences" +msgstr "_Параметры" -#: data/ui/import_failed.ui:134 -msgid "" -"This can have multiple reasons:\n" -"- The audio format is not supported\n" -"- The path or filename contains non utf-8 characters\n" -"- The file(s) are no valid audio files\n" -"- The file(s) are corrupt" -msgstr "" -"Это может иметь следующие причины:\n" -"- Аудиоформат не поддерживается\n" -"- Путь или имя файла содержит символы не из utf-8\n" -"- Файл(ы) не являются валидными аудиофайлами\n" -"- Файл(ы) повреждены" +#: data/ui/headerbar.ui:96 +msgid "_About Cozy" +msgstr "_О Cozy" -#: data/ui/main_window.ui:68 -msgid "Recent" -msgstr "Предыдущие" +#: data/ui/headerbar.ui:102 +msgid "_Quit" +msgstr "_Выход" -#: data/ui/main_window.ui:90 -msgid "List of authors" -msgstr "Список авторов" +#: data/ui/main_window.ui:26 +msgid "Drop Audio Books Here to Add Them to Your Library" +msgstr "Перетяните аудиокниги сюда, чтобы добавить их в библиотеку" + +#: data/ui/main_window.ui:48 +msgid "Library" +msgstr "Библиотека" + +#: data/ui/main_window.ui:65 +msgid "Recent" +msgstr "Недавние" -#: data/ui/main_window.ui:106 data/ui/main_window.ui:250 -#: data/ui/search_popover.ui:107 +#: data/ui/main_window.ui:77 data/ui/search_page.ui:46 msgid "Author" msgstr "Автор" -#: data/ui/main_window.ui:128 -msgid "List of readers" -msgstr "Список дикторов" +#: data/ui/main_window.ui:89 +msgid "List of authors" +msgstr "Список авторов" -#: data/ui/main_window.ui:144 data/ui/search_popover.ui:201 +#: data/ui/main_window.ui:108 data/ui/search_page.ui:59 msgid "Reader" -msgstr "Диктор" +msgstr "Чтец" -#: data/ui/main_window.ui:189 +#: data/ui/main_window.ui:120 +msgid "List of readers" +msgstr "Список чтецов" + +#: data/ui/main_window.ui:172 msgid "List of books" msgstr "Список книг" -#: data/ui/main_window.ui:222 -msgid "" -"Start exploring your library by switching to the Author or Reader view." -msgstr "" -"Начните изучать свою библиотеку, переключившись на просмотр «Автор» или " -"«Диктор»." - -#: data/ui/main_window.ui:280 -msgid "Stay tuned while Cozy is preparing your library…" -msgstr "Подождите, пока Cozy подготавливает библиотеку…" +#: data/ui/main_window.ui:194 +msgid "No Recent Books Yet" +msgstr "Недавних книг пока нет" -#: data/ui/main_window.ui:334 -msgid "Import your Audiobooks" -msgstr "Импорт аудиокниг" - -#: data/ui/main_window.ui:353 -msgid "" -"Cozy automatically imports your audiobooks in one directory - your library" +#: data/ui/main_window.ui:195 +msgid "Explore your library by switching to the Author or Reader view" msgstr "" -"Cozy автоматически импортирует аудиокниги из указанного каталога в " -"библиотеку" - -#: data/ui/main_window.ui:385 -msgid "Drag & Drop" -msgstr "Перетаскивание" +"Изучайте свою библиотеку, переключившись на просмотр «Автор» или «Чтец»" -#: data/ui/main_window.ui:387 -msgid "Drag your audiobooks into cozy and they will be automatically imported" -msgstr "" -"Перенесите ваши аудиокниги в уютное местечко — Cozy, и они автоматически " -"импортируются" +#: data/ui/media_controller.ui:48 +msgid "Currently playing" +msgstr "Сейчас воспроизводится" -#: data/ui/main_window.ui:414 -msgid "Load audiobooks from a directory, network drive or an external disk" -msgstr "Загружайте аудиокниги из каталога, сетевого или внешнего диска" +#: data/ui/media_controller.ui:65 +msgid "Title of currently playing book" +msgstr "Название текущей аудиокниги" -#: data/ui/main_window.ui:417 -msgid "Select" -msgstr "Выбрать" +#: data/ui/media_controller.ui:82 +msgid "Title of the currently playing part" +msgstr "Название текущей части" -#: data/ui/media_controller.ui:64 data/ui/media_controller.ui:482 -#: data/ui/media_controller_big.ui:189 data/ui/media_controller_small.ui:70 +#: data/ui/media_controller.ui:111 msgid "Rewind" msgstr "Перемотать" -#: data/ui/media_controller.ui:71 data/ui/media_controller.ui:489 -#: data/ui/media_controller_big.ui:197 data/ui/media_controller_small.ui:77 -msgid "Rewind button" -msgstr "Кнопка перемотки" - -#: data/ui/media_controller.ui:72 data/ui/media_controller.ui:490 -#: data/ui/media_controller_big.ui:198 data/ui/media_controller_small.ui:78 +#: data/ui/media_controller.ui:116 msgid "Rewind playback" msgstr "Обратное воспроизведение" -#: data/ui/media_controller.ui:89 data/ui/media_controller.ui:507 -#: data/ui/media_controller_big.ui:220 data/ui/media_controller_small.ui:100 +#: data/ui/media_controller.ui:130 msgid "Start playback" msgstr "Начать воспроизведение" -#: data/ui/media_controller.ui:96 data/ui/media_controller.ui:514 -#: data/ui/media_controller_big.ui:228 data/ui/media_controller_small.ui:107 -msgid "Play/Pause Button" -msgstr "Кнопка воспр./паузы" - -#: data/ui/media_controller.ui:97 data/ui/media_controller.ui:515 -#: data/ui/media_controller_big.ui:229 data/ui/media_controller_small.ui:108 +#: data/ui/media_controller.ui:135 msgid "Start or pause the playback" -msgstr "Запуск или приостановка воспроизведения" +msgstr "Воспроизведение или пауза" -#: data/ui/media_controller.ui:113 data/ui/media_controller.ui:531 -#: data/ui/media_controller_big.ui:252 data/ui/media_controller_small.ui:131 +#: data/ui/media_controller.ui:148 msgid "Forward" msgstr "Вперёд" -#: data/ui/media_controller.ui:120 data/ui/media_controller.ui:538 -#: data/ui/media_controller_big.ui:260 data/ui/media_controller_small.ui:138 -msgid "Forward button" -msgstr "Кнопка вперёд" - -#: data/ui/media_controller.ui:121 data/ui/media_controller.ui:539 -#: data/ui/media_controller_big.ui:261 data/ui/media_controller_small.ui:139 +#: data/ui/media_controller.ui:153 msgid "Forward Playback" msgstr "Воспроизведение вперёд" -#: data/ui/media_controller.ui:175 data/ui/media_controller_big.ui:76 -msgid "Currently playing" -msgstr "Сейчас воспроизводится" - -#: data/ui/media_controller.ui:190 data/ui/media_controller_big.ui:97 -msgid "Booktitle" -msgstr "Заголовок аудиокниги" - -#: data/ui/media_controller.ui:191 data/ui/media_controller_big.ui:98 -msgid "Title of currently playing book" -msgstr "Название текущей аудиокниги" - -#: data/ui/media_controller.ui:217 data/ui/media_controller_big.ui:126 -msgid "Part name" -msgstr "Название части" - -#: data/ui/media_controller.ui:218 data/ui/media_controller_big.ui:127 -msgid "Title of the currently playing part" -msgstr "Название текущей части" - -#: data/ui/media_controller.ui:256 data/ui/seek_bar.ui:20 -msgid "Elapsed time" -msgstr "Пройденное время" - -#: data/ui/media_controller.ui:264 data/ui/seek_bar.ui:28 -msgid "Time elapsed" -msgstr "Прошло времени" - -#: data/ui/media_controller.ui:265 data/ui/seek_bar.ui:29 -msgid "Elapsed time of current part" -msgstr "Истекшее время текущей части" - -#: data/ui/media_controller.ui:281 data/ui/seek_bar.ui:45 -msgid "Jump to position in current chapter" -msgstr "Перейти на позицию в текущей главе" - -#: data/ui/media_controller.ui:290 data/ui/seek_bar.ui:56 -msgid "Position slider" -msgstr "Ползунок положения" - -#: data/ui/media_controller.ui:291 data/ui/seek_bar.ui:57 -msgid "Position of the current part in seconds" -msgstr "Положение текущей части в секундах" - -#: data/ui/media_controller.ui:310 data/ui/seek_bar.ui:76 -msgid "Remaining time" -msgstr "Оставшееся время" - -#: data/ui/media_controller.ui:317 data/ui/seek_bar.ui:83 -msgid "Time remaining" -msgstr "Времени осталось" - -#: data/ui/media_controller.ui:318 data/ui/seek_bar.ui:84 -msgid "Remaining time of current part" -msgstr "Оставшееся время текущей части" - -#: data/ui/media_controller.ui:350 data/ui/media_controller_big.ui:324 +#: data/ui/media_controller.ui:179 msgid "Volume control" msgstr "Регулятор громкости" -#: data/ui/media_controller.ui:387 data/ui/media_controller.ui:572 -#: data/ui/media_controller_big.ui:367 data/ui/media_controller_small.ui:175 +#: data/ui/media_controller.ui:202 msgid "Playback speed" msgstr "Скорость воспроизведения" -#: data/ui/media_controller.ui:408 data/ui/media_controller_big.ui:394 -msgid "Sleep timer" +#: data/ui/media_controller.ui:213 data/ui/preferences.ui:80 +msgid "Sleep Timer" msgstr "Таймер сна" -#: data/ui/media_controller.ui:418 data/ui/media_controller_big.ui:404 -msgid "Timer menu button" -msgstr "Кнопка меню таймера" - -#: data/ui/media_controller.ui:419 data/ui/media_controller_big.ui:405 +#: data/ui/media_controller.ui:220 msgid "Open the sleep timer popover" msgstr "Открыть окно таймера сна" -#: data/ui/media_controller_big.ui:53 -msgid "Open book" -msgstr "Открыть книгу" - -#: data/ui/preferences.ui:55 +#: data/ui/preferences.ui:27 msgid "General" msgstr "Общие" -#: data/ui/preferences.ui:60 +#: data/ui/preferences.ui:30 msgid "Appearance" msgstr "Внешний вид" -#: data/ui/preferences.ui:83 +#: data/ui/preferences.ui:33 +msgid "Dark Mode" +msgstr "Тёмная тема" + +#: data/ui/preferences.ui:40 msgid "Tags" msgstr "Метки" -#: data/ui/preferences.ui:90 +#: data/ui/preferences.ui:43 +msgid "Swap Author and Reader" +msgstr "Поменять местами автора и чтеца" + +#: data/ui/preferences.ui:44 msgid "Activate if author and reader are displayed the wrong way" -msgstr "Активируйте, если автор и диктор отображаются неправильно" +msgstr "Включите, если автор и чтец отображаются неправильно" -#: data/ui/preferences.ui:107 +#: data/ui/preferences.ui:51 msgid "Playback" -msgstr "Проигрывание" +msgstr "Воспроизведение" -#: data/ui/preferences.ui:114 +#: data/ui/preferences.ui:54 +msgid "Replay" +msgstr "Повтор" + +#: data/ui/preferences.ui:55 msgid "Rewind 30 seconds of the current book when starting Cozy" msgstr "Перемотка текущей книги на 30 секунд назад при запуске Cozy" -#: data/ui/preferences.ui:172 -msgid "Sleep Timer" -msgstr "Таймер сна" +#: data/ui/preferences.ui:60 +msgid "Rewind Duration" +msgstr "Период перемотки назад" -#: data/ui/preferences.ui:218 +#: data/ui/preferences.ui:69 +msgid "Forward Duration" +msgstr "Период перемотки вперёд" + +#: data/ui/preferences.ui:83 +msgid "Fadeout" +msgstr "Затухание" + +#: data/ui/preferences.ui:88 +msgid "Fadeout Duration" +msgstr "Продолжительность затухания" + +#: data/ui/preferences.ui:104 msgid "Storage" msgstr "Хранилище" -#: data/ui/preferences.ui:223 +#: data/ui/preferences.ui:107 msgid "Artwork" msgstr "Произведение" -#: data/ui/preferences.ui:230 +#: data/ui/preferences.ui:110 +msgid "Prefer External Images Over Embedded Cover" +msgstr "Предпочитать внешние изображения встроенной обложке" + +#: data/ui/preferences.ui:111 msgid "Always use images (cover.jpg, *.png, …) when available" msgstr "Всегда использовать изображения (cover.jpg, *.png, …), когда доступно" -#: data/ui/preferences.ui:247 data/ui/preferences.ui:253 -msgid "Storage locations" -msgstr "Места хранения " - -#: data/ui/preferences.ui:312 -msgid "Add location" -msgstr "Добавить расположение" - -#: data/ui/preferences.ui:338 -msgid "Remove location" -msgstr "Удалить расположение" +#: data/ui/preferences.ui:121 +msgid "Feedback" +msgstr "Обратная связь" -#: data/ui/preferences.ui:376 -msgid "Toggle this storage location to be internal/external." -msgstr "Изменить память на внутреннюю/внешнюю" +#: data/ui/search_page.ui:9 +msgid "Search in your library" +msgstr "Поиск в библиотеке" -#: data/ui/preferences.ui:405 -msgid "Set as default storage location for new audiobooks" -msgstr "Установить как место хранения по умолчанию для новых аудиокниг" +#: data/ui/search_page.ui:15 +msgid "No results found" +msgstr "Ничего не найдено" -#: data/ui/preferences.ui:409 -msgid "Set as default" -msgstr "Установить по умолчанию" +#: data/ui/search_page.ui:33 +msgid "Book" +msgstr "Книга" -#: data/ui/preferences.ui:453 -msgid "Feedback" -msgstr "Обратная связь" +#: data/ui/seek_bar.ui:15 +msgid "Elapsed time" +msgstr "Пройденное время" -#: data/ui/preferences.ui:463 -msgid "User Feedback" -msgstr "Обратная связь пользователей" +#: data/ui/seek_bar.ui:21 +msgid "Elapsed time of current part" +msgstr "Истекшее время текущей части" -#: data/ui/search_popover.ui:24 -msgid "Search" -msgstr "Поиск" +#: data/ui/seek_bar.ui:32 +msgid "Jump to position in current chapter" +msgstr "Перейти на позицию в текущей главе" -#: data/ui/search_popover.ui:36 -msgid "Search box" -msgstr "Поисковая строка" +#: data/ui/seek_bar.ui:39 +msgid "Position of the current part in seconds" +msgstr "Положение текущей части в секундах" -#: data/ui/search_popover.ui:37 -msgid "Search your audiobook library" -msgstr "Поиск в вашей аудиобиблиотеке" +#: data/ui/seek_bar.ui:48 +msgid "Remaining time" +msgstr "Оставшееся время" -#: data/ui/search_popover.ui:67 -msgid "Which book are you looking for?" -msgstr "Какую книгу вы ищите?" +#: data/ui/seek_bar.ui:53 +msgid "Remaining time of current part" +msgstr "Оставшееся время текущей части" -#: data/ui/search_popover.ui:154 -msgid "Book" -msgstr "Книга" +#: data/ui/storage_locations.ui:5 +msgid "Storage locations" +msgstr "Места хранения" -#: data/ui/search_popover.ui:248 -msgid "Part" -msgstr "Часть" +#: data/ui/storage_locations.ui:24 +msgid "Set as default" +msgstr "Установить по умолчанию" -#: data/ui/search_popover.ui:295 -msgid "Nothing found :(" -msgstr "Ничего не найдено :(" +#: data/ui/storage_locations.ui:28 +msgid "Remove" +msgstr "Убрать" -#: data/ui/timer_popover.ui:37 +#: data/ui/timer_popover.ui:30 msgid "Timer duration" msgstr "Продолжительность таймера" -#: data/ui/timer_popover.ui:49 -msgid "Timer duration slider" -msgstr "Ползунок длительности таймера" - -#: data/ui/timer_popover.ui:50 +#: data/ui/timer_popover.ui:40 msgid "Set the sleep timer duration in minutes" msgstr "Установить таймер сна в минутах" -#: data/ui/timer_popover.ui:116 +#: data/ui/timer_popover.ui:86 msgid "Stop after current chapter" msgstr "Остановить после текущей главы" -#: data/ui/timer_popover.ui:164 +#: data/ui/timer_popover.ui:107 msgid "Enable system power control" msgstr "Задействовать управление питанием" -#: data/ui/timer_popover.ui:201 +#: data/ui/timer_popover.ui:125 msgid "" "Type of the action when the timer finishes.\n" "\"shutdown\" will attempt to turn your system off (also known as power off)\n" @@ -768,163 +736,14 @@ msgstr "" "«Выключение» попробует выключить ваш компьютер (также «отключение питания»)\n" "«Спящий режим» попробует приостановить работу компьютера (также «сон»)." -#: data/ui/timer_popover.ui:205 -msgid "" -"System power action\n" -"to perform" -msgstr "" -"Выполнить действие\n" -"по управлению питанием" +#: data/ui/timer_popover.ui:129 +msgid "System power action to perform" +msgstr "Действие с питанием системы" -#: data/ui/timer_popover.ui:221 +#: data/ui/timer_popover.ui:137 msgid "suspend" msgstr "спящий режим" -#: data/ui/timer_popover.ui:237 +#: data/ui/timer_popover.ui:143 msgid "shutdown" msgstr "выключение" - -#: data/ui/titlebar_menu.ui:7 -msgid "_Scan Library" -msgstr "_Сканировать библиотеку" - -#: data/ui/titlebar_menu.ui:13 -msgid "_Hide unavailable books" -msgstr "_Скрыть недоступные книги" - -#: data/ui/titlebar_menu.ui:19 -msgid "_Preferences" -msgstr "_Параметры" - -#: data/ui/titlebar_menu.ui:25 -msgid "_Help" -msgstr "_Справка" - -#: data/ui/titlebar_menu.ui:29 -msgid "_About" -msgstr "_О программе" - -#: data/ui/titlebar_menu.ui:33 -msgid "_Quit" -msgstr "_Выход" - -#: data/ui/welcome.ui:29 -msgid "Welcome!" -msgstr "Добро пожаловать!" - -#: data/ui/welcome.ui:46 -msgid "Add your audiobooks and let's get cozy." -msgstr "Добавьте свои аудиокниги и устраивайтесь поудобнее." - -#: data/ui/whats_new.ui:9 -msgid "Whats new?" -msgstr "Что нового?" - -#: data/ui/whats_new.ui:27 -msgid "Continue" -msgstr "Продолжить" - -#: data/ui/whats_new_importer.ui:17 data/ui/whats_new_library.ui:17 -#: data/ui/whats_new_m4b.ui:17 data/ui/whats_new_m4b_chapter.ui:17 -msgid "What's new in Cozy" -msgstr "Что нового в Cozy" - -#: data/ui/whats_new_importer.ui:52 -msgid "A completely rewritten and far more reliable media importer." -msgstr "" -"Переписанный с нуля и намного более надёжный метод импортирования файлов. " - -#: data/ui/whats_new_importer.ui:77 -msgid "" -"Did you experience audio files that couldn't be imported? Drag & Drop those " -"files onto Cozy or use the application menu in the titlebar to rescan your " -"audiobook directories!" -msgstr "" -"Были ли у вас проблемы с импортом аудиофайлов? Можно перетащить эти файлы в " -"окно Cozy, или воспользоваться меню приложения для нового сканирования " -"каталогов ваших аудиокниг!" - -#: data/ui/whats_new_importer.ui:92 -msgid "Supported media files currently are mp3, m4a, flac, ogg, opus and wav." -msgstr "" -"На данный момент, программа поддерживает форматы mp3, m4a, flac, ogg, opus и" -" wav." - -#: data/ui/whats_new_importer.ui:107 -msgid "More to come in a later update." -msgstr "Мы добавим больше в следующем обновлении." - -#: data/ui/whats_new_library.ui:52 -msgid "An important change in library management" -msgstr "Важные изменения в управлении библиотекой" - -#: data/ui/whats_new_library.ui:77 -msgid "" -"Previously every file which was imported in your library but couldn't be " -"found anymore was removed from the library during a scan." -msgstr "" -"Раньше каждый файл, который был импортирован в вашу библиотеку, но который " -"не удавалось найти, удалялся из библиотеки во время сканирования." - -#: data/ui/whats_new_library.ui:92 -msgid "" -"Now audiobooks are not removed from your library automatically anymore. This" -" prevents accidentally loosing the progress of a audiobook when a file can't" -" be found temporarily." -msgstr "" -"Теперь аудиокниги больше не удаляются из вашей библиотеки автоматически. Это" -" предотвращает случайную потерю прогресса чтения аудиокниги, когда файл " -"временно не может быть найден." - -#: data/ui/whats_new_library.ui:107 -msgid "" -"To remove an audiobook from the library simply right-click on it and choose " -"the remove from library option." -msgstr "" -"Чтобы удалить аудиокнигу из библиотеки, просто нажмите на нее правой кнопкой" -" мыши и выберите параметр «Удалить из библиотеки»." - -#: data/ui/whats_new_m4b.ui:52 -msgid "Basic support for m4b audio books." -msgstr "Поддержка аудиокниг формата m4b." - -#: data/ui/whats_new_m4b.ui:77 -msgid "" -"Many of you have been waiting for it: Support for m4b audio books! This " -"version features basic support for m4b files without chapter support." -msgstr "" -"По многочисленным просьбам, мы добавили поддержку книг формата m4b. Эта " -"версия включает в себя базовую поддержку формата m4b, но не поддерживает " -"использование глав." - -#: data/ui/whats_new_m4b.ui:92 -msgid "" -"Drag & Drop your m4b files onto Cozy or use the application menu in the " -"titlebar to rescan your audiobook directories." -msgstr "" -"Перетащите файлы m4b в окно Cozy или используйте меню приложения чтобы ещё " -"раз сканировать папку с вашими аудиокнигами." - -#: data/ui/whats_new_m4b.ui:107 -msgid "Chapter support will follow in a later update. Stay tuned!" -msgstr "Поддержка глав будет добавлена в будущем обновлении." - -#: data/ui/whats_new_m4b_chapter.ui:52 -msgid "Chapter support for m4b audio books." -msgstr "Поддержка глав аудиокниг формата m4b." - -#: data/ui/whats_new_m4b_chapter.ui:77 -msgid "This version of Cozy features chapter support for m4b audio books!" -msgstr "Эта версия Cozy поддерживает главы для аудиокниг в формате m4b!" - -#: data/ui/whats_new_m4b_chapter.ui:92 -msgid "" -"If you already have m4b files imported you'll need to start a scan of your " -"library from the app menu." -msgstr "" -"Если у вас уже есть импортированные файлы m4b, вам нужно запустить " -"сканирование вашей библиотеки из меню приложения." - -#: data/ui/whats_new_m4b_chapter.ui:107 -msgid "The chapters will then be detected." -msgstr "После этого главы будут удалены." From c8187e48a4a60ea21271c27db92022e6922e43a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Sat, 23 Mar 2024 13:59:13 +0100 Subject: [PATCH 14/28] Port to libadwaita adaptive dialogs (#902) --- README.md | 2 +- com.github.geigi.cozy.json | 2 +- cozy/ui/about_window.py | 5 ++--- cozy/ui/db_migration_failed_view.py | 8 +++++--- cozy/ui/delete_book_view.py | 7 ++++--- cozy/ui/file_not_found_dialog.py | 9 +++++---- cozy/ui/import_failed_dialog.py | 7 ++++--- cozy/ui/preferences_window.py | 5 ++--- data/ui/preferences.blp | 2 +- meson.build | 2 +- 10 files changed, 26 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 3f78995b..05f0e252 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed instructions and developing Co - `python3` - `meson >= 0.40.0` as build system - `gtk4 >= 4.10` -- `libadwaita >= 1.4.0` +- `libadwaita >= 1.5.0` - `peewee >= 3.9.6` as object relation mapper - `mutagen` for meta tag management - `distro` diff --git a/com.github.geigi.cozy.json b/com.github.geigi.cozy.json index b9202a58..7a990386 100644 --- a/com.github.geigi.cozy.json +++ b/com.github.geigi.cozy.json @@ -1,7 +1,7 @@ { "app-id": "com.github.geigi.cozy", "runtime": "org.gnome.Platform", - "runtime-version": "45", + "runtime-version": "46", "sdk": "org.gnome.Sdk", "command": "com.github.geigi.cozy", "finish-args": [ diff --git a/cozy/ui/about_window.py b/cozy/ui/about_window.py index 00acf0cd..3d28f804 100644 --- a/cozy/ui/about_window.py +++ b/cozy/ui/about_window.py @@ -5,7 +5,7 @@ class AboutWindow: def __init__(self, version: str) -> None: - self._window = Adw.AboutWindow.new_from_appdata( + self._window = Adw.AboutDialog.new_from_appdata( "/com/github/geigi/cozy/appdata/com.github.geigi.cozy.appdata.xml", release_notes_version=version, ) @@ -53,5 +53,4 @@ def set_extra_credits(self) -> None: ) def present(self, parent: Adw.ApplicationWindow) -> None: - self._window.set_transient_for(parent) - self._window.present() + self._window.present(parent) diff --git a/cozy/ui/db_migration_failed_view.py b/cozy/ui/db_migration_failed_view.py index f2e81593..3b91bf53 100644 --- a/cozy/ui/db_migration_failed_view.py +++ b/cozy/ui/db_migration_failed_view.py @@ -9,14 +9,13 @@ You can help resolve this problem by reporting an issue on GitHub.") -class DBMigrationFailedView(Adw.MessageDialog): +class DBMigrationFailedView(Adw.AlertDialog): def __init__(self): super().__init__( heading=_("Failed to Update Database"), body=EXPLANATION, default_response="help", close_response="close", - modal=True, ) self.add_response("close", _("Close Cozy")) @@ -25,7 +24,10 @@ def __init__(self): self.connect("response", self.get_help) - def get_help(self, *_, response): + def get_help(self, _, response): if response == "help": webbrowser.open("https://github.com/geigi/cozy/issues", new=2) + def present(self) -> None: + super().present() + diff --git a/cozy/ui/delete_book_view.py b/cozy/ui/delete_book_view.py index 7271cc3f..e0ba98c5 100644 --- a/cozy/ui/delete_book_view.py +++ b/cozy/ui/delete_book_view.py @@ -5,7 +5,7 @@ from cozy.ui.widgets.book_row import BookRow -class DeleteBookView(Adw.MessageDialog): +class DeleteBookView(Adw.AlertDialog): main_window = inject.attr("MainWindow") def __init__(self, callback, book: Book): @@ -14,8 +14,6 @@ def __init__(self, callback, book: Book): body=_("The audiobook will be removed from your disk and from Cozy's library."), default_response="cancel", close_response="cancel", - transient_for=self.main_window.window, - modal=True, ) self.add_response("cancel", _("Cancel")) @@ -27,3 +25,6 @@ def __init__(self, callback, book: Book): self.set_extra_child(list_box) self.connect("response", callback, book) + + def present(self) -> None: + super().present(self.main_window.window) diff --git a/cozy/ui/file_not_found_dialog.py b/cozy/ui/file_not_found_dialog.py index 4beba83d..0f4192fb 100644 --- a/cozy/ui/file_not_found_dialog.py +++ b/cozy/ui/file_not_found_dialog.py @@ -7,7 +7,7 @@ from cozy.model.chapter import Chapter -class FileNotFoundDialog(Adw.MessageDialog): +class FileNotFoundDialog(Adw.AlertDialog): main_window = inject.attr("MainWindow") _importer: Importer = inject.attr(Importer) @@ -19,15 +19,13 @@ def __init__(self, chapter: Chapter): body=_("This file could not be found. Do you want to locate it manually?"), default_response="locate", close_response="cancel", - transient_for=self.main_window.window, - modal=True, ) self.add_response("cancel", _("Cancel")) self.add_response("locate", _("Locate")) self.set_response_appearance("locate", Adw.ResponseAppearance.SUGGESTED) - label = Gtk.Label(label=chapter.file, margin_top=12) + label = Gtk.Label(label=chapter.file, margin_top=12, wrap=True) label.add_css_class("monospace") self.set_extra_child(label) @@ -62,3 +60,6 @@ def _file_dialog_open_callback(self, dialog, result): self.missing_chapter.file = file.get_path() self._importer.scan() + def present(self) -> None: + super().present(self.main_window.window) + diff --git a/cozy/ui/import_failed_dialog.py b/cozy/ui/import_failed_dialog.py index 7b98fa86..980745ad 100644 --- a/cozy/ui/import_failed_dialog.py +++ b/cozy/ui/import_failed_dialog.py @@ -17,7 +17,7 @@ message = HEADER + POSSIBILITIES -class ImportFailedDialog(Adw.MessageDialog): +class ImportFailedDialog(Adw.AlertDialog): """ Dialog that displays failed files on import. """ @@ -28,8 +28,6 @@ def __init__(self, files: list[str]): heading=_("Some files could not be imported"), default_response="cancel", close_response="cancel", - transient_for=self.main_window.window, - modal=True, ) self.add_response("cancel", _("Ok")) @@ -57,3 +55,6 @@ def __init__(self, files: list[str]): box.append(scroller) self.set_extra_child(box) + def present(self) -> None: + super().present(self.main_window.window) + diff --git a/cozy/ui/preferences_window.py b/cozy/ui/preferences_window.py index 0ad0e95c..1df7caa6 100644 --- a/cozy/ui/preferences_window.py +++ b/cozy/ui/preferences_window.py @@ -7,7 +7,7 @@ @Gtk.Template.from_resource("/com/github/geigi/cozy/ui/preferences.ui") -class PreferencesWindow(Adw.PreferencesWindow): +class PreferencesWindow(Adw.PreferencesDialog): __gtype_name__ = "PreferencesWindow" _glib_settings: Gio.Settings = inject.attr(Gio.Settings) @@ -57,5 +57,4 @@ def _on_lock_ui_changed(self) -> None: self.storage_locations_view.set_sensitive(not self._view_model.lock_ui) def present(self, parent: Adw.ApplicationWindow) -> None: - self.set_transient_for(parent) - super().present() + super().present(parent) diff --git a/data/ui/preferences.blp b/data/ui/preferences.blp index 71947c06..49d9b696 100644 --- a/data/ui/preferences.blp +++ b/data/ui/preferences.blp @@ -23,7 +23,7 @@ Adjustment rewind_duration_adjustment { page-increment: 10; } -template $PreferencesWindow: Adw.PreferencesWindow { +template $PreferencesWindow: Adw.PreferencesDialog { Adw.PreferencesPage { icon-name: 'settings-symbolic'; title: _('General'); diff --git a/meson.build b/meson.build index 2a5b4e87..763b3c60 100644 --- a/meson.build +++ b/meson.build @@ -13,7 +13,7 @@ else endif dependency('glib-2.0') -dependency('libadwaita-1', version: '>= 1.4.0') +dependency('libadwaita-1', version: '>= 1.5.0') # from https://github.com/AsavarTzeth/pulseeffects/blob/master/meson.build # Support Debian non-standard python paths From 027efb7622ef38795d3cc006fb0704e3a8f86ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Wed, 27 Mar 2024 22:29:15 +0100 Subject: [PATCH 15/28] Code style changes (#906) --- .github/workflows/checks.yml | 2 +- cozy/app_controller.py | 21 +++++++++--------- cozy/application.py | 1 - cozy/architecture/event_sender.py | 5 ++--- cozy/architecture/observable.py | 2 +- cozy/architecture/profiler.py | 4 ++-- cozy/architecture/singleton.py | 2 +- cozy/control/artwork_cache.py | 12 ++++------ cozy/control/db.py | 6 +---- cozy/control/db_updater.py | 9 ++++---- cozy/control/filesystem_monitor.py | 9 +++----- cozy/control/offline_cache.py | 19 +++++----------- cozy/control/string_representation.py | 3 +-- cozy/db/artwork_cache.py | 2 +- cozy/db/book.py | 3 ++- cozy/db/offline_cache.py | 4 ++-- cozy/db/settings.py | 4 ++-- cozy/db/storage.py | 2 +- cozy/db/track.py | 4 ++-- cozy/ext/inject/__init__.py | 1 - cozy/media/files.py | 5 ++--- cozy/media/gst_player.py | 4 ++-- cozy/media/importer.py | 21 +++++++++--------- cozy/media/media_detector.py | 9 ++++---- cozy/media/media_file.py | 5 ++--- cozy/media/player.py | 4 ++-- cozy/media/tag_reader.py | 17 ++++---------- cozy/model/book.py | 15 +++++-------- cozy/model/database_importer.py | 22 ++++++++---------- cozy/model/library.py | 14 ++++++------ cozy/model/track.py | 4 ++-- cozy/report/report_to_loki.py | 27 +++++++++++------------ cozy/report/reporter.py | 4 +--- cozy/tools.py | 16 ++++++-------- cozy/ui/app_view.py | 4 ++-- cozy/ui/book_detail_view.py | 11 ++++----- cozy/ui/chapter_element.py | 2 +- cozy/ui/db_migration_failed_view.py | 1 - cozy/ui/headerbar.py | 10 +-------- cozy/ui/import_failed_dialog.py | 1 - cozy/ui/library_view.py | 5 ++--- cozy/ui/main_view.py | 9 ++------ cozy/ui/media_controller.py | 4 +--- cozy/ui/search_view.py | 8 +++---- cozy/ui/widgets/album_element.py | 5 ++--- cozy/ui/widgets/book_element.py | 2 +- cozy/ui/widgets/error_reporting.py | 6 ++--- cozy/ui/widgets/filter_list_box.py | 4 +--- cozy/ui/widgets/first_import_button.py | 6 ++--- cozy/ui/widgets/playback_speed_popover.py | 6 ++--- cozy/ui/widgets/sleep_timer.py | 13 ++++------- cozy/view_model/headerbar_view_model.py | 1 - cozy/view_model/library_view_model.py | 19 ++++------------ cozy/view_model/settings_view_model.py | 2 +- pyproject.toml | 5 ++++- test/cozy/media/test_importer.py | 9 ++++---- test/cozy/model/test_book.py | 14 ++++++------ test/cozy/model/test_database_importer.py | 2 +- test/cozy/model/test_library.py | 4 ++-- test/cozy/model/test_settings.py | 10 ++++----- test/cozy/model/test_storage.py | 4 ++-- 61 files changed, 179 insertions(+), 270 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index d9d9b846..0a3e1a00 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -13,4 +13,4 @@ jobs: - uses: actions/checkout@v4 - uses: chartboost/ruff-action@v1 with: - args: --exit-zero \ No newline at end of file + args: --output-format github diff --git a/cozy/app_controller.py b/cozy/app_controller.py index 6d94e952..a81193d5 100644 --- a/cozy/app_controller.py +++ b/cozy/app_controller.py @@ -1,36 +1,35 @@ from gi.repository import Gio - -import cozy.ext.inject as inject from peewee import SqliteDatabase -from cozy.control.offline_cache import OfflineCache -from cozy.media.files import Files -from cozy.media.gst_player import GstPlayer -from cozy.media.player import Player -from cozy.model.database_importer import DatabaseImporter -from cozy.power_manager import PowerManager -from cozy.report import reporter +import cozy.ext.inject as inject from cozy.application_settings import ApplicationSettings from cozy.architecture.singleton import Singleton from cozy.control.db import get_db from cozy.control.filesystem_monitor import FilesystemMonitor +from cozy.control.offline_cache import OfflineCache +from cozy.media.files import Files +from cozy.media.gst_player import GstPlayer +from cozy.media.player import Player from cozy.model.book import Book +from cozy.model.database_importer import DatabaseImporter from cozy.model.library import Library from cozy.model.settings import Settings from cozy.open_view import OpenView +from cozy.power_manager import PowerManager +from cozy.report import reporter from cozy.ui.app_view import AppView from cozy.ui.book_detail_view import BookDetailView from cozy.ui.headerbar import Headerbar -from cozy.ui.toaster import ToastNotifier from cozy.ui.library_view import LibraryView from cozy.ui.main_view import CozyUI from cozy.ui.media_controller import MediaController from cozy.ui.search_view import SearchView +from cozy.ui.toaster import ToastNotifier from cozy.view import View from cozy.view_model.app_view_model import AppViewModel from cozy.view_model.book_detail_view_model import BookDetailViewModel from cozy.view_model.headerbar_view_model import HeaderbarViewModel -from cozy.view_model.library_view_model import LibraryViewModel, LibraryViewMode +from cozy.view_model.library_view_model import LibraryViewMode, LibraryViewModel from cozy.view_model.playback_control_view_model import PlaybackControlViewModel from cozy.view_model.playback_speed_view_model import PlaybackSpeedViewModel from cozy.view_model.search_view_model import SearchViewModel diff --git a/cozy/application.py b/cozy/application.py index 4c8dfab1..d4a72fce 100644 --- a/cozy/application.py +++ b/cozy/application.py @@ -1,5 +1,4 @@ import logging -import os import platform import sys import threading diff --git a/cozy/architecture/event_sender.py b/cozy/architecture/event_sender.py index 11c440f4..82b6a88e 100644 --- a/cozy/architecture/event_sender.py +++ b/cozy/architecture/event_sender.py @@ -1,11 +1,10 @@ -from typing import List, Callable +from typing import Callable -import gi from gi.repository import GLib class EventSender: - _listeners: List[Callable] + _listeners: list[Callable] def __init__(self): self._listeners = [] diff --git a/cozy/architecture/observable.py b/cozy/architecture/observable.py index 9380d4f7..bbf2c7ea 100644 --- a/cozy/architecture/observable.py +++ b/cozy/architecture/observable.py @@ -1,9 +1,9 @@ +import logging from typing import Callable from gi.repository import GLib from cozy.report import reporter -import logging log = logging.getLogger("observable") diff --git a/cozy/architecture/profiler.py b/cozy/architecture/profiler.py index ca85f029..dd99b446 100644 --- a/cozy/architecture/profiler.py +++ b/cozy/architecture/profiler.py @@ -1,6 +1,6 @@ -import time -import logging import functools +import logging +import time log = logging.getLogger("timing") diff --git a/cozy/architecture/singleton.py b/cozy/architecture/singleton.py index da75d21a..0f28f4e5 100644 --- a/cozy/architecture/singleton.py +++ b/cozy/architecture/singleton.py @@ -2,6 +2,6 @@ class Singleton(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: - cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) + cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls] \ No newline at end of file diff --git a/cozy/control/artwork_cache.py b/cozy/control/artwork_cache.py index 85b1ac12..020862f1 100644 --- a/cozy/control/artwork_cache.py +++ b/cozy/control/artwork_cache.py @@ -1,6 +1,6 @@ +import logging import os import uuid -import logging from gi.repository import Gdk, GdkPixbuf @@ -55,8 +55,7 @@ def delete_artwork_cache(self): q.execute() def _on_importer_event(self, event, data): - if event == "scan": - if data == ScanStatus.STARTED: + if event == "scan" and data == ScanStatus.STARTED: self.delete_artwork_cache() def _create_artwork_cache(self, book, pixbuf, size): @@ -97,7 +96,7 @@ def get_album_art_path(self, book, size): if query.exists(): try: uuid = query.first().uuid - except Exception as e: + except Exception: reporter.error("artwork_cache", "load_pixbuf_from_cache: query exists but query.first().uuid crashed.") return None else: @@ -123,10 +122,7 @@ def _load_pixbuf_from_cache(self, book, size): path = self.get_album_art_path(book, size) try: - if path: - pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) - else: - pixbuf = None + pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) if path else None except Exception as e: log.warning("Failed to load pixbuf from path: %s. Deleting file.", path) log.debug(e) diff --git a/cozy/control/db.py b/cozy/control/db.py index 5f79b909..cce7ff17 100644 --- a/cozy/control/db.py +++ b/cozy/control/db.py @@ -1,7 +1,6 @@ import logging import time - from cozy.control.db_updater import update_db from cozy.db.artwork_cache import ArtworkCache from cozy.db.book import Book @@ -91,10 +90,7 @@ def get_track_for_playback(book): query = Track.select().where(Track.id == book.position) if book.position < 1: track_items = get_tracks(book) - if len(track_items) > 0: - track = get_tracks(book)[0] - else: - track = None + track = get_tracks(book)[0] if len(track_items) > 0 else None elif query.exists(): track = query.get() else: diff --git a/cozy/control/db_updater.py b/cozy/control/db_updater.py index ec66d02c..962a659f 100644 --- a/cozy/control/db_updater.py +++ b/cozy/control/db_updater.py @@ -2,9 +2,8 @@ import os import shutil from datetime import datetime -from typing import List -from peewee import IntegerField, BooleanField, FloatField, ForeignKeyField, fn +from peewee import BooleanField, FloatField, ForeignKeyField, IntegerField, fn from playhouse.migrate import SqliteMigrator, migrate from playhouse.reflection import generate_models @@ -124,8 +123,8 @@ def _update_db_9(db): db.stop() db.start() - files: List[File] = [] - track_to_files: List[TrackToFile] = [] + files: list[File] = [] + track_to_files: list[TrackToFile] = [] file_id = 1 if "file" in models["track"]._meta.sorted_field_names: @@ -240,7 +239,7 @@ def update_db(): # First test for version 1 try: next(c for c in db.get_columns("settings") if c.name == "version") - except Exception as e: + except Exception: if len(db.get_tables()) == 0: data_dir = get_data_dir() if os.path.exists(os.path.join(data_dir, "cozy.db")): diff --git a/cozy/control/filesystem_monitor.py b/cozy/control/filesystem_monitor.py index 9b212456..c33599ff 100644 --- a/cozy/control/filesystem_monitor.py +++ b/cozy/control/filesystem_monitor.py @@ -1,9 +1,8 @@ import logging -from typing import List -import cozy.ext.inject as inject from gi.repository import Gio +import cozy.ext.inject as inject from cozy.architecture.event_sender import EventSender from cozy.model.book import Book from cozy.model.settings import Settings @@ -27,7 +26,7 @@ def __init__(self, storage: Storage, online: bool): class FilesystemMonitor(EventSender): - external_storage: List[ExternalStorage] = [] + external_storage: list[ExternalStorage] = [] _settings: Settings = inject.attr(Settings) def __init__(self): @@ -43,7 +42,6 @@ def __init__(self): self._settings_view_model.add_listener(self.__on_settings_changed) def init_offline_mode(self): - external_storage = [] mounts = self.volume_monitor.get_mounts() # go through all audiobook locations and test if they can be found in the mounts list @@ -59,7 +57,6 @@ def close(self): Free all references. """ # self.volume_monitor.unref() - pass def get_book_online(self, book: Book): try: @@ -84,7 +81,7 @@ def is_storage_online(self, storage: Storage) -> bool: return storage.online def is_external(self, directory: str) -> bool: - mounts: List[Gio.Mount] = self.volume_monitor.get_mounts() + mounts: list[Gio.Mount] = self.volume_monitor.get_mounts() for mount in mounts: root = mount.get_root() diff --git a/cozy/control/offline_cache.py b/cozy/control/offline_cache.py index 2b378f31..593e6053 100644 --- a/cozy/control/offline_cache.py +++ b/cozy/control/offline_cache.py @@ -1,15 +1,12 @@ import logging -import uuid import os +import uuid +from gi.repository import Gio +import cozy.tools as tools from cozy.architecture.event_sender import EventSender from cozy.control.application_directories import get_cache_dir -import cozy.tools as tools -import cozy.ui - -from gi.repository import Gio - from cozy.db.file import File from cozy.db.offline_cache import OfflineCache as OfflineCacheModel from cozy.db.track_to_file import TrackToFile @@ -119,7 +116,7 @@ def remove_all_for_storage(self, storage): def get_cached_path(self, chapter: Chapter): query = OfflineCacheModel.select().where(OfflineCacheModel.original_file == chapter.file_id, - OfflineCacheModel.copied == True) + OfflineCacheModel.copied) if query.count() > 0: return os.path.join(self.cache_dir, query.get().cached_file) else: @@ -245,11 +242,7 @@ def _is_book_downloaded(self, book: Book): offline_files = OfflineCacheModel.select().where(OfflineCacheModel.original_file << file_ids) offline_file_ids = [file.original_file.id for file in offline_files] - for chapter in book.chapters: - if chapter.file_id not in offline_file_ids: - return False - - return True + return all(chapter.file_id in offline_file_ids for chapter in book.chapters) def _is_processing(self): """ @@ -260,7 +253,7 @@ def _is_processing(self): return False def _fill_queue_from_db(self): - for item in OfflineCacheModel.select().where(OfflineCacheModel.copied == False): + for item in OfflineCacheModel.select().where(not OfflineCacheModel.copied): if not any(item.id == queued.id for queued in self.queue): self.queue.append(item) self.total_batch_count += 1 diff --git a/cozy/control/string_representation.py b/cozy/control/string_representation.py index 7ea188bb..125928d2 100644 --- a/cozy/control/string_representation.py +++ b/cozy/control/string_representation.py @@ -9,12 +9,11 @@ def seconds_to_str(seconds, max_length=None, include_seconds=True): h, m = divmod(m, 60) if max_length: - max_m, max_s = divmod(max_length, 60) + max_m, _ = divmod(max_length, 60) max_h, max_m = divmod(max_m, 60) else: max_h = h max_m = m - max_s = s if (max_h >= 10): result = "%02d:%02d" % (h, m) diff --git a/cozy/db/artwork_cache.py b/cozy/db/artwork_cache.py index a0744490..e7d98773 100644 --- a/cozy/db/artwork_cache.py +++ b/cozy/db/artwork_cache.py @@ -1,4 +1,4 @@ -from peewee import ForeignKeyField, CharField +from peewee import CharField, ForeignKeyField from cozy.db.book import Book from cozy.db.model_base import ModelBase diff --git a/cozy/db/book.py b/cozy/db/book.py index 99623efd..eae82ecf 100644 --- a/cozy/db/book.py +++ b/cozy/db/book.py @@ -1,5 +1,6 @@ +from peewee import BlobField, BooleanField, CharField, FloatField, IntegerField + from cozy.db.model_base import ModelBase -from peewee import CharField, IntegerField, BlobField, FloatField, BooleanField class Book(ModelBase): diff --git a/cozy/db/offline_cache.py b/cozy/db/offline_cache.py index a71adb81..4607fa6f 100644 --- a/cozy/db/offline_cache.py +++ b/cozy/db/offline_cache.py @@ -1,7 +1,7 @@ -from peewee import ForeignKeyField, BooleanField, CharField +from peewee import BooleanField, CharField, ForeignKeyField -from cozy.db.model_base import ModelBase from cozy.db.file import File +from cozy.db.model_base import ModelBase class OfflineCache(ModelBase): diff --git a/cozy/db/settings.py b/cozy/db/settings.py index e50944aa..851e0f23 100644 --- a/cozy/db/settings.py +++ b/cozy/db/settings.py @@ -1,7 +1,7 @@ -from peewee import CharField, BooleanField, ForeignKeyField, IntegerField +from peewee import BooleanField, CharField, ForeignKeyField, IntegerField -from cozy.db.model_base import ModelBase from cozy.db.book import Book +from cozy.db.model_base import ModelBase DB_VERSION = 10 diff --git a/cozy/db/storage.py b/cozy/db/storage.py index 77c17c36..96d1480a 100644 --- a/cozy/db/storage.py +++ b/cozy/db/storage.py @@ -1,4 +1,4 @@ -from peewee import CharField, IntegerField, BooleanField +from peewee import BooleanField, CharField, IntegerField from cozy.db.model_base import ModelBase diff --git a/cozy/db/track.py b/cozy/db/track.py index 9a4e7619..c89cc8be 100644 --- a/cozy/db/track.py +++ b/cozy/db/track.py @@ -1,7 +1,7 @@ -from peewee import CharField, IntegerField, ForeignKeyField, FloatField +from peewee import CharField, FloatField, ForeignKeyField, IntegerField -from cozy.db.model_base import ModelBase from cozy.db.book import Book +from cozy.db.model_base import ModelBase class Track(ModelBase): diff --git a/cozy/ext/inject/__init__.py b/cozy/ext/inject/__init__.py index f3a77dab..18316e02 100644 --- a/cozy/ext/inject/__init__.py +++ b/cozy/ext/inject/__init__.py @@ -82,7 +82,6 @@ def my_config(binder): import logging import sys import threading -import types from functools import wraps from typing import (Any, Awaitable, Callable, Dict, Generic, Hashable, Optional, Type, TypeVar, Union, cast, get_type_hints, diff --git a/cozy/media/files.py b/cozy/media/files.py index c4d9092a..0bdb97ed 100644 --- a/cozy/media/files.py +++ b/cozy/media/files.py @@ -1,6 +1,5 @@ import logging import os -import urllib from pathlib import Path from gi.repository import Gio @@ -59,7 +58,7 @@ def _copy_file(self, source_path: str, dest_path: str): flags = Gio.FileCopyFlags.OVERWRITE self.filecopy_cancel = Gio.Cancellable() try: - copied = source.copy(destination, flags, self.filecopy_cancel, self._update_copy_status, None) + source.copy(destination, flags, self.filecopy_cancel, self._update_copy_status, None) except Exception as e: if e.code == Gio.IOErrorEnum.CANCELLED: pass @@ -77,7 +76,7 @@ def _copy_file(self, source_path: str, dest_path: str): def _copy_directory(self, path, destination): main_source_path = os.path.split(path)[0] - for dirpath, dirnames, filenames in os.walk(path): + for dirpath, _, filenames in os.walk(path): dirname = os.path.relpath(dirpath, main_source_path) destination_dir = os.path.join(destination, dirname) try: diff --git a/cozy/media/gst_player.py b/cozy/media/gst_player.py index 6d57d553..cea6c53c 100644 --- a/cozy/media/gst_player.py +++ b/cozy/media/gst_player.py @@ -5,11 +5,11 @@ from enum import Enum, auto from typing import Optional +from gi.repository import Gst + from cozy.architecture.event_sender import EventSender from cozy.report import reporter -from gi.repository import Gst - log = logging.getLogger("gst_player") diff --git a/cozy/media/importer.py b/cozy/media/importer.py index 0009d8c9..d6e044af 100644 --- a/cozy/media/importer.py +++ b/cozy/media/importer.py @@ -4,14 +4,13 @@ import time from enum import Enum, auto from multiprocessing.pool import Pool as Pool -from typing import List, Set -from urllib.parse import urlparse, unquote +from urllib.parse import unquote, urlparse from cozy.architecture.event_sender import EventSender from cozy.architecture.profiler import timing from cozy.control.filesystem_monitor import FilesystemMonitor, StorageNotFound from cozy.ext import inject -from cozy.media.media_detector import MediaDetector, NotAnAudioFile, AudioFileCouldNotBeDiscovered +from cozy.media.media_detector import AudioFileCouldNotBeDiscovered, MediaDetector, NotAnAudioFile from cozy.media.media_file import MediaFile from cozy.model.database_importer import DatabaseImporter from cozy.model.library import Library @@ -38,7 +37,7 @@ def import_file(path: str): try: media_detector = MediaDetector(path) media_data = media_detector.get_media_data() - except NotAnAudioFile as e: + except NotAnAudioFile: return None except AudioFileCouldNotBeDiscovered as e: return unquote(urlparse(str(e)).path) @@ -85,7 +84,7 @@ def scan(self): logging.info(undetected_files) self.emit_event_main_thread("import-failed", undetected_files) - def _execute_import(self, files_to_scan: List[str]) -> (Set[str], Set[str]): + def _execute_import(self, files_to_scan: list[str]) -> tuple[set[str], set[str]]: new_or_changed_files = set() undetected_files = set() @@ -106,7 +105,7 @@ def _execute_import(self, files_to_scan: List[str]) -> (Set[str], Set[str]): undetected_files.update({file for file in import_result if isinstance(file, str)}) media_files = {file for file in import_result if isinstance(file, MediaFile)} - new_or_changed_files.update((file.path for file in media_files)) + new_or_changed_files.update(file.path for file in media_files) self._progress += CHUNK_SIZE @@ -141,14 +140,14 @@ def _count_files_to_scan(self) -> int: reporter.exception("importer", e, "_count_files_to_scan raised a stop iteration.") return 1 - def _get_files_to_scan(self) -> List[str]: + def _get_files_to_scan(self) -> list[str]: paths_to_scan = self._get_configured_storage_paths() files_in_media_folders = self._walk_paths_to_scan(paths_to_scan) files_to_scan = self._filter_unchanged_files(files_in_media_folders) return files_to_scan - def _get_configured_storage_paths(self) -> List[str]: + def _get_configured_storage_paths(self) -> list[str]: """From all storage path configured by the user, we only want to scan those paths that are currently online and exist.""" paths = [storage.path @@ -165,15 +164,15 @@ def _get_configured_storage_paths(self) -> List[str]: return [path for path in paths if os.path.exists(path)] - def _walk_paths_to_scan(self, paths: List[str]) -> List[str]: + def _walk_paths_to_scan(self, paths: list[str]) -> list[str]: """Get all files recursive inside a directory. Returns absolute paths.""" for path in paths: - for directory, subdirectories, files in os.walk(path): + for directory, _, files in os.walk(path): for file in files: filepath = os.path.join(directory, file) yield filepath - def _filter_unchanged_files(self, files: List[str]) -> List[str]: + def _filter_unchanged_files(self, files: list[str]) -> list[str]: """Filter all files that are already imported and that have not changed from a list of paths.""" imported_files = self._library.files diff --git a/cozy/media/media_detector.py b/cozy/media/media_detector.py index cfb1a6d4..63a894cb 100644 --- a/cozy/media/media_detector.py +++ b/cozy/media/media_detector.py @@ -1,13 +1,12 @@ import logging import pathlib -from cozy.architecture.event_sender import EventSender +from gi.repository import Gst, GstPbutils +from cozy.architecture.event_sender import EventSender from cozy.media.media_file import MediaFile from cozy.media.tag_reader import TagReader -from gi.repository import Gst, GstPbutils - log = logging.getLogger("media_detector") @@ -33,9 +32,9 @@ def get_media_data(self) -> MediaFile: try: discoverer_info: GstPbutils.DiscovererInfo = self.discoverer.discover_uri(self.uri) - except Exception as e: + except Exception: log.info("Skipping file because it couldn't be detected: %s", self.uri) - raise AudioFileCouldNotBeDiscovered(self.uri) + raise AudioFileCouldNotBeDiscovered(self.uri) from None is_valid_audio_file = self._is_valid_audio_file(discoverer_info) if is_valid_audio_file: diff --git a/cozy/media/media_file.py b/cozy/media/media_file.py index 1e08b090..978f3f48 100644 --- a/cozy/media/media_file.py +++ b/cozy/media/media_file.py @@ -1,4 +1,3 @@ -from typing import List from cozy.media.chapter import Chapter @@ -11,10 +10,10 @@ class MediaFile: cover: bytes path: str modified: int - chapters: List[Chapter] + chapters: list[Chapter] def __init__(self, book_name: str, author: str, reader: str, disk: int, cover: bytes, path: str, modified: int, - chapters: List[Chapter]): + chapters: list[Chapter]): self.book_name = book_name self.author = author self.reader = reader diff --git a/cozy/media/player.py b/cozy/media/player.py index 795ce382..5db7ac63 100644 --- a/cozy/media/player.py +++ b/cozy/media/player.py @@ -3,7 +3,6 @@ import time from threading import Thread from typing import Optional -from cozy.media.importer import Importer, ScanStatus from gi.repository import GLib, Gst @@ -12,6 +11,7 @@ from cozy.control.offline_cache import OfflineCache from cozy.ext import inject from cozy.media.gst_player import GstPlayer, GstPlayerState +from cozy.media.importer import Importer, ScanStatus from cozy.model.book import Book from cozy.model.chapter import Chapter from cozy.model.library import Library @@ -384,7 +384,7 @@ def _emit_tick(self): def _fadeout_playback(self): duration = self._app_settings.sleep_timer_fadeout_duration * 20 current_vol = self._gst_player.volume - for i in range(0, duration): + for i in range(duration): volume = max(current_vol - (i / duration), 0) self._gst_player.position = volume time.sleep(0.05) diff --git a/cozy/media/tag_reader.py b/cozy/media/tag_reader.py index 00425b48..8cf83096 100644 --- a/cozy/media/tag_reader.py +++ b/cozy/media/tag_reader.py @@ -1,12 +1,10 @@ import os -from typing import List from urllib.parse import unquote, urlparse import mutagen +from gi.repository import GLib, Gst, GstPbutils from mutagen.mp4 import MP4 -from gi.repository import GstPbutils, Gst, GLib - from cozy.media.chapter import Chapter from cozy.media.media_file import MediaFile @@ -139,24 +137,19 @@ def _get_string_list(self, tag: str): return values - def _get_m4b_chapters(self, mutagen_tags: MP4) -> List[Chapter]: + def _get_m4b_chapters(self, mutagen_tags: MP4) -> list[Chapter]: chapters = [] if not mutagen_tags.chapters or len(mutagen_tags.chapters) == 0: return self._get_single_chapter() - index = 0 - - for chapter in mutagen_tags.chapters: + for index, chapter in enumerate(mutagen_tags.chapters): if index < len(mutagen_tags.chapters) - 1: length = mutagen_tags.chapters[index + 1].start - chapter.start else: length = self._get_length_in_seconds() - chapter.start - if chapter.title: - title = chapter.title - else: - title = "" + title = chapter.title or "" chapters.append(Chapter( name=title, @@ -165,8 +158,6 @@ def _get_m4b_chapters(self, mutagen_tags: MP4) -> List[Chapter]: number=index + 1 )) - index += 1 - return chapters def _parse_with_mutagen(self) -> MP4: diff --git a/cozy/model/book.py b/cozy/model/book.py index a5b62775..8d7e359a 100644 --- a/cozy/model/book.py +++ b/cozy/model/book.py @@ -1,14 +1,13 @@ import logging -from typing import List +from contextlib import suppress -from peewee import SqliteDatabase, DoesNotExist +from peewee import DoesNotExist, SqliteDatabase from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable -from cozy.architecture.profiler import timing -from cozy.db.collation import collate_natural from cozy.db.book import Book as BookModel +from cozy.db.collation import collate_natural from cozy.db.track import Track as TrackModel from cozy.db.track_to_file import TrackToFile from cozy.ext import inject @@ -24,7 +23,7 @@ class BookIsEmpty(Exception): class Book(Observable, EventSender): - _chapters: List[Chapter] = None + _chapters: list[Chapter] = None _settings: Settings = inject.attr(Settings) _app_settings: ApplicationSettings = inject.attr(ApplicationSettings) @@ -161,7 +160,7 @@ def current_chapter(self): @property def duration(self): - return sum((chapter.length for chapter in self.chapters)) + return sum(chapter.length for chapter in self.chapters) @property def progress(self): @@ -223,10 +222,8 @@ def _fetch_chapters(self): def _on_chapter_event(self, event: str, chapter: Chapter): if event == "chapter-deleted": - try: + with suppress(ValueError): self.chapters.remove(chapter) - except ValueError: - pass if len(self._chapters) < 1: if self._settings.last_played_book and self._settings.last_played_book.id == self._db_object.id: diff --git a/cozy/model/database_importer.py b/cozy/model/database_importer.py index 29aa10d8..64ebd43c 100644 --- a/cozy/model/database_importer.py +++ b/cozy/model/database_importer.py @@ -1,7 +1,6 @@ import logging -from typing import List, Set -from peewee import fn, SqliteDatabase +from peewee import SqliteDatabase, fn from cozy.db.book import Book as BookModel from cozy.db.file import File @@ -39,9 +38,9 @@ class DatabaseImporter: _db = inject.attr(SqliteDatabase) def __init__(self): - self._book_update_positions: List[BookUpdatePositionRequest] = [] + self._book_update_positions: list[BookUpdatePositionRequest] = [] - def insert_many(self, media_files: Set[MediaFile]): + def insert_many(self, media_files: set[MediaFile]): self._book_update_positions = [] files = self._prepare_files_db_objects(media_files) @@ -50,7 +49,7 @@ def insert_many(self, media_files: Set[MediaFile]): self._insert_tracks(tracks) self._update_book_positions() - def _prepare_files_db_objects(self, media_files: Set[MediaFile]) -> List[object]: + def _prepare_files_db_objects(self, media_files: set[MediaFile]) -> list[object]: files = [] for media_file in media_files: @@ -71,8 +70,8 @@ def _update_files_in_db(self, file: File, media_file: MediaFile): file.modified = media_file.modified file.save(only=file.dirty_fields) - def _prepare_track_db_objects(self, media_files: Set[MediaFile]) -> Set[TrackInsertRequest]: - book_db_objects: Set[BookModel] = set() + def _prepare_track_db_objects(self, media_files: set[MediaFile]) -> set[TrackInsertRequest]: + book_db_objects: set[BookModel] = set() for media_file in media_files: if not media_file: @@ -150,7 +149,7 @@ def _create_book_db_object(self, media_file: MediaFile) -> BookModel: position=0, rating=-1) - def _get_track_db_objects_for_media_file(self, media_file: MediaFile) -> List[Track]: + def _get_track_db_objects_for_media_file(self, media_file: MediaFile) -> list[Track]: all_track_mappings = TrackToFile.select().join(File).where(TrackToFile.file.path == media_file.path) for item in all_track_mappings: @@ -163,17 +162,14 @@ def _delete_tracks_from_db(self, media_file: MediaFile): def _is_chapter_count_in_db_different(self, media_file: MediaFile) -> bool: all_track_mappings = self._get_chapter_count_in_db(media_file) - if all_track_mappings != len(media_file.chapters): - return True - else: - return False + return all_track_mappings != len(media_file.chapters) def _get_chapter_count_in_db(self, media_file: MediaFile) -> int: all_track_mappings = TrackToFile.select().join(File).where(TrackToFile.file.path == media_file.path) return all_track_mappings.count() - def _insert_tracks(self, tracks: Set[TrackInsertRequest]): + def _insert_tracks(self, tracks: set[TrackInsertRequest]): for track in tracks: track_db = Track.insert(track.track_data).execute() TrackToFile.create(track=track_db, file=track.file, start_at=track.start_at) diff --git a/cozy/model/library.py b/cozy/model/library.py index d377dece..2abe83ec 100644 --- a/cozy/model/library.py +++ b/cozy/model/library.py @@ -1,5 +1,5 @@ import logging -from typing import List, Set, Optional +from typing import Optional from peewee import SqliteDatabase @@ -20,9 +20,9 @@ class Library(EventSender): _db = cache = inject.attr(SqliteDatabase) _settings: Settings = inject.attr(Settings) - _books: List[Book] = [] - _chapters: Set[Chapter] = set() - _files: Set[str] = set() + _books: list[Book] = [] + _chapters: set[Chapter] = set() + _files: set[str] = set() def __init__(self): super().__init__() @@ -40,21 +40,21 @@ def readers(self): return readers @property - def books(self) -> List[Book]: + def books(self) -> list[Book]: if not self._books: self._load_all_books() return self._books @property - def chapters(self) -> Set[Chapter]: + def chapters(self) -> set[Chapter]: if not self._chapters: self._load_all_chapters() return self._chapters @property - def files(self) -> Set[str]: + def files(self) -> set[str]: if not self._files: self._load_all_files() diff --git a/cozy/model/track.py b/cozy/model/track.py index 983fccbe..6a6b74a0 100644 --- a/cozy/model/track.py +++ b/cozy/model/track.py @@ -1,6 +1,6 @@ import logging -from peewee import SqliteDatabase, DoesNotExist +from peewee import DoesNotExist, SqliteDatabase from cozy.db.file import File from cozy.db.track import Track as TrackModel @@ -28,7 +28,7 @@ def __init__(self, db: SqliteDatabase, track: TrackModel): except DoesNotExist: log.error("Inconsistent DB, TrackToFile object is missing. Deleting this track.") self._db_object.delete_instance(recursive=True, delete_nullable=False) - raise TrackInconsistentData + raise TrackInconsistentData from None @property def name(self): diff --git a/cozy/report/report_to_loki.py b/cozy/report/report_to_loki.py index 6720a100..efa98455 100644 --- a/cozy/report/report_to_loki.py +++ b/cozy/report/report_to_loki.py @@ -1,19 +1,19 @@ +import datetime import os +import platform +from contextlib import suppress -import requests -import datetime -import pytz import distro -import platform +import pytz +import requests +from gi.repository import Gtk +from mutagen import version_string as MutagenVersion +from peewee import __version__ as PeeweeVersion from cozy.application_settings import ApplicationSettings from cozy.ext import inject from cozy.report.log_level import LogLevel from cozy.version import __version__ as CozyVersion -from peewee import __version__ as PeeweeVersion -from mutagen import version_string as MutagenVersion - -from gi.repository import Gtk URL = 'https://errors.cozy.sh:3100/api/prom/push' ENABLE = '@INSTALLED@' @@ -50,7 +50,7 @@ def report(component: str, type: LogLevel, message: str, exception: Exception): labels = __append_label(labels, "app", "cozy") labels = __append_label(labels, "level", LOG_LEVEL_MAP[type]) - labels = __append_label(labels, "gtk_version", "{}.{}".format(Gtk.get_major_version(), Gtk.get_minor_version())) + labels = __append_label(labels, "gtk_version", f"{Gtk.get_major_version()}.{Gtk.get_minor_version()}") labels = __append_label(labels, "python_version", platform.python_version()) labels = __append_label(labels, "peewee_version", PeeweeVersion) labels = __append_label(labels, "mutagen_version", MutagenVersion) @@ -69,7 +69,7 @@ def report(component: str, type: LogLevel, message: str, exception: Exception): payload = { 'streams': [ { - 'labels': "{{{}}}".format(labels), + 'labels': f"{{{labels}}}", 'entries': [ { 'ts': curr_datetime, @@ -79,10 +79,9 @@ def report(component: str, type: LogLevel, message: str, exception: Exception): } ] } - try: + + with suppress(Exception): requests.post(URL, json=payload, headers=headers, timeout=10) - except: - pass def __append_label(labels, new_label_name, new_label_content): @@ -91,6 +90,6 @@ def __append_label(labels, new_label_name, new_label_content): else: labels = "" - labels += "{}=\"{}\"".format(new_label_name, new_label_content) + labels += f"{new_label_name}=\"{new_label_content}\"" return labels diff --git a/cozy/report/reporter.py b/cozy/report/reporter.py index 71be3fd6..c5e6849b 100644 --- a/cozy/report/reporter.py +++ b/cozy/report/reporter.py @@ -1,9 +1,7 @@ import traceback - -from cozy.report.log_level import LogLevel - from multiprocessing.pool import ThreadPool as Pool +from cozy.report.log_level import LogLevel from cozy.report.report_to_loki import report report_pool = Pool(5) diff --git a/cozy/tools.py b/cozy/tools.py index 69fc1a97..f5607da8 100644 --- a/cozy/tools.py +++ b/cozy/tools.py @@ -1,10 +1,11 @@ -from datetime import datetime -import time +import logging as log import threading -from platform import system as get_system +import time +from datetime import datetime from enum import Enum from gettext import ngettext -import logging as log +from platform import system as get_system + import distro @@ -37,10 +38,7 @@ def is_elementary(): """ dist = distro.linux_distribution(full_distribution_name=False) log.debug(dist) - if '"elementary"' in dist or 'elementary' in dist: - return True - else: - return False + return '"elementary"' in dist or 'elementary' in dist # https://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python @@ -49,7 +47,7 @@ class StoppableThread(threading.Thread): regularly for the stopped() condition.""" def __init__(self, target=None): - super(StoppableThread, self).__init__(target=target) + super().__init__(target=target) self._stop_event = threading.Event() def stop(self): diff --git a/cozy/ui/app_view.py b/cozy/ui/app_view.py index 09d5ca89..feb69606 100644 --- a/cozy/ui/app_view.py +++ b/cozy/ui/app_view.py @@ -1,8 +1,8 @@ -from gi.repository import Gtk, Adw +from gi.repository import Adw, Gtk from cozy.ext import inject -from cozy.view_model.app_view_model import AppViewModel from cozy.view import View +from cozy.view_model.app_view_model import AppViewModel LIBRARY = "main" EMPTY_STATE = "welcome" diff --git a/cozy/ui/book_detail_view.py b/cozy/ui/book_detail_view.py index 48c9a3df..7952594c 100644 --- a/cozy/ui/book_detail_view.py +++ b/cozy/ui/book_detail_view.py @@ -1,9 +1,10 @@ import logging import time +from contextlib import suppress from threading import Event, Thread -from typing import Optional, Callable +from typing import Callable, Optional -import gi +from gi.repository import Adw, GLib, Gtk from cozy.control.artwork_cache import ArtworkCache from cozy.ext import inject @@ -14,8 +15,6 @@ from cozy.ui.disk_element import DiskElement from cozy.view_model.book_detail_view_model import BookDetailViewModel -from gi.repository import Adw, GLib, Gtk - log = logging.getLogger("BookDetailView") @@ -279,10 +278,8 @@ def _set_cover_image(self, book: Book): def _interrupt_chapters_jobs(self): self._chapters_job_locked = True - try: + with suppress(AttributeError): self._chapters_thread.join(timeout=0.2) - except AttributeError as e: - pass def _prepare_chapters_job(self): self._chapters_job_locked: bool = False diff --git a/cozy/ui/chapter_element.py b/cozy/ui/chapter_element.py index ff75af4b..66343c1d 100644 --- a/cozy/ui/chapter_element.py +++ b/cozy/ui/chapter_element.py @@ -1,4 +1,4 @@ -from gi.repository import Gtk, Pango, GObject, Gdk +from gi.repository import Gdk, GObject, Gtk from cozy.control.string_representation import seconds_to_str from cozy.model.chapter import Chapter diff --git a/cozy/ui/db_migration_failed_view.py b/cozy/ui/db_migration_failed_view.py index 3b91bf53..16f502a0 100644 --- a/cozy/ui/db_migration_failed_view.py +++ b/cozy/ui/db_migration_failed_view.py @@ -1,6 +1,5 @@ import webbrowser -import gi from gi.repository import Adw EXPLANATION = _("During an update of the database an error occurred and Cozy will not be able to startup.\ diff --git a/cozy/ui/headerbar.py b/cozy/ui/headerbar.py index fbca9e70..b7063aa0 100644 --- a/cozy/ui/headerbar.py +++ b/cozy/ui/headerbar.py @@ -1,12 +1,6 @@ import logging -import gi - -from cozy.ext import inject -from cozy.ui.widgets.progress_popover import ProgressPopover -from cozy.view_model.headerbar_view_model import HeaderbarViewModel, HeaderBarState - -from gi.repository import Adw, Gtk, GObject +from gi.repository import Adw, GObject, Gtk from cozy.ext import inject from cozy.ui.widgets.progress_popover import ProgressPopover @@ -96,8 +90,6 @@ def _set_show_sidebar_button_visible(self, *_): self.search_button.set_active(False) def _on_mobile_view(self, widget, _): - page = self.sort_stack.props.visible_child_name - if widget.props.reveal: self.headerbar.set_title_widget(Adw.WindowTitle(title="Cozy")) else: diff --git a/cozy/ui/import_failed_dialog.py b/cozy/ui/import_failed_dialog.py index 980745ad..1cbefca5 100644 --- a/cozy/ui/import_failed_dialog.py +++ b/cozy/ui/import_failed_dialog.py @@ -4,7 +4,6 @@ from cozy.ext import inject - HEADER = _("This can have multiple reasons:") POSSIBILITIES = "\n • ".join(( # yes, it is a hack, because \t would be too wide "", diff --git a/cozy/ui/library_view.py b/cozy/ui/library_view.py index 59eb2eaf..717173f1 100644 --- a/cozy/ui/library_view.py +++ b/cozy/ui/library_view.py @@ -1,13 +1,12 @@ -import functools from typing import Optional from gi.repository import Adw, Gtk from cozy.ext import inject -from cozy.ui.widgets.book_element import BookElement from cozy.ui.delete_book_view import DeleteBookView +from cozy.ui.widgets.book_element import BookElement from cozy.ui.widgets.filter_list_box import FilterListBox -from cozy.view_model.library_view_model import LibraryViewModel, LibraryViewMode +from cozy.view_model.library_view_model import LibraryViewMode, LibraryViewModel READER_PAGE = "reader" AUTHOR_PAGE = "author" diff --git a/cozy/ui/main_view.py b/cozy/ui/main_view.py index c113e1b3..ecdd53e7 100644 --- a/cozy/ui/main_view.py +++ b/cozy/ui/main_view.py @@ -1,6 +1,4 @@ import logging -import os -from collections import defaultdict from threading import Thread from typing import Callable @@ -17,14 +15,11 @@ from cozy.media.importer import Importer, ScanStatus from cozy.media.player import Player from cozy.model.settings import Settings as SettingsModel -from cozy.view_model.settings_view_model import SettingsViewModel -from cozy.view_model.storages_view_model import StoragesViewModel -from cozy.open_view import OpenView -from cozy.ui.library_view import LibraryView from cozy.ui.about_window import AboutWindow +from cozy.ui.library_view import LibraryView from cozy.ui.preferences_window import PreferencesWindow from cozy.ui.widgets.first_import_button import FirstImportButton - +from cozy.view_model.storages_view_model import StoragesViewModel log = logging.getLogger("ui") diff --git a/cozy/ui/media_controller.py b/cozy/ui/media_controller.py index 15100bce..5007ba68 100644 --- a/cozy/ui/media_controller.py +++ b/cozy/ui/media_controller.py @@ -1,6 +1,6 @@ import logging -import gi +from gi.repository import Adw, Gdk, Gtk from cozy.control.artwork_cache import ArtworkCache from cozy.db.book import Book @@ -10,8 +10,6 @@ from cozy.ui.widgets.sleep_timer import SleepTimer from cozy.view_model.playback_control_view_model import PlaybackControlViewModel -from gi.repository import Adw, Gtk, Gdk - log = logging.getLogger("MediaController") COVER_SIZE = 46 diff --git a/cozy/ui/search_view.py b/cozy/ui/search_view.py index 99ec3b31..bfc22b8b 100644 --- a/cozy/ui/search_view.py +++ b/cozy/ui/search_view.py @@ -1,5 +1,6 @@ import threading -from typing import Callable, Sequence +from collections.abc import Sequence +from typing import Callable from gi.repository import Adw, Gtk @@ -109,10 +110,7 @@ def _populate_listbox( if not results: return - if isinstance(results[0], Book): - row_type = BookRow - else: - row_type = ArtistResultRow + row_type = BookRow if isinstance(results[0], Book) else ArtistResultRow for result in results: listbox.append(row_type(result, callback)) diff --git a/cozy/ui/widgets/album_element.py b/cozy/ui/widgets/album_element.py index 790d08d6..875a8a41 100644 --- a/cozy/ui/widgets/album_element.py +++ b/cozy/ui/widgets/album_element.py @@ -2,12 +2,11 @@ import math import cairo +from gi.repository import GObject, Gtk from cozy.control.artwork_cache import ArtworkCache -from cozy.model.book import Book from cozy.ext import inject - -from gi.repository import Gtk, GObject, Gdk +from cozy.model.book import Book ALBUM_ART_SIZE = 200 PLAY_BUTTON_ICON_SIZE = Gtk.IconSize.NORMAL diff --git a/cozy/ui/widgets/book_element.py b/cozy/ui/widgets/book_element.py index efeb965a..0d6c13e0 100644 --- a/cozy/ui/widgets/book_element.py +++ b/cozy/ui/widgets/book_element.py @@ -1,4 +1,4 @@ -from gi.repository import Gtk, GObject, Gdk, Gio +from gi.repository import Gdk, Gio, GObject, Gtk from cozy.model.book import Book from cozy.ui.widgets.album_element import AlbumElement diff --git a/cozy/ui/widgets/error_reporting.py b/cozy/ui/widgets/error_reporting.py index a5c0887b..28e37eac 100644 --- a/cozy/ui/widgets/error_reporting.py +++ b/cozy/ui/widgets/error_reporting.py @@ -1,12 +1,10 @@ from gettext import gettext as _ -import gi +from gi.repository import Gtk from cozy.application_settings import ApplicationSettings from cozy.ext import inject -from gi.repository import Gtk - LEVELS = [ _("Disabled"), _("Basic error reporting"), @@ -87,7 +85,7 @@ def _update_details(self, value): details = "" for i in range(value + 1): for line in LEVEL_DETAILS[i]: - details += "• {}\n".format(line) + details += f"• {line}\n" self.details_label.set_text(details) def _on_app_setting_changed(self, event, _): diff --git a/cozy/ui/widgets/filter_list_box.py b/cozy/ui/widgets/filter_list_box.py index 74e65ae4..269238db 100644 --- a/cozy/ui/widgets/filter_list_box.py +++ b/cozy/ui/widgets/filter_list_box.py @@ -1,9 +1,7 @@ -from typing import List from gi.repository import Gtk from cozy.ui.list_box_row_with_data import ListBoxRowWithData -from cozy.ui.list_box_separator_row import ListBoxSeparatorRow class FilterListBox(Gtk.ListBox): @@ -12,7 +10,7 @@ class FilterListBox(Gtk.ListBox): def __init__(self, **properties): super().__init__(**properties) - def populate(self, elements: List[str]): + def populate(self, elements: list[str]): self.remove_all_children() all_row = ListBoxRowWithData(_("All"), True) diff --git a/cozy/ui/widgets/first_import_button.py b/cozy/ui/widgets/first_import_button.py index f4271d3f..3160fcf2 100644 --- a/cozy/ui/widgets/first_import_button.py +++ b/cozy/ui/widgets/first_import_button.py @@ -1,8 +1,8 @@ -from gi.repository import Adw, Gtk, GObject +from typing import Callable -from .storages import ask_storage_location +from gi.repository import Adw, Gtk -from typing import Callable +from .storages import ask_storage_location @Gtk.Template.from_resource('/com/github/geigi/cozy/ui/first_import_button.ui') diff --git a/cozy/ui/widgets/playback_speed_popover.py b/cozy/ui/widgets/playback_speed_popover.py index 6478e8ca..2ffa2413 100644 --- a/cozy/ui/widgets/playback_speed_popover.py +++ b/cozy/ui/widgets/playback_speed_popover.py @@ -1,8 +1,8 @@ +from gi.repository import Gtk + from cozy.ext import inject from cozy.view_model.playback_speed_view_model import PlaybackSpeedViewModel -from gi.repository import Gtk - @Gtk.Template.from_resource('/com/github/geigi/cozy/ui/playback_speed_popover.ui') class PlaybackSpeedPopover(Gtk.Popover): @@ -28,7 +28,7 @@ def _on_playback_speed_scale_changed(self, _): speed = round(self.playback_speed_scale.get_value(), 2) self._view_model.playback_speed = speed - self.playback_speed_label.set_markup("{speed:3.1f} x".format(speed=speed)) + self.playback_speed_label.set_markup(f"{speed:3.1f} x") def _on_playback_speed_changed(self): self.playback_speed_scale.set_value(self._view_model.playback_speed) diff --git a/cozy/ui/widgets/sleep_timer.py b/cozy/ui/widgets/sleep_timer.py index b7bad85a..20f650da 100644 --- a/cozy/ui/widgets/sleep_timer.py +++ b/cozy/ui/widgets/sleep_timer.py @@ -1,8 +1,8 @@ +from gi.repository import Gtk + from cozy.ext import inject from cozy.view_model.sleep_timer_view_model import SleepTimerViewModel, SystemPowerControl -from gi.repository import Gtk - @Gtk.Template.from_resource('/com/github/geigi/cozy/ui/timer_popover.ui') class SleepTimer(Gtk.Popover): @@ -71,7 +71,7 @@ def _on_remaining_seconds_changed(self): if self._view_model.remaining_seconds < 1: value = 0 else: - value = int((self._view_model.remaining_seconds / 60)) + 1 + value = int(self._view_model.remaining_seconds / 60) + 1 self.timer_scale.set_value(value) @@ -93,10 +93,5 @@ def _on_stop_after_chapter_changed(self): self.chapter_switch.set_active(self._view_model.stop_after_chapter) def _on_timer_enabled_changed(self): - if self._view_model.timer_enabled: - icon = "bed-symbolic" - else: - icon = "no-bed-symbolic" - - self._timer_image.set_from_icon_name(icon) + self._timer_image.set_from_icon_name('bed-symbolic' if self._view_model.timer_enabled else 'no-bed-symbolic') diff --git a/cozy/view_model/headerbar_view_model.py b/cozy/view_model/headerbar_view_model.py index d160220a..d40d3789 100644 --- a/cozy/view_model/headerbar_view_model.py +++ b/cozy/view_model/headerbar_view_model.py @@ -7,7 +7,6 @@ from cozy.media.files import Files from cozy.media.importer import Importer, ScanStatus from cozy.model.library import Library -from cozy.open_view import OpenView from cozy.view import View diff --git a/cozy/view_model/library_view_model.py b/cozy/view_model/library_view_model.py index 2639ca8e..116ab552 100644 --- a/cozy/view_model/library_view_model.py +++ b/cozy/view_model/library_view_model.py @@ -13,11 +13,10 @@ from cozy.media.player import Player from cozy.model.book import Book from cozy.model.library import Library -from cozy.model.storage import Storage from cozy.open_view import OpenView from cozy.report import reporter -from cozy.ui.widgets.book_element import BookElement from cozy.ui.import_failed_dialog import ImportFailedDialog +from cozy.ui.widgets.book_element import BookElement from cozy.view_model.storages_view_model import StoragesViewModel log = logging.getLogger("library_view_model") @@ -79,10 +78,7 @@ def selected_filter(self, value): @property def is_any_book_in_progress(self) -> bool: - for book in self.books: - if book.position > 0: - return True - return False + return any(book.position > 0 for book in self.books) @property def authors(self): @@ -153,17 +149,10 @@ def open_library(self): self._notify("library_view_mode") def book_files_exist(self, book: Book) -> bool: - for chapter in book.chapters: - if os.path.isfile(chapter.file): - return True - return False + return any(os.path.isfile(chapter.file) for chapter in book.chapters) def _on_fs_monitor_event(self, event, _): - if event == "storage-online": - self._notify("authors") - self._notify("readers") - self._notify("books-filter") - elif event == "storage-offline": + if event in {"storage-online", "storage-offline"}: self._notify("authors") self._notify("readers") self._notify("books-filter") diff --git a/cozy/view_model/settings_view_model.py b/cozy/view_model/settings_view_model.py index f5333529..a24e5147 100644 --- a/cozy/view_model/settings_view_model.py +++ b/cozy/view_model/settings_view_model.py @@ -1,6 +1,6 @@ import logging -from gi.repository import Adw, Gtk +from gi.repository import Adw from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender diff --git a/pyproject.toml b/pyproject.toml index 9e634c5d..e705a7eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,11 +6,14 @@ skip-magic-trailing-comma = true line_length = 100 profile = "black" multi_line_output = 3 +skip = ["cozy/ext/inject/"] [tool.ruff] line-length = 100 builtins = ["_"] -output-format = "github" +output-format = "grouped" [tool.ruff.lint] extend-select = ["B", "SIM", "PIE", "C4", "INT", "LOG"] +extend-ignore = ["E402", "E731"] +exclude = ["cozy/ext/inject/*"] diff --git a/test/cozy/media/test_importer.py b/test/cozy/media/test_importer.py index fe599f62..dbc2025d 100644 --- a/test/cozy/media/test_importer.py +++ b/test/cozy/media/test_importer.py @@ -33,7 +33,7 @@ def test_external_paths_are_excluded_when_offline(mocker): internal_storages_in_db = Storage.select().where(Storage.external is not False) internal_storage_paths = [storage.path for storage in internal_storages_in_db] assert len(internal_storage_paths) == len(paths_to_import) - assert all([a == b for a, b in zip(internal_storage_paths, paths_to_import)]) + assert all(a == b for a, b in zip(internal_storage_paths, paths_to_import)) def test_paths_not_existing_are_excluded(mocker): @@ -60,7 +60,7 @@ def test_all_existing_paths_are_included(mocker): internal_storage_paths = [storage.path for storage in internal_storages_in_db] assert len(internal_storage_paths) == len(paths_to_import) - assert all([a == b for a, b in zip(internal_storage_paths, paths_to_import)]) + assert all(a == b for a, b in zip(internal_storage_paths, paths_to_import)) def test_import_file_returns_false_for_directory(mocker): @@ -76,12 +76,11 @@ def test_import_file_returns_false_for_directory(mocker): def test_filter_unchanged_files_returns_only_new_or_changed_files(mocker): from cozy.media.importer import Importer - example_chapters = [] mocker.patch("cozy.model.library.Library.chapters") mocker.patch("os.path.getmtime", return_value=100) - importer = Importer() + Importer() def test_scan_emits_start_event(mocker): @@ -200,4 +199,4 @@ def iterator(self): importer = Importer() imported, _ = importer._execute_import(["a", "b"]) - assert all([a == b for a, b in zip(imported, ["path", "path2"])]) + assert all(a == b for a, b in zip(imported, ["path", "path2"])) diff --git a/test/cozy/model/test_book.py b/test/cozy/model/test_book.py index 5c894514..1c22c141 100644 --- a/test/cozy/model/test_book.py +++ b/test/cozy/model/test_book.py @@ -116,7 +116,7 @@ def test_cover_returns_default_value(peewee_database): from cozy.db.book import Book as BookDB book = Book(peewee_database, BookDB.get(1)) - assert book.cover == None + assert book.cover is None def test_setting_cover_updates_in_book_object_and_database(peewee_database): @@ -170,7 +170,7 @@ def test_offline_returns_default_value(peewee_database): from cozy.db.book import Book as BookDB book = Book(peewee_database, BookDB.get(1)) - assert book.offline == False + assert not book.offline def test_setting_offline_updates_in_book_object_and_database(peewee_database): @@ -179,8 +179,8 @@ def test_setting_offline_updates_in_book_object_and_database(peewee_database): book = Book(peewee_database, BookDB.get(1)) book.offline = True - assert book.offline is True - assert BookDB.get_by_id(1).offline is True + assert book.offline + assert BookDB.get_by_id(1).offline def test_downloaded_returns_default_value(peewee_database): @@ -188,7 +188,7 @@ def test_downloaded_returns_default_value(peewee_database): from cozy.db.book import Book as BookDB book = Book(peewee_database, BookDB.get(1)) - assert book.downloaded == False + assert not book.downloaded def test_setting_downloaded_updates_in_book_object_and_database(peewee_database): @@ -218,7 +218,7 @@ def test_tracks_are_ordered_by_disk_number_name(peewee_database): chapters_manually_sorted = book.chapters.copy() chapters_manually_sorted.sort(key=lambda chapter: (chapter.disk, chapter.number, chapter.name)) - assert all([a == b for a, b in zip(book.chapters, chapters_manually_sorted)]) + assert all(a == b for a, b in zip(book.chapters, chapters_manually_sorted)) def test_current_track_is_actually_current_track(peewee_database): @@ -274,7 +274,7 @@ def test_deleted_book_removed_from_last_played_book_if_necessary(peewee_database settings.last_played_book = book book._on_chapter_event("chapter-deleted", book.chapters[0]) - assert settings.last_played_book == None + assert settings.last_played_book is None def test_skipping_removing_a_non_existing_chapter(peewee_database): diff --git a/test/cozy/model/test_database_importer.py b/test/cozy/model/test_database_importer.py index d5c28278..3afcf41a 100644 --- a/test/cozy/model/test_database_importer.py +++ b/test/cozy/model/test_database_importer.py @@ -65,7 +65,7 @@ def test_update_files_db_objects_updates_modified_field(): database_importer = DatabaseImporter() file = File.select().where(File.path == "test.mp3").get() - file_objects = database_importer._update_files_in_db(file, media_file) + database_importer._update_files_in_db(file, media_file) assert File.select().where(File.path == "test.mp3").get().modified == 12345678 diff --git a/test/cozy/model/test_library.py b/test/cozy/model/test_library.py index 34556bf9..2fcc0d03 100644 --- a/test/cozy/model/test_library.py +++ b/test/cozy/model/test_library.py @@ -83,7 +83,7 @@ def test_rebase_path(): from cozy.model.library import Library library = Library() - chapters = {chapter for chapter in library.chapters if chapter.file.startswith("20.000 Meilen unter dem Meer")} + chapters = {chapter for chapter in library.chapters if chapter.file.startswith("20.000 Meilen unter dem Meer")} # noqa: F841 library.rebase_path("20.000 Meilen unter dem Meer", "new path") @@ -96,7 +96,7 @@ def test_empty_last_book_returns_none(): assert library.last_played_book is None -def test_empty_last_book_returns_none(): +def test_library_last_book_returns_the_book_it_was_set_to(): from cozy.model.library import Library library = Library() diff --git a/test/cozy/model/test_settings.py b/test/cozy/model/test_settings.py index 8cf0639b..7d467973 100644 --- a/test/cozy/model/test_settings.py +++ b/test/cozy/model/test_settings.py @@ -33,10 +33,10 @@ def test_external_storage_locations_contain_only_external_storages(peewee_databa from cozy.db.storage import Storage settings = Settings() - storage_locations = Storage.select().where(Storage.external == True) + storage_locations = Storage.select().where(Storage.external) assert len(settings.external_storage_locations) == len(storage_locations) - assert all([storage.external for storage in settings.external_storage_locations]) + assert all(storage.external for storage in settings.external_storage_locations) def test_last_played_book_returns_correct_value(peewee_database): @@ -55,8 +55,8 @@ def test_setting_last_played_book_to_none_updates_in_settings_object_and_databas settings = Settings() settings.last_played_book = None - assert settings.last_played_book == None - assert SettingsModel.get().last_played_book == None + assert settings.last_played_book is None + assert SettingsModel.get().last_played_book is None def test_fetching_non_existent_last_played_book_returns_none(peewee_database): @@ -81,8 +81,8 @@ def test_fetching_non_existent_last_played_book_sets_it_to_none(peewee_database) db_object.save(only=db_object.dirty_fields) settings = Settings() - dummy = settings.last_played_book + assert hasattr(settings, "last_played_book") assert SettingsModel.get().last_played_book is None diff --git a/test/cozy/model/test_storage.py b/test/cozy/model/test_storage.py index 30109c17..46d0e87b 100644 --- a/test/cozy/model/test_storage.py +++ b/test/cozy/model/test_storage.py @@ -53,7 +53,7 @@ def test_default_returns_correct_default_value(peewee_database_storage): from cozy.model.storage import Storage storage = Storage(peewee_database_storage, 1) - assert storage.default == False + assert not storage.default def test_setting_default_updates_in_track_object_and_database(peewee_database_storage): @@ -72,7 +72,7 @@ def test_external_returns_correct_default_value(peewee_database_storage): from cozy.model.storage import Storage storage = Storage(peewee_database_storage, 1) - assert storage.external == False + assert not storage.external def test_setting_external_updates_in_track_object_and_database(peewee_database_storage): From de397605295c0baea0228b07a76fc9a019d256c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Mon, 1 Apr 2024 16:34:20 +0300 Subject: [PATCH 16/28] appdata: `translate=no` properties It appears that the appstream project no longer supports `translatable=no` properties, and gettext extract the `translatable=no` marked strings as translatable. I opened an issue to inform about the situation, but `translatable=no` properties are not accepted by developers. You can find the issue here: `https://github.com/ximion/appstream/issues/623` **Please test your script or string extraction process before merging this PR.** > In MetaInfo files, each individual paragraph of a description > (or enumerated entry) is translated individually, however, > you can only exclude the complete block from being translated > by adding `translate="no"` to the description element. Source: https://freedesktop.org/software/appstream/docs/sect-Quickstart-Translation.html --- data/com.github.geigi.cozy.appdata.xml | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/data/com.github.geigi.cozy.appdata.xml b/data/com.github.geigi.cozy.appdata.xml index a9a79399..143f3784 100644 --- a/data/com.github.geigi.cozy.appdata.xml +++ b/data/com.github.geigi.cozy.appdata.xml @@ -1,15 +1,15 @@ com.github.geigi.cozy - Cozy + Cozy CC0 GPL-3.0+ com.github.geigi.cozy.desktop com.github.geigi.cozy - Julian Geywitz - Julian Geywitz + Julian Geywitz + Julian Geywitz cozy@geigi.de Listen to audio books @@ -49,7 +49,7 @@ - +

After almost two years, a new version of Cozy is finally here! This release brings an updated user interface along with numerous bug fixes and improved performance.

@@ -67,7 +67,7 @@
- +
  • Support for GTK style manager (thanks A6GibKm)
  • Use natural sorting for chapter titles
  • @@ -76,7 +76,7 @@ - +

    This release features a redesigned preference window. All settings can now be searched. Good news for mobile users too: the redesign should work a lot better on mobile devices now.

    @@ -91,7 +91,7 @@
    - +

    A small bugfix release which makes Cozy more reliable.

    @@ -104,7 +104,7 @@
    - +

    A small bugfix release which makes Cozy more reliable.

    @@ -120,7 +120,7 @@
    - +

    A small bugfix release which makes Cozy more reliable.

    @@ -136,7 +136,7 @@
    - +

    This release features a redesigned library with responsiveness in mind.

    @@ -153,7 +153,7 @@
    - +

    Performance improvements for the book detail view and some bugfixes.

    @@ -168,7 +168,7 @@
    - +

    A small bugfix release which makes Cozy more reliable.

    @@ -183,7 +183,7 @@
    - +

    A small bugfix release which makes Cozy more reliable.

    @@ -198,7 +198,7 @@
    - +

    This release features chapter support for m4b files.

    @@ -212,7 +212,7 @@
    - +

    This release features chapter support for m4b files.

    From 2da25a725e3e30bc055c715ffd6b0f12f384bc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Mon, 1 Apr 2024 16:35:10 +0300 Subject: [PATCH 17/28] appdata: Update developer ID Flathub requires a developer tag and developer ID. Also Appstream decided to use rdns structure for developer ID. It allows reverse-dns IDs like sh.cozy, de.geigi or Fediverse handle (like @user@example.org) > A developer tag with a name child tag must be present. > Only one developer tag is allowed and the name tag also must be present only once in untranslated form. ``` Developer name ``` Source: https://docs.flathub.org/docs/for-app-authors/metainfo-guidelines/#name-summary-and-developer-name > The element should have a id property, containing a unique ID to identify the component developer / development team. It is recommended to use a reverse-DNS name, like org.gnome or io.github.ximion, or a Fediverse handle (like @user@example.org) as ID to achieve a higher chance of uniqueness. Source: https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-developer --- data/com.github.geigi.cozy.appdata.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/com.github.geigi.cozy.appdata.xml b/data/com.github.geigi.cozy.appdata.xml index 143f3784..450f1557 100644 --- a/data/com.github.geigi.cozy.appdata.xml +++ b/data/com.github.geigi.cozy.appdata.xml @@ -7,8 +7,8 @@ com.github.geigi.cozy.desktop com.github.geigi.cozy - Julian Geywitz + Julian Geywitz cozy@geigi.de From 7f29381ffd27f970823bd5604a72795724cce41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Wed, 17 Apr 2024 20:47:58 +0300 Subject: [PATCH 18/28] data: Update blp files Gettext typically cannot extract single quoted strings from .blp files. --- data/ui/album_element.blp | 2 +- data/ui/book_detail.blp | 16 ++++++------- data/ui/book_element.blp | 2 +- data/ui/chapter_element.blp | 2 +- data/ui/error_reporting.blp | 12 +++++----- data/ui/first_import_button.blp | 2 +- data/ui/headerbar.blp | 24 ++++++++++---------- data/ui/main_window.blp | 20 ++++++++--------- data/ui/media_controller.blp | 26 ++++++++++----------- data/ui/preferences.blp | 40 ++++++++++++++++----------------- data/ui/search_page.blp | 10 ++++----- data/ui/seek_bar.blp | 12 +++++----- data/ui/storage_locations.blp | 8 +++---- data/ui/timer_popover.blp | 16 ++++++------- 14 files changed, 96 insertions(+), 96 deletions(-) diff --git a/data/ui/album_element.blp b/data/ui/album_element.blp index fea55dc5..58acfcd9 100644 --- a/data/ui/album_element.blp +++ b/data/ui/album_element.blp @@ -37,7 +37,7 @@ template $AlbumElement: Box { height-request: 40; focusable: true; focus-on-click: false; - tooltip-text: _('Play'); + tooltip-text: _("Play"); halign: center; valign: center; icon-name: 'media-playback-start-symbolic'; diff --git a/data/ui/book_detail.blp b/data/ui/book_detail.blp index 43ae11f1..8dbd7904 100644 --- a/data/ui/book_detail.blp +++ b/data/ui/book_detail.blp @@ -109,7 +109,7 @@ template $BookDetail: Box { Label download_label { margin-start: 5; margin-end: 4; - label: _('Download'); + label: _("Download"); } } @@ -137,7 +137,7 @@ template $BookDetail: Box { Label remaining_text { halign: start; hexpand: true; - label: _('Remaining'); + label: _("Remaining"); styles [ "dim-label", @@ -184,7 +184,7 @@ template $BookDetail: Box { Label { halign: start; - label: _('Total'); + label: _("Total"); styles [ "dim-label", @@ -198,7 +198,7 @@ template $BookDetail: Box { Label { halign: start; - label: _('Last played'); + label: _("Last played"); styles [ "dim-label", @@ -212,7 +212,7 @@ template $BookDetail: Box { Label published_text { halign: start; - label: _('Published'); + label: _("Published"); styles [ "dim-label", @@ -237,7 +237,7 @@ template $BookDetail: Box { } Box unavailable_box { - tooltip-text: _('Some or all files of this book cannot be found.'); + tooltip-text: _("Some or all files of this book cannot be found."); halign: center; spacing: 4; @@ -250,7 +250,7 @@ template $BookDetail: Box { } Label { - label: _('unavailable'); + label: _("unavailable"); styles [ "unavailable_label", @@ -342,7 +342,7 @@ template $BookDetail: Box { Label chapters_loading_text { halign: center; - label: _('Loading chapters, please wait...'); + label: _("Loading chapters, please wait..."); } }; } diff --git a/data/ui/book_element.blp b/data/ui/book_element.blp index a8090ec0..6b8acea9 100644 --- a/data/ui/book_element.blp +++ b/data/ui/book_element.blp @@ -6,7 +6,7 @@ template $BookElement: FlowBoxChild { child: Box container_box { focusable: true; - tooltip-text: _('Open book overview'); + tooltip-text: _("Open book overview"); orientation: vertical; spacing: 1; valign: start; diff --git a/data/ui/chapter_element.blp b/data/ui/chapter_element.blp index a3017374..298c19f1 100644 --- a/data/ui/chapter_element.blp +++ b/data/ui/chapter_element.blp @@ -1,7 +1,7 @@ using Gtk 4.0; template $ChapterElement: Box { - tooltip-text: _('Play this part'); + tooltip-text: _("Play this part"); Box { margin-start: 12; diff --git a/data/ui/error_reporting.blp b/data/ui/error_reporting.blp index 8eaac02b..e34670cf 100644 --- a/data/ui/error_reporting.blp +++ b/data/ui/error_reporting.blp @@ -22,7 +22,7 @@ template $ErrorReporting: Box { spacing: 15; Label { - label: _('User feedback'); + label: _("User feedback"); wrap: true; styles [ @@ -64,14 +64,14 @@ template $ErrorReporting: Box { Label { halign: start; valign: center; - label: C_('Error and crash reporting dialog', 'You can help improve Cozy by contributing information in case of errors and crashes. '); + label: C_("Error and crash reporting dialog", "You can help improve Cozy by contributing information in case of errors and crashes. "); wrap: true; xalign: 0; } Label { valign: center; - label: C_('Error and crash reporting dialog', 'Contributing this information is optional and completely anonymous. We will never collect personal data, files you import or any information that could identify you.'); + label: C_("Error and crash reporting dialog", "Contributing this information is optional and completely anonymous. We will never collect personal data, files you import or any information that could identify you."); wrap: true; xalign: 0; } @@ -79,7 +79,7 @@ template $ErrorReporting: Box { Label { valign: center; halign: start; - label: C_('Error and crash reporting dialog', 'Cozy is opensource and the user feedback source code can be inspected here: '); + label: C_("Error and crash reporting dialog", "Cozy is opensource and the user feedback source code can be inspected here: "); wrap: true; xalign: 0; } @@ -145,7 +145,7 @@ template $ErrorReporting: Box { Label level_label { halign: start; - label: _('Detailed error reporting with import errors'); + label: _("Detailed error reporting with import errors"); wrap: true; xalign: 0; @@ -157,7 +157,7 @@ template $ErrorReporting: Box { Label description_label { halign: start; valign: start; - label: _('The following information will be sent in case of an error or crash:'); + label: _("The following information will be sent in case of an error or crash:"); wrap: true; xalign: 0; } diff --git a/data/ui/first_import_button.blp b/data/ui/first_import_button.blp index 00fd60b4..57219637 100644 --- a/data/ui/first_import_button.blp +++ b/data/ui/first_import_button.blp @@ -9,7 +9,7 @@ template $FirstImportButton: Button { Adw.ButtonContent label { halign: center; - label: _('Select Folder'); + label: _("Select Folder"); icon-name: 'folder-open-symbolic'; } diff --git a/data/ui/headerbar.blp b/data/ui/headerbar.blp index 7f71b50b..88f00f14 100644 --- a/data/ui/headerbar.blp +++ b/data/ui/headerbar.blp @@ -14,28 +14,28 @@ template $Headerbar: Box { ToggleButton show_sidebar_button { visible: false; icon-name: 'sidebar-show-symbolic'; - tooltip-text: _('Toggle Filter Sidebar'); + tooltip-text: _("Toggle Filter Sidebar"); } [end] MenuButton menu_button { - tooltip-text: _('Options'); + tooltip-text: _("Options"); menu-model: primary_menu; icon-name: 'open-menu-symbolic'; accessibility { - label: _('Open the options popover'); + label: _("Open the options popover"); } } [end] ToggleButton search_button { name: 'Search toggle button'; - tooltip-text: _('Search your library'); + tooltip-text: _("Search your library"); icon-name: 'loupe-large-symbolic'; accessibility { - label: _('Open the search popover'); + label: _("Open the search popover"); } } @@ -43,7 +43,7 @@ template $Headerbar: Box { MenuButton progress_menu_button { visible: false; can-focus: true; - tooltip-text: _('Display background task progress'); + tooltip-text: _("Display background task progress"); Spinner progress_spinner {} @@ -64,7 +64,7 @@ template $Headerbar: Box { SearchEntry search_entry { search-delay: 100; - placeholder-text: _('Start typing...'); + placeholder-text: _("Start typing..."); hexpand: true; } } @@ -75,33 +75,33 @@ menu primary_menu { section { item { action: 'app.scan'; - label: _('_Scan Library'); + label: _("_Scan Library"); } } section { item { action: 'app.hide_offline'; - label: _('_Hide unavailable books'); + label: _("_Hide unavailable books"); } } section { item { action: 'app.prefs'; - label: _('_Preferences'); + label: _("_Preferences"); } item { action: 'app.about'; - label: _('_About Cozy'); + label: _("_About Cozy"); } } section { item { action: 'app.quit'; - label: _('_Quit'); + label: _("_Quit"); } } } diff --git a/data/ui/main_window.blp b/data/ui/main_window.blp index 77f34eed..ad3d711b 100644 --- a/data/ui/main_window.blp +++ b/data/ui/main_window.blp @@ -25,7 +25,7 @@ Adw.ApplicationWindow app_window { Adw.StatusPage { icon-name: 'library-symbolic'; - title: _('Drop Audio Books Here to Add Them to Your Library'); + title: _("Drop Audio Books Here to Add Them to Your Library"); styles [ "drag-overlay-status-page", @@ -43,7 +43,7 @@ Adw.ApplicationWindow app_window { content: Adw.NavigationView navigation_view { Adw.NavigationPage { - title: _('Library'); + title: _("Library"); tag: 'main'; Adw.ToolbarView header_container { @@ -59,7 +59,7 @@ Adw.ApplicationWindow app_window { Adw.ViewStackPage { name: 'recent'; - title: _('Recent'); + title: _("Recent"); icon-name: 'recent-symbolic'; child: Label { @@ -69,7 +69,7 @@ Adw.ApplicationWindow app_window { Adw.ViewStackPage { name: 'author'; - title: _('Author'); + title: _("Author"); icon-name: 'person-symbolic'; child: ScrolledWindow sort_author_scroller { @@ -80,7 +80,7 @@ Adw.ApplicationWindow app_window { child: Viewport sort_author_viewport { $FilterListBox author_box { accessibility { - label: _('List of authors'); + label: _("List of authors"); } styles [ @@ -97,7 +97,7 @@ Adw.ApplicationWindow app_window { Adw.ViewStackPage { name: 'reader'; - title: _('Reader'); + title: _("Reader"); icon-name: 'microphone2-symbolic'; child: ScrolledWindow sort_reader_scroller { @@ -108,7 +108,7 @@ Adw.ApplicationWindow app_window { child: Viewport sort_reader_viewport { $FilterListBox reader_box { accessibility { - label: _('List of readers'); + label: _("List of readers"); } styles [ @@ -158,7 +158,7 @@ Adw.ApplicationWindow app_window { selection-mode: none; accessibility { - label: _('List of books'); + label: _("List of books"); } styles [ @@ -178,8 +178,8 @@ Adw.ApplicationWindow app_window { child: Adw.StatusPage { icon-name: 'library-symbolic'; - title: _('No Recent Books Yet'); - description: _('Explore your library by switching to the Author or Reader view'); + title: _("No Recent Books Yet"); + description: _("Explore your library by switching to the Author or Reader view"); }; } diff --git a/data/ui/media_controller.blp b/data/ui/media_controller.blp index c1ef2a58..91e3fb89 100644 --- a/data/ui/media_controller.blp +++ b/data/ui/media_controller.blp @@ -48,7 +48,7 @@ template $MediaController: Adw.BreakpointBin { Box title_box { hexpand: true; - tooltip-text: _('Currently playing'); + tooltip-text: _("Currently playing"); valign: center; orientation: vertical; spacing: 2; @@ -63,7 +63,7 @@ template $MediaController: Adw.BreakpointBin { xalign: 0; accessibility { - label: _('Title of currently playing book'); + label: _("Title of currently playing book"); } styles [ @@ -81,7 +81,7 @@ template $MediaController: Adw.BreakpointBin { xalign: 0; accessibility { - label: _('Title of the currently playing part'); + label: _("Title of the currently playing part"); } } } @@ -106,13 +106,13 @@ template $MediaController: Adw.BreakpointBin { Button prev_button { focusable: true; receives-default: true; - tooltip-text: _('Rewind'); + tooltip-text: _("Rewind"); halign: center; valign: center; icon-name: 'object-rotate-left-symbolic'; accessibility { - label: _('Rewind playback'); + label: _("Rewind playback"); } styles [ @@ -126,13 +126,13 @@ template $MediaController: Adw.BreakpointBin { height-request: 42; focusable: true; receives-default: true; - tooltip-text: _('Start playback'); + tooltip-text: _("Start playback"); halign: center; valign: center; icon-name: 'media-playback-start-symbolic'; accessibility { - label: _('Start or pause the playback'); + label: _("Start or pause the playback"); } styles [ @@ -145,13 +145,13 @@ template $MediaController: Adw.BreakpointBin { Button next_button { focusable: true; receives-default: true; - tooltip-text: _('Forward'); + tooltip-text: _("Forward"); halign: center; valign: center; icon-name: 'object-rotate-right-symbolic'; accessibility { - label: _('Forward Playback'); + label: _("Forward Playback"); } styles [ @@ -175,7 +175,7 @@ template $MediaController: Adw.BreakpointBin { spacing: 3; ScaleButton volume_button { - tooltip-text: _('Volume control'); + tooltip-text: _("Volume control"); adjustment: Adjustment { lower: 0; @@ -193,7 +193,7 @@ template $MediaController: Adw.BreakpointBin { MenuButton playback_speed_button { focusable: true; receives-default: true; - tooltip-text: _('Playback speed'); + tooltip-text: _("Playback speed"); icon-name: 'playback-speed-symbolic'; styles [ @@ -204,14 +204,14 @@ template $MediaController: Adw.BreakpointBin { MenuButton timer_button { focusable: true; receives-default: true; - tooltip-text: _('Sleep Timer'); + tooltip-text: _("Sleep Timer"); Image timer_image { icon-name: 'bed-symbolic'; } accessibility { - label: _('Open the sleep timer popover'); + label: _("Open the sleep timer popover"); } styles [ diff --git a/data/ui/preferences.blp b/data/ui/preferences.blp index 49d9b696..37c9e126 100644 --- a/data/ui/preferences.blp +++ b/data/ui/preferences.blp @@ -26,35 +26,35 @@ Adjustment rewind_duration_adjustment { template $PreferencesWindow: Adw.PreferencesDialog { Adw.PreferencesPage { icon-name: 'settings-symbolic'; - title: _('General'); + title: _("General"); Adw.PreferencesGroup { - title: _('Appearance'); + title: _("Appearance"); Adw.SwitchRow dark_mode_switch { - title: _('Dark Mode'); + title: _("Dark Mode"); } } Adw.PreferencesGroup { - title: _('Tags'); + title: _("Tags"); Adw.SwitchRow swap_author_reader_switch { - title: _('Swap Author and Reader'); - subtitle: _('Activate if author and reader are displayed the wrong way'); + title: _("Swap Author and Reader"); + subtitle: _("Activate if author and reader are displayed the wrong way"); } } Adw.PreferencesGroup { - title: _('Playback'); + title: _("Playback"); Adw.SwitchRow replay_switch { - title: _('Replay'); - subtitle: _('Rewind 30 seconds of the current book when starting Cozy'); + title: _("Replay"); + subtitle: _("Rewind 30 seconds of the current book when starting Cozy"); } Adw.SpinRow rewind_duration_spin_button { - title: _('Rewind Duration'); + title: _("Rewind Duration"); focusable: true; adjustment: rewind_duration_adjustment; snap-to-ticks: true; @@ -62,7 +62,7 @@ template $PreferencesWindow: Adw.PreferencesDialog { } Adw.SpinRow forward_duration_spin_button { - title: _('Forward Duration'); + title: _("Forward Duration"); focusable: true; adjustment: forward_duration_adjustment; snap-to-ticks: true; @@ -71,15 +71,15 @@ template $PreferencesWindow: Adw.PreferencesDialog { } Adw.PreferencesGroup { - title: _('Sleep Timer'); + title: _("Sleep Timer"); Adw.ExpanderRow sleep_timer_fadeout_switch { - title: _('Fadeout'); + title: _("Fadeout"); expanded: true; show-enable-switch: true; Adw.SpinRow { - title: _('Fadeout Duration'); + title: _("Fadeout Duration"); focusable: true; adjustment: fadeout_duration_adjustment; snap-to-ticks: true; @@ -91,24 +91,24 @@ template $PreferencesWindow: Adw.PreferencesDialog { Adw.PreferencesPage storages_page { icon-name: 'harddisk-symbolic'; - title: _('Storage'); + title: _("Storage"); Adw.PreferencesGroup { - title: _('Artwork'); + title: _("Artwork"); Adw.SwitchRow artwork_prefer_external_switch { - title: _('Prefer External Images Over Embedded Cover'); - subtitle: _('Always use images (cover.jpg, *.png, …) when available'); + title: _("Prefer External Images Over Embedded Cover"); + subtitle: _("Always use images (cover.jpg, *.png, …) when available"); } } } Adw.PreferencesPage { icon-name: 'papyrus-vertical-symbolic'; - title: _('Feedback'); + title: _("Feedback"); Adw.PreferencesGroup user_feedback_preference_group { - title: _('User feedback'); + title: _("User feedback"); } } } diff --git a/data/ui/search_page.blp b/data/ui/search_page.blp index d32e2c41..b043e990 100644 --- a/data/ui/search_page.blp +++ b/data/ui/search_page.blp @@ -4,12 +4,12 @@ using Adw 1; template $SearchView: Adw.Bin { Stack stack { Adw.StatusPage start_searching_page { - title: _('Search in your library'); + title: _("Search in your library"); icon-name: 'library-symbolic'; } Adw.StatusPage nothing_found_page { - title: _('No results found'); + title: _("No results found"); icon-name: 'edit-find-symbolic'; } @@ -25,7 +25,7 @@ template $SearchView: Adw.Bin { spacing: 24; Adw.PreferencesGroup book_result_box { - title: _('Book'); + title: _("Book"); visible: false; ListBox book_result_list { @@ -36,7 +36,7 @@ template $SearchView: Adw.Bin { } Adw.PreferencesGroup author_result_box { - title: _('Author'); + title: _("Author"); visible: false; ListBox author_result_list { @@ -47,7 +47,7 @@ template $SearchView: Adw.Bin { } Adw.PreferencesGroup reader_result_box { - title: _('Reader'); + title: _("Reader"); visible: false; ListBox reader_result_list { diff --git a/data/ui/seek_bar.blp b/data/ui/seek_bar.blp index 9b43833a..b3cb54e2 100644 --- a/data/ui/seek_bar.blp +++ b/data/ui/seek_bar.blp @@ -12,14 +12,14 @@ template $SeekBar: Box { spacing: 5; Label current_label { - tooltip-text: _('Elapsed time'); + tooltip-text: _("Elapsed time"); halign: end; valign: center; label: '--:--'; single-line-mode: true; accessibility { - label: _('Elapsed time of current part'); + label: _("Elapsed time of current part"); } styles [ @@ -30,7 +30,7 @@ template $SeekBar: Box { Scale progress_scale { width-request: 150; focusable: true; - tooltip-text: _('Jump to position in current chapter'); + tooltip-text: _("Jump to position in current chapter"); valign: center; hexpand: true; adjustment: seek_bar_adjustment; @@ -38,7 +38,7 @@ template $SeekBar: Box { fill-level: 0; accessibility { - label: _('Position of the current part in seconds'); + label: _("Position of the current part in seconds"); } } @@ -46,13 +46,13 @@ template $SeekBar: Box { valign: center; Label remaining_label { - tooltip-text: _('Remaining time'); + tooltip-text: _("Remaining time"); halign: start; label: '--:--'; single-line-mode: true; accessibility { - label: _('Remaining time of current part'); + label: _("Remaining time of current part"); } styles [ diff --git a/data/ui/storage_locations.blp b/data/ui/storage_locations.blp index c463b3be..2b59a738 100644 --- a/data/ui/storage_locations.blp +++ b/data/ui/storage_locations.blp @@ -2,7 +2,7 @@ using Gtk 4.0; using Adw 1; template $StorageLocations: Adw.PreferencesGroup { - title: _('Storage locations'); + title: _("Storage locations"); ListBox storage_locations_list { margin-bottom: 18; @@ -16,19 +16,19 @@ template $StorageLocations: Adw.PreferencesGroup { menu storage_menu { section { item { - label: _('External drive'); + label: _("External drive"); action: 'storage.mark-external'; } } section { item { - label: _('Set as default'); + label: _("Set as default"); action: 'storage.make-default'; } item { - label: _('Remove'); + label: _("Remove"); action: 'storage.remove'; } } diff --git a/data/ui/timer_popover.blp b/data/ui/timer_popover.blp index 07cd347a..9d01e2d2 100644 --- a/data/ui/timer_popover.blp +++ b/data/ui/timer_popover.blp @@ -27,7 +27,7 @@ template $SleepTimer: Popover { Scale timer_scale { width-request: 205; focusable: true; - tooltip-text: _('Timer duration'); + tooltip-text: _("Timer duration"); halign: start; margin-end: 10; adjustment: timer_value; @@ -38,7 +38,7 @@ template $SleepTimer: Popover { value-pos: right; accessibility { - label: _('Set the sleep timer duration in minutes'); + label: _("Set the sleep timer duration in minutes"); } layout { @@ -51,7 +51,7 @@ template $SleepTimer: Popover { halign: end; valign: center; margin-start: 6; - label: _('min'); + label: _("min"); layout { column: '2'; @@ -81,7 +81,7 @@ template $SleepTimer: Popover { hexpand: true; halign: start; margin-end: 10; - label: _('Stop after current chapter'); + label: _("Stop after current chapter"); } Switch chapter_switch { @@ -97,7 +97,7 @@ template $SleepTimer: Popover { Label { hexpand: true; halign: start; - label: _('Enable system power control'); + label: _("Enable system power control"); } Switch power_control_switch { @@ -114,19 +114,19 @@ template $SleepTimer: Popover { hexpand: true; tooltip-markup: _('Type of the action when the timer finishes.\n"shutdown" will attempt to turn your system off (also known as power off)\n"suspend" will attempt to suspend your system (also known as sleep).'); halign: start; - label: _('System power action to perform'); + label: _("System power action to perform"); } Box { orientation: vertical; CheckButton system_suspend_radiob { - label: _('suspend'); + label: _("suspend"); active: true; } CheckButton system_shutdown_radiob { - label: _('shutdown'); + label: _("shutdown"); group: system_suspend_radiob; } } From 56528e1904c1cc6a0305447eb59b17885a03720d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Wed, 17 Apr 2024 20:48:17 +0300 Subject: [PATCH 19/28] data: Update blp files Gettext typically cannot extract single quoted strings from .blp files. These two strings contain escaped double quotes. --- data/ui/error_reporting.blp | 2 +- data/ui/timer_popover.blp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/ui/error_reporting.blp b/data/ui/error_reporting.blp index e34670cf..6f59a85d 100644 --- a/data/ui/error_reporting.blp +++ b/data/ui/error_reporting.blp @@ -86,7 +86,7 @@ template $ErrorReporting: Box { } Label { - label: _('Sourcecode on GitHub'); + label: _("Sourcecode on GitHub"); use-markup: true; } }; diff --git a/data/ui/timer_popover.blp b/data/ui/timer_popover.blp index 9d01e2d2..0548f4f7 100644 --- a/data/ui/timer_popover.blp +++ b/data/ui/timer_popover.blp @@ -112,7 +112,7 @@ template $SleepTimer: Popover { Label { hexpand: true; - tooltip-markup: _('Type of the action when the timer finishes.\n"shutdown" will attempt to turn your system off (also known as power off)\n"suspend" will attempt to suspend your system (also known as sleep).'); + tooltip-markup: _("Type of the action when the timer finishes.\n“shutdown” will attempt to turn your system off (also known as power off)\n“suspend” will attempt to suspend your system (also known as sleep)."); halign: start; label: _("System power action to perform"); } From 0de692ff7937c2aae3f3ad9e10f54fc89d07daec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Wed, 17 Apr 2024 20:48:33 +0300 Subject: [PATCH 20/28] data: Update POTFILES - Add missing files - Correct a file name --- po/POTFILES | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/po/POTFILES b/po/POTFILES index 28be621d..2d5811fe 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -5,6 +5,7 @@ cozy/media/files.py cozy/media/importer.py cozy/model/track.py cozy/tools.py +cozy/ui/about_window.py cozy/ui/book_detail_view.py cozy/ui/chapter_element.py cozy/ui/db_migration_failed_view.py @@ -13,7 +14,7 @@ cozy/ui/disk_element.py cozy/ui/file_not_found_dialog.py cozy/ui/import_failed_dialog.py cozy/ui/main_view.py -cozy/ui/preferences_view.py +cozy/ui/preferences_window.py cozy/ui/widgets/book_element.py cozy/ui/widgets/book_row.py cozy/ui/widgets/error_reporting.py From cd5e96ce836e4efa5f96becb68ea194f850dd3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Wed, 17 Apr 2024 21:11:27 +0300 Subject: [PATCH 21/28] i18n: Mark some strings translatable Mark some more strings as translatable --- data/ui/book_detail.blp | 4 ++-- data/ui/main_window.blp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/ui/book_detail.blp b/data/ui/book_detail.blp index 8dbd7904..369ef47f 100644 --- a/data/ui/book_detail.blp +++ b/data/ui/book_detail.blp @@ -60,7 +60,7 @@ template $BookDetail: Box { Label book_label { halign: start; valign: end; - label: 'Book name'; + label: _("Book name"); wrap: true; wrap-mode: word_char; ellipsize: end; @@ -78,7 +78,7 @@ template $BookDetail: Box { halign: start; valign: start; margin-bottom: 6; - label: 'Book author'; + label: _("Book author"); wrap: true; wrap-mode: word_char; ellipsize: end; diff --git a/data/ui/main_window.blp b/data/ui/main_window.blp index ad3d711b..4a96dc38 100644 --- a/data/ui/main_window.blp +++ b/data/ui/main_window.blp @@ -63,7 +63,7 @@ Adw.ApplicationWindow app_window { icon-name: 'recent-symbolic'; child: Label { - label: 'Empty'; + label: _("Empty"); }; } @@ -193,7 +193,7 @@ Adw.ApplicationWindow app_window { } Adw.NavigationPage { - title: 'Book title'; + title: _("Book title"); tag: 'book_overview'; child: Adw.ToolbarView book_details_container {}; @@ -225,8 +225,8 @@ Adw.ApplicationWindow app_window { content: Adw.StatusPage { icon-name: 'com.github.geigi.cozy'; - title: 'Importing'; - description: 'Stay tuned while Cozy is preparing your library…'; + title: _("Importing"); + description: _("Stay tuned while Cozy is preparing your library…"); }; }; } @@ -242,8 +242,8 @@ Adw.ApplicationWindow app_window { content: Adw.StatusPage welcome_status_page { icon-name: 'com.github.geigi.cozy'; - title: 'Let\'s get cozy'; - description: 'Select a Folder, or Drag Audiobooks Here to Add Them to Your Library'; + title: _("Let's get cozy"); + description: _("Select a Folder, or Drag Audiobooks Here to Add Them to Your Library"); }; }; } From f79749658bc1b2915c1888df4202999e40102e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Wed, 17 Apr 2024 21:19:03 +0300 Subject: [PATCH 22/28] i18n: Mark unknown tags as translatable Mark two the unknown tags as translatable --- cozy/media/tag_reader.py | 4 ++-- po/POTFILES | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cozy/media/tag_reader.py b/cozy/media/tag_reader.py index 8cf83096..22a1b0d6 100644 --- a/cozy/media/tag_reader.py +++ b/cozy/media/tag_reader.py @@ -58,7 +58,7 @@ def _get_author(self): if len(authors) > 0 and authors[0]: return "; ".join(authors) else: - return "Unknown" + return _("Unknown") def _get_reader(self): readers = self._get_string_list(Gst.TAG_ARTIST) @@ -66,7 +66,7 @@ def _get_reader(self): if len(readers) > 0 and readers[0]: return "; ".join(readers) else: - return "Unknown" + return _("Unknown") def _get_disk(self): success, value = self.tags.get_uint_index(Gst.TAG_ALBUM_VOLUME_NUMBER, 0) diff --git a/po/POTFILES b/po/POTFILES index 2d5811fe..c3520ed5 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -3,6 +3,7 @@ cozy/control/mpris.py cozy/control/offline_cache.py cozy/media/files.py cozy/media/importer.py +cozy/media/tag_reader.py cozy/model/track.py cozy/tools.py cozy/ui/about_window.py From e61cdf16ba8d84af069001e0138ee4f079d36206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sabri=20=C3=9Cnal?= Date: Wed, 17 Apr 2024 21:25:48 +0300 Subject: [PATCH 23/28] app: Improve play button tooltips The tooltip for the 'Start playback' button is somewhat misleading. ```tooltip-text: _("Start/Stop playback");``` This button not only starts the playback but also pauses it. It was already declared in the accessibility string. ``` accessibility { label: _("Start or pause the playback"); } ``` The tooltip for this button should be something like the following strings: - Toggle Playback - Start/Stop playback - Start/Stop --- data/ui/album_element.blp | 5 ++++- data/ui/book_detail.blp | 4 ++++ data/ui/media_controller.blp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/data/ui/album_element.blp b/data/ui/album_element.blp index 58acfcd9..84eeb458 100644 --- a/data/ui/album_element.blp +++ b/data/ui/album_element.blp @@ -37,10 +37,13 @@ template $AlbumElement: Box { height-request: 40; focusable: true; focus-on-click: false; - tooltip-text: _("Play"); + tooltip-text: _("Start/Stop playback"); halign: center; valign: center; icon-name: 'media-playback-start-symbolic'; + accessibility { + label: _("Start or pause the playback"); + } styles [ "circular", diff --git a/data/ui/book_detail.blp b/data/ui/book_detail.blp index 369ef47f..5a1dc1f2 100644 --- a/data/ui/book_detail.blp +++ b/data/ui/book_detail.blp @@ -271,6 +271,10 @@ template $BookDetail: Box { receives-default: true; halign: center; icon-name: 'media-playback-start-symbolic'; + tooltip-text: _("Start/Stop playback"); + accessibility { + label: _("Start or pause the playback"); + } styles [ "suggested-action", diff --git a/data/ui/media_controller.blp b/data/ui/media_controller.blp index 91e3fb89..2fa0ee47 100644 --- a/data/ui/media_controller.blp +++ b/data/ui/media_controller.blp @@ -126,7 +126,7 @@ template $MediaController: Adw.BreakpointBin { height-request: 42; focusable: true; receives-default: true; - tooltip-text: _("Start playback"); + tooltip-text: _("Start/Stop playback"); halign: center; valign: center; icon-name: 'media-playback-start-symbolic'; From fb563bfb1ead32d8e6cdcea2ee02e24cd8bb3159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Sun, 28 Apr 2024 11:29:53 +0200 Subject: [PATCH 24/28] Update and cleanup the README (#905) * Update and cleanup the README * Minor improvements --- README.md | 245 ++++++------------------------------------------------ 1 file changed, 24 insertions(+), 221 deletions(-) diff --git a/README.md b/README.md index 05f0e252..5b7dbd49 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -![Unit Testing](https://github.com/geigi/cozy/workflows/Unit%20Testing/badge.svg)

    @@ -8,111 +7,51 @@ # It's getting Cozy +![Unit Testing](https://github.com/geigi/cozy/workflows/Unit%20Testing/badge.svg) +![Flathub Downloads](https://img.shields.io/flathub/downloads/com.github.geigi.cozy?color=e66100&logo=flatpak) + ![Screenshot](https://raw.githubusercontent.com/geigi/cozy/img/img/screenshot1.png) Cozy is a modern audiobook player for Linux. -Head over to [Matrix](https://matrix.to/#/#cozy:gnome.org?via=matrix.org&via=gnome.org) to join the conversation. +Head over to [Matrix](https://matrix.to/#/#cozy:gnome.org) to join the conversation. ## Here are some of the current features: -- **Import** your audiobooks into Cozy to browse them comfortably +- **Import** all your audio books into Cozy to browse them comfortably - **Sort** your audio books by author, reader & name - **Remembers** your **playback position** - **Sleep timer** -- **Playback speed control** +- **Playback speed control** for each book individually - **Search** your library - **Offline Mode!** This allows you to keep an audio book on your internal storage if you store your audiobooks on an external or network drive. Perfect for listening on the go! - Add **mulitple storage locations** - **Drag & Drop** to import new audio books -- Support for DRM free **mp3, m4a (aac, ALAC, …), flac, ogg, opus, wav** files -- Mpris integration (**Media keys** & playback info for desktop environment) +- Listen to your DRM free **mp3, m4b, m4a (aac, ALAC, …), flac, ogg and wav** audio books +- MPRIS integration (**Media keys** & playback info for desktop environment) # Install +The preferred source for installing Cozy is Flathub + +Download on Flathub + +### Distro packages + | Distro | Package | |--------|:---------:| -| Flatpak | Download on Flathub | | openSUSE |
    cozy | | Fedora |
    cozy | | Arch Linux (AUR) | cozy-audiobooks
    | | VoidLinux | cozy | | Solus | cozy | | MX Linux |
    Cozy | -| elementaryOS | Currently out of date. Please use Flatpak for now. | | Ubuntu (PPA) |
    cozy | | OpenBSD |
    cozy | | Nix |
    cozy | - -## elementaryOS -The App Center version of Cozy is currently out of date. elementaryOS ships with old versions of dependencies needed by Cozy. Those are not compatible anymore. Therefore I'm unable to update the App Center version to the latest version of Cozy. Please switch over to the Flatpak version for now. If you experience issues with moving your library, let me know! - -elementaryOS is working on a new version of App Center which will be based on Flatpak. When the new App Center is live, Cozy will be back on the app center! :) Thanks for everyone who supported me on the App Center. - -## macOS -**Currently discontinued** - -There is an older beta of Cozy 0.6.7 which is tested on macOS 10.14. It might not work with newer versions of macOS. -Because the build process is rather complicated and not easy to automate I've currently discontinued building for macOS. If you're interested in the build process: have a look at my [writeup](https://gist.github.com/geigi/a3b6d661daeb7b181d3bdd3cab517092). - -Some information about the old beta: - -- no integration in notification center or any other desktop integration really -- media keys are not working -- dark mode requires 2x switching in settings + is not loading automatically at startup -- large Cozy.app - -You can download it here: Cozy 0.6.7 beta3 for macOS - # Development +See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed instructions about developing Cozy in GNOME Builder, Fedora and Ubuntu -See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed instructions and developing Cozy on Ubuntu. - -## Requirements -- `python3` -- `meson >= 0.40.0` as build system -- `gtk4 >= 4.10` -- `libadwaita >= 1.5.0` -- `peewee >= 3.9.6` as object relation mapper -- `mutagen` for meta tag management -- `distro` -- `requests` -- `pytz` -- `gi-cairo` -- `gst-1.0` -- `file` -- `gstreamer1.0-plugins-good` -- `gstreamer1.0-plugins-bad` -- `gstreamer1.0-plugins-ugly` -- `gstreamer1.0-libav` for mp4 support - -## Bundled Requirements -- `inject`: https://github.com/ivankorobkov/python-inject - -This dependency is bundled because it is not generally available as a linux package. The licence is respected and included. - -## Build - -```bash -$ git clone https://github.com/geigi/cozy.git -$ cd cozy -$ meson --prefix= -$ ninja -C install -``` - -## Update `po` files -```bash -$ ninja -C com.github.geigi.cozy-update-po -$ ninja -C extra-update-po -``` - -## Running a local build -``` -XDG_DATA_DIRS=/share:/usr/share \ -PYTHONPATH=/lib/python3.[your_python3_version]/site-packages \ - app/bin/com.github.geigi.cozy -``` - -## Q&A +## FAQ ### I have imported wrong files and cannot get rid of them: Delete the following folders to reset cozy (this will loose all saved progress): ``` @@ -123,162 +62,26 @@ Delete the following folders to reset cozy (this will loose all saved progress): ### I can't uninstall the Flatpak: Try -``` +```console flatpak uninstall com.github.geigi.cozy/x86_64/stable ``` or -``` +```console flatpak uninstall --user com.github.geigi.cozy/x86_64/stable ``` Thanks to @Meresmata ### I store my audiobooks in a location that is not accessible in the Flatpak sandbox: -You can override the flatpak settings and allow access to a path (e.g. /media) like this: -``` +You can override the flatpak settings and allow access to a path (e.g. `/media`) like this: +```console flatpak --user override --filesystem=/media com.github.geigi.cozy ``` -## A big thanks -To the contributors on GitHub: -- A6GibKm -- alyssais -- apandada1 -- AsavarTzeth -- Fatih20 -- NathanBnm -- camellan -- chris-kobrzak -- elya5 -- foliva -- grenade -- jimmac -- jnbr -- jubalh -- kaphula -- leuc -- magnickolas -- meisenzahl -- naglis -- oleg-krv -- paper42 -- phpwutz -- rapenne-s -- rdbende -- thibaultamartin -- umeboshi2 -- worldofpeace - -The translators: -- Ainte -- AndreBarata -- Andrey389 -- Asyx -- BunColak -- Caarmi -- CiTyBear -- Distil62 -- Fitoschido -- Floflr -- Foxyriot -- HansCz -- IngrownMink4 -- IvoIliev -- Jagadeeshvarma -- Kwentin -- MageJohn -- NHiX -- Nimmerliefde -- Oi_Suomi_On -- Okton -- Panwar108 -- Potty0 -- Sebosun -- TheMBTH -- TheRuleOfMike -- Vistaus -- W2hJ3MOmIRovEpTeahe80jC -- WhiredPlanck -- _caasi -- aKodi -- abcmen -- abuyop -- albanobattistella -- amadeussss -- andreapillai -- arejano -- artnay -- b3nj4m1n -- baschdl78 -- camellan -- cavinsmith -- cho2 -- chris109b -- cjfloss -- ckaotik -- corentinbettiol -- dtgoitia -- dzerus3 -- elgosz -- endiamesos -- eson -- fishcake13 -- fountain -- fran.dieguez -- georgelemental -- giuscasula -- goran.p1123581321 -- hamidout -- hkoivuneva -- jan.sundman -- jan_nekvasil -- jouselt -- karaagac -- kevinmueller -- leondorus -- Sabri Unal -- linuxmasterclub -- magnickolas -- makaleks -- mannycalavera42 -- mardojai -- markluethje -- milotype -- mvainola -- n1k7as -- nikkpark -- no404error -- nvivant -- oleg_krv -- ooverloord -- oscfdezdz -- pavelz -- rafaelff1 -- ragouel -- saarikko -- sobeitnow0 -- sojuz151 -- steno -- tclokie -- test21 -- thibaultmartin -- translatornator -- tsitokhtsev -- twardowskidev -- txelu -- useruseruser1233211 -- vanhoxx -- vlabo -- xfgusta -- yalexaner -- bittin +## Thanks +A big thanks to all the contributors and translators! See the complete list in [AUTHORS.md](AUTHORS.MD) -To nedrichards for the Flatpak. - -## Help me translate cozy! -Cozy is on Transifex, where anyone can contribute and translate. Can't find your language in the list? Let me know! +## Help us translate Cozy! +Cozy is on Transifex, where anyone can contribute and translate. Can't find your language in the list? Let us know! If you like this project, consider supporting me on Patreon :) - ----- -[![Maintainability](https://api.codeclimate.com/v1/badges/fde8cbdff23033adaca2/maintainability)](https://codeclimate.com/github/geigi/cozy/maintainability) From a43f93af569378aa271f879a761020699ee5d892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Sun, 28 Apr 2024 12:00:15 +0200 Subject: [PATCH 25/28] Remove legacy things (#904) --- .travis.yml | 34 --------------------- com.github.geigi.cozy.json | 10 ++---- cozy/__init__.py | 1 + cozy/application.py | 2 +- cozy/control/mpris.py | 2 +- cozy/control/offline_cache.py | 3 +- cozy/report/report_to_loki.py | 2 +- cozy/tools.py | 37 ----------------------- cozy/version.py | 1 - cozy/view_model/sleep_timer_view_model.py | 11 +++---- data/ui/progress_popover.blp | 1 - meson.build | 4 +-- 12 files changed, 15 insertions(+), 93 deletions(-) delete mode 100644 .travis.yml delete mode 100644 cozy/version.py diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e0cc00ce..00000000 --- a/.travis.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- - -language: node_js - -node_js: - - 10/* - -sudo: required - -services: - - docker - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - libstdc++-5-dev - -cache: - directories: - - /tmp/liftoff - -matrix: - include: - - env: DIST=loki - - env: DIST=juno - -install: - - npm i -g @elementaryos/houston - -script: - - houston ci - --distribution $DIST diff --git a/com.github.geigi.cozy.json b/com.github.geigi.cozy.json index 7a990386..71689c45 100644 --- a/com.github.geigi.cozy.json +++ b/com.github.geigi.cozy.json @@ -6,19 +6,15 @@ "command": "com.github.geigi.cozy", "finish-args": [ "--share=ipc", + "--share=network", "--socket=fallback-x11", "--socket=wayland", - "--device=dri", - "--share=network", "--socket=pulseaudio", + "--device=dri", "--filesystem=host", "--filesystem=xdg-run/gvfs", "--filesystem=xdg-run/gvfsd", - "--talk-name=org.freedesktop.Notifications", - "--talk-name=org.gtk.vfs.*", - "--own-name=org.mpris.MediaPlayer2.Cozy", - "--metadata=X-DConf=migrate-path=/com/github/geigi/cozy/", - "--env=LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/lib" + "--talk-name=org.gtk.vfs.*" ], "modules": [ { diff --git a/cozy/__init__.py b/cozy/__init__.py index e69de29b..b238b3b9 100644 --- a/cozy/__init__.py +++ b/cozy/__init__.py @@ -0,0 +1 @@ +__version__ = "@VERSION@" diff --git a/cozy/application.py b/cozy/application.py index d4a72fce..b9c240c8 100644 --- a/cozy/application.py +++ b/cozy/application.py @@ -8,6 +8,7 @@ import distro from gi.repository import Adw, GLib +from cozy import __version__ from cozy.app_controller import AppController from cozy.control.db import init_db from cozy.control.mpris import MPRIS @@ -16,7 +17,6 @@ from cozy.report import reporter from cozy.ui.main_view import CozyUI from cozy.ui.widgets.filter_list_box import FilterListBox -from cozy.version import __version__ log = logging.getLogger("application") diff --git a/cozy/control/mpris.py b/cozy/control/mpris.py index da206fa9..fa4558cb 100644 --- a/cozy/control/mpris.py +++ b/cozy/control/mpris.py @@ -219,7 +219,7 @@ def __init__(self, app) -> None: self._bus = Gio.bus_get_sync(Gio.BusType.SESSION, None) Gio.bus_own_name_on_connection( self._bus, - "org.mpris.MediaPlayer2.Cozy", + "org.mpris.MediaPlayer2.com.github.geigi.cozy", Gio.BusNameOwnerFlags.NONE, None, None, diff --git a/cozy/control/offline_cache.py b/cozy/control/offline_cache.py index 593e6053..c69e701b 100644 --- a/cozy/control/offline_cache.py +++ b/cozy/control/offline_cache.py @@ -191,8 +191,7 @@ def _process_queue(self): if not new_item.copied and os.path.exists(new_item.original_file.path): log.info("Copying item: %r", new_item) - self.emit_event_main_thread("message", - _("Copying") + " " + tools.shorten_string(book.name, 30)) + self.emit_event_main_thread("message", _("Copying") + " " + book.name) self.current = new_item destination = Gio.File.new_for_path(os.path.join(self.cache_dir, new_item.cached_file)) diff --git a/cozy/report/report_to_loki.py b/cozy/report/report_to_loki.py index efa98455..7b57a766 100644 --- a/cozy/report/report_to_loki.py +++ b/cozy/report/report_to_loki.py @@ -10,10 +10,10 @@ from mutagen import version_string as MutagenVersion from peewee import __version__ as PeeweeVersion +from cozy import __version__ as CozyVersion from cozy.application_settings import ApplicationSettings from cozy.ext import inject from cozy.report.log_level import LogLevel -from cozy.version import __version__ as CozyVersion URL = 'https://errors.cozy.sh:3100/api/prom/push' ENABLE = '@INSTALLED@' diff --git a/cozy/tools.py b/cozy/tools.py index f5607da8..6a033c35 100644 --- a/cozy/tools.py +++ b/cozy/tools.py @@ -1,44 +1,7 @@ -import logging as log import threading import time from datetime import datetime -from enum import Enum from gettext import ngettext -from platform import system as get_system - -import distro - - -class Platform(Enum): - Linux = 0 - Mac = 1 - - -def system_platform(): - os = get_system().upper() - if "LINUX" in os: - return Platform.Linux - else: - return Platform.Mac - - -def shorten_string(string, length): - """ - Shortens a string when it is longer than length and adds … at the end. - :param string: Text to be shortened - :param length: Max. length of string - :return : string or shortened string - """ - return (string[:length] + '…') if len(string) > length else string - - -def is_elementary(): - """ - Currently we are only checking for elementaryOS - """ - dist = distro.linux_distribution(full_distribution_name=False) - log.debug(dist) - return '"elementary"' in dist or 'elementary' in dist # https://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python diff --git a/cozy/version.py b/cozy/version.py deleted file mode 100644 index 7ff32e43..00000000 --- a/cozy/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "@VERSION@" \ No newline at end of file diff --git a/cozy/view_model/sleep_timer_view_model.py b/cozy/view_model/sleep_timer_view_model.py index 296ef8c1..c7f4f87a 100644 --- a/cozy/view_model/sleep_timer_view_model.py +++ b/cozy/view_model/sleep_timer_view_model.py @@ -1,9 +1,9 @@ import logging import os +import sys from enum import Enum, auto from typing import Optional -from cozy import tools from cozy.application_settings import ApplicationSettings from cozy.architecture.observable import Observable from cozy.ext import inject @@ -80,7 +80,7 @@ def _start_timer(self): return log.info("Start Timer") - self._sleep_timer = tools.IntervalTimer(1, self._on_timer_tick) + self._sleep_timer = IntervalTimer(1, self._on_timer_tick) self._sleep_timer.start() def _stop_timer(self): @@ -119,18 +119,17 @@ def _stop_playback(self): self._player.pause(fadeout=fadeout > 0) def _handle_system_power_event(self): - platform = tools.system_platform() - command = "" + command = None if self.system_power_control == SystemPowerControl.SHUTDOWN: log.info("system will attempt to shutdown now!") - if platform is tools.Platform.Linux: + if "linux" in sys.platform.lower(): command = "systemctl poweroff" else: command = "shutdown -h now" elif self.system_power_control == SystemPowerControl.SUSPEND: log.info("system will attempt to suspend now!") - if platform is tools.Platform.Linux: + if "linux" in sys.platform.lower(): command = "systemctl suspend" if command: diff --git a/data/ui/progress_popover.blp b/data/ui/progress_popover.blp index 6e453e16..1de13da6 100644 --- a/data/ui/progress_popover.blp +++ b/data/ui/progress_popover.blp @@ -21,7 +21,6 @@ template $ProgressPopover: Popover { ProgressBar progress_bar { fraction: 0.5; - text: 'dfsg'; } } } diff --git a/meson.build b/meson.build index 763b3c60..c24fc502 100644 --- a/meson.build +++ b/meson.build @@ -81,8 +81,8 @@ install_subdir( ) configure_file( - input: 'cozy/version.py', - output: 'version.py', + input: 'cozy/__init__.py', + output: '__init__.py', configuration: conf, install_dir: python_dir + '/cozy' ) From 5afc97310d8ef5eaf48c120537d293e60ecab6a0 Mon Sep 17 00:00:00 2001 From: Kian-Meng Ang Date: Sun, 28 Apr 2024 18:28:05 +0800 Subject: [PATCH 26/28] Fix typos (#761) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Found via `codespell -S po,test,data -L childs` Co-authored-by: Benedek Dévényi --- README.md | 2 +- cozy/control/string_representation.py | 2 +- cozy/media/tag_reader.py | 2 +- cozy/ui/main_view.py | 2 +- main.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5b7dbd49..45a4ed57 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Head over to [Matrix](https://matrix.to/#/#cozy:gnome.org) to join the conversat - **Playback speed control** for each book individually - **Search** your library - **Offline Mode!** This allows you to keep an audio book on your internal storage if you store your audiobooks on an external or network drive. Perfect for listening on the go! -- Add **mulitple storage locations** +- Add **multiple storage locations** - **Drag & Drop** to import new audio books - Listen to your DRM free **mp3, m4b, m4a (aac, ALAC, …), flac, ogg and wav** audio books - MPRIS integration (**Media keys** & playback info for desktop environment) diff --git a/cozy/control/string_representation.py b/cozy/control/string_representation.py index 125928d2..5e2a8f3a 100644 --- a/cozy/control/string_representation.py +++ b/cozy/control/string_representation.py @@ -1,6 +1,6 @@ def seconds_to_str(seconds, max_length=None, include_seconds=True): """ - Converts seconds to a string with the following apperance: + Converts seconds to a string with the following appearance: hh:mm:ss :param seconds: The seconds as float diff --git a/cozy/media/tag_reader.py b/cozy/media/tag_reader.py index 22a1b0d6..5b1b8c0a 100644 --- a/cozy/media/tag_reader.py +++ b/cozy/media/tag_reader.py @@ -14,7 +14,7 @@ class TagReader: def __init__(self, uri: str, discoverer_info: GstPbutils.DiscovererInfo): if not uri: - raise ValueError("URI must not be None or emtpy") + raise ValueError("URI must not be None or empty") if not discoverer_info: raise ValueError("discoverer_info must not be None") diff --git a/cozy/ui/main_view.py b/cozy/ui/main_view.py index ecdd53e7..1710a201 100644 --- a/cozy/ui/main_view.py +++ b/cozy/ui/main_view.py @@ -146,7 +146,7 @@ def play_pause(self, *_): def block_ui_buttons(self, block, scan=False): """ - Makes the buttons to interact with the player insensetive. + Makes the buttons to interact with the player insensitive. :param block: Boolean """ sensitive = not block diff --git a/main.py b/main.py index 0eb3cf4a..0ae6f8b2 100755 --- a/main.py +++ b/main.py @@ -108,7 +108,7 @@ def main(): application = Application(pkgdatadir) try: - # Handle the debug option seperatly without the Glib stuff + # Handle the debug option separately without the Glib stuff if "-d" in sys.argv: sys.argv.remove("-d") ret = application.run(sys.argv) From 5feb9cf8f60fd40f9a1762f41d75844fdf9c57b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedek=20D=C3=A9v=C3=A9nyi?= Date: Sun, 28 Apr 2024 12:28:42 +0200 Subject: [PATCH 27/28] Remove dark mode switch (#836) --- cozy/application_settings.py | 8 -------- cozy/ui/preferences_window.py | 2 -- cozy/view_model/settings_view_model.py | 17 ----------------- data/com.github.geigi.cozy.gschema.xml | 7 +------ data/ui/preferences.blp | 8 -------- 5 files changed, 1 insertion(+), 41 deletions(-) diff --git a/cozy/application_settings.py b/cozy/application_settings.py index 8a4cbe62..fa59a654 100644 --- a/cozy/application_settings.py +++ b/cozy/application_settings.py @@ -109,14 +109,6 @@ def forward_duration(self) -> int: def forward_duration(self, new_value): self._settings.set_int("forward-duration", new_value) - @property - def dark_mode(self) -> bool: - return self._settings.get_boolean("dark-mode") - - @dark_mode.setter - def dark_mode(self, new_value: bool): - self._settings.set_boolean("dark-mode", new_value) - @property def window_width(self) -> int: return self._settings.get_int("window-width") diff --git a/cozy/ui/preferences_window.py b/cozy/ui/preferences_window.py index 1df7caa6..19239a6e 100644 --- a/cozy/ui/preferences_window.py +++ b/cozy/ui/preferences_window.py @@ -16,7 +16,6 @@ class PreferencesWindow(Adw.PreferencesDialog): storages_page: Adw.PreferencesPage = Gtk.Template.Child() user_feedback_preference_group: Adw.PreferencesGroup = Gtk.Template.Child() - dark_mode_switch: Adw.SwitchRow = Gtk.Template.Child() swap_author_reader_switch: Adw.SwitchRow = Gtk.Template.Child() replay_switch: Adw.SwitchRow = Gtk.Template.Child() sleep_timer_fadeout_switch: Adw.SwitchRow = Gtk.Template.Child() @@ -44,7 +43,6 @@ def _bind_settings(self) -> None: setting, widget, propetry, Gio.SettingsBindFlags.DEFAULT ) - bind_settings("dark-mode", self.dark_mode_switch, "active") bind_settings("swap-author-reader", self.swap_author_reader_switch, "active") bind_settings("replay", self.replay_switch, "active") bind_settings("rewind-duration", self.rewind_duration_adjustment, "value") diff --git a/cozy/view_model/settings_view_model.py b/cozy/view_model/settings_view_model.py index a24e5147..0c9ba931 100644 --- a/cozy/view_model/settings_view_model.py +++ b/cozy/view_model/settings_view_model.py @@ -1,7 +1,5 @@ import logging -from gi.repository import Adw - from cozy.application_settings import ApplicationSettings from cozy.architecture.event_sender import EventSender from cozy.architecture.observable import Observable @@ -23,11 +21,6 @@ def __init__(self): self._lock_ui: bool = False - self.style_manager = Adw.StyleManager.get_default() - self._set_dark_mode() - - self._app_settings.add_listener(self._on_app_setting_changed) - if self._model.first_start: self._importer.scan() @@ -39,13 +32,3 @@ def lock_ui(self) -> bool: def lock_ui(self, new_value: bool): self._lock_ui = new_value self._notify("lock_ui") - - def _set_dark_mode(self): - if self._app_settings.dark_mode: - self.style_manager.set_color_scheme(Adw.ColorScheme.PREFER_DARK) - else: - self.style_manager.set_color_scheme(Adw.ColorScheme.PREFER_LIGHT) - - def _on_app_setting_changed(self, event: str, data): - if event == "dark-mode": - self._set_dark_mode() diff --git a/data/com.github.geigi.cozy.gschema.xml b/data/com.github.geigi.cozy.gschema.xml index ecb44add..b8ddeec9 100644 --- a/data/com.github.geigi.cozy.gschema.xml +++ b/data/com.github.geigi.cozy.gschema.xml @@ -41,11 +41,6 @@ Display the time according to the playback speed. - - false - Enable Dark Mode. - - false Swap author and reader tag assignment. @@ -112,4 +107,4 @@ - \ No newline at end of file + diff --git a/data/ui/preferences.blp b/data/ui/preferences.blp index 37c9e126..beaa90ca 100644 --- a/data/ui/preferences.blp +++ b/data/ui/preferences.blp @@ -28,14 +28,6 @@ template $PreferencesWindow: Adw.PreferencesDialog { icon-name: 'settings-symbolic'; title: _("General"); - Adw.PreferencesGroup { - title: _("Appearance"); - - Adw.SwitchRow dark_mode_switch { - title: _("Dark Mode"); - } - } - Adw.PreferencesGroup { title: _("Tags"); From e83b03c5a0f5af0c7b924b490746e89af9d34f4b Mon Sep 17 00:00:00 2001 From: Edward Betts Date: Tue, 14 May 2024 09:40:19 +0100 Subject: [PATCH 28/28] Correct spelling mistakes (#916) --- cozy/ui/preferences_window.py | 4 ++-- test/cozy/extensions/test_set.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cozy/ui/preferences_window.py b/cozy/ui/preferences_window.py index 19239a6e..3798e39f 100644 --- a/cozy/ui/preferences_window.py +++ b/cozy/ui/preferences_window.py @@ -39,8 +39,8 @@ def __init__(self) -> None: self._bind_settings() def _bind_settings(self) -> None: - bind_settings = lambda setting, widget, propetry: self._glib_settings.bind( - setting, widget, propetry, Gio.SettingsBindFlags.DEFAULT + bind_settings = lambda setting, widget, property: self._glib_settings.bind( + setting, widget, property, Gio.SettingsBindFlags.DEFAULT ) bind_settings("swap-author-reader", self.swap_author_reader_switch, "active") diff --git a/test/cozy/extensions/test_set.py b/test/cozy/extensions/test_set.py index bf6b3033..3acd5e05 100644 --- a/test/cozy/extensions/test_set.py +++ b/test/cozy/extensions/test_set.py @@ -2,7 +2,7 @@ def test_split_strings_does_nothing_for_non_seperated_element(): - test = "This is a nice test. Nothing should be splitted." + test = "This is a nice test. Nothing should be split." result = split_strings_to_set({test}) assert {test} == result