Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51b60cda70 |
No files matched your search
@@ -5,6 +5,22 @@ Toutes les évolutions notables de Noxely sont documentées ici.
|
|||||||
Le format suit [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/)
|
Le format suit [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/)
|
||||||
et le versionnage [SemVer](https://semver.org/lang/fr/).
|
et le versionnage [SemVer](https://semver.org/lang/fr/).
|
||||||
|
|
||||||
|
## [2.1.0] — 2026-09-13
|
||||||
|
|
||||||
|
### Ajouté
|
||||||
|
|
||||||
|
- **Appairage du téléphone.** Plus de jeton à recopier : on ouvre une fenêtre depuis l'interface
|
||||||
|
du serveur, on appuie sur « Appairer » dans Réglages ▸ Connexion, et l'application reçoit le
|
||||||
|
jeton. Le champ de saisie reste disponible pour qui préfère le coller à la main.
|
||||||
|
|
||||||
|
Le téléphone ne peut pas deviner un jeton — c'est ce qu'il protège — mais il peut le recevoir,
|
||||||
|
sous trois conditions cumulées : ouvrir la fenêtre exige déjà le jeton, elle expire au bout de
|
||||||
|
deux minutes, et elle se referme dès qu'un appareil s'est servi. La demande doit en outre venir
|
||||||
|
d'une adresse privée : un appairage n'est jamais joignable depuis Internet.
|
||||||
|
|
||||||
|
- En-têtes de licence GPL v3 dans les cinquante fichiers de code (Kotlin, Python, HTML), rédigés
|
||||||
|
en français comme le reste du projet, le texte faisant foi restant celui de `LICENSE`.
|
||||||
|
|
||||||
## [2.0.1] — 2026-09-13
|
## [2.0.1] — 2026-09-13
|
||||||
|
|
||||||
### Ajouté
|
### Ajouté
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
[](https://kotlinlang.org)
|
[](https://kotlinlang.org)
|
||||||
[](https://developer.android.com/jetpack/compose)
|
[](https://developer.android.com/jetpack/compose)
|
||||||
[](https://developer.android.com/media/media3)
|
[](https://developer.android.com/media/media3)
|
||||||
[](VERSION)
|
[](VERSION)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
[](#-comment-ça-marche)
|
[](#-comment-ça-marche)
|
||||||
|
|
||||||
@@ -59,6 +59,7 @@ synchronisations : c'est là qu'est l'économie.
|
|||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| 🔄 **Synchronisation sobre** | Toutes les 6 h, en Wi-Fi non facturé et batterie suffisante |
|
| 🔄 **Synchronisation sobre** | Toutes les 6 h, en Wi-Fi non facturé et batterie suffisante |
|
||||||
|
| 📱 **Appairage** | Un bouton côté serveur, un bouton côté téléphone : aucun jeton à recopier |
|
||||||
| 🎵 **Lecture** | Audio et vidéo, arrière-plan, casque, écran verrouillé, ±15 s, stop |
|
| 🎵 **Lecture** | Audio et vidéo, arrière-plan, casque, écran verrouillé, ±15 s, stop |
|
||||||
| 📚 **Bibliothèque** | Médias reçus du serveur et contenu déjà présent sur l'appareil |
|
| 📚 **Bibliothèque** | Médias reçus du serveur et contenu déjà présent sur l'appareil |
|
||||||
| 📋 **Playlists** | Listes nommées, appui long pour y ajouter un titre |
|
| 📋 **Playlists** | Listes nommées, appui long pour y ajouter un titre |
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely
|
package fr.tuxgyver.noxely
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely
|
package fr.tuxgyver.noxely
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.library
|
package fr.tuxgyver.noxely.library
|
||||||
|
|
||||||
import fr.tuxgyver.noxely.model.MediaEntry
|
import fr.tuxgyver.noxely.model.MediaEntry
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.library
|
package fr.tuxgyver.noxely.library
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.library
|
package fr.tuxgyver.noxely.library
|
||||||
|
|
||||||
import fr.tuxgyver.noxely.model.MediaEntry
|
import fr.tuxgyver.noxely.model.MediaEntry
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.library
|
package fr.tuxgyver.noxely.library
|
||||||
|
|
||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.library
|
package fr.tuxgyver.noxely.library
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.model
|
package fr.tuxgyver.noxely.model
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.model
|
package fr.tuxgyver.noxely.model
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.offline
|
package fr.tuxgyver.noxely.offline
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.offline
|
package fr.tuxgyver.noxely.offline
|
||||||
|
|
||||||
import android.app.Notification
|
import android.app.Notification
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.offline
|
package fr.tuxgyver.noxely.offline
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.playback
|
package fr.tuxgyver.noxely.playback
|
||||||
|
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.playback
|
package fr.tuxgyver.noxely.playback
|
||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.playback
|
package fr.tuxgyver.noxely.playback
|
||||||
|
|
||||||
import android.content.ComponentName
|
import android.content.ComponentName
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.radio
|
package fr.tuxgyver.noxely.radio
|
||||||
|
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.sources
|
package fr.tuxgyver.noxely.sources
|
||||||
|
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.sync
|
package fr.tuxgyver.noxely.sync
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.sync
|
package fr.tuxgyver.noxely.sync
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -44,6 +56,41 @@ class SyncClient(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère le jeton auprès du serveur, pendant sa fenêtre d'appairage.
|
||||||
|
*
|
||||||
|
* Le téléphone ne peut pas deviner un jeton — c'est ce qu'il protège. Il peut en revanche le
|
||||||
|
* recevoir, à condition que quelqu'un ait ouvert la fenêtre depuis l'interface du serveur, et
|
||||||
|
* que la demande vienne du réseau local.
|
||||||
|
*/
|
||||||
|
suspend fun pair(baseUrl: String): Result<String> = withContext(Dispatchers.IO) {
|
||||||
|
runCatching {
|
||||||
|
val base = baseUrl.trim().trimEnd('/')
|
||||||
|
val connection = openConnection("$base/api/pair", readTimeoutMs = 20_000).apply {
|
||||||
|
requestMethod = "POST"
|
||||||
|
doOutput = true
|
||||||
|
outputStream.close()
|
||||||
|
}
|
||||||
|
val body = try {
|
||||||
|
when (connection.responseCode) {
|
||||||
|
403 -> throw IllegalStateException(
|
||||||
|
connection.errorStream?.bufferedReader()?.readText()
|
||||||
|
?.let { json.parseToJsonElement(it).jsonObject.text("detail") }
|
||||||
|
?: "Aucun appairage en cours sur le serveur"
|
||||||
|
)
|
||||||
|
in 200..299 -> connection.inputStream.bufferedReader().readText()
|
||||||
|
else -> throw IllegalStateException("Le serveur a répondu ${connection.responseCode}")
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
connection.disconnect()
|
||||||
|
}
|
||||||
|
val payload = json.parseToJsonElement(body).jsonObject
|
||||||
|
val token = payload.text("token") ?: throw IllegalStateException("Réponse sans jeton")
|
||||||
|
settings.update { it.copy(baseUrl = base, token = token) }
|
||||||
|
"${payload.text("name")} ${payload.text("version")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun sync(): SyncResult = withContext(Dispatchers.IO) {
|
suspend fun sync(): SyncResult = withContext(Dispatchers.IO) {
|
||||||
val config = settings.config.value
|
val config = settings.config.value
|
||||||
if (!config.isConfigured) return@withContext SyncResult(0, 0, "Serveur non configuré")
|
if (!config.isConfigured) return@withContext SyncResult(0, 0, "Serveur non configuré")
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.sync
|
package fr.tuxgyver.noxely.sync
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui
|
package fr.tuxgyver.noxely.ui
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.about
|
package fr.tuxgyver.noxely.ui.about
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.about
|
package fr.tuxgyver.noxely.ui.about
|
||||||
|
|
||||||
import fr.tuxgyver.noxely.BuildConfig
|
import fr.tuxgyver.noxely.BuildConfig
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.about
|
package fr.tuxgyver.noxely.ui.about
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.components
|
package fr.tuxgyver.noxely.ui.components
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.components
|
package fr.tuxgyver.noxely.ui.components
|
||||||
|
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.components
|
package fr.tuxgyver.noxely.ui.components
|
||||||
|
|
||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.library
|
package fr.tuxgyver.noxely.ui.library
|
||||||
|
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.offline
|
package fr.tuxgyver.noxely.ui.offline
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.player
|
package fr.tuxgyver.noxely.ui.player
|
||||||
|
|
||||||
import androidx.compose.foundation.basicMarquee
|
import androidx.compose.foundation.basicMarquee
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.player
|
package fr.tuxgyver.noxely.ui.player
|
||||||
|
|
||||||
import androidx.annotation.OptIn
|
import androidx.annotation.OptIn
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.playlists
|
package fr.tuxgyver.noxely.ui.playlists
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.playlists
|
package fr.tuxgyver.noxely.ui.playlists
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.playlists
|
package fr.tuxgyver.noxely.ui.playlists
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.server
|
package fr.tuxgyver.noxely.ui.server
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -127,7 +139,7 @@ fun ServerScreen(
|
|||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = token,
|
value = token,
|
||||||
onValueChange = { token = it; probe = null },
|
onValueChange = { token = it; probe = null },
|
||||||
label = { Text("Jeton") },
|
label = { Text("Jeton (rempli par l'appairage)") },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
visualTransformation = PasswordVisualTransformation(),
|
visualTransformation = PasswordVisualTransformation(),
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
@@ -135,6 +147,26 @@ fun ServerScreen(
|
|||||||
Spacer(Modifier.size(14.dp))
|
Spacer(Modifier.size(14.dp))
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Button(
|
Button(
|
||||||
|
enabled = !busy && url.isNotBlank(),
|
||||||
|
onClick = {
|
||||||
|
busy = true
|
||||||
|
probe = null
|
||||||
|
scope.launch {
|
||||||
|
container.sync.pair(url).fold(
|
||||||
|
onSuccess = { name ->
|
||||||
|
token = container.serverSettings.config.value.token
|
||||||
|
probe = "Connecté à $name — jeton reçu"
|
||||||
|
},
|
||||||
|
onFailure = { probe = it.message ?: "Appairage impossible" },
|
||||||
|
)
|
||||||
|
busy = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) { Text("Appairer") }
|
||||||
|
|
||||||
|
Spacer(Modifier.width(10.dp))
|
||||||
|
|
||||||
|
TextButton(
|
||||||
enabled = !busy && url.isNotBlank() && token.isNotBlank(),
|
enabled = !busy && url.isNotBlank() && token.isNotBlank(),
|
||||||
onClick = {
|
onClick = {
|
||||||
busy = true
|
busy = true
|
||||||
@@ -152,7 +184,7 @@ fun ServerScreen(
|
|||||||
busy = false
|
busy = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
) { Text("Tester et enregistrer") }
|
) { Text("Tester") }
|
||||||
|
|
||||||
Spacer(Modifier.width(10.dp))
|
Spacer(Modifier.width(10.dp))
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.sources
|
package fr.tuxgyver.noxely.ui.sources
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.ui.theme
|
package fr.tuxgyver.noxely.ui.theme
|
||||||
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.update
|
package fr.tuxgyver.noxely.update
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.update
|
package fr.tuxgyver.noxely.update
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
|||||||
@@ -1,3 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
* Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
*
|
||||||
|
* Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
* selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
* telle que publiée par la Free Software Foundation.
|
||||||
|
*
|
||||||
|
* Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
* Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
*/
|
||||||
|
|
||||||
package fr.tuxgyver.noxely.update
|
package fr.tuxgyver.noxely.update
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""Point d'entrée : `python -m noxely_server`."""
|
"""Point d'entrée : `python -m noxely_server`."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""API HTTP du serveur Noxely.
|
"""API HTTP du serveur Noxely.
|
||||||
|
|
||||||
Le client Android ne consomme que `/api/health`, `/api/library` et `/api/media/{id}/file` :
|
Le client Android ne consomme que `/api/health`, `/api/library` et `/api/media/{id}/file` :
|
||||||
@@ -7,6 +17,8 @@ mobile doit pouvoir se contenter d'un sondage bref, c'est là qu'est le gain de
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import ipaddress
|
||||||
|
import time
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -19,6 +31,7 @@ from .storage import Storage
|
|||||||
from .workers import Downloader, Watcher, safe_name
|
from .workers import Downloader, Watcher, safe_name
|
||||||
|
|
||||||
VERSION = "1.0.0"
|
VERSION = "1.0.0"
|
||||||
|
PAIRING_WINDOW_SECONDS = 120
|
||||||
WEB_DIR = Path(__file__).parent / "web"
|
WEB_DIR = Path(__file__).parent / "web"
|
||||||
|
|
||||||
config = config_module.load()
|
config = config_module.load()
|
||||||
@@ -180,6 +193,53 @@ def queue_state() -> dict:
|
|||||||
return {"items": [m.public() for m in pending if m.state != "ready"][:50]}
|
return {"items": [m.public() for m in pending if m.state != "ready"][:50]}
|
||||||
|
|
||||||
|
|
||||||
|
#: Fenêtre d'appairage : instant d'expiration, ou None si elle est fermée.
|
||||||
|
_pairing_until: float | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def _is_private(host: str) -> bool:
|
||||||
|
"""Le réseau local, et lui seul."""
|
||||||
|
try:
|
||||||
|
address = ipaddress.ip_address(host)
|
||||||
|
return address.is_private or address.is_loopback
|
||||||
|
except ValueError:
|
||||||
|
return host in ("localhost", "")
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/pair/open", dependencies=[Depends(authorised)])
|
||||||
|
def open_pairing() -> dict:
|
||||||
|
"""Ouvre une fenêtre de deux minutes pendant laquelle un appareil du réseau local peut
|
||||||
|
réclamer le jeton. Fermée le reste du temps : sinon le jeton ne protégerait plus rien."""
|
||||||
|
global _pairing_until
|
||||||
|
_pairing_until = time.time() + PAIRING_WINDOW_SECONDS
|
||||||
|
return {"open": True, "seconds": PAIRING_WINDOW_SECONDS}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/pair/state", dependencies=[Depends(authorised)])
|
||||||
|
def pairing_state() -> dict:
|
||||||
|
remaining = int(_pairing_until - time.time()) if _pairing_until else 0
|
||||||
|
return {"open": remaining > 0, "seconds": max(0, remaining)}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/pair")
|
||||||
|
def pair(request: Request) -> dict:
|
||||||
|
"""Livre le jeton à un appareil du réseau local, pendant la fenêtre d'appairage.
|
||||||
|
|
||||||
|
La fenêtre se referme dès qu'un appareil s'est servi : une ouverture, un appairage.
|
||||||
|
"""
|
||||||
|
global _pairing_until
|
||||||
|
client = request.client.host if request.client else ""
|
||||||
|
if not _pairing_until or time.time() > _pairing_until:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=403,
|
||||||
|
detail="Aucun appairage en cours. Ouvrez-en un depuis l'interface du serveur.",
|
||||||
|
)
|
||||||
|
if not _is_private(client):
|
||||||
|
raise HTTPException(status_code=403, detail="Appairage réservé au réseau local")
|
||||||
|
_pairing_until = None
|
||||||
|
return {"token": config.token, "name": "Noxely", "version": VERSION}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/api/bootstrap")
|
@app.get("/api/bootstrap")
|
||||||
def bootstrap(request: Request) -> dict:
|
def bootstrap(request: Request) -> dict:
|
||||||
"""Livre le jeton — uniquement à une requête venue de la machine elle-même.
|
"""Livre le jeton — uniquement à une requête venue de la machine elle-même.
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""Configuration du serveur Noxely, lue de l'environnement.
|
"""Configuration du serveur Noxely, lue de l'environnement.
|
||||||
|
|
||||||
Aucune valeur sensible n'est écrite dans le dépôt : le jeton et les chemins viennent d'un
|
Aucune valeur sensible n'est écrite dans le dépôt : le jeton et les chemins viennent d'un
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""Catalogues libres et annuaire radio, portés depuis le client Android.
|
"""Catalogues libres et annuaire radio, portés depuis le client Android.
|
||||||
|
|
||||||
Les pièges vérifiés côté mobile restent valables ici et sont conservés en commentaire :
|
Les pièges vérifiés côté mobile restent valables ici et sont conservés en commentaire :
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""Recherche dans les catalogues libres de droits."""
|
"""Recherche dans les catalogues libres de droits."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""Annuaire des stations et lecture des métadonnées ICY."""
|
"""Annuaire des stations et lecture des métadonnées ICY."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""Index des médias et des guets, en SQLite.
|
"""Index des médias et des guets, en SQLite.
|
||||||
|
|
||||||
Les fichiers vivent sur le disque ; la base ne porte que leurs métadonnées et l'état de la
|
Les fichiers vivent sur le disque ; la base ne porte que leurs métadonnées et l'état de la
|
||||||
|
|||||||
@@ -1,4 +1,15 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
<!--
|
||||||
|
Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
|
||||||
|
Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
telle que publiée par la Free Software Foundation.
|
||||||
|
|
||||||
|
Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
-->
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
@@ -46,6 +57,7 @@
|
|||||||
<span class="grow" style="flex:1"></span>
|
<span class="grow" style="flex:1"></span>
|
||||||
<input type="password" id="token" placeholder="Jeton" style="width:190px">
|
<input type="password" id="token" placeholder="Jeton" style="width:190px">
|
||||||
<button class="ghost" onclick="saveToken()">Enregistrer</button>
|
<button class="ghost" onclick="saveToken()">Enregistrer</button>
|
||||||
|
<button class="go" onclick="openPairing()">📱 Appairer</button>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
@@ -245,6 +257,15 @@ async function sweep() {
|
|||||||
loadWatches();
|
loadWatches();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function openPairing() {
|
||||||
|
try {
|
||||||
|
const { seconds } = await api('/pair/open', { method: 'POST' });
|
||||||
|
alert(`Appairage ouvert pour ${seconds} secondes.\n\n` +
|
||||||
|
`Sur le téléphone : Réglages ▸ Connexion ▸ Appairer.\n` +
|
||||||
|
`La fenêtre se referme dès qu'un appareil s'est servi.`);
|
||||||
|
} catch (e) { alert('Appairage impossible : ' + e); }
|
||||||
|
}
|
||||||
|
|
||||||
const esc = (s) => String(s).replace(/[&<>"']/g, (c) =>
|
const esc = (s) => String(s).replace(/[&<>"']/g, (c) =>
|
||||||
({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]));
|
({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]));
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
# Noxely — collecte côté serveur, écoute hors connexion côté mobile.
|
||||||
|
# Copyright © 2026 Johnny (tuxgyver)
|
||||||
|
#
|
||||||
|
# Ce programme est un logiciel libre : vous pouvez le redistribuer et le modifier
|
||||||
|
# selon les termes de la GNU General Public License, version 3 ou ultérieure,
|
||||||
|
# telle que publiée par la Free Software Foundation.
|
||||||
|
#
|
||||||
|
# Il est distribué dans l'espoir d'être utile, mais SANS AUCUNE GARANTIE.
|
||||||
|
# Voir le fichier LICENSE à la racine du dépôt pour le texte complet.
|
||||||
|
|
||||||
"""Tâches de fond : file de téléchargement, guet radio et enregistrement.
|
"""Tâches de fond : file de téléchargement, guet radio et enregistrement.
|
||||||
|
|
||||||
C'est ici que se déplace la consommation qui pesait sur le téléphone : le serveur balaie les
|
C'est ici que se déplace la consommation qui pesait sur le téléphone : le serveur balaie les
|
||||||
|
|||||||
Reference in new issue
Block a user