aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.env.template4
-rw-r--r--README.md82
-rw-r--r--app.py37
-rw-r--r--index.css18
4 files changed, 32 insertions, 109 deletions
diff --git a/.env.template b/.env.template
new file mode 100644
index 0000000..648a522
--- /dev/null
+++ b/.env.template
@@ -0,0 +1,4 @@
+TS_HOST=
+TS_PORT=
+TS_WEBQUERY_PORT=
+TS_SERVER_ID=
diff --git a/README.md b/README.md
index f9ded92..aba85b2 100644
--- a/README.md
+++ b/README.md
@@ -1,81 +1 @@
-# 🚀 Explorateur Web TeamSpeak 6 (WebQuery)
-
-Un visualiseur de serveur TeamSpeak léger, moderne et 100% AJAX, conçu spécifiquement pour la nouvelle API (WebQuery) de TeamSpeak 6.
-
-Il permet d'afficher en temps réel les salons et les joueurs sur votre site web. Aucune base de données n'est requise. Le script utilise un système de cache pour protéger votre serveur TeamSpeak contre le spam.
-
----
-
-##📸 Screenshots
-https://i.imgur.com/ie9SaXu.jpeg
-
----
-
-## ✨ Fonctionnalités
-* **Actualisation Fluide :** La page se met à jour en temps réel sans jamais clignoter.
-* **Respect de votre Serveur :** Affiche les salons et sous-canaux exactement dans le même ordre que sur votre TeamSpeak.
-* **Système de Rôles :** Affiche les icônes de vos groupes (Admins, VIP, etc.) à côté des pseudos.
-* **Zéro Risque :** Fonctionne avec une clé API en lecture seule. Aucun risque de piratage de votre serveur vocal.
-* **Outil de Diagnostic :** Un script `debug.php` inclus pour vous aider si la connexion échoue.
-
----
-
-## 🛠️ Prérequis
-Pour faire fonctionner ce script, vous avez besoin de :
-1. **Un hébergement web** (ou un serveur local type Unraid/Docker) supportant **PHP 7.4 ou supérieur**.
-2. Un serveur **TeamSpeak 6** actif.
-3. Le port **WebQuery** de votre TeamSpeak accessible (par défaut le port `10080`).
-
----
-
-## 📦 Guide d'Installation pour Débutants
-
-### Étape 1 : Télécharger les fichiers
-1. En haut de cette page GitHub, cliquez sur le bouton vert **"Code"**, puis sur **"Download ZIP"**.
-2. Décompressez le fichier `.zip` sur votre ordinateur.
-3. Envoyez tous ces fichiers sur votre hébergement web (via votre logiciel FTP comme FileZilla, ou le gestionnaire de fichiers de votre hébergeur).
-
-### Étape 2 : Créer votre fichier de configuration
-1. Allez dans le dossier où vous avez envoyé les fichiers.
-2. Cherchez le fichier nommé `config.example.php`.
-3. **Renommez-le** simplement en `config.php`.
-4. Ouvrez ce nouveau fichier `config.php` avec un éditeur de texte (comme Notepad++, Bloc-notes ou VS Code). Vous y entrerez vos informations à l'étape suivante.
-
----
-
-## 🔑 Obtenir votre Clé API TeamSpeak 6
-
-Pour que le site web puisse lire la liste des joueurs, il lui faut une "Clé API". Pour des raisons de sécurité, nous allons créer une clé qui a **uniquement le droit de lire**, et aucun droit de modifier votre serveur.
-
-**Voici comment la créer pas à pas :**
-1. Ouvrez le terminal de votre ordinateur (ou utilisez un logiciel comme **PuTTY**).
-2. Connectez-vous à l'IP de votre serveur TeamSpeak en mode **SSH** sur le port ServerQuery (port par défaut : **10022**).
- *Exemple de commande :* `ssh serveradmin@VOTRE_IP -p 10022`
-3. Une console s'ouvre et vous demande votre mot de passe `serveradmin`. Tapez-le (il ne s'affiche pas à l'écran, c'est normal) et appuyez sur *Entrée*.
-4. Tapez les commandes suivantes, en appuyant sur la touche *Entrée* après chaque ligne :
-
- *Pour sélectionner votre serveur vocal principal :*
- `use 1`
-
- *Pour générer une clé en lecture seule permanente :*
- `apikeyadd scope=read lifetime=0`
-
-5. Le serveur va vous répondre avec une ligne contenant `apikey=VOTRE_CLE_ICI`. Copiez cette longue suite de caractères.
-6. Tapez `quit` pour fermer la console.
-
-### Finalisation
-Retournez dans votre fichier `config.php` ouvert précédemment, assurez-vous que le port API est bien configuré sur **10080**, et collez votre clé à cet endroit :
-`'api_key' => 'VOTRE_CLE_ICI',`
-Enregistrez le fichier. C'est prêt, votre site fonctionne ! 🎉
-
----
-
-## 🛡️ Conseil de Sécurité
-Si vous utilisez un hébergement avancé ou un VPS (avec Nginx), il est fortement recommandé de bloquer l'accès direct aux fichiers système pour empêcher les curieux de lire votre configuration.
-
-Ajoutez ceci dans la configuration de votre site :
-```nginx
-location ~* /(config\.php|cache\.json|debug\.php)$ {
- deny all;
- return 403;
-}
+# Teamspeak 6 Web Server Status
diff --git a/app.py b/app.py
index 197b5fd..d8879e1 100644
--- a/app.py
+++ b/app.py
@@ -105,10 +105,17 @@ def build_context():
api_ping = round((time.perf_counter() - start_time) * 1000)
raw_channels = ts_data.get("channels") or []
+ afk_count = None
for channel in raw_channels:
- channel["channel_name"] = channel.get("channel_name").replace("[Cspacer]", "")
+ original_name = channel.get("channel_name", "")
+ channel["is_spacer"] = "[Cspacer]" in original_name and "AFK" not in original_name
+ if "AFK" in original_name:
+ afk_count = channel.get("total_clients", None)
+ channel["channel_name"] = original_name.replace("[Cspacer]", "")
raw_clients = ts_data.get("clients") or []
is_online = bool(raw_channels)
+ if afk_count is not None:
+ afk_count = int(afk_count) - 1
channels = sort_ts_channels(raw_channels, 0)
@@ -133,14 +140,23 @@ def build_context():
"medium_stars": generate_stars(50, 0.6),
"large_stars": generate_stars(15, 0.8),
"total_real_clients": total_real_clients,
+ "afk_count": afk_count,
}
FRAGMENT_TEMPLATE = """
{% if is_online %}
- <div class="stat-item">
- <span class="stat-label">Users Online</span>
- <span class="stat-value">{{ total_real_clients }}</span>
+ <div class="server-stats">
+ <div class="stat-item">
+ <span class="stat-label">Users Online</span>
+ <span class="stat-value">{{ total_real_clients }}</span>
+ </div>
+ {% if afk_count is not none %}
+ <div class="stat-item">
+ <span class="stat-label">AFK Users</span>
+ <span class="stat-value">{{ afk_count }}</span>
+ </div>
+ {% endif %}
</div>
<div class="channel-list">
{% for channel in channels %}
@@ -149,7 +165,6 @@ FRAGMENT_TEMPLATE = """
{% set channel_clients = clients_by_channel.get(cid, []) %}
{% set bg_img = config.channel_banners.get(c_name, config.generic_images.get('background', '')) %}
{% set icon_img = config.channel_icons.get(c_name, config.generic_images.get('icon', '')) %}
- {% set max_clients = channel.get('channel_maxclients') %}
{% if bg_img %}
{% set bg_style = "background-image: linear-gradient(90deg, rgba(9, 18, 32, 0.96) 0%, rgba(9, 18, 32, 0.78) 45%, rgba(9, 18, 32, 0.94) 100%), url('" ~ safe_url(bg_img) ~ "');" %}
@@ -157,6 +172,7 @@ FRAGMENT_TEMPLATE = """
{% set bg_style = "" %}
{% endif %}
+ {% if not channel.is_spacer %}
<article class="channel">
<header class="channel-header" style="{{ bg_style }}">
<div class="channel-title-group">
@@ -166,15 +182,12 @@ FRAGMENT_TEMPLATE = """
<h2>{{ c_name }}</h2>
</div>
{# Only show client count for non-spacer channels #}
- {% if '[spacer' not in c_name %}
- <span class="channel-meta">
- {{ channel_clients|length }} / {{ '∞' if max_clients == -1 or max_clients == '-1' else max_clients }}
- </span>
- {% endif %}
+ <span class="channel-meta">
+ {{ channel_clients|length }}
+ </span>
</header>
{# Only show client list for non-spacer channels #}
- {% if '[spacer' not in c_name|lower and '[cspacer' not in c_name|lower and channel_clients %}
<ul class="client-list">
{% for client in channel_clients %}
<li class="client">
@@ -194,8 +207,8 @@ FRAGMENT_TEMPLATE = """
</li>
{% endfor %}
</ul>
- {% endif %}
</article>
+ {% endif %}
{% endfor %}
</div>
{% else %}
diff --git a/index.css b/index.css
index 6c8da93..69c037b 100644
--- a/index.css
+++ b/index.css
@@ -42,16 +42,6 @@ body {
color: var(--cl-white);
}
-/* Neutralize the old space background elements */
-body::before,
-#space-bg,
-.star-layer,
-.stars-s,
-.stars-m,
-.stars-l {
- display: none;
-}
-
.app-container {
position: relative;
width: 100%;
@@ -111,7 +101,7 @@ body::before,
color: var(--cl-white);
font-size: 2.2rem;
font-weight: bold;
- magin-top: 20px;
+ margin-top: 25px
}
.header p {
@@ -154,12 +144,8 @@ body::before,
.server-stats {
display: grid;
- grid-template-columns: repeat(3, minmax(0, 1fr));
+ grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
- margin-bottom: 1.5rem;
- padding: 1rem;
- border: 2px solid var(--cl-gray-2);
- background-color: var(--cl-gray-1);
}
.stat-item {
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage