formatting and clean-up 🧹
This commit is contained in:
parent
34b740e0df
commit
225a2750e3
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,4 +5,5 @@ venv
|
||||
dist
|
||||
build
|
||||
.pytest_cache
|
||||
.vscode
|
||||
.vscode
|
||||
.aider*
|
||||
|
@ -137,9 +137,7 @@ def timeline():
|
||||
def search():
|
||||
q = request.args.get("q")
|
||||
entries = get_all_entries()
|
||||
embeddings = [
|
||||
np.frombuffer(entry.embedding, dtype=np.float64) for entry in entries
|
||||
]
|
||||
embeddings = [np.frombuffer(entry.embedding, dtype=np.float64) for entry in entries]
|
||||
query_embedding = get_embedding(q)
|
||||
similarities = [cosine_similarity(query_embedding, emb) for emb in embeddings]
|
||||
indices = np.argsort(similarities)[::-1]
|
||||
|
@ -2,9 +2,7 @@ import os
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="OpenRecall"
|
||||
)
|
||||
parser = argparse.ArgumentParser(description="OpenRecall")
|
||||
|
||||
parser.add_argument(
|
||||
"--storage-path",
|
||||
@ -38,11 +36,12 @@ def get_appdata_folder(app_name="openrecall"):
|
||||
os.makedirs(path)
|
||||
return path
|
||||
|
||||
|
||||
if args.storage_path:
|
||||
appdata_folder = args.storage_path
|
||||
screenshots_path = os.path.join(appdata_folder, "screenshots")
|
||||
db_path = os.path.join(appdata_folder, "recall.db")
|
||||
else:
|
||||
else:
|
||||
appdata_folder = get_appdata_folder()
|
||||
db_path = os.path.join(appdata_folder, "recall.db")
|
||||
screenshots_path = os.path.join(appdata_folder, "screenshots")
|
||||
|
@ -9,7 +9,11 @@ from openrecall.config import screenshots_path, args
|
||||
from openrecall.database import insert_entry
|
||||
from openrecall.nlp import get_embedding
|
||||
from openrecall.ocr import extract_text_from_image
|
||||
from openrecall.utils import get_active_app_name, get_active_window_title, is_user_active
|
||||
from openrecall.utils import (
|
||||
get_active_app_name,
|
||||
get_active_window_title,
|
||||
is_user_active,
|
||||
)
|
||||
|
||||
|
||||
def mean_structured_similarity_index(img1, img2, L=255):
|
||||
@ -45,18 +49,19 @@ def take_screenshots(monitor=1):
|
||||
|
||||
if args.primary_monitor_only and monitor != 1:
|
||||
continue
|
||||
|
||||
|
||||
monitor_ = sct.monitors[monitor]
|
||||
screenshot = np.array(sct.grab(monitor_))
|
||||
screenshot = screenshot[:, :, [2, 1, 0]]
|
||||
screenshots.append(screenshot)
|
||||
|
||||
|
||||
return screenshots
|
||||
|
||||
|
||||
def record_screenshots_thread():
|
||||
# TODO: fix the error from huggingface tokenizers
|
||||
import os
|
||||
|
||||
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
||||
|
||||
last_screenshots = take_screenshots()
|
||||
@ -65,11 +70,11 @@ def record_screenshots_thread():
|
||||
if not is_user_active():
|
||||
time.sleep(3)
|
||||
continue
|
||||
|
||||
|
||||
screenshots = take_screenshots()
|
||||
|
||||
|
||||
for i, screenshot in enumerate(screenshots):
|
||||
|
||||
|
||||
last_screenshot = last_screenshots[i]
|
||||
|
||||
if not is_similar(screenshot, last_screenshot):
|
||||
@ -88,5 +93,5 @@ def record_screenshots_thread():
|
||||
insert_entry(
|
||||
text, timestamp, embedding, active_app_name, active_window_title
|
||||
)
|
||||
|
||||
|
||||
time.sleep(3)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import sys
|
||||
|
||||
|
||||
def human_readable_time(timestamp):
|
||||
import datetime
|
||||
|
||||
@ -35,6 +36,7 @@ def get_active_app_name_osx():
|
||||
except:
|
||||
return ""
|
||||
|
||||
|
||||
def get_active_window_title_osx():
|
||||
from Quartz import (
|
||||
CGWindowListCopyWindowInfo,
|
||||
@ -80,11 +82,12 @@ def get_active_window_title_windows():
|
||||
|
||||
|
||||
def get_active_app_name_linux():
|
||||
return ''
|
||||
return ""
|
||||
|
||||
|
||||
def get_active_window_title_linux():
|
||||
return ''
|
||||
return ""
|
||||
|
||||
|
||||
def get_active_app_name():
|
||||
if sys.platform == "win32":
|
||||
@ -107,28 +110,29 @@ def get_active_window_title():
|
||||
else:
|
||||
raise NotImplementedError("This platform is not supported")
|
||||
|
||||
|
||||
def is_user_active_osx():
|
||||
import subprocess
|
||||
|
||||
try:
|
||||
# Run the 'ioreg' command to get idle time information
|
||||
output = subprocess.check_output(["ioreg", "-c", "IOHIDSystem"]).decode()
|
||||
|
||||
|
||||
# Find the line containing "HIDIdleTime"
|
||||
for line in output.split('\n'):
|
||||
for line in output.split("\n"):
|
||||
if "HIDIdleTime" in line:
|
||||
# Extract the idle time value
|
||||
idle_time = int(line.split('=')[-1].strip())
|
||||
|
||||
idle_time = int(line.split("=")[-1].strip())
|
||||
|
||||
# Convert idle time from nanoseconds to seconds
|
||||
idle_seconds = idle_time / 1000000000
|
||||
|
||||
|
||||
# If idle time is less than 5 seconds, consider the user not idle
|
||||
return idle_seconds < 5
|
||||
|
||||
|
||||
# If "HIDIdleTime" is not found, assume the user is not idle
|
||||
return True
|
||||
|
||||
|
||||
except subprocess.CalledProcessError:
|
||||
# If there's an error running the command, assume the user is not idle
|
||||
return True
|
||||
@ -137,6 +141,7 @@ def is_user_active_osx():
|
||||
# If there's any other error, assume the user is not idle
|
||||
return True
|
||||
|
||||
|
||||
def is_user_active():
|
||||
if sys.platform == "win32":
|
||||
return True
|
||||
@ -146,4 +151,3 @@ def is_user_active():
|
||||
return True
|
||||
else:
|
||||
raise NotImplementedError("This platform is not supported")
|
||||
|
11
setup.py
11
setup.py
@ -17,12 +17,17 @@ install_requires = [
|
||||
"shapely==2.0.4",
|
||||
"h5py==3.11.0",
|
||||
"rapidfuzz==3.9.3",
|
||||
"Pillow==10.3.0"
|
||||
"Pillow==10.3.0",
|
||||
]
|
||||
|
||||
# Define OS-specific dependencies
|
||||
extras_require = {"windows": ["pywin32", "psutil"], "macos": ["pyobjc==10.3"], "linux": [],
|
||||
'python-doctr': ['python-doctr @ git+https://github.com/koenvaneijk/doctr.git@af711bc04eb8876a7189923fb51ec44481ee18cd']
|
||||
extras_require = {
|
||||
"windows": ["pywin32", "psutil"],
|
||||
"macos": ["pyobjc==10.3"],
|
||||
"linux": [],
|
||||
"python-doctr": [
|
||||
"python-doctr @ git+https://github.com/koenvaneijk/doctr.git@af711bc04eb8876a7189923fb51ec44481ee18cd"
|
||||
],
|
||||
}
|
||||
|
||||
# Determine the current OS
|
||||
|
@ -2,29 +2,35 @@ import pytest
|
||||
from unittest import mock
|
||||
from openrecall.config import get_appdata_folder
|
||||
|
||||
|
||||
def test_get_appdata_folder_windows(tmp_path):
|
||||
with mock.patch('sys.platform', 'win32'):
|
||||
with mock.patch.dict('os.environ', {'APPDATA': str(tmp_path)}):
|
||||
expected_path = tmp_path / 'openrecall'
|
||||
with mock.patch("sys.platform", "win32"):
|
||||
with mock.patch.dict("os.environ", {"APPDATA": str(tmp_path)}):
|
||||
expected_path = tmp_path / "openrecall"
|
||||
assert get_appdata_folder() == str(expected_path)
|
||||
assert expected_path.exists()
|
||||
|
||||
|
||||
def test_get_appdata_folder_windows_no_appdata():
|
||||
with mock.patch('sys.platform', 'win32'):
|
||||
with mock.patch.dict('os.environ', {}, clear=True):
|
||||
with pytest.raises(EnvironmentError, match="APPDATA environment variable is not set."):
|
||||
with mock.patch("sys.platform", "win32"):
|
||||
with mock.patch.dict("os.environ", {}, clear=True):
|
||||
with pytest.raises(
|
||||
EnvironmentError, match="APPDATA environment variable is not set."
|
||||
):
|
||||
get_appdata_folder()
|
||||
|
||||
|
||||
def test_get_appdata_folder_darwin(tmp_path):
|
||||
with mock.patch('sys.platform', 'darwin'):
|
||||
with mock.patch('os.path.expanduser', return_value=str(tmp_path)):
|
||||
expected_path = tmp_path / 'Library' / 'Application Support' / 'openrecall'
|
||||
with mock.patch("sys.platform", "darwin"):
|
||||
with mock.patch("os.path.expanduser", return_value=str(tmp_path)):
|
||||
expected_path = tmp_path / "Library" / "Application Support" / "openrecall"
|
||||
assert get_appdata_folder() == str(expected_path)
|
||||
assert expected_path.exists()
|
||||
|
||||
|
||||
def test_get_appdata_folder_linux(tmp_path):
|
||||
with mock.patch('sys.platform', 'linux'):
|
||||
with mock.patch('os.path.expanduser', return_value=str(tmp_path)):
|
||||
expected_path = tmp_path / '.local' / 'share' / 'openrecall'
|
||||
with mock.patch("sys.platform", "linux"):
|
||||
with mock.patch("os.path.expanduser", return_value=str(tmp_path)):
|
||||
expected_path = tmp_path / ".local" / "share" / "openrecall"
|
||||
assert get_appdata_folder() == str(expected_path)
|
||||
assert expected_path.exists()
|
||||
|
@ -2,34 +2,42 @@ import pytest
|
||||
import numpy as np
|
||||
from openrecall.nlp import cosine_similarity
|
||||
|
||||
|
||||
def test_cosine_similarity_identical_vectors():
|
||||
a = np.array([1, 0, 0])
|
||||
b = np.array([1, 0, 0])
|
||||
assert cosine_similarity(a, b) == 1.0
|
||||
|
||||
|
||||
def test_cosine_similarity_orthogonal_vectors():
|
||||
a = np.array([1, 0, 0])
|
||||
b = np.array([0, 1, 0])
|
||||
assert cosine_similarity(a, b) == 0.0
|
||||
|
||||
|
||||
def test_cosine_similarity_opposite_vectors():
|
||||
a = np.array([1, 0, 0])
|
||||
b = np.array([-1, 0, 0])
|
||||
assert cosine_similarity(a, b) == -1.0
|
||||
|
||||
|
||||
def test_cosine_similarity_non_unit_vectors():
|
||||
a = np.array([3, 0, 0])
|
||||
b = np.array([1, 0, 0])
|
||||
assert cosine_similarity(a, b) == 1.0
|
||||
|
||||
|
||||
def test_cosine_similarity_arbitrary_vectors():
|
||||
a = np.array([1, 2, 3])
|
||||
b = np.array([4, 5, 6])
|
||||
expected_similarity = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
|
||||
assert cosine_similarity(a, b) == pytest.approx(expected_similarity)
|
||||
|
||||
|
||||
def test_cosine_similarity_zero_vector():
|
||||
a = np.array([0, 0, 0])
|
||||
b = np.array([1, 0, 0])
|
||||
result = cosine_similarity(a, b)
|
||||
assert np.isnan(result), "Expected result to be NaN when one of the vectors is a zero vector"
|
||||
assert np.isnan(
|
||||
result
|
||||
), "Expected result to be NaN when one of the vectors is a zero vector"
|
||||
|
Loading…
Reference in New Issue
Block a user