Skip to content

Commit

Permalink
Merge pull request #87 from t00m/0.0.51
Browse files Browse the repository at this point in the history
Bump version to 0.0.99
  • Loading branch information
t00m authored Jul 25, 2024
2 parents c5c07ab + 70c99f6 commit 004e0ca
Show file tree
Hide file tree
Showing 28 changed files with 174 additions and 191 deletions.
12 changes: 9 additions & 3 deletions MiAZ/backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def load(self, filepath: str) -> dict:
items = []
return items
else:
# ~ self.log.debug(f"Loading {self.config_for} items from cache ({filepath})")
self.log.trace(f"Loading {self.config_for} items from cache ({filepath})")
self.cache[filepath]['changed'] = False
return self.cache[filepath]['items']

Expand Down Expand Up @@ -227,10 +227,16 @@ def remove_used_batch(self, keys: list):
self.remove_batch(self.used, keys)

def remove_available(self, key: str):
self.remove(self.available, key)
updated = self.remove(self.available, key)
if updated:
self.emit('available-updated')
return updated

def remove_used(self, key: str) -> bool:
return self.remove(self.used, key)
updated = self.remove(self.used, key)
if updated:
self.emit('used-updated')
return updated

def remove_batch(self, filepath: str, keys: list):
# FIXME: check del operation
Expand Down
31 changes: 11 additions & 20 deletions MiAZ/backend/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,24 @@
import sys
import datetime
import logging
from enum import Enum

# Define new trace level
TRACE = logging.DEBUG - 1
setattr(logging, "TRACE", TRACE)
logging.addLevelName(TRACE, "TRACE")


class DebugLevel(int, Enum):
NONE = 0
DEFAULT = 1
TRACE = 2
SUPERTRACE = 3


GREY = "\x1b[38;21m"
CYAN = "\x1b[36;21m"
MAUVE = "\x1b[34;21m"
YELLOW = "\x1b[33;21m"
RED = "\x1b[31;21m"
# Define colors
GREY = "\x1b[38;20m"
CYAN = "\x1b[36;20m"
MAUVE = "\x1b[34;20m"
YELLOW = "\x1b[33;20m"
RED = "\x1b[31;20m"
BOLD_RED = "\x1b[31;1m"
RESET = "\x1b[0m"


def make_format(color):
return f"{color}%(levelname)s{RESET}: %(name)s: %(message)s"

return f"{color}%(levelname)7s | %(lineno)4d |%(name)-25s | %(asctime)s | %(message)s{RESET}"

FORMATS = {
logging.TRACE: make_format(MAUVE), # type: ignore
Expand Down Expand Up @@ -96,17 +88,16 @@ def __init__(self, name='MiAZ', log_dir=None):
C0116: Missing function or method docstring (missing-function-docstring)
"""
super().__init__(name)
# ~ print(dir(self.root))
# ~ exit()

# Create custom logger logging all five levels
self.setLevel(logging.DEBUG)
self.setLevel(logging.TRACE)

# Create stream handler for logging to stdout (log all five levels)
if self.stdout_handler is None:
self.stdout_handler = logging.StreamHandler(sys.stdout)
# ~ self.stdout_handler.setLevel(logging.TRACE)
self.stdout_handler.setLevel(logging.DEBUG)
self.stdout_handler.setFormatter(logging.Formatter("%(levelname)7s | %(lineno)4d |%(name)-25s | %(asctime)s | %(message)s"))
self.stdout_handler.setFormatter(ColorFormatter()) #logging.Formatter("%(levelname)7s | %(lineno)4d |%(name)-25s | %(asctime)s | %(message)s"))
self.enable_console_output()

# Add file handler only if the log directory was specified
Expand Down
105 changes: 63 additions & 42 deletions MiAZ/backend/pluginsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,45 +64,64 @@ def import_plugin(self, plugin_path):
"""
Import plugin in the user space.
"A plugin zip file is valid if:
- Contains only 2 files
- Their names are identical
- Extensions are .plugin and .py
- Contains at least 2 files
- Their names are identical
- Extensions are .plugin and .py
- Their names are the same than the plugin name
- Optionally, a directory named resources
- with a subdirectory with the same name as the plugin
Eg.:
hello.zip
├── hello.plugin
├── hello.py
└── resources
└── hello
└── css
└── noprint.css
"""
utils = self.app.get_service('util')
valid = False
azip = zipfile.ZipFile(plugin_path)
files = azip.namelist()
if len(files) == 2:
fn1_name, fn1_ext = self.util.filename_details(files[0])
fn2_name, fn2_ext = self.util.filename_details(files[1])
if fn1_name == fn2_name:
if fn1_ext == 'py' and fn2_ext == 'plugin':
valid = True
elif fn1_ext == 'plugin' and fn2_ext == 'py':
valid = True
if valid:
ENV = self.app.get_env()
azip.extractall(ENV['LPATH']['PLUGINS'])
self.engine.rescan_plugins()
config = self.app.get_config('Plugin')
config.add_available(key=fn1_name)
plugin_fname = os.path.basename(plugin_path)
self.log.debug(f"Plugin '{plugin_fname}' added to 'ENV['LPATH']['PLUGINS']'")
plugin_name, plugin_ext = utils.filename_details(plugin_path)
plugin_code = f"{plugin_name}.py"
plugin_meta = f"{plugin_name}.plugin"
plugin_code_exist = plugin_code in azip.namelist()
plugin_meta_exist = plugin_meta in azip.namelist()
if plugin_code_exist and plugin_meta_exist:
valid = True

if valid:
ENV = self.app.get_env()
azip.extractall(ENV['LPATH']['PLUGINS'])
self.engine.rescan_plugins()
config = self.app.get_config('Plugin')
config.add_available(key=plugin_name)
plugin_fname = os.path.basename(plugin_path)
self.log.debug(f"Plugin '{plugin_fname}' added to '{ENV['LPATH']['PLUGINS']}'")
# ~ self.emit('plugins-updated')
return valid

def remove_plugin(self, plugin: Peas.PluginInfo):
"""Remove plugin for user space plugins"""
# FIXME: Make sure the plugin is deleted and unloaded
ENV = self.app.get_env()
module = plugin.get_module_name()
self.unload_plugin(plugin)
plugin_head = os.path.join(ENV['LPATH']['PLUGINS'], f'{module}.plugin')
plugin_body = os.path.join(ENV['LPATH']['PLUGINS'], f'{module}.py')
os.unlink(plugin_head)
os.unlink(plugin_body)
config = self.app.get_config('Plugin')
config.remove_available(key=module)
return True
module = plugin.get_module_name()
if not config.exists_used(module):
self.log.debug(f"Plugin '{module}' is not being used and will be deleted")
utils = self.app.get_service('util')
ENV = self.app.get_env()
self.unload_plugin(plugin)
plugin_head = os.path.join(ENV['LPATH']['PLUGINS'], f'{module}.plugin')
plugin_body = os.path.join(ENV['LPATH']['PLUGINS'], f'{module}.py')
os.unlink(plugin_head)
os.unlink(plugin_body)
plugin_res = os.path.join(ENV['LPATH']['PLUGRES'], module)
utils.directory_remove(plugin_res)
config.remove_available(key=module)
return True
else:
self.log.warning(f"Plugin {module} can't be deleted because it is still in use")
return False

def rescan_plugins(self):
try:
Expand All @@ -114,25 +133,31 @@ def rescan_plugins(self):

def load_plugin(self, plugin: Peas.PluginInfo) -> bool:
ptype = self.get_plugin_type(plugin)
pname = plugin.get_name()
pvers = plugin.get_version()
# ~ pinfo = self.get_plugin_info(plugin)
try:
self.engine.load_plugin(plugin)

if plugin.is_loaded():
self.log.debug(f"Plugin {plugin.get_name()} ({ptype}) loaded")

self.log.debug(f"Plugin {pname} v{pvers} ({ptype}) loaded")
return True
else:
self.log.error(f"Plugin {plugin.get_name()} ({ptype}) couldn't be loaded")
self.log.error(f"Plugin {pname} v{pvers} ({ptype}) couldn't be loaded")
return False
except Exception as error:
self.log.error(error)
self.log.error("Plugin {plugin.get_name()} ({ptype}) couldn't be loaded")
self.log.error("Plugin {pname} v{pvers} ({ptype}) couldn't be loaded")
return False

def unload_plugin(self, plugin: Peas.PluginInfo):
try:
ptype = self.get_plugin_type(plugin)
pname = plugin.get_name()
pvers = plugin.get_version()
self.engine.unload_plugin(plugin)
self.log.debug(f"Plugin {plugin.get_name()} ({ptype}) unloaded")
self.log.debug(f"Plugin {pname} v{pvers} ({ptype}) unloaded")
except Exception as error:
self.log.error(error)

Expand Down Expand Up @@ -208,14 +233,10 @@ def _setup_plugins_dir(self):
# User plugins
# All user space plugins are available for all repositories
# However, each repository can use none, any or all of them

# FIXME: User plugins disabled temporary
# ~ if not os.path.exists(ENV['LPATH']['PLUGINS']):
# ~ os.makedirs(ENV['LPATH']['PLUGINS'], exist_ok=True)
# ~ self.engine.add_search_path(ENV['LPATH']['PLUGINS'])
# ~ self.log.debug(f"Added user plugins dir: {ENV['LPATH']['PLUGINS']}")


if not os.path.exists(ENV['LPATH']['PLUGINS']):
os.makedirs(ENV['LPATH']['PLUGINS'], exist_ok=True)
self.engine.add_search_path(ENV['LPATH']['PLUGINS'])
self.log.debug(f"Added user plugins dir: {ENV['LPATH']['PLUGINS']}")

@staticmethod
def __extension_removed_cb(unused_set, unused_plugin_info, extension):
Expand Down
13 changes: 13 additions & 0 deletions MiAZ/backend/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import shutil
import tempfile
import traceback
import mimetypes
import zipfile
from datetime import datetime, timedelta
# ~ from dateutil.parser import parse as dateparser
Expand All @@ -27,6 +28,8 @@
from MiAZ.backend.models import Purpose, SentBy
from MiAZ.backend.models import SentTo, Date

mimetypes.init()

Field = {}
Field[Date] = 0
Field[Country] = 1
Expand Down Expand Up @@ -100,6 +103,16 @@ def field_used(self, repo_dir, item_type, value):
used = True
return used, docs

def get_mimetype(self, filename: str) -> str:
if sys.platform == 'win32':
name, ext = self.filename_details(filename)
mimetype = f'.{ext}'
else:
url = f"file://{filename}"
mimetype, encoding = mimetypes.guess_type(url)
return mimetype


def get_temp_dir(self):
ENV = self.app.get_env()
ts = datetime.now().strftime('%Y%m%d_%H%M%S')
Expand Down
29 changes: 18 additions & 11 deletions MiAZ/frontend/desktop/services/dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def create( self,
height: int = -1,
):

factory = self.app.get_service('factory')
icm = self.app.get_service('icons')

# Build dialog
Expand All @@ -62,9 +63,10 @@ def create( self,
destroy_with_parent=False,
modal=True,
message_type=miaz_dialog[dtype]['type'],
secondary_text=body,
secondary_use_markup=True,
# ~ secondary_text=body,
# ~ secondary_use_markup=True,
buttons=miaz_dialog[dtype]['buttons'])
dialog.set_property('secondary-use-markup', True)

# FIXME: Set custom size
# ~ self.log.debug(f"Setting dialog size to {width}x{height}")
Expand All @@ -80,18 +82,23 @@ def create( self,
header.set_title_widget(lblTitle)
dialog.set_titlebar(header)

message_area = dialog.get_message_area()
message_area.set_visible(False)
content_area = dialog.get_content_area()

# Add body
if len(body) > 0:
box = factory.create_box_vertical(margin=12)
label = Gtk.Label()
label.get_style_context().add_class(class_name='toolbar')
label.set_markup(body)
box.append(label)
content_area.append(child=box)

# Add custom widget
if widget is not None:
dialog.set_default_size(width, height)
message_area = dialog.get_message_area()
if len(body) > 0:
message_area.set_visible(True)
message_area.set_vexpand(False)
message_area.set_margin_bottom(12)
else:
message_area.set_visible(False)
content_area = dialog.get_content_area()
content_area.set_spacing(0)
content_area.set_spacing(6)
content_area.append(child=widget)

# Assign callback, if any. Otherwise, default is closing.
Expand Down
7 changes: 4 additions & 3 deletions MiAZ/frontend/desktop/widgets/configview.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,10 @@ def __init__(self, app):
def plugins_updated(self, *args):
self._update_view_available()

# ~ def update_views(self, *args):
# ~ self._update_view_available()
# ~ self._update_view_used()

def _setup_view_finish(self):
# Setup Available and Used Column Views
self.viewAv = MiAZColumnViewPlugin(self.app)
Expand Down Expand Up @@ -484,7 +488,4 @@ def _on_item_used_add(self, *args):
else:
self.log.debug(f"{i_title} {selected_plugin.id} is already being used")

def update_views(self, *args):
# ~ self.log.debug("Update user plugin views")
pass

Loading

0 comments on commit 004e0ca

Please sign in to comment.