YnM Loged (Jellyfin&Gotfy&Sopel) + Php py

**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

1 Like