File size: 5,718 Bytes
a31f556
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
"""

modules/app_monitor.py β€” FRIDAY Tracks What's Playing



Monitors active applications and detects:

- What app is in focus

- If video/audio is playing

- Browser video detection

- Media state detection

"""

import time
import os
import json
import subprocess
from config import DATA_DIR


MONITOR_FILE = os.path.join(DATA_DIR, "app_monitor.json")


def _load() -> dict:
    if not os.path.exists(MONITOR_FILE):
        return {"active": "", "title": "", "last_change": 0, "media_playing": False}
    try:
        with open(MONITOR_FILE, "r") as f:
            return json.load(f)
    except Exception:
        return {"active": "", "title": "", "last_change": 0, "media_playing": False}


def _save(data: dict):
    os.makedirs(DATA_DIR, exist_ok=True)
    try:
        with open(MONITOR_FILE, "w") as f:
            json.dump(data, f, indent=2)
    except Exception:
        pass


# ── Get Active Window ───────────────────────────────────────────────

def get_active_window() -> dict:
    """Get currently active window info."""
    try:
        import psutil

        # Get foreground window
        foreground = psutil.Process()._proc.info.get('name')

        # Use Windows API for window title
        import ctypes
        from ctypes import wintypes

        user32 = ctypes.windll.user32
        hwnd = user32.GetForegroundWindow()
        length = user32.GetWindowTextLengthW(hwnd)
        if length > 0:
            buffer = ctypes.create_unicode_buffer(length + 1)
            user32.GetWindowTextW(hwnd, buffer, length + 1)
            title = buffer.value
        else:
            title = ""

        return {"hwnd": hwnd, "title": title[:100], "time": time.time()}

    except Exception:
        return {"title": "", "time": time.time()}


# ── Detect Video Playing ─────────────────────────────────────

def is_video_playing() -> bool:
    """Detect if video/media is playing."""
    data = _load()
    title = data.get("title", "").lower()
    active = data.get("active", "").lower()

    # Browser video detection
    video_patterns = ["youtube", "netflix", "prime", "disney", "hulu", "spotify", "twitch"]

    for pattern in video_patterns:
        if pattern in title or pattern in active:
            return True

    return is_media_playing()


def get_current_app() -> str:
    """Get current active application."""
    return _load().get("active", "")


def get_current_title() -> str:
    """Get current window title."""
    return _load().get("title", "")


def get_current_app() -> str:
    """Get current active application."""
    return _load().get("active", "")


def get_current_title() -> str:
    """Get current window title."""
    return _load().get("title", "")


# ── Background Monitor ─────────────────────────────────────────

def check_active():
    """Check and update active window."""
    try:
        window = get_active_window()
        title = window.get("title", "")

        # Determine app from title
        app = "unknown"
        if "youtube" in title.lower():
            app = "YouTube"
        elif "chrome" in title.lower():
            app = "Chrome"
        elif "edge" in title.lower():
            app = "Edge"
        elif "spotify" in title.lower():
            app = "Spotify"
        elif "discord" in title.lower():
            app = "Discord"
        elif "code" in title.lower():
            app = "VS Code"
        elif "game" in title.lower():
            app = "Game"

        data = _load()
        data["active"] = app
        data["title"] = title[:100]
        data["last_change"] = time.time()
        data["media_playing"] = title.lower().find("playing") > 0 or title.lower().find("youtube") > 0
        _save(data)

        return data

    except Exception:
        return _load()


# ── Media State ───────────────────────────────────────────────

def set_media_state(playing: bool):
    """Set media playing state."""
    data = _load()
    data["media_playing"] = playing
    data["media_time"] = time.time()
    _save(data)


def is_media_playing() -> bool:
    """Check if media is playing."""
    return _load().get("media_playing", False)


# ── Background Loop ──────────────────────────────────────────

def start_monitor():
    """Start app monitor in background."""
    import threading
    import time

    def _loop():
        while True:
            try:
                check_active()
            except Exception:
                pass
            time.sleep(2)  # Check every 2 seconds

    t = threading.Thread(target=_loop, daemon=True)
    t.start()


# ── Brain Integration ─────────────────────────────────────────

def get_app_context() -> str:
    """Get app context for brain."""
    data = _load()

    parts = []
    active = data.get("active", "")
    title = data.get("title", "")

    if active:
        parts.append(f"On: {active}")

    if is_media_playing():
        parts.append("Media playing")

    if parts:
        return "[APP] " + " | ".join(parts)

    return ""