[Docs] improve documentation of custom Importers and Exporters

This commit is contained in:
MinchinWeb 2021-05-05 21:40:43 -06:00
parent 2706314306
commit a75f153df9

View file

@ -8,32 +8,32 @@ 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 can traditional Python packages, and are Custom Importers and Exporters are traditional Python packages, and are
installed simply by installing them so they are available to the Python installed (into jrnl) simply by installing them so they are available to the
intrepreter that is running jrnl. Python interpreter that is running jrnl.
## Entry Class ## Entry Class
Both the Importers and the Exporters work on the `Entry` class. Below is a Both the Importers and the Exporters work on the `Entry` class. Below is a
(selective) desciption of the class, it's properties and functions: (selective) description of the class, it's properties and functions:
- **Entry** (class) at `jrnl.Entry.Entry`. - **Entry** (class) at `jrnl.Entry.Entry`.
- **title** (string): a single line that represents a entry's title. - **title** (string): a single line that represents a entry's title.
- **date** (datetime.datetime): the date and time asigned to an entry. - **date** (datetime.datetime): the date and time assigned to an entry.
- **body** (string): the main body of the entry. Can be basically any - **body** (string): the main body of the entry. Can be basically any
length. *jrnl* assumes no particular structure here. length. *jrnl* assumes no particular structure here.
- **starred** (boolean): is an entry starred? Presumably, starred entries - **starred** (boolean): is an entry starred? Presumably, starred entries
are of partiulcar importance. are of particular importance.
- **tags** (list of strings): the tags attached to an entry. Each tag - **tags** (list of strings): the tags attached to an entry. Each tag
includes the pre-facing "tag symbol". includes the pre-facing "tag symbol".
- **__init__(journal, date=None, text="", starred=False)**: contructor - **\_\_init\_\_(journal, date=None, text="", starred=False)**: contractor
method method
- **jounral** (*jrnl.Journal.Journal*): a link to an existing Jounral - **journal** (*jrnl.Journal.Journal*): a link to an existing Journal
class. Mainly used to access it's configuration. class. Mainly used to access it's configuration.
- **date** (datetime.datetime) - **date** (datetime.datetime)
- **text** (string): assumed to include both the title and the body. When - **text** (string): assumed to include both the title and the body.
the title, body, or tags of an entry are requested, this text will the When the title, body, or tags of an entry are requested, this text
parsed to determine the tree. will the parsed to determine the tree.
- **starred** (boolean) - **starred** (boolean)
Entries also have "advanced" metadata if they are using the DayOne backend, but Entries also have "advanced" metadata if they are using the DayOne backend, but
@ -50,21 +50,18 @@ nicely formated JSON file:
~~~ python ~~~ python
# pelican\contrib\importer\json_importer.py # pelican\contrib\importer\json_importer.py
import sys
from jrnl import Entry
from jrnl.plugins.base import BaseImporter
__version__ = "1.0.0"
class Importer: class Importer:
"""JSON Importer for jrnl.""" """JSON Importer for jrnl."""
import sys
from jrnl import Entry
names = ["json"] names = ["json"]
version = "1.0.0" version = __version__
@classmethod
def class_path(cls):
return cls.__module__
@staticmethod @staticmethod
def import_(journal, input=None) def import_(journal, input=None)
@ -91,11 +88,11 @@ class Importer:
raw = json_entry["title"] + "/n" + json_entry["body"] raw = json_entry["title"] + "/n" + json_entry["body"]
date = json_entry["date"] date = json_entry["date"]
entry = Entry.Entry(self, date, raw) entry = Entry.Entry(self, date, raw)
jounral.entries.append(entry) journal.entries.append(entry)
new_cnt = len(journal.entries) new_cnt = len(journal.entries)
print( print(
"[{} imported to {} journal]".format( "[{} entries imported to '{}' journal]".format(
new_cnt - old_cnt, journal.name new_cnt - old_cnt, journal.name
), ),
file=sys.stderr, file=sys.stderr,
@ -107,21 +104,22 @@ try to import all possible entry metadata.
Some implementation notes: Some implementation notes:
- The importer class must be named **Importer**. - The importer class must be named **Importer**, and should sub-class
**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 any `__init__.py` files in the base directories. - The importer must not have any `__init__.py` files in the base directories.
- 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 intrepretor 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:
- **version** (string): the version of the plugin. Displayed to help user - **version** (string): the version of the plugin. Displayed to help the
debug their installations. user debug their installations.
- **names** (list of strings): these are the "names" that can be passed to - **names** (list of strings): these are the "names" that can be passed to
the CLI to invole your importer. If you specify one used by a built-in the CLI to invole your importer. If you specify one used by a built-in
plugin, it will overwrite it (effectively making the built-in one plugin, it will overwrite it (effectively making the built-in one
unavailable). unavailable).
- **import_(journal, input=None)**: the actual importer. Must append entries - **import_(journal, input=None)**: the actual importer. Must append
to the jounral passed to it. It is recommended to accept either a filename entries to the journal passed to it. It is recommended to accept either a
or standard input as a source. filename or standard input as a source.
## Custom Exporter ## Custom Exporter
@ -135,18 +133,21 @@ included in jrnl and so this (if installed) would override the built in
exporter. exporter.
~~~ python ~~~ python
# pelican\contrib\importer\custom_json_exporter.py # pelican\contrib\exporter\custom_json_exporter.py
import json import json
from jrnl.plugins.exporter.text_exporter import Exporter as TextExporter from jrnl.plugins.base import BaseExporter
class Exporter(TextExporter): __version__ = "1.0.0"
class Exporter(BaseExporter):
""" """
This basic Exporter can convert entries and journals into JSON. This basic Exporter can convert entries and journals into JSON.
""" """
names = ["json"] names = ["json"]
extension = "json" extension = "json"
version = __version__
@classmethod @classmethod
def entry_to_dict(cls, entry): def entry_to_dict(cls, entry):
@ -178,23 +179,29 @@ export all entry metadata.
Some implementation notes: Some implementation notes:
- the exporter class must be named **Exporter**. - the exporter class must be named **Exporter** and should sub-class
**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 any `__init__.py` files in the base directories. - The exporter must not have any `__init__.py` files in the base directories.
- 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 intrepretor 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
(there are a few more you will need to define if you don't subclass (there are a few more you will need to define if you don't subclass
`jrnl.plugins.exporter.text_exporter`): `jrnl.plugins.exporter.text_exporter`):
- **version** (string): the version of the plugin. Displayed to help user - **version** (string): the version of the plugin. Displayed to help the
debug their installations. user debug their installations.
- **names** (list of strings): these are the "names" that can be passed to - **names** (list of strings): these are the "names" that can be passed to
the CLI to invole your exporter. If you specific one used by a built-in the CLI to invole your exporter. If you specific one used by a built-in
plugin, it will overwrite it (effectively making the built-in one plugin, it will overwrite it (effectively making the built-in one
unavailable). unavailable).
- **extension** (string): the file extention used on exported entries. - **extension** (string): the file extention used on exported entries.
- **class_path()**: returns the module of the exporter.
- **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)**: given a journal, returns a string of the
formatted, exported entries of the journal. formatted, exported entries of the journal.
## Development Tips
- 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
install of both jrnl and your plugin.