From e80cce00f391a88f92a410c9c368b3700d4aaf1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Fri, 1 Jun 2018 16:20:20 +0200 Subject: [PATCH] Add sphinx API documentation --- docs/Makefile | 20 +++ docs/make.bat | 36 ++++ docs/source/components/components.rst | 25 +++ docs/source/conf.py | 166 ++++++++++++++++++ docs/source/foundations/eventhandlers.rst | 12 ++ docs/source/foundations/fsms.rst | 12 ++ docs/source/foundations/tfwserver.rst | 7 + docs/source/index.rst | 45 +++++ docs/source/networking/networking.rst | 17 ++ lib/tfw/components/history_monitor.py | 8 +- lib/tfw/components/ide_event_handler.py | 31 ++-- .../log_monitoring_event_handler.py | 13 +- .../process_managing_event_handler.py | 4 +- lib/tfw/components/terminal_commands.py | 6 +- lib/tfw/components/terminal_event_handler.py | 14 +- lib/tfw/linear_fsm.py | 1 - 16 files changed, 381 insertions(+), 36 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/components/components.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/foundations/eventhandlers.rst create mode 100644 docs/source/foundations/fsms.rst create mode 100644 docs/source/foundations/tfwserver.rst create mode 100644 docs/source/index.rst create mode 100644 docs/source/networking/networking.rst diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..1a264d7 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = baseimage-tutorial-framework +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..0a0210b --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=baseimage-tutorial-framework + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/components/components.rst b/docs/source/components/components.rst new file mode 100644 index 0000000..87dee5b --- /dev/null +++ b/docs/source/components/components.rst @@ -0,0 +1,25 @@ +Components +---------- + +.. automodule:: tfw.components + +.. autoclass:: IdeEventHandler + :members: + +.. autoclass:: TerminalEventHandler + :members: + +.. autoclass:: ProcessManagingEventHandler + :members: + +.. autoclass:: LogMonitoringEventHandler + :members: + +.. autoclass:: TerminalCommands + :members: + +.. autoclass:: HistoryMonitor + :members: + +.. autoclass:: BashMonitor + :members: diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..5c596d0 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../../lib')) + + +# -- Project information ----------------------------------------------------- + +project = 'baseimage-tutorial-framework' +copyright = '2018, Avatao Innovative Learning Kft' +author = 'Kristóf Tóth' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = 'bombay' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'baseimage-tutorial-frameworkdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'baseimage-tutorial-framework.tex', 'baseimage-tutorial-framework Documentation', + 'Kristóf Tóth', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'baseimage-tutorial-framework', 'baseimage-tutorial-framework Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'baseimage-tutorial-framework', 'baseimage-tutorial-framework Documentation', + author, 'baseimage-tutorial-framework', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- +def skip(app, what, name, obj, skip, options): + if name == "__init__": + return False + return skip + +def setup(app): + app.connect("autodoc-skip-member", skip) diff --git a/docs/source/foundations/eventhandlers.rst b/docs/source/foundations/eventhandlers.rst new file mode 100644 index 0000000..9b8d91c --- /dev/null +++ b/docs/source/foundations/eventhandlers.rst @@ -0,0 +1,12 @@ +Event handler base classes +-------------------------- + +Subclass these to create your cusom event handlers. + +.. automodule:: tfw + +.. autoclass:: EventHandlerBase + :members: + +.. autoclass:: TriggeredEventHandler + :members: diff --git a/docs/source/foundations/fsms.rst b/docs/source/foundations/fsms.rst new file mode 100644 index 0000000..190ee8b --- /dev/null +++ b/docs/source/foundations/fsms.rst @@ -0,0 +1,12 @@ +FSM base classes +---------------- + +Subclass these to create an FSM that fits your tutorial/challenge. + +.. automodule:: tfw + +.. autoclass:: FSMBase + :members: + +.. autoclass:: LinearFSM + :members: diff --git a/docs/source/foundations/tfwserver.rst b/docs/source/foundations/tfwserver.rst new file mode 100644 index 0000000..3dddaa4 --- /dev/null +++ b/docs/source/foundations/tfwserver.rst @@ -0,0 +1,7 @@ +TFWServer +--------- + +.. automodule:: tfw.networking + +.. autoclass:: TFWServer + :members: diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..3d674ad --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,45 @@ +.. baseimage-tutorial-framework documentation master file, created by + sphinx-quickstart on Fri Jun 1 14:29:07 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to baseimage-tutorial-framework's documentation! +======================================================== + +Foundations +----------- + +This part covers the soil which the framework is based on and stuff you will need to develop your own challenges. + +.. toctree:: + :glob: + + foundations/* + +Networking +---------- + +You can use these to send messages to the frontend or the event handlers through TFWServer. + +.. toctree:: + :glob: + + networking/* + +Components +---------- + +These are pre-written components for you to use, such as our IDE, terminal or console. + +.. toctree:: + :glob: + + components/* + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/networking/networking.rst b/docs/source/networking/networking.rst new file mode 100644 index 0000000..317d266 --- /dev/null +++ b/docs/source/networking/networking.rst @@ -0,0 +1,17 @@ +Networking +---------- + +.. automodule:: tfw.networking + +.. autoclass:: TFWServerConnector + :members: + +.. automodule:: tfw.networking.event_handlers + +.. autoclass:: ServerUplinkConnector + :members: + +.. automodule:: tfw.networking + +.. autoclass:: MessageSender + :members: diff --git a/lib/tfw/components/history_monitor.py b/lib/tfw/components/history_monitor.py index b103bb9..e775c08 100644 --- a/lib/tfw/components/history_monitor.py +++ b/lib/tfw/components/history_monitor.py @@ -74,10 +74,10 @@ class BashMonitor(HistoryMonitor): HistoryMonitor for monitoring bash CLI sessions. This requires the following to be set in bash (note that this is done automatically by TFW): - PROMPT_COMMAND="history -a" - shopt -s cmdhist - shopt -s histappend - unset HISTCONTROL + PROMPT_COMMAND="history -a" + shopt -s cmdhist + shopt -s histappend + unset HISTCONTROL """ @property def command_pattern(self): diff --git a/lib/tfw/components/ide_event_handler.py b/lib/tfw/components/ide_event_handler.py index 7c9fda3..4c4fa6f 100644 --- a/lib/tfw/components/ide_event_handler.py +++ b/lib/tfw/components/ide_event_handler.py @@ -101,9 +101,10 @@ class IdeEventHandler(EventHandlerBase, MonitorManagerMixin): When any file in the selected directory changes they are automatically refreshed on the frontend (this is done by listening to inotify events). - This EventHandler accepts messages that have a data["command"] key specifying + This EventHandler accepts messages that have a data['command'] key specifying a command to be executed. - The API of each command is documented in their respective handlers. + + The API of each command is documented in their respective handler. """ def __init__(self, key, directory, allowed_directories, selected_file=None, exclude=None, additional_watched_directories=None): @@ -112,7 +113,7 @@ class IdeEventHandler(EventHandlerBase, MonitorManagerMixin): :param directory: working directory which the EventHandler should serve files from :param allowed_directories: list of directories that can be switched to using the selectdir command :param selected_file: file that is selected by default - :param exclude: list of filenames that should not appear between files (for *.o, *.pyc, etc.) + :param exclude: list of filenames that should not appear between files (for .o, .pyc, etc.) :param additional_watched_directories: refresh the selected file when files change in these directories (the working directory is watched by default, this is useful for symlinks and such) @@ -139,7 +140,7 @@ class IdeEventHandler(EventHandlerBase, MonitorManagerMixin): """ Read the currently selected file. - :return: message with the contents of the file in data['content'] + :return dict: message with the contents of the file in data['content'] """ try: data['content'] = self.filemanager.file_contents @@ -155,8 +156,9 @@ class IdeEventHandler(EventHandlerBase, MonitorManagerMixin): """ Overwrites a file with the desired string. - :param data: TFW message data containing keys: - |-string: containing the desired file contents + :param data: TFW message data containing key 'content' + (new file content) + """ self.monitor.ignore = self.monitor.ignore + 1 try: @@ -170,8 +172,8 @@ class IdeEventHandler(EventHandlerBase, MonitorManagerMixin): """ Selects a file from the current directory. - :param data: TFW message data containing keys: - |-filename: name of file to select relative to the current directory + :param data: TFW message data containing 'filename' + (name of file to select relative to the current directory) """ try: self.filemanager.filename = data['filename'] @@ -183,10 +185,10 @@ class IdeEventHandler(EventHandlerBase, MonitorManagerMixin): """ Select a new working directory to display files from. - :param data: TFW message data containing keys: - |-directory: absolute path of diretory to select. - must be a path whitelisted in - self.allowed_directories + :param data: TFW message data containing 'directory' + (absolute path of diretory to select. + must be a path whitelisted in + self.allowed_directories) """ try: self.filemanager.workdir = data['directory'] @@ -204,8 +206,9 @@ class IdeEventHandler(EventHandlerBase, MonitorManagerMixin): """ Overwrite list of excluded files - :param data: TFW message data containing keys: - |-exclude: list of filename patterns to be excluded, e.g.: ["*.pyc", "*.o"] + :param data: TFW message data containing 'exclude' + (list of unix-style filename patterns to be excluded, + e.g.: ["\*.pyc", "\*.o") """ try: self.filemanager.exclude = list(data['exclude']) diff --git a/lib/tfw/components/log_monitoring_event_handler.py b/lib/tfw/components/log_monitoring_event_handler.py index 10058ce..eb9782f 100644 --- a/lib/tfw/components/log_monitoring_event_handler.py +++ b/lib/tfw/components/log_monitoring_event_handler.py @@ -14,7 +14,10 @@ class LogMonitoringEventHandler(EventHandlerBase, MonitorManagerMixin): Monitors the output of a supervisor process (stdout, stderr) and sends the results to the frontend. - Exposes API to change monitoring parameters. + Accepts messages that have a data['command'] key specifying + a command to be executed. + + The API of each command is documented in their respective handler. """ def __init__(self, key, process_name, log_tail=0): super().__init__(key) @@ -39,8 +42,8 @@ class LogMonitoringEventHandler(EventHandlerBase, MonitorManagerMixin): """ Changes the monitored process. - :param data: TFW message data containing keys: - |-value: name of the process to monitor + :param data: TFW message data containing 'value' + (name of the process to monitor) """ self.set_monitor_args(data['value'], self.log_tail) @@ -50,8 +53,8 @@ class LogMonitoringEventHandler(EventHandlerBase, MonitorManagerMixin): to the frontend (the monitor will send back the last 'value' characters of the log). - :param data: TFW message data containing keys: - |-value: new tail length + :param data: TFW message data containing 'value' + (new tail length) """ self.set_monitor_args(self.process_name, data['value']) diff --git a/lib/tfw/components/process_managing_event_handler.py b/lib/tfw/components/process_managing_event_handler.py index a512c1e..0a3d052 100644 --- a/lib/tfw/components/process_managing_event_handler.py +++ b/lib/tfw/components/process_managing_event_handler.py @@ -25,9 +25,9 @@ class ProcessManagingEventHandler(EventHandlerBase): """ Event handler that can manage processes managed by supervisor. - This EventHandler accepts messages that have a data["command"] key specifying + This EventHandler accepts messages that have a data['command'] key specifying a command to be executed. - Every message must contain a data["process_name"] field with the name of the + Every message must contain a data['process_name'] field with the name of the process to manage. This is the name specified in supervisor config files like so: [program:someprogram] diff --git a/lib/tfw/components/terminal_commands.py b/lib/tfw/components/terminal_commands.py index edaa16f..ae22975 100644 --- a/lib/tfw/components/terminal_commands.py +++ b/lib/tfw/components/terminal_commands.py @@ -19,13 +19,13 @@ class TerminalCommands(ABC): To receive events you need to subscribe TerminalCommand.callback to a HistoryMonitor instance. - Inherit from this class and define methods which start with "command_". When the user + Inherit from this class and define methods which start with "command\_". When the user executes the command specified after the underscore, your method will be invoked. All - such commands must expect the parameter *args which will contain the arguments of the + such commands must expect the parameter \*args which will contain the arguments of the command. For example to define a method that runs when someone starts vim in the terminal - you have to define a method like: "def command_vim(self, *args)" + you have to define a method like: "def command_vim(self, \*args)" You can also use this class to create new commands similarly. """ diff --git a/lib/tfw/components/terminal_event_handler.py b/lib/tfw/components/terminal_event_handler.py index 9f7a640..3f7e208 100644 --- a/lib/tfw/components/terminal_event_handler.py +++ b/lib/tfw/components/terminal_event_handler.py @@ -16,9 +16,9 @@ class TerminalEventHandler(EventHandlerBase): sessions to connect to. You need to instanciate this in order for frontend terminals to work. - This EventHandler accepts messages that have a data["command"] key specifying + This EventHandler accepts messages that have a data['command'] key specifying a command to be executed. - The API of each command is documented in their respective handlers. + The API of each command is documented in their respective handler. """ def __init__(self, key, monitor): """ @@ -54,8 +54,8 @@ class TerminalEventHandler(EventHandlerBase): Writes a string to the terminal session (on the pty level). Useful for pre-typing and executing commands for the user. - :param data: TFW message data containing keys: - |-value: command to be written to the pty + :param data: TFW message data containing 'value' + (command to be written to the pty) """ self.terminado_server.pty.write(data['value']) @@ -63,9 +63,9 @@ class TerminalEventHandler(EventHandlerBase): """ Reads the history of commands executed. - :param data: TFW message data containing keys: - |-count: the number of history elements to return - :return: message with list of commands in data['history'] + :param data: TFW message data containing 'count' + (the number of history elements to return) + :return dict: message with list of commands in data['history'] """ data['count'] = int(data.get('count', 1)) if self.historymonitor: diff --git a/lib/tfw/linear_fsm.py b/lib/tfw/linear_fsm.py index 2728655..61e4c43 100644 --- a/lib/tfw/linear_fsm.py +++ b/lib/tfw/linear_fsm.py @@ -11,7 +11,6 @@ class LinearFSM(FSMBase): a number of steps specified in the constructor. It automatically sets up 2 actions (triggers) between states as such: (0) -- step_1 --> (1) -- step_2 --> (2) -- step_3 --> (3) ... and so on - \-step_next-/ \-step_next-/ \-step_next-/ """ def __init__(self, number_of_steps): self.states = list(map(str, range(number_of_steps)))