Appairage du téléphone, en-têtes de licence (2.1.0)
Recopier un jeton de trente-trois caractères sur un clavier tactile n'était pas un réglage, c'était une corvée. On ouvre désormais une fenêtre depuis le serveur, on appuie sur Appairer côté téléphone, et c'est fait. Le jeton n'est pas pour autant distribué : ouvrir la fenêtre l'exige déjà, elle dure deux minutes, se referme dès qu'un appareil s'est servi, et ne répond qu'à une adresse privée. Le champ de saisie reste là pour qui préfère le coller. Les cinquante fichiers de code portent en outre leur notice de licence, comme la GPL le recommande. Elle est en français, comme le reste ; le texte qui fait foi demeure celui de LICENSE, non traduit.
This commit is contained in:
1 parent
b3ddc2117b
commit
a8dc611bdd
53 files changed
+717
-4
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