**Loged.py V1.2 **
import json
import os
from sopel import plugin
import requests
import re
import time
from datetime import datetime, timedelta
# Konfigurációs változók
GOTIFY_URL = "http://192.168.0.150:81/message"
GOTIFY_CLIENT_TOKEN = "*********"
APP_IDS = {9} # Csak az appid 9 üzeneteit olvassuk be
USER_DATA_FILE = "/home/ai/.sopel/plugins/notify/user_data.json"
# Ensure all required files are initialized at the start
def initialize_file(file_path, default_data):
"""Biztosítja, hogy a fájl létezik és alapértelmezett adatokat tartalmaz."""
if not os.path.exists(file_path):
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, 'w') as f:
json.dump(default_data, f, indent=4)
initialize_file(USER_DATA_FILE, {'last_message_id': None, 'user_data': {}})
def load_user_data():
"""Betölti a felhasználói adatokat a fájlból."""
if os.path.exists(USER_DATA_FILE):
with open(USER_DATA_FILE, 'r') as f:
return json.load(f)
else:
initialize_file(USER_DATA_FILE, {'last_message_id': None, 'user_data': {}})
return {'last_message_id': None, 'user_data': {}}
def save_user_data(data):
"""Elmenti a felhasználói adatokat a fájlba."""
os.makedirs(os.path.dirname(USER_DATA_FILE), exist_ok=True)
with open(USER_DATA_FILE, 'w') as f:
json.dump(data, f, indent=4)
def clean_markdown(text):
"""Eltávolítja a markdown formázást, mint a ** (félkövér), * (dőlt), stb."""
return re.sub(r'\*{1,2}(.*?)\*{1,2}', r'\1', text)
def format_date(date_string):
"""A dátum formázása: 2024-12-27T17:20:32.726530857+02:00 -> 2024.12.27 time: 18:11:12"""
try:
# Parse the ISO format timestamp to a datetime object
date_obj = datetime.fromisoformat(date_string)
# Format the datetime object to the desired format
formatted_date = date_obj.strftime('%Y.%m.%d time: %H:%M:%S')
return formatted_date
except ValueError:
return 'N/A'
def update_login_count(user, client_ip):
"""
Update the login count for the given user and their associated IP address.
"""
# Assuming you are storing user data in some form of a dictionary
if user in user_data['user_data']:
user_ips = user_data['user_data'][user]['ips']
# Search for the IP in the user's IP list
for ip_data in user_ips:
if ip_data['ip'] == client_ip:
# If found, increment the login count
ip_data['count_login'] = ip_data.get('count_login', 0) + 1
break
# Betöltjük a legutolsó üzenet ID-ját, ha van
user_data = load_user_data()
last_message_id = user_data['last_message_id']
def get_gotify_messages():
global last_message_id
try:
response = requests.get(f"{GOTIFY_URL}?token={GOTIFY_CLIENT_TOKEN}")
response.raise_for_status()
data = response.json()
filtered_messages = [msg for msg in data.get('messages', []) if msg['appid'] in APP_IDS]
filtered_messages.sort(key=lambda msg: msg['id'], reverse=True)
if filtered_messages:
latest_message = filtered_messages[0]
message_id = latest_message.get('id')
if last_message_id is None or int(message_id) > int(last_message_id):
last_message_id = message_id
user_data['last_message_id'] = message_id
save_user_data(user_data)
message = latest_message.get('message', '')
user = re.search(r'User:\s*([^\n]+)', message)
client = re.search(r'Client:\s*([^\n]+)', message)
device = re.search(r'Device:\s*([^\n]+)', message)
client_ip = re.search(r'Client IP:\s*([^\n]+)', message)
date = latest_message.get('date', 'N/A')
title = latest_message.get('title', 'N/A')
cleaned_user = clean_markdown(user.group(1) if user else 'N/A').strip()
cleaned_client = clean_markdown(client.group(1) if client else 'N/A')
cleaned_device = clean_markdown(device.group(1) if device else 'N/A')
cleaned_client_ip = clean_markdown(client_ip.group(1) if client_ip else 'N/A').strip()
# Format the date using the new format function
formatted_date = format_date(date)
# Replace Jellyfin with YnM in the client and device fields
cleaned_client = cleaned_client.replace("Jellyfin", "YnM")
cleaned_device = cleaned_device.replace("Jellyfin", "YnM")
current_time = datetime.now()
user_data_dict = user_data['user_data']
if cleaned_user not in user_data_dict:
user_data_dict[cleaned_user] = {"ips": [], "message_send": "yes"}
last_ips = user_data_dict[cleaned_user]["ips"]
ip_found = False
for ip_data in last_ips:
if ip_data["ip"] == cleaned_client_ip:
ip_found = True
last_login_time = datetime.fromisoformat(ip_data["last_login_iso"])
counter_last_login_time = datetime.fromisoformat(ip_data["counter_last_login_iso"])
time_diff = current_time - last_login_time
counter_time_diff = current_time - counter_last_login_time # Always update counter_time_diff
# If more than 24 hours since the last login, reset both timers and count
if time_diff >= timedelta(hours=24):
ip_data["last_login_iso"] = current_time.isoformat()
ip_data["last_login"] = current_time.strftime('%Y.%m.%d time: %H:%M:%S')
ip_data["count_login"] = 1
ip_data["counter_last_login_iso"] = current_time.isoformat()
ip_data["counter_last_login"] = current_time.strftime('%Y.%m.%d time: %H:%M:%S')
# If more than 24 hours since the last message sent, reset only the counter timer
if counter_time_diff >= timedelta(hours=24):
ip_data["count_login"] = 1
ip_data["counter_last_login_iso"] = current_time.isoformat()
ip_data["counter_last_login"] = current_time.strftime('%Y.%m.%d time: %H:%M:%S')
else:
# If login within 24 hours, just increment the login count without resetting the timers
ip_data["count_login"] = ip_data.get("count_login", 0) + 1
break
if not ip_found:
ip_data = {
"ip": cleaned_client_ip,
"login_count": 1,
"last_login_iso": current_time.isoformat(),
"last_login": current_time.strftime('%Y.%m.%d time: %H:%M:%S'),
"count_login": 1, # Initialize count_login for new IP
"counter_last_login_iso": current_time.isoformat(),
"counter_last_login": current_time.strftime('%Y.%m.%d time: %H:%M:%S') # Initialize counter
}
formatted_message = (
f"Title: {title} | "
f"User: {cleaned_user} | "
f"Client: {cleaned_client} | "
f"Device: {cleaned_device} | "
f"Client IP: {cleaned_client_ip} | "
f"Date: {formatted_date} | "
f"Last login count (24 hours): {ip_data['count_login']}"
)
formatted_magyar_message = f"👤 {cleaned_user} 🟢 🎥 🌐 https://ai.ynm.hu/top"
last_ips.append(ip_data)
save_user_data(user_data)
return formatted_message, formatted_magyar_message
# Update the user IPs with the modified or new IP data
user_data_dict[cleaned_user] = {
"ips": last_ips
}
# Now it's safe to use ip_data for formatting
formatted_message = (
f"Title: {title} | "
f"User: {cleaned_user} | "
f"Client: {cleaned_client} | "
f"Device: {cleaned_device} | "
f"Client IP: {cleaned_client_ip} | "
f"Date: {formatted_date} | "
f"Last login count (24 hours): {ip_data['count_login']}"
)
# Check if enough time has passed since the last message (24 hours)
if counter_time_diff >= timedelta(hours=24):
# Create the message for Gotify
formatted_magyar_message = f"Client: {cleaned_client} online"
return formatted_message, formatted_magyar_message
else:
return None, None # Don't send the Gotify message if less than 24 hours since the last message
return None, None # Return None, None if no messages found
except requests.RequestException as e:
return f"Hiba történt az üzenetek lekérésekor: {e}", None
@plugin.interval(30)
def check_gotify_messages(bot):
detailed_message, magyar_message = get_gotify_messages()
if detailed_message:
bot.say(f"YnM Media:\n{detailed_message}", "#YnM")
time.sleep(2) # Optional sleep if you want a slight delay between messages
if magyar_message:
bot.say(f"YnM Media:\n{magyar_message}", "#Magyar")
@plugin.command('gotify')
def gotify_messages(bot, trigger):
detailed_message, magyar_message = get_gotify_messages()
if detailed_message:
bot.say(f"YnM Media:\n{detailed_message}", "#YnM")
else:
bot.say("YnM Media.", "#YnM")
Php Script
// Fájl elérési útja
$file_path = '/home/ai/.sopel/plugins/notify/user_data.json';
// Fájl betöltése
$json_data = file_get_contents($file_path);
$data = json_decode($json_data, true);
// Hibakezelés, ha nem sikerül a JSON beolvasása
if (!$data) {
die("<p>Nem sikerült a statisztikák betöltése.</p>");
}
// Felhasználók adatainak kezelése, bejelentkezések összeadása
$users_info = [];
foreach ($data['user_data'] as $user => $user_data) {
// A felhasználó bejelentkezési adatait összegyűjtjük
$total_login_count = 0;
$last_login = '';
$counter_last_login = '';
// Minden IP címhez hozzáadjuk a login_count értékeket
foreach ($user_data['ips'] as $ip_data) {
$total_login_count += $ip_data['count_login'];
// Az utolsó bejelentkezést tekintjük a legutolsó login időpontnak
$last_login = $ip_data['last_login'];
$counter_last_login = $ip_data['counter_last_login'];
}
// Dátum és idő bontása a last_login és counter_last_login alapján
$last_login_parts = explode(' time: ', $last_login);
$datum = $last_login_parts[0]; // Dátum
$ora = $last_login_parts[1]; // Idő
$counter_last_login_parts = explode(' time: ', $counter_last_login);
$counter_datum = $counter_last_login_parts[0]; // Counter dátum
$counter_ora = $counter_last_login_parts[1]; // Counter idő
// Felhasználó és bejelentkezési információ tárolása
$users_info[] = [
'username' => $user,
'datum' => $datum,
'ora' => $ora,
'counter_datum' => $counter_datum,
'counter_ora' => $counter_ora,
'login_count' => $total_login_count
];
}
// Felhasználók rendezése login_count alapján csökkenő sorrendben
usort($users_info, function ($a, $b) {
return $b['login_count'] - $a['login_count'];
});
// HTML generálása
?>
<!DOCTYPE html>
<html lang="hu">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Filmkérések listája az ai.ynm.hu oldalon. Böngésszen a legújabb és korábbi filmkérések között, állapotuk szerint rendezve." />
<meta name="keywords" content="film kérések, filmek listája, teljesített filmek, függőben lévő kérések, ai.ynm.hu, filmek állapota" />
<meta name="author" content="ai.ynm.hu" />
<meta name="robots" content="index, follow" />
<meta property="og:title" content="YnM Media Top - ai.ynm.hu" />
<meta property="og:description" content="Tekintse meg az ai.ynm.hu top nézők listáját. Rendezett és állapot szerint kategorizált lista a legnépszerűbb filmekről." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://ai.ynm.hu/" />
<meta property="og:image" content="https://ai.ynm.hu/icon/YnM-Ai.webp" />
<meta property="og:site_name" content="ai.ynm.hu" />
<meta property="og:locale" content="hu_HU" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="YnM Media Top - ai.ynm.hu" />
<meta name="twitter:description" content="Tekintse meg az ai.ynm.hu top nézők listáját. Rendezett és állapot szerint kategorizált lista a legnépszerűbb filmekről." />
<meta name="twitter:image" content="https://ai.ynm.hu/icon/YnM-Ai.webp" />
<meta name="twitter:site" content="@your_twitter_handle" />
<link rel="icon" href="https://ai.ynm.hu/icon/YnM-Ai.webp" type="image/x-icon" />
<link rel="shortcut icon" href="https://ai.ynm.hu/icon/YnM-Ai.webp" type="image/x-icon" />
<title>YnM Media Top</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
.container {
margin-top: 50px;
}
table {
width: 90%;
max-width: 600px;
margin: 0 auto;
border-collapse: collapse;
background-color: #fff;
}
th, td {
padding: 15px;
border-bottom: 1px solid #ddd;
}
th {
background-color: #4CAF50;
color: white;
}
tr:hover {
background-color: #f1f1f1;
}
</style>
</head>
<body>
<div class="container">
<h1>Felhasználói Legutolsó Bejelentkezési Időpontok</h1>
<table>
<tr>
<th>Felhasználó</th>
<th>Dátum</th>
<th>Óra</th>
<th>Számláló dátum</th>
<th>Számláló Óra</th>
<th>Bejelentkezések</th>
</tr>
<?php foreach ($users_info as $user_info): ?>
<tr>
<td><?php echo htmlspecialchars($user_info['username']); ?></td>
<td><?php echo htmlspecialchars($user_info['datum']); ?></td>
<td><?php echo htmlspecialchars($user_info['ora']); ?></td>
<td><?php echo htmlspecialchars($user_info['counter_datum']); ?></td>
<td><?php echo htmlspecialchars($user_info['counter_ora']); ?></td>
<td><?php echo htmlspecialchars($user_info['login_count']); ?></td>
</tr>
<?php endforeach; ?>
</table>
</div>
</body>
<footer class="footer mt-auto py-3">
<div class="container text-center">
<span class="text-body-secondary">
<p class="footer-text">© 2012 <a href="https://ynm.hu">YnM</a> ℠ ™ - All rights reserved.</p>
<p class="footer-text">® 2012 - <span id="currentYear"></span> <a href="https://ynm.hu">YnM</a> LCC</p>
</span>
</div>
</footer>
<script src="/js/ynm-date.js"></script>
</html>
Jellyfin Webhook
{
"extras": {
"client::display": {
"contentType": "text/markdown"
}
},
"title": "✅ Success ✅",
"message": "--------------\n\n**User:** {{NotificationUsername}}\n\n**ID:** {{UserId}}\n\n**Client:** {{Client}}\n\n**Device:** {{DeviceName}} \n\n**Client IP:** {{RemoteEndPoint}}",
"priority": {{Priority}}
}
YnM Media Top ← Online