mirror of
https://github.com/jrnl-org/jrnl.git
synced 2025-05-19 04:28:31 +02:00
improved code documentation
This commit is contained in:
parent
2a70636b4d
commit
f22d985330
3 changed files with 68 additions and 10 deletions
|
@ -3,14 +3,33 @@
|
||||||
|
|
||||||
# Extending jrnl
|
# Extending jrnl
|
||||||
|
|
||||||
jrnl can be extended with custom importers and exporters.
|
*jrnl* can be extended with custom importers and exporters.
|
||||||
|
|
||||||
Note that custom importers and exporters can be given the same name as a
|
Note that custom importers and exporters can be given the same name as a
|
||||||
built-in importer or exporter to override it.
|
built-in importer or exporter to override it.
|
||||||
|
|
||||||
Custom Importers and Exporters are traditional Python packages, and are
|
Custom Importers and Exporters are traditional Python packages, and are
|
||||||
installed (into jrnl) simply by installing them so they are available to the
|
installed (into *jrnl*) simply by installing them so they are available to the
|
||||||
Python interpreter that is running jrnl.
|
Python interpreter that is running *jrnl*.
|
||||||
|
|
||||||
|
Exporter are also used as "formatters" when entries are written to the command
|
||||||
|
line.
|
||||||
|
|
||||||
|
## Rational
|
||||||
|
|
||||||
|
I added this feature because *jrnl* was overall working well for me, but I
|
||||||
|
found myself maintaining a private fork so I could have a slightly customized
|
||||||
|
export format. Implemeneting (import and) export plugins was seen as a way to
|
||||||
|
maintain my custom exporter without the need to maintaining my private fork.
|
||||||
|
|
||||||
|
This implementation tries to keep plugins as light as possible, and as free of
|
||||||
|
boilerplate code as reasonable. As well, internal importers and exporters are
|
||||||
|
implemented in almost exactly the same way as custom importers and exporters,
|
||||||
|
and so it is hoped that plugins can be moved from "contributed" to "internal"
|
||||||
|
easily, or that internal plugins can serve as a base and/or a demonstration for
|
||||||
|
external plugins.
|
||||||
|
|
||||||
|
-- @MinchinWeb, May 2021
|
||||||
|
|
||||||
## Entry Class
|
## Entry Class
|
||||||
|
|
||||||
|
@ -63,7 +82,9 @@ Some implementation notes:
|
||||||
- The importer class must be named **Importer**, and should sub-class
|
- The importer class must be named **Importer**, and should sub-class
|
||||||
**jrnl.plugins.base.BaseImporter**.
|
**jrnl.plugins.base.BaseImporter**.
|
||||||
- The importer module must be within the **jrnl.contrib.importer** namespace.
|
- The importer module must be within the **jrnl.contrib.importer** namespace.
|
||||||
- The importer must not have any `__init__.py` files in the base directories.
|
- The importer must not have any `__init__.py` files in the base directories
|
||||||
|
(but you can have one for your importer base directory if it is in a
|
||||||
|
directory rather than a single file).
|
||||||
- The importer must be installed as a Python package available to the same
|
- The importer must be installed as a Python package available to the same
|
||||||
Python interpreter running jrnl.
|
Python interpreter running jrnl.
|
||||||
- The importer must expose at least the following the following members:
|
- The importer must expose at least the following the following members:
|
||||||
|
@ -85,7 +106,7 @@ generator or blogging engine.
|
||||||
|
|
||||||
An exporter take either a whole journal or a specific entry and exports it.
|
An exporter take either a whole journal or a specific entry and exports it.
|
||||||
Below is a basic JSON Exporter; note that a more extensive JSON exporter is
|
Below is a basic JSON Exporter; note that a more extensive JSON exporter is
|
||||||
included in jrnl and so this (if installed) would override the built in
|
included in *jrnl* and so this (if installed) would override the built in
|
||||||
exporter.
|
exporter.
|
||||||
|
|
||||||
~~~ python
|
~~~ python
|
||||||
|
@ -103,7 +124,9 @@ Some implementation notes:
|
||||||
- the exporter class must be named **Exporter** and should sub-class
|
- the exporter class must be named **Exporter** and should sub-class
|
||||||
**jrnl.plugins.base.BaseExporter**.
|
**jrnl.plugins.base.BaseExporter**.
|
||||||
- the exporter module must be within the **jrnl.contrib.exporter** namespace.
|
- the exporter module must be within the **jrnl.contrib.exporter** namespace.
|
||||||
- The exporter must not have any `__init__.py` files in the base directories.
|
- The exporter must not have any `__init__.py` files in the base directories
|
||||||
|
(but you can have one for your exporter base directory if it is in a
|
||||||
|
directory rather than a single file).
|
||||||
- The exporter must be installed as a Python package available to the same
|
- The exporter must be installed as a Python package available to the same
|
||||||
Python interpreter running jrnl.
|
Python interpreter running jrnl.
|
||||||
- the exporter should expose at least the following the following members
|
- the exporter should expose at least the following the following members
|
||||||
|
@ -118,11 +141,16 @@ Some implementation notes:
|
||||||
- **extension** (string): the file extention used on exported entries.
|
- **extension** (string): the file extention used on exported entries.
|
||||||
- **export_entry(entry)**: given an entry, returns a string of the formatted,
|
- **export_entry(entry)**: given an entry, returns a string of the formatted,
|
||||||
exported entry.
|
exported entry.
|
||||||
- **export_journal(journal)**: given a journal, returns a string of the
|
- **export_journal(journal)**: (optional) given a journal, returns a string
|
||||||
formatted, exported entries of the journal.
|
of the formatted, exported entries of the journal. If not implemented,
|
||||||
|
*jrnl* will call **export_entry()** on each entry in turn and then
|
||||||
|
concatenate the results together.
|
||||||
|
|
||||||
## Development Tips
|
## Development Tips
|
||||||
|
|
||||||
- editable installs (`pip install -e ...`) don't seem to play nice with
|
- editable installs (`pip install -e ...`) don't seem to play nice with
|
||||||
the namespace layout. If your plugin isn't appearing, try a non-editable
|
the namespace layout. If your plugin isn't appearing, try a non-editable
|
||||||
install of both jrnl and your plugin.
|
install of both *jrnl* and your plugin.
|
||||||
|
- for examples, you can look to the *jrnl*'s internal importers and exporters.
|
||||||
|
As well, there are some basic external examples included in *jrnl*'s git repo
|
||||||
|
at `tests/external_plugins_src` (including the example code above).
|
||||||
|
|
|
@ -1,5 +1,20 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
# Copyright (C) 2012-2021 jrnl contributors
|
||||||
|
# License: https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
|
||||||
|
"""
|
||||||
|
This file ("meta") uses that title in the reflexive sense; i.e. it is the
|
||||||
|
collection of code that allows plugins to deal with themselves.
|
||||||
|
|
||||||
|
In particular, the code here collects the list of imports and exporters, both
|
||||||
|
internal and external, and tells the main program which plugins are available.
|
||||||
|
Actual calling of the plugins is done directly and works because given plugin
|
||||||
|
functions are importable/callable at predetermined (code) locations.
|
||||||
|
|
||||||
|
Internal plugins are located in the `jrnl.plugins` namespace, and external
|
||||||
|
plugins are located in the `jrnl.contrib` namespace.
|
||||||
|
"""
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
import pkgutil
|
import pkgutil
|
||||||
|
@ -64,10 +79,15 @@ __importer_types = {
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_FORMATS = sorted(__exporter_types.keys())
|
EXPORT_FORMATS = sorted(__exporter_types.keys())
|
||||||
|
"""list of stings: all available export formats."""
|
||||||
IMPORT_FORMATS = sorted(__importer_types.keys())
|
IMPORT_FORMATS = sorted(__importer_types.keys())
|
||||||
|
"""list of stings: all available import formats."""
|
||||||
|
|
||||||
|
|
||||||
def get_exporter(format):
|
def get_exporter(format):
|
||||||
|
"""
|
||||||
|
Given an export format, returns the (callable) class of the corresponding exporter.
|
||||||
|
"""
|
||||||
# print('get_exporter')
|
# print('get_exporter')
|
||||||
# print(__exporter_types)
|
# print(__exporter_types)
|
||||||
for exporter_name, exporter_class in __exporter_types.items():
|
for exporter_name, exporter_class in __exporter_types.items():
|
||||||
|
@ -82,6 +102,9 @@ def get_exporter(format):
|
||||||
|
|
||||||
|
|
||||||
def get_importer(format):
|
def get_importer(format):
|
||||||
|
"""
|
||||||
|
Given an import format, returns the (callable) class of the corresponding importer.
|
||||||
|
"""
|
||||||
for importer_name, importer_class in __importer_types.items():
|
for importer_name, importer_class in __importer_types.items():
|
||||||
if (
|
if (
|
||||||
hasattr(importer_class, "Importer")
|
hasattr(importer_class, "Importer")
|
||||||
|
|
|
@ -4,7 +4,14 @@
|
||||||
# License: https://www.gnu.org/licenses/gpl-3.0.html
|
# License: https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Exporter for testing and experimentation purposes
|
Exporter for testing and experimentation purposes.
|
||||||
|
|
||||||
|
The presence of this plugin is also used as a "switch" by the test suite to
|
||||||
|
decide on whether or not to run the "vanilla" test suite, or the test suite
|
||||||
|
for external plugins.
|
||||||
|
|
||||||
|
The `export_entry` and `export_journal` methods are both purposely not
|
||||||
|
implemented to confirm behavior on plugins that don't implement them.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from jrnl.plugins.base import BaseExporter
|
from jrnl.plugins.base import BaseExporter
|
||||||
|
|
Loading…
Add table
Reference in a new issue