Initial commit with some skeleton functionality

main
Sergio Alvariño 2 years ago
parent c4094f6019
commit 03475d4b04

@ -0,0 +1,8 @@
# This is mach5 config
[General]
# default_menu_file = ~/.config/mach5/menu.yml
default_menu_file = ./etc/menu.yml
# root window title and geometry
rtitle = Mach5
rgeometry = 300x600

@ -0,0 +1,22 @@
name: Principal
sc: null
entries:
- cmd: gimp
name: Gimp
sc: g
- cmd: inkscape
name: Inkscape
sc: i
- name: Ideas
sc: j
entries:
- cmd: ~/apps/Treesheets/current
name: Treesheets
sc: t
- cmd: ~/apps/freeplane/current
name: Freeplane
sc: f
- name: Emacs
sc: e
cmd: emacs

48
mach5

@ -0,0 +1,48 @@
#!/usr/bin/env python
import argparse
from configparser import ConfigParser, ExtendedInterpolation
import os
import errno
import machlib.menu as mm
# default_configuration_file = "~/.config/mach5/config.ini"
_default_configuration_file = "./etc/config.ini"
# _default_menu_file = "~/.config/mach5/menu.yml"
_default_menu_file = "./etc/menu.yml"
# -------------------- MAIN --------------------
# Parse command line options
arg_parser = argparse.ArgumentParser(
description='Our simple chords application')
arg_parser.add_argument('-c', '--cfg',
help='Config ini file',
default=_default_configuration_file)
arg_parser.add_argument('-m', '--menu',
help='Menu yaml file',
default=_default_menu_file)
args = arg_parser.parse_args()
# Load configuration file
_configuration = ConfigParser(interpolation=ExtendedInterpolation())
found = _configuration.read(os.path.expanduser(args.cfg))
if (not found):
print('[ERROR] Config file not found')
raise FileNotFoundError(errno.ENOENT,
os.strerror(errno.ENOENT), args.cfg)
menu = mm.Menu.from_file(args.menu)
print(menu)
print(menu.get_entries().keys())
for v in menu.get_entries().values():
print(f" {v}")
print(f"Len is {len(menu)}")
print ("-"*10)
for i in menu:
print(i)

@ -0,0 +1,119 @@
"""Implement Mach5 menus."""
import os
import errno
import yaml
from collections import OrderedDict
import subprocess
def get_data_from(menu_file):
"""Get menu data from a yaml menu definition file."""
menu_file = os.path.expanduser(menu_file)
if not os.path.exists(menu_file):
raise FileNotFoundError(errno.ENOENT,
os.strerror(errno.ENOENT), menu_file)
with open(menu_file, 'r') as yaml_file:
menu_data = yaml.safe_load(yaml_file)
#######################################################################
# WARNING #
# yaml.safe_load does NOT return and OrderedDict #
# so far, dict in Python are ordered, but IT CAN CHANGE #
#######################################################################
if 'entries' not in menu_data:
raise ValueError(f"Malformed file {menu_file}.\
First entry is not a menu")
return menu_data
class Command:
"""A Mach5 command."""
def __init__(self, cmd_data):
"""Construct a Mach5 command object."""
if len(cmd_data['sc']) != 1:
raise ValueError(f"Shortcut must be only one character.\
{cmd_data['sc']} is invalid.")
self._name = cmd_data['name']
self._cmd = cmd_data['cmd']
self._sc = cmd_data['sc']
def show(self):
"""Return string for Command."""
return f"{self._sc} - {self._name}"
def __repr__(self):
"""Return representation string for Command object."""
return f"{self._sc!r} - {self._name!r} - {self._cmd!r}"
def __str__(self):
"""Return string conversion for command."""
return f"{self._sc} - {self._name}"
def execute(self):
"""Execute command."""
print(f"Execute command {self._name}")
subprocess.Popen(os.path.expanduser(self._cmd))
class Menu:
"""A Mach5 menu class."""
def __init__(self, menu_data):
"""Init a menu object instance from a menu data dict."""
self._name = menu_data['name']
self._entries = OrderedDict()
self._sc = menu_data['sc']
for e in menu_data['entries']:
if e['sc'] in self._entries:
raise ValueError(f"Repeated shortcut {e['sc']}")
if 'entries' in e:
self._entries[e['sc']] = Menu(e)
else:
self._entries[e['sc']] = Command(e)
def __len__(self):
"""Return number of items in menu."""
return len(self._entries)
def __iter__(self):
return MenuIter(self)
def from_file(path):
"""Return a Menu instance from menu definition file."""
return Menu(get_data_from(path))
def __repr__(self):
"""Return repr string for menu object."""
return f"{self._sc!r} - {self._name!r}"
def __str__(self):
"""Return string conversion for menu."""
if self._sc:
return f"{self._sc} - {self._name}"
else:
return f"{self._name}"
def get_entries(self):
"""Return entries for menu instance."""
return self._entries
class MenuIter:
"""A helper class to make iterables Menu objects"""
def __init__(self, menu):
"""Return an iterable menu"""
self._entries = menu.get_entries()
self._current = 0
def __iter__(self):
return self
def __next__(self):
if self._current < len(self._entries):
item = self._entries[self._current]
self._current += 1
return item
raise StopIteration

@ -0,0 +1 @@
PyYAML==6.0
Loading…
Cancel
Save