FIrst pass at allow external plugins

This commit is contained in:
MinchinWeb 2020-12-13 21:28:19 -07:00
parent 1714d1eeef
commit e25869e9bc
18 changed files with 113 additions and 76 deletions

View file

@ -462,7 +462,7 @@ def run(context, command, text=""):
def load_template(context, filename):
full_path = os.path.join("features/data/templates", filename)
exporter = plugins.template_exporter.__exporter_from_file(full_path)
plugins.__exporter_types[exporter.names[0]] = exporter
plugins.meta.__exporter_types[exporter.names[0]] = exporter
@when('we set the keyring password of "{journal}" to "{password}"')

View file

@ -12,9 +12,9 @@ from .commands import postconfig_list
from .commands import preconfig_diagnostic
from .commands import preconfig_version
from .output import deprecated_cmd
from .plugins import EXPORT_FORMATS
from .plugins import IMPORT_FORMATS
from .plugins import util
from .plugins.meta import EXPORT_FORMATS
from .plugins.meta import IMPORT_FORMATS
class WrappingFormatter(argparse.RawTextHelpFormatter):

View file

@ -47,7 +47,7 @@ def postconfig_list(config, **kwargs):
def postconfig_import(args, config, **kwargs):
from .Journal import open_journal
from .plugins import get_importer
from .plugins.meta import get_importer
# Requires opening the journal
journal = open_journal(args.journal_name, config)

View file

View file

View file

@ -330,13 +330,13 @@ def _display_search_results(args, journal, **kwargs):
print(journal.pprint())
elif args.tags:
print(plugins.get_exporter("tags").export(journal))
print(plugins.meta.get_exporter("tags").export(journal))
elif args.export:
exporter = plugins.get_exporter(args.export)
exporter = plugins.meta.get_exporter(args.export)
print(exporter.export(journal, args.filename))
elif kwargs["config"].get("display_format"):
exporter = plugins.get_exporter(kwargs["config"]["display_format"])
exporter = plugins.meta.get_exporter(kwargs["config"]["display_format"])
print(exporter.export(journal, args.filename))
else:
print(journal.pprint())

View file

@ -1,49 +1,5 @@
#!/usr/bin/env python
# encoding: utf-8
# Copyright (C) 2012-2021 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
from .fancy_exporter import FancyExporter
from .jrnl_importer import JRNLImporter
from .json_exporter import JSONExporter
from .markdown_exporter import MarkdownExporter
from .tag_exporter import TagExporter
from .dates_exporter import DatesExporter
from .template_exporter import __all__ as template_exporters
from .text_exporter import TextExporter
from .xml_exporter import XMLExporter
from .yaml_exporter import YAMLExporter
__exporters = [
JSONExporter,
MarkdownExporter,
TagExporter,
DatesExporter,
TextExporter,
XMLExporter,
YAMLExporter,
FancyExporter,
] + template_exporters
__importers = [JRNLImporter]
__exporter_types = {name: plugin for plugin in __exporters for name in plugin.names}
__exporter_types["pretty"] = None
__exporter_types["short"] = None
__importer_types = {name: plugin for plugin in __importers for name in plugin.names}
EXPORT_FORMATS = sorted(__exporter_types.keys())
IMPORT_FORMATS = sorted(__importer_types.keys())
def get_exporter(format):
for exporter in __exporters:
if hasattr(exporter, "names") and format in exporter.names:
return exporter
return None
def get_importer(format):
for importer in __importers:
if hasattr(importer, "names") and format in importer.names:
return importer
return None

View file

@ -5,10 +5,10 @@
from textwrap import TextWrapper
from .text_exporter import TextExporter
from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter
class FancyExporter(TextExporter):
class Exporter(TextExporter):
"""This Exporter can convert entries and journals into text with unicode box drawing characters."""
names = ["fancy", "boxed"]

View file

@ -5,11 +5,11 @@
import json
from .text_exporter import TextExporter
from .util import get_tags_count
from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter
from jrnl.plugins.util import get_tags_count
class JSONExporter(TextExporter):
class Exporter(TextExporter):
"""This Exporter can convert entries and journals into json."""
names = ["json"]

View file

@ -9,11 +9,10 @@ import sys
from jrnl.color import RESET_COLOR
from jrnl.color import WARNING_COLOR
from .text_exporter import TextExporter
from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter
class MarkdownExporter(TextExporter):
class Exporter(TextExporter):
"""This Exporter can convert entries and journals into Markdown."""
names = ["md", "markdown"]

View file

@ -3,11 +3,11 @@
# Copyright (C) 2012-2021 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
from .text_exporter import TextExporter
from .util import get_tags_count
from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter
from jrnl.plugins.util import get_tags_count
class TagExporter(TextExporter):
class Exporter(TextExporter):
"""This Exporter can lists the tags for entries and journals, exported as a plain text file."""
names = ["tags"]

View file

@ -11,7 +11,7 @@ from jrnl.color import ERROR_COLOR
from jrnl.color import RESET_COLOR
class TextExporter:
class Exporter:
"""This Exporter can convert entries and journals into text files."""
names = ["text", "txt"]

View file

@ -5,11 +5,11 @@
from xml.dom import minidom
from .json_exporter import JSONExporter
from .util import get_tags_count
from jrnl.plugins.exporter.json_exporter import Exporter as JSONExporter
from jrnl.plugins.util import get_tags_count
class XMLExporter(JSONExporter):
class Exporter(JSONExporter):
"""This Exporter can convert entries and journals into XML."""
names = ["xml"]

View file

@ -10,11 +10,10 @@ import sys
from jrnl.color import ERROR_COLOR
from jrnl.color import RESET_COLOR
from jrnl.color import WARNING_COLOR
from .text_exporter import TextExporter
from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter
class YAMLExporter(TextExporter):
class Exporter(TextExporter):
"""This Exporter can convert entries and journals into Markdown formatted text with YAML front matter."""
names = ["yaml"]

View file

@ -6,7 +6,7 @@
import sys
class JRNLImporter:
class Importer:
"""This plugin imports entries from other jrnl files."""
names = ["jrnl"]

84
jrnl/plugins/meta.py Normal file
View file

@ -0,0 +1,84 @@
#!/usr/bin/env python
# encoding: utf-8
import importlib
import pkgutil
import jrnl.contrib.exporter
import jrnl.contrib.importer
import jrnl.plugins.exporter
import jrnl.plugins.importer
from .template_exporter import __all__ as template_exporters
__exporters_builtin = list(
pkgutil.iter_modules(
jrnl.plugins.exporter.__path__, jrnl.plugins.exporter.__name__ + "."
)
)
__exporters_contrib = list(
pkgutil.iter_modules(
jrnl.contrib.exporter.__path__, jrnl.contrib.exporter.__name__ + "."
)
)
__importers_builtin = list(
pkgutil.iter_modules(
jrnl.plugins.importer.__path__, jrnl.plugins.importer.__name__ + "."
)
)
__importers_contrib = list(
pkgutil.iter_modules(
jrnl.contrib.importer.__path__, jrnl.contrib.importer.__name__ + "."
)
)
__exporter_types_builtin = {
name: importlib.import_module(plugin.name)
for plugin in __exporters_builtin
for name in importlib.import_module(plugin.name).Exporter.names
}
__exporter_types_contrib = {
name: importlib.import_module(plugin.name)
for plugin in __exporters_contrib
for name in importlib.import_module(plugin.name).Exporter.names
}
__exporter_types_template = {
name: plugin for plugin in template_exporters for name in plugin.names
}
__importer_types_builtin = {
name: importlib.import_module(plugin.name)
for plugin in __importers_builtin
for name in importlib.import_module(plugin.name).Importer.names
}
__importer_types_contrib = {
name: importlib.import_module(plugin.name)
for plugin in __importers_contrib
for name in importlib.import_module(plugin.name).Importer.names
}
__exporter_types = {
**__exporter_types_builtin,
**__exporter_types_contrib,
**__exporter_types_template,
}
__importer_types = {**__importer_types_builtin, **__importer_types_contrib}
EXPORT_FORMATS = sorted(__exporter_types.keys())
IMPORT_FORMATS = sorted(__importer_types.keys())
def get_exporter(format):
for exporter in __exporters:
if hasattr(exporter, "names") and format in exporter.names:
return exporter
return None
def get_importer(format):
for importer in __importers:
if hasattr(importer, "names") and format in importer.names:
return importer
return None

View file

@ -6,8 +6,8 @@
from glob import glob
import os
from .template import Template
from .text_exporter import TextExporter
from jrnl.plugins.template import Template
from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter
class GenericTemplateExporter(TextExporter):
@ -31,7 +31,7 @@ def __exporter_from_file(template_file):
name = os.path.basename(template_file).replace(".template", "")
template = Template.from_file(template_file)
return type(
str(f"{name.title()}Exporter"),
str(f"{name.title()}TemplateExporter"),
(GenericTemplateExporter,),
{"names": [name], "extension": template.extension, "template": template},
)

View file

@ -3,11 +3,10 @@
# Copyright (C) 2012-2021 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html
def get_tags_count(journal):
"""Returns a set of tuples (count, tag) for all tags present in the journal."""
# Astute reader: should the following line leave you as puzzled as me the first time
# I came across this construction, worry not and embrace the ensuing moment of enlightment.
# I came across this construction, worry not and embrace the ensuing moment of enlightenment.
tags = [tag for entry in journal.entries for tag in set(entry.tags)]
# To be read: [for entry in journal.entries: for tag in set(entry.tags): tag]
tag_counts = {(tags.count(tag), tag) for tag in tags}