4 Commits

Author SHA1 Message Date
Storm Dragon afb2d804d9 Merge branch 'testing' into wine-access 2026-07-18 14:38:07 -04:00
Storm Dragon 394d814ad0 updated PKGBUILDs. 2026-07-18 14:24:42 -04:00
Storm Dragon 006612c1da Merge branch 'testing' 2026-07-18 02:55:04 -04:00
Storm Dragon 49f0d3c612 Tests for the new plugins dialogue updates. 2026-07-18 02:54:53 -04:00
8 changed files with 134 additions and 148 deletions
+22 -45
View File
@@ -1,24 +1,25 @@
# Maintainer: Storm Dragon <storm_dragon@stormux.org>
# shellcheck shell=bash disable=SC2034,SC2154,SC2164
pkgbase=cthulhu-git
pkgname=(cthulhu-git cthulhu-wine-access-git)
_pkgname=cthulhu
pkgver=2026.05.25.r423.g0576b6f
pkgrel=1
pkgrel=2
pkgdesc="Desktop-agnostic screen reader with plugin system, forked from Orca"
url="https://git.stormux.org/storm/cthulhu"
arch=(x86_64 aarch64 armv7h)
license=(LGPL)
provides=("${_pkgname}")
license=(LGPL-2.1-or-later)
provides=("${_pkgname}=${pkgver}")
conflicts=("${_pkgname}")
depends=(
# Core AT-SPI accessibility
at-spi2-core
glib2
gobject-introspection-runtime
python-gobject
python-cairo
gtk3
python-pywayland
# Audio and speech
speech-dispatcher
gstreamer
@@ -26,57 +27,44 @@ depends=(
gst-plugins-good # pulsesink, more decoders
# Braille support
brltty
python-brltty
liblouis
# Plugin system and D-Bus remote control
python-pluggy
python-tomlkit
python-dasbus
# AI Assistant dependencies (for screenshots, HTTP requests, and actions)
python-requests
python-pyautogui
python-msgpack
python-tornado
python-xlib
# Desktop integration
hicolor-icon-theme
libwnck3
pango
# System utilities
python
python-setproctitle
socat # for self-voicing feature
xorg-xkbcomp
xorg-xmodmap
)
optdepends=(
'espeak-ng: Alternative TTS engine'
'festival: Alternative TTS engine'
'flite: Lightweight TTS engine'
'espeak: Legacy TTS engine'
'git: Install and update third-party plugin sources'
'python-pywayland: Wayland shared workspace backend'
'piper-tts: Piper speech backend'
'socat: Send text to the Self Voice socket from the command line'
# AI Assistant providers (optional)
'python-requests: AI Assistant plugin and HTTP provider support'
'python-pyautogui: AI Assistant mouse and keyboard actions'
'claude-code: Claude AI provider support'
'openai-codex: ChatGPT AI provider support'
'openai-codex: OpenAI Codex provider support'
'gemini-cli: Gemini AI provider support'
'ollama: Local AI model support'
# OCR plugin dependencies (optional)
'python-pillow: Image processing for OCR and AI Assistant'
'python-pillow: Image processing for OCR'
'python-pytesseract: Python wrapper for Tesseract OCR engine'
'python-pdf2image: PDF to image conversion for OCR'
'python-scipy: Scientific computing for OCR color analysis'
'python-webcolors: Color name lookup for OCR text decoration'
'tesseract: OCR engine for text recognition'
'tesseract-data-eng: English language data for Tesseract'
# nvda2cthulhu plugin (optional)
'python-msgpack: Msgpack decoding for nvda2cthulhu'
'python-tornado: WebSocket server for nvda2cthulhu'
# Window Title Reader plugin (optional)
'python-xlib: X11 access for Wine window title plugin'
)
optdepends_x86_64=(
'cthulhu-wine-access-git: Wine, Proton, NVDA Controller, and Tolk integration'
@@ -84,24 +72,13 @@ optdepends_x86_64=(
makedepends=(
git
meson
ninja
python-build
python-installer
python-wheel
)
makedepends_x86_64=(
cmake
wine
)
install=cthulhu.install
source=(
"${_pkgname}::git+https://git.stormux.org/storm/${_pkgname}.git#branch=master"
"cthulhu.install"
)
b2sums=(
'SKIP'
'SKIP'
)
source=("${_pkgname}::git+https://git.stormux.org/storm/${_pkgname}.git#branch=master")
sha512sums=('SKIP')
pkgver() {
cd "${_pkgname}"
@@ -125,7 +102,7 @@ build() {
package_cthulhu-git() {
arch=(any)
provides=(cthulhu)
provides=("cthulhu=${pkgver}")
conflicts=(cthulhu)
cd "${_pkgname}"
meson install -C _build --destdir "$pkgdir"
@@ -1,11 +0,0 @@
post_install() {
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
}
post_upgrade() {
post_install
}
post_remove() {
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
}
+27 -50
View File
@@ -1,79 +1,67 @@
# Maintainer: Storm Dragon <storm_dragon@stormux.org>
# shellcheck shell=bash disable=SC2034,SC2154,SC2164
pkgbase=cthulhu
pkgname=(cthulhu cthulhu-wine-access)
pkgver=2026.05.25
pkgver=2026.07.18
pkgrel=1
pkgdesc="Desktop-agnostic screen reader with plugin system, forked from Orca"
url="https://git.stormux.org/storm/cthulhu"
arch=(x86_64 aarch64 armv7h)
license=(LGPL)
license=(LGPL-2.1-or-later)
depends=(
# Core AT-SPI accessibility
at-spi2-core
glib2
gobject-introspection-runtime
python-gobject
python-cairo
gtk3
python-pywayland
# Audio and speech
speech-dispatcher
gstreamer
gst-plugins-base # playbin, audiotestsrc, basic decoders
gst-plugins-good # pulsesink, more decoders
# Braille support
brltty
python-brltty
liblouis
# Plugin system and D-Bus remote control
python-pluggy
python-tomlkit
python-dasbus
# AI Assistant dependencies (for screenshots, HTTP requests, and actions)
python-requests
python-pyautogui
python-msgpack
python-tornado
python-xlib
# Desktop integration
hicolor-icon-theme
libwnck3
pango
# System utilities
python
python-setproctitle
socat # for self-voicing feature
xorg-xkbcomp
xorg-xmodmap
)
optdepends=(
'espeak-ng: Alternative TTS engine'
'festival: Alternative TTS engine'
'flite: Lightweight TTS engine'
'espeak: Legacy TTS engine'
'git: Install and update third-party plugin sources'
'python-pywayland: Wayland shared workspace backend'
'piper-tts: Piper speech backend'
'socat: Send text to the Self Voice socket from the command line'
# AI Assistant providers (optional)
'python-requests: AI Assistant plugin and HTTP provider support'
'python-pyautogui: AI Assistant mouse and keyboard actions'
'claude-code: Claude AI provider support'
'openai-codex: ChatGPT AI provider support'
'openai-codex: OpenAI Codex provider support'
'gemini-cli: Gemini AI provider support'
'ollama: Local AI model support'
# OCR plugin dependencies (optional)
'python-pillow: Image processing for OCR and AI Assistant'
'python-pytesseract: Python wrapper for Tesseract OCR engine'
'python-pdf2image: PDF to image conversion for OCR'
'python-scipy: Scientific computing for OCR color analysis'
'python-webcolors: Color name lookup for OCR text decoration'
'tesseract: OCR engine for text recognition'
'tesseract-data-eng: English language data for Tesseract'
# nvda2cthulhu plugin (optional)
'python-msgpack: Msgpack decoding for nvda2cthulhu'
'python-tornado: WebSocket server for nvda2cthulhu'
# Window Title Reader plugin (optional)
'python-xlib: X11 access for Wine window title plugin'
# OCR plugin dependencies (optional)
'python-pillow: Image processing for OCR'
'python-pytesseract: Python wrapper for Tesseract OCR engine'
'tesseract: OCR engine for text recognition'
)
optdepends_x86_64=(
'cthulhu-wine-access: Wine, Proton, NVDA Controller, and Tolk integration'
@@ -81,24 +69,13 @@ optdepends_x86_64=(
makedepends=(
git
meson
ninja
python-build
python-installer
python-wheel
)
makedepends_x86_64=(
cmake
wine
)
install=cthulhu.install
source=(
"git+https://git.stormux.org/storm/cthulhu.git#tag=${pkgver}"
"cthulhu.install"
)
b2sums=(
'SKIP'
'SKIP'
)
source=("git+https://git.stormux.org/storm/cthulhu.git#tag=${pkgver}")
sha512sums=('SKIP')
build() {
cd cthulhu
@@ -108,7 +85,7 @@ build() {
package_cthulhu() {
arch=(any)
provides=(cthulhu)
provides=("cthulhu=${pkgver}")
conflicts=(cthulhu)
cd cthulhu
meson install -C _build --destdir "$pkgdir"
@@ -1,11 +0,0 @@
post_install() {
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
}
post_upgrade() {
post_install
}
post_remove() {
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
}
+1 -5
View File
@@ -1,5 +1,5 @@
project('cthulhu',
version: '2026.05.25',
version: '2026.07.18',
meson_version: '>= 1.0.0',
)
@@ -56,12 +56,8 @@ optional_modules = {
'louis': 'contracted braille',
'speechd': 'speech output',
'dasbus': 'D-Bus remote controller',
'psutil': 'system information commands',
'pywayland': 'Wayland shared workspace backend',
'gi.repository.Wnck': 'mouse review',
'pdf2image': 'PDF processing for OCR',
'scipy': 'Scientific computing for OCR analysis',
'webcolors': 'Color name resolution for OCR',
}
summary = {}
+1 -1
View File
@@ -23,5 +23,5 @@
# Forked from Orca screen reader.
# Cthulhu project: https://git.stormux.org/storm/cthulhu
version = "2026.07.17"
version = "2026.07.18"
codeName = "wine-access"
+1 -25
View File
@@ -47,28 +47,6 @@ try:
except ImportError:
PYTESSERACT_AVAILABLE = False
# pdf2image
try:
from pdf2image import convert_from_path
PDF2IMAGE_AVAILABLE = True
except ImportError:
PDF2IMAGE_AVAILABLE = False
# scipy
try:
from scipy.spatial import KDTree
SCIPY_AVAILABLE = True
except ImportError:
SCIPY_AVAILABLE = False
# webcolors
try:
from webcolors import CSS3_HEX_TO_NAMES
from webcolors import hex_to_rgb
WEBCOLORS_AVAILABLE = True
except ImportError:
WEBCOLORS_AVAILABLE = False
# GTK/GDK
try:
gi.require_version("Gtk", "3.0")
@@ -594,9 +572,7 @@ class OCRDesktop(Plugin):
"""Get color information for OCR text (simplified version)."""
if not self._colorCalculation:
return 'unknown'
if not SCIPY_AVAILABLE or not WEBCOLORS_AVAILABLE:
return 'unknown'
# Simplified color calculation - just return "unknown" for now
# Full implementation would require the color analysis from ocrdesktop
return 'unknown'
@@ -0,0 +1,82 @@
#!/usr/bin/env python3
"""Regression tests for the plugin controls in Preferences."""
import unittest
from unittest import mock
from cthulhu import cthulhu # Import first to satisfy the application's initialization order.
from cthulhu import cthulhu_gui_prefs
class PluginPreferencesRegressionTests(unittest.TestCase):
"""Keep plugin state changes independent from their presentation widgets."""
@staticmethod
def _create_gui():
gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(
cthulhu_gui_prefs.CthulhuSetupGUI
)
gui.prefsDict = {
"activePlugins": ["HiddenPlugin", "SourceOne"],
"pluginSources": ["https://example.com/plugins.git"],
}
gui._available_plugins = {"HiddenPlugin", "SourceOne", "SourceTwo", "Required"}
gui._plugin_entries = {
"SourceOne": {"active": True, "can_toggle": True},
"SourceTwo": {"active": False, "can_toggle": True},
"Required": {"active": True, "can_toggle": False},
}
gui._plugin_canonical_map = {
"SourceOne": "SharedPlugin",
"SourceTwo": "SharedPlugin",
"Required": "Required",
}
gui._plugin_group_map = {
"SharedPlugin": ["SourceOne", "SourceTwo"],
"Required": ["Required"],
}
gui._update_selected_plugin_controls = mock.Mock()
gui._update_plugin_tabs = mock.Mock()
return gui
def test_active_plugins_include_hidden_and_selected_plugins(self):
gui = self._create_gui()
self.assertEqual(
gui._get_active_plugins_from_ui(),
["HiddenPlugin", "SourceOne", "Required"],
)
def test_enabling_plugin_disables_other_copy_with_same_name(self):
gui = self._create_gui()
gui._set_plugin_active("SourceTwo", True)
self.assertFalse(gui._plugin_entries["SourceOne"]["active"])
self.assertTrue(gui._plugin_entries["SourceTwo"]["active"])
gui._update_selected_plugin_controls.assert_called_once_with()
gui._update_plugin_tabs.assert_called_once_with()
def test_required_plugin_cannot_be_disabled(self):
gui = self._create_gui()
gui._set_plugin_active("Required", False)
self.assertTrue(gui._plugin_entries["Required"]["active"])
gui._update_plugin_tabs.assert_not_called()
def test_apply_does_not_modify_plugin_sources(self):
gui = self._create_gui()
gui._populate_plugin_list = mock.Mock()
gui._apply_plugin_changes()
self.assertEqual(
gui.prefsDict["pluginSources"],
["https://example.com/plugins.git"],
)
if __name__ == "__main__":
unittest.main()