<commit_before>
Extend ``pibooth`` functionalities
----------------------------------

The ``pibooth`` application is built on the top of
`pluggy <https://pluggy.readthedocs.io/en/latest/index.html>`_
that gives users the ability to extend or modify its behavior.

What is a plugin?
^^^^^^^^^^^^^^^^^

A plugin is a set of functions (called ``hooks``) defined in a python module
and participating to the ``pibooth`` execution when they are invoked.

The list of available ``hooks`` are defined in the file
`hookspecs.py <https://github.com/werdeil/pibooth/blob/master/pibooth/plugins/hookspecs.py>`_.

A plugin implements a subset of the functions of this specification.

Influencing states
^^^^^^^^^^^^^^^^^^

The ``pibooth`` application is built on the principle of states. Each state
is defined by a specific screen and possible actions available to the user.

The following states are defined:
 * ``wait``       : wait for starting a new sequence
 * ``choose``     : selection of the number of captures
 * ``chosen``     : confirm the number of captures
 * ``preview``    : show preview and countdown
 * ``capture``    : take captures
 * ``processing`` : build the final picture
 * ``print``      : show preview and ask for printing
 * ``finish``     : thank before going back to wait state
 * ``failsafe``   : oops message when an exception occurs

.. image:: https://raw.githubusercontent.com/werdeil/pibooth/master/templates/state_sequence_details.png
    :align: center
    :alt: State sequence

There are four hooks defined for each state. The ``enter`` hook is invoked one
time when the state is activated. The ``do`` one is invoked in a loop until
the state is switching to an other one. The ``validate``, also invoked in a
loop, returns the name  of the next state. And finally the ``exit`` hook is
invoked one time when the state is exited.

Example #1 : Hello from plugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``pibooth_hello.py``

.. code-block:: python

    import pibooth
    from pibooth.utils import LOGGER

    @pibooth.hookimpl
    def state_wait_enter():
        LOGGER.info("Hello from '%s' plugin", __name__)

Example #2 : Flash light on capture
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``pibooth_flash.py``

.. code-block:: python

    import pibooth
    from pibooth.controls.light import PtbLed

    FLASH = PtbLed(36)

    @pibooth.hookimpl
    def state_capture_enter():
        FLASH.switch_on()

    @pibooth.hookimpl
    def state_capture_exit():
        FLASH.switch_off()

Example #3 : Upload to FTP
^^^^^^^^^^^^^^^^^^^^^^^^^^

``pibooth_ftp.py``

.. code-block:: python

    import os
    from ftplib import FTP
    import pibooth

<commit_msg>Add precision about plugins naming<commit_after>
Extend ``pibooth`` functionalities
----------------------------------

The ``pibooth`` application is built on the top of
`pluggy <https://pluggy.readthedocs.io/en/latest/index.html>`_
that gives users the ability to extend or modify its behavior.

What is a plugin?
^^^^^^^^^^^^^^^^^

A plugin is a set of functions (called ``hooks``) defined in a python module
and participating to the ``pibooth`` execution when they are invoked.

The list of available ``hooks`` are defined in the file
`hookspecs.py <https://github.com/werdeil/pibooth/blob/master/pibooth/plugins/hookspecs.py>`_.

A plugin implements a subset of the functions of this specification.

Influencing states
^^^^^^^^^^^^^^^^^^

The ``pibooth`` application is built on the principle of states. Each state
is defined by a specific screen and possible actions available to the user.

The following states are defined:
 * ``wait``       : wait for starting a new sequence
 * ``choose``     : selection of the number of captures
 * ``chosen``     : confirm the number of captures
 * ``preview``    : show preview and countdown
 * ``capture``    : take captures
 * ``processing`` : build the final picture
 * ``print``      : show preview and ask for printing
 * ``finish``     : thank before going back to wait state
 * ``failsafe``   : oops message when an exception occurs

.. image:: https://raw.githubusercontent.com/werdeil/pibooth/master/templates/state_sequence_details.png
    :align: center
    :alt: State sequence

There are four hooks defined for each state. The ``enter`` hook is invoked one
time when the state is activated. The ``do`` one is invoked in a loop until
the state is switching to an other one. The ``validate``, also invoked in a
loop, returns the name  of the next state. And finally the ``exit`` hook is
invoked one time when the state is exited.

The name of each hook has always the same syntax::

    state_<name>_enter
    state_<name>_do
    state_<name>_validate
    state_<name>_exit

.. note:: The hooks specification define all arguments that can be used by the
          hook, but in the implementation there is no need to defined arguments
          that are no used.

Example #1 : Hello from plugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``pibooth_hello.py``

.. code-block:: python

    import pibooth
    from pibooth.utils import LOGGER

    @pibooth.hookimpl
    def state_wait_enter():
        LOGGER.info("Hello from '%s' plugin", __name__)

Example #2 : Flash light on capture
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``pibooth_flash.py``

.. code-block:: python

    import pibooth
    from pibooth.controls.light import PtbLed

    FLASH = PtbLed(36) # GPIO configured as BOARD

    @pibooth.hookimpl
    def state_capture_enter():
        FLASH.switch_on()

    @pibooth.hookimpl
    def state_capture_exit():
        FLASH.switch_off()

Example #3 : Upload to FTP
^^^^^^^^^^^^^^^^^^^^^^^^^^

``pibooth_ftp.py``

.. code-block:: python

    import os
    from ftplib import FTP
    import pibooth


{'fraction_non_alphanumeric': 0.14113326337880377, 'fraction_numerical': 0.0017488632388947185, 'mean_word_length': 3.5173775671406005, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3047232', 'n_tokens_mistral': 1674, 'n_tokens_neox': 1639, 'n_words': 649}