Compare commits
8 Commits
72c76c9fda
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| df2bef7685 | |||
| 5d08a48b6c | |||
| 82b0cf7aaa | |||
| e4744bab81 | |||
| 872dbfc792 | |||
| 64781af68f | |||
| 0ebfbdb3a9 | |||
| bf3920ad35 |
52
bar/config.py
Normal file
52
bar/config.py
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import yaml
|
||||||
|
import os
|
||||||
|
from platformdirs import user_config_dir
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
|
||||||
|
APP_NAME = "makku_bar"
|
||||||
|
|
||||||
|
XDG_CONFIG_HOME = user_config_dir(appname=APP_NAME)
|
||||||
|
XDG_CONFIG_FILE = os.path.join(XDG_CONFIG_HOME, "config.yaml")
|
||||||
|
|
||||||
|
|
||||||
|
def load_config(config_path=XDG_CONFIG_FILE):
|
||||||
|
"""Loads configuration from a YAML file."""
|
||||||
|
if config_path is None:
|
||||||
|
print("No configuration file path provided or found.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(config_path, "r") as f:
|
||||||
|
config = yaml.safe_load(f)
|
||||||
|
return config
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"Error: Configuration file not found at {config_path}")
|
||||||
|
return None
|
||||||
|
except yaml.YAMLError as e:
|
||||||
|
print(f"Error parsing YAML file '{config_path}': {e}")
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An unexpected error occurred loading config file '{config_path}': {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def load_args():
|
||||||
|
parser = argparse.ArgumentParser(description="makku_bar")
|
||||||
|
parser.add_argument(
|
||||||
|
"-c",
|
||||||
|
"--config",
|
||||||
|
help="Path to a custom configuration file.",
|
||||||
|
type=str,
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
return args.config
|
||||||
|
|
||||||
|
|
||||||
|
app_config = load_config() if not load_args() else load_config(load_args())
|
||||||
|
|
||||||
|
if app_config is None:
|
||||||
|
raise Exception("Config file missing")
|
||||||
|
|
||||||
|
VINYL = app_config.get("vinyl", {"enable": False})
|
||||||
57
bar/main.py
57
bar/main.py
@@ -1,5 +1,3 @@
|
|||||||
# fabric bar.py example
|
|
||||||
# https://github.com/Fabric-Development/fabric/blob/rewrite/examples/bar/bar.py
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from fabric import Application
|
from fabric import Application
|
||||||
@@ -12,39 +10,44 @@ from fabric.utils import (
|
|||||||
get_relative_path,
|
get_relative_path,
|
||||||
)
|
)
|
||||||
from .modules.bar import StatusBar
|
from .modules.bar import StatusBar
|
||||||
|
from .modules.window_fuzzy import FuzzyWindowFinder
|
||||||
|
|
||||||
|
|
||||||
|
tray = SystemTray(name="system-tray", spacing=4)
|
||||||
|
river = get_river_connection()
|
||||||
|
|
||||||
|
dummy = Window(visible=False)
|
||||||
|
finder = FuzzyWindowFinder()
|
||||||
|
|
||||||
|
bar_windows = []
|
||||||
|
|
||||||
|
app = Application("bar", dummy, finder)
|
||||||
|
app.set_stylesheet_from_file(get_relative_path("styles/main.css"))
|
||||||
|
|
||||||
|
|
||||||
|
def spawn_bars():
|
||||||
|
logger.info("[Bar] Spawning bars after river ready")
|
||||||
|
outputs = river.outputs
|
||||||
|
|
||||||
|
if not outputs:
|
||||||
|
logger.warning("[Bar] No outputs found — skipping bar spawn")
|
||||||
|
return
|
||||||
|
|
||||||
|
output_ids = sorted(outputs.keys())
|
||||||
|
|
||||||
|
for i, output_id in enumerate(output_ids):
|
||||||
|
bar = StatusBar(display=output_id, tray=tray if i == 0 else None, monitor=i)
|
||||||
|
bar_windows.append(bar)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
tray = SystemTray(name="system-tray", spacing=4)
|
|
||||||
river = get_river_connection()
|
|
||||||
|
|
||||||
dummy = Window(visible=False)
|
|
||||||
|
|
||||||
bar_windows = []
|
|
||||||
|
|
||||||
def spawn_bars():
|
|
||||||
logger.info("[Bar] Spawning bars after river ready")
|
|
||||||
outputs = river.outputs
|
|
||||||
|
|
||||||
if not outputs:
|
|
||||||
logger.warning("[Bar] No outputs found — skipping bar spawn")
|
|
||||||
return
|
|
||||||
|
|
||||||
output_ids = sorted(outputs.keys())
|
|
||||||
|
|
||||||
for i, output_id in enumerate(output_ids):
|
|
||||||
bar = StatusBar(display=output_id, tray=tray if i == 0 else None, monitor=i)
|
|
||||||
bar_windows.append(bar)
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
if river.ready:
|
if river.ready:
|
||||||
spawn_bars()
|
spawn_bars()
|
||||||
else:
|
else:
|
||||||
river.connect("notify::ready", lambda sender, pspec: spawn_bars())
|
river.connect("notify::ready", lambda sender, pspec: spawn_bars())
|
||||||
|
|
||||||
app = Application("bar", dummy)
|
|
||||||
app.set_stylesheet_from_file(get_relative_path("styles/main.css"))
|
|
||||||
app.run()
|
app.run()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ from fabric.utils import (
|
|||||||
)
|
)
|
||||||
from fabric.widgets.circularprogressbar import CircularProgressBar
|
from fabric.widgets.circularprogressbar import CircularProgressBar
|
||||||
|
|
||||||
|
from bar.config import VINYL
|
||||||
|
|
||||||
|
|
||||||
class StatusBar(Window):
|
class StatusBar(Window):
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -74,7 +76,9 @@ class StatusBar(Window):
|
|||||||
overlays=[self.cpu_progress_bar, self.progress_label],
|
overlays=[self.cpu_progress_bar, self.progress_label],
|
||||||
)
|
)
|
||||||
self.player = Player()
|
self.player = Player()
|
||||||
self.vinyl = VinylButton()
|
self.vinyl = None
|
||||||
|
if VINYL["enable"]:
|
||||||
|
self.vinyl = VinylButton()
|
||||||
|
|
||||||
self.status_container = Box(
|
self.status_container = Box(
|
||||||
name="widgets-container",
|
name="widgets-container",
|
||||||
@@ -83,11 +87,12 @@ class StatusBar(Window):
|
|||||||
children=self.progress_bars_overlay,
|
children=self.progress_bars_overlay,
|
||||||
)
|
)
|
||||||
|
|
||||||
end_container_children = [
|
end_container_children = []
|
||||||
self.vinyl,
|
|
||||||
self.status_container,
|
|
||||||
]
|
|
||||||
|
|
||||||
|
if self.vinyl:
|
||||||
|
end_container_children.append(self.vinyl)
|
||||||
|
|
||||||
|
end_container_children.append(self.status_container)
|
||||||
if self.system_tray:
|
if self.system_tray:
|
||||||
end_container_children.append(self.system_tray)
|
end_container_children.append(self.system_tray)
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,14 @@ class VinylButton(Box):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
active_command="""pw-link alsa_input.pci-0000_12_00.6.analog-stereo:capture_FL alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX0
|
active_command=[
|
||||||
pw-link alsa_input.pci-0000_12_00.6.analog-stereo:capture_FR alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX1""",
|
"pw-link alsa_input.pci-0000_12_00.6.analog-stereo:capture_FL alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX0",
|
||||||
inactive_command="""pw-link -d alsa_input.pci-0000_12_00.6.analog-stereo:capture_FL alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX0
|
"pw-link alsa_input.pci-0000_12_00.6.analog-stereo:capture_FR alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX1",
|
||||||
pw-link -d alsa_input.pci-0000_12_00.6.analog-stereo:capture_FR alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX1 """,
|
],
|
||||||
|
inactive_command=[
|
||||||
|
"pw-link -d alsa_input.pci-0000_12_00.6.analog-stereo:capture_FL alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX0",
|
||||||
|
"pw-link -d alsa_input.pci-0000_12_00.6.analog-stereo:capture_FR alsa_output.usb-BEHRINGER_UMC1820_A71E9E3E-00.multichannel-output:playback_AUX1 ",
|
||||||
|
],
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
@@ -80,13 +84,15 @@ pw-link -d alsa_input.pci-0000_12_00.6.analog-stereo:capture_FR alsa_output.usb-
|
|||||||
def _execute_active_command(self):
|
def _execute_active_command(self):
|
||||||
"""Execute shell command when button is activated"""
|
"""Execute shell command when button is activated"""
|
||||||
try:
|
try:
|
||||||
subprocess.Popen(self._active_command, shell=True)
|
for cmd in self._active_command:
|
||||||
|
subprocess.Popen(cmd, shell=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error executing active command: {e}")
|
print(f"Error executing active command: {e}")
|
||||||
|
|
||||||
def _execute_inactive_command(self):
|
def _execute_inactive_command(self):
|
||||||
"""Execute shell command when button is deactivated"""
|
"""Execute shell command when button is deactivated"""
|
||||||
try:
|
try:
|
||||||
subprocess.Popen(self._inactive_command, shell=True)
|
for cmd in self._inactive_command:
|
||||||
|
subprocess.Popen(cmd, shell=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error executing inactive command: {e}")
|
print(f"Error executing inactive command: {e}")
|
||||||
|
|||||||
75
bar/modules/window_fuzzy.py
Normal file
75
bar/modules/window_fuzzy.py
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import operator
|
||||||
|
from fabric.widgets.wayland import WaylandWindow as Window
|
||||||
|
from fabric.widgets.box import Box
|
||||||
|
from fabric.widgets.label import Label
|
||||||
|
from fabric.widgets.entry import Entry
|
||||||
|
from fabric.utils import idle_add
|
||||||
|
from gi.repository import Gdk
|
||||||
|
|
||||||
|
|
||||||
|
class FuzzyWindowFinder(Window):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
monitor: int = 0,
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
name="finder",
|
||||||
|
anchor="center",
|
||||||
|
monitor=monitor,
|
||||||
|
keyboard_mode="on-demand",
|
||||||
|
type="popup",
|
||||||
|
visible=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
self._all_windows = ["Test", "Uwu", "Tidal"]
|
||||||
|
|
||||||
|
self.viewport = Box(name="viewport", spacing=4, orientation="v")
|
||||||
|
|
||||||
|
self.search_entry = Entry(
|
||||||
|
name="search-entry",
|
||||||
|
placeholder="Search Windows...",
|
||||||
|
h_expand=True,
|
||||||
|
editable=True,
|
||||||
|
notify_text=self.notify_text,
|
||||||
|
on_activate=lambda entry, *_: self.on_search_entry_activate(
|
||||||
|
entry.get_text()
|
||||||
|
),
|
||||||
|
on_key_press_event=self.on_search_entry_key_press,
|
||||||
|
)
|
||||||
|
self.picker_box = Box(
|
||||||
|
name="picker-box",
|
||||||
|
spacing=4,
|
||||||
|
orientation="v",
|
||||||
|
children=[self.search_entry, self.viewport],
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add(self.picker_box)
|
||||||
|
self.arrange_viewport("")
|
||||||
|
|
||||||
|
def notify_text(self, entry, *_):
|
||||||
|
text = entry.get_text()
|
||||||
|
self.arrange_viewport(text) # Update list on typing
|
||||||
|
print(text)
|
||||||
|
|
||||||
|
def on_search_entry_key_press(self, widget, event):
|
||||||
|
# if event.keyval in (Gdk.KEY_Up, Gdk.KEY_Down, Gdk.KEY_Left, Gdk.KEY_Right):
|
||||||
|
# self.move_selection_2d(event.keyval)
|
||||||
|
# return True
|
||||||
|
print(event.keyval)
|
||||||
|
if event.keyval in [Gdk.KEY_Escape, 103]:
|
||||||
|
self.hide()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_search_entry_activate(self, text):
|
||||||
|
print(f"activate {text}")
|
||||||
|
|
||||||
|
def arrange_viewport(self, query: str = ""):
|
||||||
|
self.viewport.children = [] # Clear previous entries
|
||||||
|
|
||||||
|
filtered = [w for w in self._all_windows if query.lower() in w.lower()]
|
||||||
|
|
||||||
|
for window in filtered:
|
||||||
|
self.viewport.add(
|
||||||
|
Box(name="slot-box", orientation="h", children=[Label(label=window)])
|
||||||
|
)
|
||||||
29
bar/styles/finder.css
Normal file
29
bar/styles/finder.css
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#picker-box {
|
||||||
|
padding: 12px;
|
||||||
|
background-color: rgba(40, 40, 40, 0.95); /* darker for contrast */
|
||||||
|
border-radius: 8px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#viewport {
|
||||||
|
padding: 8px;
|
||||||
|
background-color: rgba(30, 30, 30, 0.9); /* dark background for contrast */
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
color: white; /* ensure contrast */
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewport > * {
|
||||||
|
padding: 6px 10px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
#viewport:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.15); /* hover feedback */
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
@import url("./menu.css");
|
@import url("./menu.css");
|
||||||
@import url("./vinyl.css");
|
@import url("./vinyl.css");
|
||||||
@import url("./bar.css");
|
@import url("./bar.css");
|
||||||
|
@import url("./finder.css");
|
||||||
|
|
||||||
|
|
||||||
/* unset so we can style everything from the ground up. */
|
/* unset so we can style everything from the ground up. */
|
||||||
|
|||||||
2
example.yaml
Normal file
2
example.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
vinyl:
|
||||||
|
enabled: true
|
||||||
56
flake.nix
56
flake.nix
@@ -32,7 +32,12 @@
|
|||||||
{
|
{
|
||||||
formatter = pkgs.nixfmt-rfc-style;
|
formatter = pkgs.nixfmt-rfc-style;
|
||||||
devShells.default = pkgs.callPackage ./nix/shell.nix { inherit pkgs; };
|
devShells.default = pkgs.callPackage ./nix/shell.nix { inherit pkgs; };
|
||||||
packages.default = pkgs.callPackage ./nix/derivation.nix { inherit (pkgs) lib python3Packages; };
|
packages = {
|
||||||
|
default = pkgs.callPackage ./nix/derivation.nix { inherit (pkgs) lib python3Packages; };
|
||||||
|
makku = pkgs.writeShellScriptBin "makku" ''
|
||||||
|
dbus-send --session --print-reply --dest=org.Fabric.fabric.bar /org/Fabric/fabric org.Fabric.fabric.Evaluate string:"finder.show()" > /dev/null 2>&1
|
||||||
|
'';
|
||||||
|
};
|
||||||
apps.default = {
|
apps.default = {
|
||||||
type = "app";
|
type = "app";
|
||||||
program = "${self.packages.${system}.default}/bin/bar";
|
program = "${self.packages.${system}.default}/bin/bar";
|
||||||
@@ -47,6 +52,11 @@
|
|||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.services.makku-bar;
|
||||||
|
|
||||||
|
settingsFormat = pkgs.formats.yaml { };
|
||||||
|
in
|
||||||
{
|
{
|
||||||
options.services.makku-bar = {
|
options.services.makku-bar = {
|
||||||
enable = lib.mkEnableOption "makku-bar status bar";
|
enable = lib.mkEnableOption "makku-bar status bar";
|
||||||
@@ -56,24 +66,44 @@
|
|||||||
default = self.packages.${pkgs.system}.default;
|
default = self.packages.${pkgs.system}.default;
|
||||||
description = "The makku-bar package to use.";
|
description = "The makku-bar package to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
vinyl = {
|
||||||
|
enable = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = {
|
||||||
|
vinyl.enable = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf config.services.makku-bar.enable {
|
config = lib.mkIf config.services.makku-bar.enable {
|
||||||
systemd.user.services.makku-bar = {
|
systemd.user.services.makku-bar =
|
||||||
Unit = {
|
let
|
||||||
Description = "Makku Status Bar";
|
configFile = settingsFormat.generate "config.yaml" cfg.settings;
|
||||||
After = [ "graphical-session.target" ];
|
in
|
||||||
};
|
{
|
||||||
|
Unit = {
|
||||||
|
Description = "Makku Status Bar";
|
||||||
|
After = [ "graphical-session.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
Service = {
|
Service = {
|
||||||
ExecStart = "${config.services.makku-bar.package}/bin/bar";
|
ExecStart = "${config.services.makku-bar.package}/bin/bar --config ${configFile}";
|
||||||
Restart = "on-failure";
|
Restart = "on-failure";
|
||||||
};
|
};
|
||||||
|
|
||||||
Install = {
|
Install = {
|
||||||
WantedBy = [ "default.target" ];
|
WantedBy = [ "default.target" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,10 +43,26 @@ python3Packages.buildPythonApplication {
|
|||||||
dependencies = with python3Packages; [
|
dependencies = with python3Packages; [
|
||||||
python-fabric
|
python-fabric
|
||||||
pywayland
|
pywayland
|
||||||
|
pyyaml
|
||||||
|
platformdirs
|
||||||
];
|
];
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
dontWrapGApps = true;
|
dontWrapGApps = true;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
mkdir -p $out/${python3Packages.python.sitePackages}
|
||||||
|
cp -r bar $out/${python3Packages.python.sitePackages}/
|
||||||
|
|
||||||
|
# If you have any scripts to install
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp scripts/launcher.py $out/bin/bar
|
||||||
|
chmod +x $out/bin/bar
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
|
||||||
preFixup = ''
|
preFixup = ''
|
||||||
makeWrapperArgs+=("''${gappsWrapperArgs[@]}")
|
makeWrapperArgs+=("''${gappsWrapperArgs[@]}")
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ pkgs.mkShell {
|
|||||||
wayland-scanner
|
wayland-scanner
|
||||||
wayland
|
wayland
|
||||||
wayland-protocols
|
wayland-protocols
|
||||||
|
playerctl
|
||||||
|
|
||||||
(python3.withPackages (
|
(python3.withPackages (
|
||||||
ps: with ps; [
|
ps: with ps; [
|
||||||
setuptools
|
setuptools
|
||||||
@@ -39,6 +41,8 @@ pkgs.mkShell {
|
|||||||
pylsp-mypy
|
pylsp-mypy
|
||||||
pyls-isort
|
pyls-isort
|
||||||
python-lsp-ruff
|
python-lsp-ruff
|
||||||
|
pyyaml
|
||||||
|
platformdirs
|
||||||
]
|
]
|
||||||
))
|
))
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -14,14 +14,11 @@ description = "Fabric using Nix example."
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = {file = "LICENSE"}
|
license = {file = "LICENSE"}
|
||||||
|
|
||||||
[project.scripts]
|
|
||||||
bar = "bar.main:main"
|
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
include-package-data = true
|
include-package-data = true
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages]
|
||||||
where = ["."]
|
find = { namespaces = true }
|
||||||
|
|
||||||
[tool.setuptools.package-data]
|
[tool.setuptools.package-data]
|
||||||
"*" = ["*.css", "styles"]
|
"*" = ["*.css", "styles"]
|
||||||
|
|||||||
21
scripts/launcher.py
Normal file
21
scripts/launcher.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
site_packages_dir = os.path.join(
|
||||||
|
script_dir,
|
||||||
|
os.pardir,
|
||||||
|
"lib",
|
||||||
|
f"python{sys.version_info.major}.{sys.version_info.minor}",
|
||||||
|
"site-packages",
|
||||||
|
)
|
||||||
|
|
||||||
|
if site_packages_dir not in sys.path:
|
||||||
|
sys.path.insert(0, site_packages_dir)
|
||||||
|
|
||||||
|
|
||||||
|
from bar.main import *
|
||||||
|
|
||||||
|
sys.argv[0] = os.path.join(script_dir, os.path.basename(__file__))
|
||||||
|
sys.exit(main())
|
||||||
Reference in New Issue
Block a user