Skip to content

Commit

Permalink
Merge branch 'beta' of github.com:oskarsh/Yin-Yang into add-flatpak
Browse files Browse the repository at this point in the history
  • Loading branch information
chase9 committed Apr 19, 2024
2 parents 9209b0c + 9188801 commit 861fa6b
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 118 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ jobs:
run: |
sudo apt install qt6-base-dev libsystemd-dev gcc
- name: Install Poetry dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
# if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: |
poetry install --no-interaction
poetry install --sync --no-interaction
# Compile and build Yin-Yang
- name: Compile ui, translations and resources
run: poetry run ./scripts/build_ui.sh
Expand All @@ -67,6 +67,9 @@ jobs:
arch: [x86_64]
steps:
- uses: actions/checkout@v4
- name: Install deps
run: |
dnf -y install python3-pip python3-wheel
- name: Download build from last step
uses: actions/download-artifact@v4
with:
Expand All @@ -77,4 +80,4 @@ jobs:
bundle: yin-yang.flatpak
manifest-path: sh.oskar.yin-yang.json
cache-key: flatpak-builder-${{ github.sha }}
arch: ubuntu-22.04
arch: x86_64
9 changes: 6 additions & 3 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,35 @@ jobs:
os: [ubuntu-22.04]
runs-on: ${{matrix.os}}
steps:
# Checkout repo and set up python
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: ${{matrix.python-version}}
# Install and configure poetry
- name: Install Poetry
uses: abatilo/actions-poetry@v2
- name: Set up local virtual environment
run: |
poetry config virtualenvs.create true --local
poetry config virtualenvs.in-project true --local
# Load cached venv if it exists
- name: Cache packages
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
# This path is specific to ubuntu
path: ./.venv
key: venv-${{ hashFiles('poetry.lock') }}
# Install dependencies
# Install dependencies of cache does not exist
- name: Install system dependencies
run: |
sudo apt install qt6-base-dev libsystemd-dev gcc
- name: Install Poetry dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
# if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: |
poetry install --no-interaction
poetry install --sync --no-interaction
# Build and test Yin-Yang
- name: Compile ui, translations and resources
run: poetry run ./scripts/build_ui.sh
Expand Down
2 changes: 1 addition & 1 deletion scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ echo "Installing dependencies …"
# Tell Poetry not to use a keyring
export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring
# create virtual environment and install packages
poetry install --sync
poetry env use python
poetry install --sync
poetry build
pip install ./dist/yin_yang-*-py3-none-any.whl

Expand Down
1 change: 0 additions & 1 deletion sh.oskar.yin-yang.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"buildsystem": "simple",
"build-commands": [
"poetry install --sync",
"poetry build",
"find dist -name 'yin_yang-*-py3-none-any.whl' -exec pip install --no-deps --no-build-isolation --prefix=/app {} \\;",
"install -D runner.sh /app/bin/runner.sh"
],
Expand Down
34 changes: 26 additions & 8 deletions yin_yang/NotificationHandler.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
import logging
import subprocess
from logging import Handler

logger = logging.getLogger()
from PySide6.QtDBus import QDBusConnection, QDBusMessage


def create_dbus_message(title: str, body: str):
message = QDBusMessage.createMethodCall(
"org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.Notification",
"AddNotification",
)

notification = {
"title": title,
"body": body,
"icon": "yin_yang",
"priority": "low",
}

message.setArguments(["YingYang.ThemeChanged", notification])

return message


class NotificationHandler(Handler):
"""Shows logs as notifications"""

def emit(self, record):
try:
subprocess.call(['notify-send', record.levelname, str(record.msg),
'-a', 'Yin & Yang', '-u', 'low', '--icon', 'yin_yang'])
except FileNotFoundError:
logger.warn('notify-send not found. Notifications will not work!')
connection = QDBusConnection.sessionBus()
message = create_dbus_message(record.levelname, str(record.msg))
connection.call(message)
19 changes: 18 additions & 1 deletion yin_yang/plugins/_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from abc import ABC, abstractmethod
from configparser import ConfigParser
from pathlib import Path
from typing import Optional
from typing import Optional, List

from PySide6.QtDBus import QDBusConnection, QDBusMessage
from PySide6.QtGui import QColor, QRgba64
Expand Down Expand Up @@ -366,3 +366,20 @@ def flatpak_user(app_id: str) -> Path:

def snap_path(app: str) -> Path:
return Path(f'/var/lib/snapd/snap/{app}/current')

def themes_from_theme_directories(type: str) -> List[Path]:
theme_directories = [
Path('/usr/share/themes'),
Path('/usr/local/share/themes'),
Path.home() / '.themes',
Path.home() / '.local/share/themes',
]

themes = []
for directory in theme_directories:
if not directory.is_dir():
continue

themes.extend(d.name for d in directory.iterdir() if d.is_dir() and (d / type).is_dir())

return themes
108 changes: 56 additions & 52 deletions yin_yang/plugins/gtk.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import logging
from os import scandir, path
from os import path, scandir
from pathlib import Path

from PySide6.QtDBus import QDBusMessage

from yin_yang import helpers

from ._plugin import PluginDesktopDependent, PluginCommandline, DBusPlugin
from .system import test_gnome_availability
from ..meta import Desktop
from ._plugin import DBusPlugin, PluginCommandline, PluginDesktopDependent
from .system import test_gnome_availability

logger = logging.getLogger(__name__)


theme_directories = [helpers.get_usr() + 'share/themes', f'{Path.home()}/.themes']


class Gtk(PluginDesktopDependent):
name = 'GTK'
name = "GTK"

def __init__(self, desktop: Desktop):
match desktop:
Expand All @@ -26,8 +23,10 @@ def __init__(self, desktop: Desktop):
case Desktop.GNOME:
super().__init__(_Gnome())
if not self.strategy.available:
print('You need to install an extension for gnome to use it. \n'
'You can get it from here: https://extensions.gnome.org/extension/19/user-themes/')
print(
"You need to install an extension for gnome to use it. \n"
"You can get it from here: https://extensions.gnome.org/extension/19/user-themes/"
)
case Desktop.MATE:
super().__init__(_Mate())
case Desktop.XFCE:
Expand All @@ -41,58 +40,51 @@ def __init__(self, desktop: Desktop):

@property
def available_themes(self) -> dict:
themes = []

for directory in theme_directories:
if not path.isdir(directory):
continue

with scandir(directory) as entries:
themes.extend(d.name for d in entries if d.is_dir() and path.isdir(d.path + '/gtk-3.0'))

themes = themes_from_theme_directories("gtk-3.0")
return {t: t for t in themes}


class _Gnome(PluginCommandline):
name = 'GTK'
name = "GTK"

def __init__(self):
super().__init__(['gsettings', 'set', 'org.gnome.desktop.interface', 'gtk-theme', '{theme}'])
self.theme_light = 'Default'
self.theme_dark = 'Default'
super().__init__(
["gsettings", "set", "org.gnome.desktop.interface", "gtk-theme", "{theme}"]
)
self.theme_light = "Default"
self.theme_dark = "Default"

@property
def available(self) -> bool:
return test_gnome_availability(self.command)


class _Budgie(PluginCommandline):
name = 'GTK'
name = "GTK"

def __init__(self):
super().__init__(['gsettings', 'set', 'org.gnome.desktop.interface', 'gtk-theme', '{theme}'])
self.theme_light = 'Default'
self.theme_dark = 'Default'
super().__init__(
["gsettings", "set", "org.gnome.desktop.interface", "gtk-theme", "{theme}"]
)
self.theme_light = "Default"
self.theme_dark = "Default"

@property
def available(self) -> bool:
return test_gnome_availability(self.command)


class _Kde(DBusPlugin):
name = 'GTK'
name = "GTK"

def __init__(self):
super().__init__()
self.theme_light = 'Breeze'
self.theme_dark = 'Breeze'
self.theme_light = "Breeze"
self.theme_dark = "Breeze"

def create_message(self, theme: str) -> QDBusMessage:
message = QDBusMessage.createMethodCall(
'org.kde.GtkConfig',
'/GtkConfig',
'org.kde.GtkConfig',
'setGtkTheme'
"org.kde.GtkConfig", "/GtkConfig", "org.kde.GtkConfig", "setGtkTheme"
)
message.setArguments([theme])
return message
Expand All @@ -103,49 +95,61 @@ def set_theme(self, theme: str):
if response.type() != QDBusMessage.MessageType.ErrorMessage:
return

logger.warning('kde-gtk-config not available, trying xsettingsd')
xsettingsd_conf_path = Path.home() / '.config/xsettingsd/xsettingsd.conf'
logger.warning("kde-gtk-config not available, trying xsettingsd")
xsettingsd_conf_path = Path.home() / ".config/xsettingsd/xsettingsd.conf"
if not xsettingsd_conf_path.exists():
logger.warning('xsettingsd not available')
logger.warning("xsettingsd not available")
return

with open(xsettingsd_conf_path, 'r') as f:
with open(xsettingsd_conf_path, "r") as f:
lines = f.readlines()
for i, line in enumerate(lines):
if line.startswith('Net/ThemeName'):
if line.startswith("Net/ThemeName"):
lines[i] = f'Net/ThemeName "{theme}"\n'
break

with open(xsettingsd_conf_path, 'w') as f:
with open(xsettingsd_conf_path, "w") as f:
f.writelines(lines)

# send signal to read new config
helpers.run(['killall', '-HUP', 'xsettingsd'])
helpers.run(["killall", "-HUP", "xsettingsd"])


class _Xfce(PluginCommandline):
def __init__(self):
super(_Xfce, self).__init__(['xfconf-query', '-c', 'xsettings', '-p', '/Net/ThemeName', '-s', '{theme}'])
self.theme_light = 'Adwaita'
self.theme_dark = 'Adwaita-dark'
super(_Xfce, self).__init__(
["xfconf-query", "-c", "xsettings", "-p", "/Net/ThemeName", "-s", "{theme}"]
)
self.theme_light = "Adwaita"
self.theme_dark = "Adwaita-dark"


class _Mate(PluginCommandline):
def __init__(self):
super().__init__(['dconf', 'write', '/org/mate/desktop/interface/gtk-theme', '\'{theme}\''])
self.theme_light = 'Yaru'
self.theme_dark = 'Yaru-dark'
super().__init__(
["dconf", "write", "/org/mate/desktop/interface/gtk-theme", "'{theme}'"]
)
self.theme_light = "Yaru"
self.theme_dark = "Yaru-dark"

@property
def available(self) -> bool:
return self.check_command(['dconf', 'help'])
return self.check_command(["dconf", "help"])


class _Cinnamon(PluginCommandline):
def __init__(self):
super().__init__(['gsettings', 'set', 'org.cinnamon.desktop.interface', 'gtk-theme', '\"{theme}\"'])
self.theme_light = 'Adwaita'
self.theme_dark = 'Adwaita-dark'
super().__init__(
[
"gsettings",
"set",
"org.cinnamon.desktop.interface",
"gtk-theme",
'"{theme}"',
]
)
self.theme_light = "Adwaita"
self.theme_dark = "Adwaita-dark"

@property
def available(self) -> bool:
Expand Down
13 changes: 9 additions & 4 deletions yin_yang/plugins/notify.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
from ._plugin import PluginCommandline
from PySide6.QtDBus import QDBusMessage

from ..NotificationHandler import create_dbus_message
from ._plugin import DBusPlugin

class Notification(PluginCommandline):

class Notification(DBusPlugin):
def __init__(self):
super().__init__(['notify-send', 'Theme changed', 'Set the theme to {theme}',
'-a', 'Yin & Yang', '-u', 'low', '--icon', 'yin_yang'])
super().__init__()
self.theme_light = 'Day'
self.theme_dark = 'Night'

def create_message(self, theme: str) -> QDBusMessage:
return create_dbus_message('Theme changed', f'Set the theme to {theme}')
Loading

0 comments on commit 861fa6b

Please sign in to comment.