Plugin's main code exists at the source, argoslabs/myplugin/asciiart/__init__.py.
Here is the full source:
"""
====================================
:mod:`argoslabs.myplugin.figlet`
====================================
.. moduleauthor:: Your Name <email@yours>
.. note:: ARGOS-LABS License
Description
===========
ARGOS LABS plugin module for ASCII Art using pyfiglet
"""
# Authors
# ===========
#
# * Your Name
#
# Change Log
# --------
#
# * [2022/04/12]
# - Changed for what
# * [2022/02/02]
# - starting
################################################################################
import os
import sys
from alabs.common.util.vvargs import ModuleContext, func_log, \
ArgsError, ArgsExit, get_icon_path
from pyfiglet import Figlet
################################################################################
DIRECTION_LIST = [
'auto',
'left-to-right',
'right-to-left',
]
JUSTIFY_LIST = [
'auto',
'left',
'right',
]
################################################################################
@func_log
def do_figlet(mcxt, argspec):
mcxt.logger.info('>>>starting...')
try:
if not argspec.message:
raise ValueError(f'Invalid Message')
direction = argspec.direction
justify = argspec.justify
width = int(argspec.width)
f = Figlet(font=argspec.font, direction=direction,
justify=justify, width=width)
print(f.renderText(argspec.message), end='')
return 0
except ValueError as err:
msg = str(err)
mcxt.logger.error(msg)
sys.stderr.write('%s%s' % (msg, os.linesep))
return 1
except Exception as err:
msg = str(err)
mcxt.logger.error(msg)
sys.stderr.write('%s%s' % (msg, os.linesep))
return 99
finally:
mcxt.logger.info('>>>end...')
################################################################################
def _main(*args):
with ModuleContext(
owner='ARGOS-LABS',
group='9', # Utility Tools
version='1.0',
platform=['windows', 'darwin', 'linux'],
output_type='text',
display_name='ASCII Art',
icon_path=get_icon_path(__file__),
description='''AscII Art using Figlet''',
) as mcxt:
# ##################################### for app dependent parameters
mcxt.add_argument('font',
display_name='Font',
choices=Figlet().getFonts(),
default='standard',
help='Select font for ascii art')
mcxt.add_argument('message',
display_name='Message',
help='Message for ASCII Art')
# ##################################### for app dependent options
mcxt.add_argument('--direction',
display_name='Text Direction',
choices=DIRECTION_LIST,
default=DIRECTION_LIST[0],
help='Text direction, default [[auto]] means font''s direction')
mcxt.add_argument('--justify',
display_name='Text Justify',
choices=JUSTIFY_LIST,
default=JUSTIFY_LIST[0],
help='Text justfy, default [[auto]] means font''s justify')
mcxt.add_argument('--width',
display_name='Text Width',
type=int,
default=80,
help='Text width, default [[80]] columns')
argspec = mcxt.parse_args(args)
return do_figlet(mcxt, argspec)
################################################################################
def main(*args):
try:
return _main(*args)
except ArgsError as err:
sys.stderr.write('Error: %s\nPlease -h to print help\n' % str(err))
return 98
except ArgsExit as _:
return 0Every plugin has the function named main and _main. At the _main you can find ModuleContext with construction statement.
with ModuleContext(
owner='ARGOS-LABS',
group='9', # Utility Tools
version='1.0',
platform=['windows', 'darwin', 'linux'],
output_type='text',
display_name='ASCII Art',
icon_path=get_icon_path(__file__),
description='''AscII Art using Figlet''',
) as mcxt:This ModuleContext define plugin's main attributes as follows:
owner: You can describe who madke this plugin.ARGOS-LABSmeans our own plugin.group: This group is for grouping at STU Operation group. The value will be explained below.version: This version is reserved. Currently not used. Actual version is defined atsetup.yamlfile.platform: This platform means in what OS platform can be run. You can decide one, two or three platforms as list. Order is not important. There are three platform:windows: Windows OS platformdarwin: Mac OS platformlinux: Linux OS platform
output_type: This attribute is reserved astextand others for the future use.display_name: This attribue is the name of showed at STU icon text. This name must be unique, we can explain about this later build chapter. You can search any matching words from STU operation pane.icon_path: Fix with the value ofget_icon_path(__file__)description: This attribute is the description of this plugin.
- This
ModuleContextclass is defined atalabs.commonlibrary.- This
ModuleContextclass is enherited fromArgumentParserfrom argparse Python Standard Library. This is because our plugin idea started from that CLI parameters can be regarded as corresponding user input interface. Let us explain more detail atinput design.
Next table is for the value of group:
| Value | Category |
|---|---|
| 1 | AI Solutions |
| 2 | Business Apps |
| 3 | Cloud Solutions |
| 4 | Data Science |
| 5 | Email/Messenger |
| 6 | Files and Folders |
| 7 | Interactive |
| 8 | Storage Solutions |
| 9 | Utility Tools |
| 10 | Web Scraping |
| Other Values | Misc |
Any suggestions are welcome if you cannot find proper category.
You can see grouped plugin category at STU.
Next is for Input design python code:
# ##################################### for app dependent parameters
mcxt.add_argument('font',
display_name='Font',
choices=Figlet().getFonts(),
default='standard',
help='Select font for ascii art')
mcxt.add_argument('message',
display_name='Message',
help='Message for ASCII Art')
# ##################################### for app dependent options
mcxt.add_argument('--direction',
display_name='Text Direction',
choices=DIRECTION_LIST,
default=DIRECTION_LIST[0],
help='Text direction, default [[auto]] means font''s direction')
mcxt.add_argument('--justify',
display_name='Text Justify',
choices=JUSTIFY_LIST,
default=JUSTIFY_LIST[0],
help='Text justfy, default [[auto]] means font''s justify')
mcxt.add_argument('--width',
display_name='Text Width',
type=int,
default=80,
help='Text width, default [[80]] columns')
argspec = mcxt.parse_args(args)Our plugin idea started from that CLI parameters can be regarded as corresponding user input interface. Every command has the following structure. Refer Arguments.
| Command | Optional Parameters | Positional Parameters | Descriptions |
|---|---|---|---|
ls |
-a -l or -al |
a.py b.* |
list a.py or all files starts with b. with -l long format and all -a format option |
find |
-type f -name "*.py" |
/tmp |
find all folder, file from /tmp which have -type f the normal file type and -name "*.py" have py file extension |
Optional Parameterscan be omitted as literallyOptional Parameterscan be positioned afterPositional ParametersOptional Parametersstarts with-charecter. Usually form of-aor--all. Starting one-and following one alphabet character or starting two--and following word- On Windows
CMD.EXE,Optional Parameterslooks like/h,/?called switch.
mcxt.add_argument() function is based on argparse's ArgumentParser.add_argument(). The arguments are as follows:
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
- name or flags - Either a name or a list of option strings, e.g. foo or
-f,--foo. - action - The basic type of action to be taken when this argument is encountered at the command line.
- nargs - The number of command-line arguments that should be consumed.
- const - A constant value required by some action and nargs selections.
- default - The value produced if the argument is absent from the command line.
- type - The type to which the command-line argument should be converted.
- choices - A container of the allowable values for the argument.
- required - Whether or not the command-line option may be omitted (optionals only).
- help - A brief description of what the argument does. If the contents has
[[default]]string at help string then STU automatically showsdefaultat value window. - metavar - A name for the argument in usage messages.
- dest - The name of the attribute to be added to the object returned by parse_args().
Additionally next arguments are added at ModuleContext.add_argument():
display_name- String display label at STU's property. If omitted this value is same as abovename or flagsshow_default- Usually optional parameter, starts with-is in theAdvancedproperty and hidden. Even optional parameter if this flag is setTruethen shows aboveAdvancedsection.input_method- If this value has the one of these then STU will take proper action to get input value from user:password- Shows hidden string with*characterfileread- Shows dialog box for file readingfileread;xlsx,xls,xlsm- Shows dialog box for file reading with comma separated extensionsfilewrite- Shows dialog box for file writingfilewrite;xlsx,xls,xlsm- Shows dialog box for file writing with comma separated extensionsfolderread- Shows dialog box for folder readingfolderwrite- Shows dialog box for folder writingdateselect- Shows dialog box for date selectiontextarea- Input for multiline text (Note! Not released. Under testing)
input_group- If this value has the one of these then STU will take proper action to get input value from user:groupname- parameters are grouped into namedgroupnamegroupname;groupbox- parameters are grouped into namedgroupnamewith group boxradio=a- parameters are grouped into namedaand can be exclusively selected radio buttonradio=a;default- parameters are grouped into namedaand exclusively default selected radio button
And next are valud constrains:
min_valueorgreater_eq- Error happen when given value is less than this valuemax_valueorless_eq- Error happen when given value is greater than this valuemin_value_niorgreater- Error happen when given value is less than or equal to this valuemax_value_niorless- Error happen when given value is greater than or equal to this valueequal- Error happen when given value is not equal to this valuenot_equal- Error happen when given value is equal to this valuere_match- Error happen when given value is not match to this regulare expression
argc.add_argument('--infile', nargs='?', const='-',
help='for input stream file '
'(default is nothing, "-" means stdin)')
argc.add_argument('--outfile', nargs='?',
help='for output stream file (default is stdout)')
argc.add_argument('--errfile', nargs='?',
help='for error stream file (default is stderr)')
argc.add_argument('--statfile', nargs='?',
help='for status (default is stdout)')
argc.add_argument('--logfile', nargs='?',
help='for log file to logging, default is %s.log '
'(500K size, rotate 4)' % self.name)
argc.add_argument('--loglevel', nargs='?',
choices=['debug', 'info', 'warning',
'error', 'critical'],
help='loglevel for logfile (default is "info")')
argc.add_argument('--verbose', '-v', default=0, action='count',
help='verbose logging (-v, -vv, -vvv ... '
'more detail log)')
argc.add_argument('--dumpspec', nargs='?', choices=['json', 'yaml'],
const='json', default=None,
help='dump arguments spec as json or yaml format')These parameters are pre-defined for special functionality or PAM:
--infile- For input stream file (default is nothing,-means stdin)--outfile- For output stream file (default is stdout)--errfile- For error stream file (default is stderr)--statfile- For status (default is stdout)--logfile- For log file to logging (500K size, rotate 4)--loglevel- Loglevel for logfile (default is "info")--verboseor-v- Verbose logging (-v, -vv, -vvv ... more detail log)--dumpspec- Dump arguments spec as json or yaml format
- Do not re-define at plugin
At the end of _main() function you can see this code:
return do_figlet(mcxt, argspec)Every actual working function at the end of _main() function has two parameters:
mcxt- An instance ofModuleContextclassargspec- Parsed output of argument parsing
Next is the example ascii art code using figlet as explained earlyer chapter.
################################################################################
@func_log
def do_figlet(mcxt, argspec):
mcxt.logger.info('>>>starting...')
try:
if not argspec.message:
raise ValueError(f'Invalid Message')
direction = argspec.direction
justify = argspec.justify
width = int(argspec.width)
f = Figlet(font=argspec.font, direction=direction,
justify=justify, width=width)
print(f.renderText(argspec.message), end='')
return 0
except ValueError as err:
msg = str(err)
mcxt.logger.error(msg)
sys.stderr.write('%s%s' % (msg, os.linesep))
return 1
except Exception as err:
msg = str(err)
mcxt.logger.error(msg)
sys.stderr.write('%s%s' % (msg, os.linesep))
return 99
finally:
mcxt.logger.info('>>>end...')The most common thing with mcxt is to logging error, info, and so on. mcxt.logger have th following logging functions:
mcxt.logger.info('>>>starting...')- mcxt.logger.debug(msg, *args, **kwargs) - Logs a message with level DEBUG on the root logger. The msg is the message format string, and the args are the arguments which are merged into msg using the string formatting operator.
- mcxt.logger.info(msg, *args, **kwargs) - Logs a message with level INFO on the root logger. The arguments are interpreted as for debug().
- mcxt.logger.warning(msg, *args, **kwargs) - Logs a message with level WARNING on the root logger. The arguments are interpreted as for debug().
- mcxt.logger.error(msg, *args, **kwargs) - Logs a message with level ERROR on the root logger. The arguments are interpreted as for debug().
- mcxt.logger.critical(msg, *args, **kwargs) - Logs a message with level CRITICAL on the root logger. The arguments are interpreted as for debug().
PAMmanage plugin's log file.
You can find multiple return with different code as follows:
try:
...
return 0
except ValueError as err:
...
return 1
except Exception as err:
...
return 99This scheme is same as normal exception handling in Python.
There is one simple rule between PAM and plugin.
- return
0in case success - Otherwise return non zeon
We recommend for the broadest exception,
except Exception as errreturn99
You can use this return code as Failure code action at STU.
After run one plugin operation you can get the result at Return value section with one of types String, CSV or File.
For the plugin's return value regardless of those types String, CSV or File you can print out to STDOUT stream.
print('any message')or
import sys
...
sys.write(f'my output is {my}')or for the CSV type of output
import sys
import csv
...
c = csv.writer(sys.stdout, lineterminator='\n')
c.writerow(header)
for row in rows:
c.writerow(row)If you are familar with python CLI program with argparse this plugin is really same.
Moreover you can run our plugin as a normal python CLI command.





