Version 0.1.1

Default values are now shown in HTML-Form
This commit is contained in:
Christoph Stahl 2017-05-29 14:55:11 +02:00
parent f7fcde3100
commit de5549e43c
5 changed files with 92 additions and 4 deletions

77
README.rst Normal file
View file

@ -0,0 +1,77 @@
WARPED - a Webbased frontend for ARgparser in Python
====================================================
``warped`` can be used to execute single Python file and Python modules.
It captures calls to the ``argparse`` module of Python and renders a web
GUI based on the options and arguments defined. It also displays the
output of the program inside the web GUI and allows you to stop, pause
and resume the program, as well as downloading the output.
Install
-------
Either get a stable version from PyPI, or install the current version
from git
::
# Installation from PyPI
pip install warped
# Installation from git
pip install git+https://git.k-fortytwo.de/christofsteel/warped/
Usage
-----
::
warped [-h] [--port PORT] [--host HOST] [--module] file
a Webbased frontend for ARgparse in Python
positional arguments:
file File to run
optional arguments:
-h, --help show this help message and exit
--port PORT, -p PORT The port to listen on (default 5000)
--host HOST The host to bind to (default 0.0.0.0)
--module, -m If set, loads a module instead of a file
Sample
------
To test the capabilities of ``warped`` an example module was included.
You can run it like this:
::
warped -m warped.samples.hooked
Since ``warped`` also makes use of the argparse module, ``warped``
itself can be //warped//.
::
warped -m warped.hook
How does it work?
-----------------
When ``warped`` is executed, it starts a flask webserver. The javascript
of the website reads the ``/arguments`` resource of the server, where
the configuration of the argparser returned. In a seperate process the
given program is executed using the ``runpy`` library, redirecting
``sys.stdin`` and ``sys.stdout`` to a ``multiprocessing.Queue``, which
can be read by the warp process to display it via the web GUI.
Additionally, ``warped`` adds an entry for ``argparse`` in the
``sys.modules`` list. Python looks first looks at this list, everytime a
module is imported, to avoid importing a module multiple times. This
custom ``argparse`` module behaves similar to the original ``argparse``
module. In fact with the exception of the
``ArgumentParser.parse_args()`` method, it works exactly like the
original. Once the program calls the ``parse_args()`` method, it blocks
and waits for user interaction via the web GUI. Once the user submits
the data, the process continues.

View file

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup( setup(
name='warped', name='warped',
version='0.1.0', version='0.1.1',
packages=find_packages(), packages=find_packages(),
url='https://git.k-fortytwo.de/christofsteel/warp', url='https://git.k-fortytwo.de/christofsteel/warp',
download_url = 'https://git.k-fortytwo.de/christofsteel/warped/archive/0.1.0.tar.gz', download_url = 'https://git.k-fortytwo.de/christofsteel/warped/archive/0.1.0.tar.gz',

View file

@ -43,6 +43,7 @@ class Action():
internal_dict['dest'] = self.dest internal_dict['dest'] = self.dest
internal_dict['desc'] = self.desc internal_dict['desc'] = self.desc
internal_dict['checked'] = self.on_none if self.on_none is True or self.on_none is False else None internal_dict['checked'] = self.on_none if self.on_none is True or self.on_none is False else None
internal_dict['default'] = self.on_none if type(self.on_none) == str else None
internal_dict['optional'] = self.optional internal_dict['optional'] = self.optional
internal_dict['is_const'] = self.const is not None internal_dict['is_const'] = self.const is not None
internal_dict['type'] = self.type_function.__name__ internal_dict['type'] = self.type_function.__name__

View file

@ -21,7 +21,7 @@ def main():
group3 = group2.add_mutually_exclusive_group() group3 = group2.add_mutually_exclusive_group()
group3.add_argument('--three') group3.add_argument('--three')
group3.add_argument('--four') group3.add_argument('--four')
bla.add_argument('--test', '-t', help="Blubb") bla.add_argument('--test', '-t', help="Blubb", default="Blabla")
bla.add_argument('--bla', action="store_true", default=True) bla.add_argument('--bla', action="store_true", default=True)
bla.add_argument('--blubb', action="store_true") bla.add_argument('--blubb', action="store_true")
bla.add_argument('-f', action="append") bla.add_argument('-f', action="append")

View file

@ -120,7 +120,10 @@ function createInputAction(action) {
function disableAction(action) { function disableAction(action) {
return function () { return function () {
console.log("disable"); console.log("disable");
thisli = $('#action-' + action['uuid']); var thisli = $('#action-' + action['uuid']);
var input = $('#action-' + action['uuid'] + ' input');
thisli.attr('old_val', input.val())
$('#action-' + action['uuid'] + ' input').val(action["default"]);
thisli.prop('disabled', true).addClass('disabled'); thisli.prop('disabled', true).addClass('disabled');
delbutton = $('#action-' + action['uuid' + "button"]); delbutton = $('#action-' + action['uuid' + "button"]);
delbutton.prop('disabled', true).addClass('disabled'); delbutton.prop('disabled', true).addClass('disabled');
@ -134,7 +137,13 @@ function disableAction(action) {
function enableAction(action) { function enableAction(action) {
return function() { return function() {
console.log("enable"); console.log("enable");
thisli = $('#action-' + action['uuid']); var thisli = $('#action-' + action['uuid']);
var oldval = thisli.attr('old_val');
if (oldval !== undefined) {
var input = $('#action-' + action['uuid'] + ' input');
thisli.oldval = input.val()
$('#action-' + action['uuid'] + ' input').val(oldval);
}
thisli.prop('disabled', false).removeClass('disabled'); thisli.prop('disabled', false).removeClass('disabled');
delbutton = $('#action-' + action['uuid' + "button"]); delbutton = $('#action-' + action['uuid' + "button"]);
delbutton.prop('disabled', false).removeClass('disabled'); delbutton.prop('disabled', false).removeClass('disabled');
@ -181,6 +190,7 @@ function createAction(action) {
if(action.optional === true) { if(action.optional === true) {
li.prop('disabled', true).addClass('disabled'); li.prop('disabled', true).addClass('disabled');
input.prop('disabled', true).addClass('disabled'); input.prop('disabled', true).addClass('disabled');
input.val(action["default"]);
input.find('input').prop('disabled', true).addClass('disabled'); input.find('input').prop('disabled', true).addClass('disabled');
input.find('.addbutton').prop('disabled', true).addClass('disabled'); input.find('.addbutton').prop('disabled', true).addClass('disabled');
input.find('.rembutton').prop('disabled', true).addClass('disabled'); input.find('.rembutton').prop('disabled', true).addClass('disabled');