Le téléphone balayait quarante radios toutes les trois minutes, cherchait dans quatre catalogues et enregistrait des directs. Tout cela le tenait éveillé pour un travail qui n'a aucune raison de se faire sur batterie. Un serveur reprend la collecte : recherche, guet, enregistrement, file de téléchargement, piloté depuis un navigateur. Le mobile demande ce qui a changé depuis son curseur, télécharge et se rendort — toutes les six heures, en Wi-Fi non facturé. Vingt fichiers quittent l'application au passage. Le balayage devient continu plutôt qu'espacé de trois minutes : une sonde ne lit que le premier bloc de métadonnées avant de refermer, ce qui rend la permanence tenable quand garder les flux ouverts coûterait plusieurs mégabits par seconde. Un morceau guetté a été capté en moins de vingt-cinq secondes. La recherche interroge les quatre catalogues à la fois et fond leurs résultats, les plus légers d'abord. Quatre défauts corrigés en chemin, tous trouvés en essayant plutôt qu'en relisant : un jeton régénéré à chaque démarrage, qui aurait obligé à reconfigurer le mobile ; un 403 de Wikimedia dû à un agent trop générique, que la fusion des sources masquait ; un dossier de données par défaut inaccessible au compte qui lance le serveur ; et une lecture de métadonnées qui n'itérait rien, faute d'être asynchrone.
181 lines
6.5 KiB
Makefile
181 lines
6.5 KiB
Makefile
.DEFAULT_GOAL := help
|
||
|
||
# --- Outillage -------------------------------------------------------------
|
||
# Le SDK et adb sont rarement dans le PATH : on les retrouve sans les figer.
|
||
ANDROID_SDK ?= $(HOME)/Android/Sdk
|
||
ADB ?= $(shell command -v adb 2>/dev/null || echo $(ANDROID_SDK)/platform-tools/adb)
|
||
GRADLE := ./gradlew
|
||
|
||
VERSION := $(shell tr -d '[:space:]' < VERSION)
|
||
|
||
APPLICATION_ID := fr.tuxgyver.cachette
|
||
LAUNCH_ACTIVITY := $(APPLICATION_ID)/.MainActivity
|
||
DEBUG_APK := app/build/outputs/apk/debug/app-debug.apk
|
||
# Le nom de l'APK de release dépend de la signature (app-release.apk contre
|
||
# app-release-unsigned.apk) : on liste le répertoire au lieu de deviner.
|
||
RELEASE_DIR := app/build/outputs/apk/release
|
||
SIGNED_APK := $(RELEASE_DIR)/app-release.apk
|
||
OUTPUT_APK := Noxely-$(VERSION).apk
|
||
|
||
# --- Publication -----------------------------------------------------------
|
||
# Déléguée au script de BorisSkill, qui sait déjà tout faire : résolution du
|
||
# jeton ($GITEA_TOKEN, .gitea-token, ~/.config/gitea/token, ~/.git-credentials),
|
||
# déduction de l'hôte, du propriétaire et du dépôt depuis le remote 'origin',
|
||
# création et poussée du tag, extraction des notes depuis le CHANGELOG.
|
||
GITEA_RELEASE ?= $(HOME)/.claude/skills/BorisSkill/scripts/gitea_release.sh
|
||
|
||
##@ 🔨 Construction
|
||
|
||
.PHONY: build
|
||
build: ## Construit l'APK de debug
|
||
$(GRADLE) :app:assembleDebug
|
||
@echo "→ $(DEBUG_APK)"
|
||
|
||
.PHONY: release
|
||
release: ## Construit l'APK de release (signé si keystore.properties existe)
|
||
@test -f keystore.properties || echo "⚠️ keystore.properties absent : l'APK produit sera non signé"
|
||
$(GRADLE) :app:assembleRelease
|
||
@if [ -f $(SIGNED_APK) ]; then \
|
||
cp $(SIGNED_APK) $(OUTPUT_APK); \
|
||
echo "→ $(OUTPUT_APK)"; \
|
||
else \
|
||
ls -1 $(RELEASE_DIR)/*.apk 2>/dev/null | sed 's/^/→ /'; \
|
||
echo " (non signé : non publiable, voir keystore.properties)"; \
|
||
fi
|
||
|
||
.PHONY: apk
|
||
apk: ## Affiche le chemin et la taille des APK construits
|
||
@ls -lh $(DEBUG_APK) 2>/dev/null || echo "APK de debug : pas encore construit (make build)"
|
||
@ls -lh $(RELEASE_DIR)/*.apk 2>/dev/null || echo "APK de release : pas encore construit (make release)"
|
||
|
||
.PHONY: clean
|
||
clean: ## Supprime les artefacts de build
|
||
$(GRADLE) clean
|
||
|
||
##@ 🚀 Déploiement
|
||
|
||
.PHONY: install
|
||
install: ## Installe l'APK de debug sur l'appareil connecté
|
||
$(GRADLE) :app:installDebug
|
||
|
||
.PHONY: run
|
||
run: install ## Installe puis lance l'application
|
||
$(ADB) shell am start -n $(LAUNCH_ACTIVITY)
|
||
|
||
.PHONY: uninstall
|
||
uninstall: ## Désinstalle l'application de l'appareil connecté
|
||
$(ADB) uninstall $(APPLICATION_ID)
|
||
|
||
##@ 🧪 Qualité
|
||
|
||
.PHONY: lint
|
||
lint: ## Analyse Android Lint (rapport dans app/build/reports/lint-results-debug.html)
|
||
$(GRADLE) :app:lintDebug
|
||
|
||
##@ 🐞 Diagnostic
|
||
|
||
.PHONY: devices
|
||
devices: ## Liste les appareils et émulateurs connectés
|
||
$(ADB) devices -l
|
||
|
||
.PHONY: logcat
|
||
logcat: ## Suit les journaux de l'application (Ctrl+C pour arrêter)
|
||
$(ADB) logcat --pid=$$($(ADB) shell pidof $(APPLICATION_ID))
|
||
|
||
.PHONY: crash
|
||
crash: ## Affiche la dernière trace de plantage éventuelle
|
||
@$(ADB) logcat -d -v brief | grep -A 30 -E "FATAL EXCEPTION" | tail -40 || echo "Aucun plantage enregistré"
|
||
|
||
##@ 🖥️ Serveur
|
||
|
||
SERVER := server
|
||
SERVER_PY := $(SERVER)/venv/bin/python
|
||
SERVICE := noxely-server
|
||
UNIT_FILE := $(SERVER)/deploy/$(SERVICE).service
|
||
UNIT_DEST := /etc/systemd/system/$(SERVICE).service
|
||
PROJECT_DIR := $(abspath .)
|
||
SERVICE_USER ?= $(shell whoami)
|
||
|
||
.PHONY: server-venv
|
||
server-venv: ## Crée l'environnement Python du serveur et installe ses dépendances
|
||
python3 -m venv $(SERVER)/venv
|
||
$(SERVER)/venv/bin/pip install -q -r $(SERVER)/requirements.txt
|
||
@echo "→ $(SERVER_PY)"
|
||
|
||
.PHONY: server-token
|
||
server-token: ## Affiche le jeton du serveur (à recopier dans l'application)
|
||
@sed -n 's/^NOXELY_TOKEN=//p' $(SERVER)/.env 2>/dev/null | grep . \
|
||
|| cat $(SERVER)/data/token 2>/dev/null \
|
||
|| echo "Aucun jeton : lancez le serveur une fois, il en génère un."
|
||
|
||
.PHONY: server-run
|
||
server-run: ## Lance le serveur au premier plan (Ctrl+C pour arrêter)
|
||
@test -f $(SERVER)/.env || { echo "❌ $(SERVER)/.env absent — copiez $(SERVER)/.env.example"; exit 1; }
|
||
cd $(SERVER) && set -a && . ./.env && set +a && ./venv/bin/python -m noxely_server
|
||
|
||
.PHONY: server-install
|
||
server-install: ## Installe et active le service systemd (sudo requis)
|
||
@test -f $(SERVER)/.env || { echo "❌ $(SERVER)/.env absent — copiez $(SERVER)/.env.example"; exit 1; }
|
||
sed -e 's|__SERVICE_USER__|$(SERVICE_USER)|g' -e 's|@USER@|$(SERVICE_USER)|g' \
|
||
-e 's|@PROJECT@|$(PROJECT_DIR)|g' $(UNIT_FILE) | sudo tee $(UNIT_DEST) > /dev/null
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now $(SERVICE)
|
||
@echo "✅ $(SERVICE) installé et démarré"
|
||
|
||
.PHONY: server-start
|
||
server-start: ## Démarre le service
|
||
sudo systemctl start $(SERVICE)
|
||
|
||
.PHONY: server-stop
|
||
server-stop: ## Arrête le service
|
||
sudo systemctl stop $(SERVICE)
|
||
|
||
.PHONY: server-status
|
||
server-status: ## État du service
|
||
systemctl status $(SERVICE) --no-pager
|
||
|
||
.PHONY: server-logs
|
||
server-logs: ## Suit le journal du service
|
||
journalctl -u $(SERVICE) -f
|
||
|
||
.PHONY: server-uninstall
|
||
server-uninstall: ## Désactive et retire le service (les données sont conservées)
|
||
sudo systemctl disable --now $(SERVICE) || true
|
||
sudo rm -f $(UNIT_DEST)
|
||
sudo systemctl daemon-reload
|
||
|
||
##@ 📤 Publication
|
||
|
||
.PHONY: publish
|
||
publish: _check-apk _check-release-script ## Publie l'APK signé en release Gitea (tag + notes + asset)
|
||
bash $(GITEA_RELEASE) --version $(VERSION) --asset $(OUTPUT_APK)
|
||
|
||
.PHONY: publish-dry
|
||
publish-dry: _check-apk _check-release-script ## Simule la publication sans rien envoyer
|
||
bash $(GITEA_RELEASE) --version $(VERSION) --asset $(OUTPUT_APK) --dry-run
|
||
|
||
.PHONY: deploy
|
||
deploy: release publish ## Construit l'APK signé puis le publie
|
||
|
||
.PHONY: _check-release-script
|
||
_check-release-script:
|
||
@test -f $(GITEA_RELEASE) || \
|
||
{ echo "❌ Script de publication introuvable : $(GITEA_RELEASE)"; \
|
||
echo " Surchargez le chemin : make publish GITEA_RELEASE=/chemin/gitea_release.sh"; exit 1; }
|
||
|
||
.PHONY: _check-apk
|
||
_check-apk:
|
||
@test -f $(OUTPUT_APK) || \
|
||
{ echo "❌ $(OUTPUT_APK) introuvable — lancez d'abord 'make release' (signature requise)."; exit 1; }
|
||
@test $(OUTPUT_APK) -nt VERSION || \
|
||
{ echo "❌ $(OUTPUT_APK) est plus ancien que VERSION — relancez 'make release'."; exit 1; }
|
||
|
||
##@ ℹ️ Aide
|
||
|
||
.PHONY: help
|
||
help: ## Affiche cette aide
|
||
@awk 'BEGIN {FS = ":.*?## "} \
|
||
/^[a-zA-Z0-9_.-]+:.*?##/ { printf " \033[36m%-20s\033[0m %s\n", $$1, $$2 } \
|
||
/^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) }' $(MAKEFILE_LIST)
|
||
@echo ""
|