Skip to content

Commit 5888215

Browse files
authored
Update ActivityMonitor.py
1 parent adfd2e3 commit 5888215

File tree

1 file changed

+52
-200
lines changed

1 file changed

+52
-200
lines changed

ActivityMonitor.py

Lines changed: 52 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,100 @@
1-
import time
2-
import os
3-
import sys
4-
import re
5-
import platform
6-
import subprocess
7-
import threading
1+
import customtkinter as ctk
82
import keyboard
93
import clipboard
4+
import pygetwindow as gw
5+
import pyscreenshot as ImageGrab
6+
import time
107
import markdown2
11-
import customtkinter as ctk
8+
import threading
9+
import os
1210
import ollama
1311

14-
# Check the operating system and import necessary modules accordingly
15-
if platform.system() == "Linux":
16-
import mss
17-
import mss.tools
18-
elif platform.system() == "Windows":
19-
import pyscreenshot as ImageGrab
20-
import pygetwindow as gw
21-
22-
def generate_answers(model_name, prompt, use_ollama):
23-
"""
24-
Generate answers using the Ollama model or return the prompt as is, while preserving the original prompt.
25-
26-
Args:
27-
model_name (str): The name of the Ollama model.
28-
prompt (str): The prompt to generate answers for.
29-
use_ollama (bool): Flag indicating whether to use Ollama for analysis.
30-
31-
Returns:
32-
tuple: A tuple containing the generated detailed description and the original prompt.
33-
"""
34-
if not use_ollama:
35-
return prompt, prompt # Return the prompt twice for consistency
36-
37-
full_prompt = f"describe the following actions for this markdown documentation in short terms regarding and with context and also format in markdown for documentation purposes: {prompt}"
38-
messages = [{'role': 'user', 'content': full_prompt}]
12+
def generate_answers(model_name, prompt):
13+
model_name = "vicuna:13b-16k"
14+
messages = [
15+
{
16+
'role': 'user',
17+
'content': prompt,
18+
},
19+
]
3920
try:
4021
response = ollama.chat(model=model_name, messages=messages)
41-
# Return both the detailed description and the original prompt
42-
return response['message']['content'], prompt
22+
return response['message']['content']
4323
except Exception as e:
4424
print(f"There was an error communicating with the Ollama model: {e}")
45-
return None, prompt
46-
47-
def get_active_window_title():
48-
"""
49-
Get the title of the active window.
50-
51-
Returns:
52-
str: The title of the active window.
53-
"""
54-
if platform.system() == "Linux":
55-
try:
56-
# Get the window ID of the currently focused window
57-
window_id = subprocess.check_output(["xdotool", "getactivewindow"]).decode().strip()
58-
59-
# Get the name of the window with this ID
60-
window_name = subprocess.check_output(["xdotool", "getwindowname", window_id]).decode().strip()
61-
62-
return window_name
63-
except subprocess.CalledProcessError as e:
64-
print(f"Error retrieving window title: {e}")
65-
return None
66-
elif platform.system() == "Windows":
67-
window = gw.getActiveWindow()
68-
return window.title if window else "No active window"
25+
return None
6926

7027
class ActivityMonitor(ctk.CTk):
71-
"""
72-
Class representing an Activity Monitor application.
73-
"""
74-
def __init__(self, use_ollama=False):
75-
"""
76-
Initialize the ActivityMonitor object.
77-
78-
Args:
79-
use_ollama (bool): Flag indicating whether to use Ollama for analysis.
80-
"""
28+
def __init__(self):
8129
super().__init__()
8230
self.title("Activity Monitor")
8331
self.geometry("300x150")
84-
self.use_ollama = use_ollama
32+
8533
self.is_running = False
34+
self.text_buffer = ""
8635
self.markdown_log = ""
8736

88-
# Create GUI elements
8937
self.start_button = ctk.CTkButton(self, text="Start", command=self.start_monitoring)
9038
self.start_button.pack(pady=10)
39+
9140
self.stop_button = ctk.CTkButton(self, text="Stop", command=self.stop_monitoring)
9241
self.stop_button.pack(pady=10)
42+
9343
self.ollama_button = ctk.CTkButton(self, text="Analyze with Ollama", command=self.analyze_with_ollama)
9444
self.ollama_button.pack(pady=10)
45+
9546
self.quit_button = ctk.CTkButton(self, text="Quit", command=self.quit_monitoring)
9647
self.quit_button.pack(pady=10)
9748

98-
# Method to start monitoring activities
9949
def start_monitoring(self):
100-
"""
101-
Start monitoring activities.
102-
"""
10350
if not self.is_running:
10451
self.is_running = True
10552
threading.Thread(target=self.monitor_activities).start()
10653

107-
# Method to stop monitoring activities
10854
def stop_monitoring(self):
109-
"""
110-
Stop monitoring activities.
111-
"""
11255
self.is_running = False
11356

114-
# Method to analyze activities using Ollama
11557
def analyze_with_ollama(self):
116-
"""
117-
Analyze activities using Ollama.
118-
"""
119-
detailed_description, original_prompt = generate_answers("vicuna:13b-16k", self.markdown_log, True)
58+
detailed_description = generate_answers("vicuna:13b-16k", self.markdown_log)
12059
if detailed_description:
121-
comment = f"Original prompt preserved: {original_prompt}\nOllama's enhanced description: {detailed_description}"
122-
self.markdown_log += "\n" + comment
123-
self.append_to_markdown(comment)
60+
self.markdown_log = detailed_description
61+
self.write_markdown_file()
12462

125-
# Method to quit monitoring and write the log to a file
12663
def quit_monitoring(self):
127-
"""
128-
Quit monitoring activities and write the log to a file.
129-
"""
13064
self.stop_monitoring()
13165
self.write_markdown_file()
13266
self.destroy()
13367

134-
# Method to continuously monitor activities
13568
def monitor_activities(self):
136-
"""
137-
Continuously monitor activities.
138-
"""
69+
previous_clipboard = ""
70+
previous_window = None
13971
screenshot_directory = "screenshots"
140-
archive_directory = "archives"
14172
os.makedirs(screenshot_directory, exist_ok=True)
142-
os.makedirs(archive_directory, exist_ok=True)
143-
window_title = None
144-
previous_window = None
73+
14574
while self.is_running:
75+
# Capture clipboard content
14676
current_clipboard = clipboard.paste()
147-
self.append_to_markdown(f"\n- **Clipboard Changed**: `{current_clipboard}`")
148-
window_title = get_active_window_title()
149-
self.append_to_markdown(f"\n- **Window Selected**: {window_title}")
150-
if previous_window != window_title:
151-
self.capture_screenshot(screenshot_directory)
152-
previous_window = window_title
153-
# Capture typed keys
77+
if current_clipboard != previous_clipboard:
78+
self.markdown_log += f"\n- **Clipboard Changed**: `{current_clipboard}`"
79+
previous_clipboard = current_clipboard
80+
81+
# Capture active window and screenshot
82+
active_window = gw.getActiveWindow()
83+
if active_window and (active_window != previous_window):
84+
try:
85+
# save screenshot
86+
screenshot_path = os.path.join(screenshot_directory, f"{time.time()}_screenshot.png")
87+
screenshot = ImageGrab.grab(bbox=active_window.box)
88+
screenshot.save(screenshot_path)
89+
90+
# save title and screenshot in markdown log
91+
window_title = active_window.title if active_window.title else "Unbekanntes Fenster"
92+
self.markdown_log += f"\n- **Window Selected**: {window_title} ![Screenshot]({screenshot_path})"
93+
previous_window = active_window
94+
except Exception as e:
95+
print(f"Error getting active window: {e}")
96+
97+
# Capture typed keys (improved version)
15498
key_events = keyboard.record(until='enter')
15599
typed_text = ''.join([event.name for event in key_events if event.event_type == 'down' and len(event.name) == 1 or event.name == 'space'])
156100
if typed_text:
@@ -159,102 +103,10 @@ def monitor_activities(self):
159103

160104
time.sleep(1) # Reduce CPU usage
161105

162-
# Method to capture screenshots
163-
def capture_screenshot(self, directory):
164-
"""
165-
Capture screenshots.
166-
167-
Args:
168-
directory (str): The directory to save the screenshots.
169-
170-
Returns:
171-
str: The path of the captured screenshot.
172-
"""
173-
if platform.system() == "Linux":
174-
try:
175-
# Get the window ID of the currently focused window
176-
window_id = subprocess.check_output(["xdotool", "getactivewindow"]).decode().strip()
177-
178-
# Get the geometry of the window (position and size)
179-
geom_output = subprocess.check_output(["xdotool", "getwindowgeometry", "--shell", window_id]).decode()
180-
181-
# Use a dictionary to store variables from the shell output
182-
geom_vars = dict(re.findall(r'(\w+)=(\S+)', geom_output))
183-
184-
# Convert values to integers
185-
x = int(geom_vars['X'])
186-
y = int(geom_vars['Y'])
187-
width = int(geom_vars['WIDTH'])
188-
height = int(geom_vars['HEIGHT'])
189-
190-
with mss.mss() as sct:
191-
# The screenshot region is a tuple: (x, y, width, height)
192-
monitor = {"top": y, "left": x, "width": width, "height": height}
193-
screenshot_path = os.path.join(directory, f"{time.time()}_screenshot.png")
194-
# Capture the specified region
195-
sct_img = sct.grab(monitor)
196-
mss.tools.to_png(sct_img.rgb, sct_img.size, output=screenshot_path)
197-
return screenshot_path
198-
except Exception as e:
199-
print(f"Error capturing screenshot: {e}")
200-
return "Screenshot capture failed"
201-
202-
elif platform.system() == "Windows":
203-
window = gw.getActiveWindow()
204-
if window:
205-
screenshot_path = os.path.join(directory, f"{time.time()}_screenshot.png")
206-
screenshot = ImageGrab.grab(bbox=window.box)
207-
screenshot.save(screenshot_path)
208-
return screenshot_path
209-
210-
return "No active window for screenshot"
211-
212-
# Method to archive URLs
213-
def archive_url(self, directory):
214-
"""
215-
Archive URLs.
216-
217-
Args:
218-
directory (str): The directory to save the archived URLs.
219-
"""
220-
window_title = get_active_window_title()
221-
# Extend or adjust the list of browser window titles as needed
222-
browsers = ["Brave", "Firefox", "Chrome", "Chromium", "Edge", "Opera"]
223-
if any(browser in window_title for browser in browsers):
224-
# Set focus to the address bar and copy URL
225-
keyboard.send('ctrl+l') # Focus on address bar
226-
time.sleep(0.1) # Briefly wait for focus to be set
227-
keyboard.send('ctrl+c') # Copy URL
228-
time.sleep(0.1) # Wait for clipboard to update
229-
keyboard.send('esc') # Escape
230-
231-
# Read URL from clipboard
232-
url = clipboard.paste()
233-
if url.startswith("http") or url.startswith("https"):
234-
with open(os.path.join(self.directory, f"{time.time()}_url.txt"), "w", encoding='utf-8') as file:
235-
file.write(url)
236-
else:
237-
print("The active window is not a recognized browser window.")
238-
239-
# Method to append content to the markdown log
240-
def append_to_markdown(self, content):
241-
"""
242-
Append content to the markdown log.
243-
244-
Args:
245-
content (str): The content to append.
246-
"""
247-
if content not in self.markdown_log:
248-
self.markdown_log += content
249-
250-
# Method to write the markdown log to a file
251106
def write_markdown_file(self):
252-
"""
253-
Write the markdown log to a file.
254-
"""
255107
with open("activity_log.md", "w", encoding='utf-8') as md_file:
256-
md_file.write(markdown2.markdown(self.markdown_log))
108+
md_file.write(self.markdown_log)
257109

258110
if __name__ == "__main__":
259-
app = ActivityMonitor(use_ollama=False)
111+
app = ActivityMonitor()
260112
app.mainloop()

0 commit comments

Comments
 (0)