Merge pull request #395 from wooey/script-url-parameters

Parse URL query parameters to prepopulate subparser and script parameters
This commit is contained in:
Joseph Min 2023-12-14 10:17:45 -05:00 committed by GitHub
commit dc457291cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 154 additions and 2 deletions

View File

@ -43,3 +43,27 @@ to parse this information), updates to the script version will result in a new
version being created. If a command line library doesn't support versioning
or the version has not been updated in a script, the Script Iteration counter
will be incremented.
Using URL parameters to pre-populate script parameters
------------------------------------------------------
Wooey supports pre-populating script parameters via URL parameters. This is
useful for providing a link to a script with some parameters already set. The
following rules apply.
* URL parameters are specified as :code:`?parameter=value`
* Multiple parameters may be specified by separating them with :code:`&`.
For example, :code:`?parameter1=value1&parameter2=value2`.
* Parameters are specified by the name used in the script, **but in snake case**.
For example, a parameter named :code:`--my-parameter` would be specified as
:code:`?my_parameter=value`.
* If a parameter is a flag, passing any value will set the flag. For example,
:code:`?my_flag=1` or :code:`?my_flag=true` will set the flag.
* If a parameter accepts multiple values (:code:`nargs`), the values are specified
by passing the parameter multiple times. For example, :code:`?my_parameter=1&my_parameter=2`
will set the parameter to have two values filled out: :code:`1` and :code:`2`.
If a parameter does not support multiple values and multiple values are passed,
the last value will be used.
* If the script has subparsers, the :code:`__subparser` parameter is used to specify
the subparser to use. For example, :code:`?__subparser=mysubparser` will select the
subparser named :code:`mysubparser`.

View File

@ -56,7 +56,7 @@
<ul class="dropdown-menu">
{% for parser_info, parser_groups in form.parsers.items %}
{% with parser_pk=parser_info.0 parser_name=parser_info.1 %}
<li class="{% if forloop.first %}active{% endif %}"><a data-toggle="tab" data-parser-pk="{{ parser_pk }}" href="#parsergroup-{{ parser_pk }}">{% if not parser_name %}{% trans "Main Parser Parameters" %}{% else %}{{ parser_name|title }}{% endif %}</a></li>
<li class="{% if forloop.first %}active{% endif %}"><a data-toggle="tab" data-parser-pk="{{ parser_pk }}" data-parser-name="{{ parser_name }}" href="#parsergroup-{{ parser_pk }}">{% if not parser_name %}{% trans "Main Parser Parameters" %}{% else %}{{ parser_name|title }}{% endif %}</a></li>
{% if forloop.first %}
<li role="separator" class="divider"></li>
{% endif %}
@ -263,7 +263,10 @@
selectWooeyParser($('div[id^=parsergroup-]'))
}
var $initial_parser = $("a[data-parser-pk=" + $wooey_parser.val() + "]");
// Set initial subparser if present in url params.
const urlParams = new URLSearchParams(window.location.search);
const subparser = urlParams.get('__subparser');
var $initial_parser = $("a[data-parser-name=" + subparser + "]");
if ($initial_parser.length) {
$initial_parser.click();
}

View File

@ -59,6 +59,12 @@ class ScriptTearDown(object):
class ScriptFactoryMixin(ScriptTearDown, object):
def setUp(self):
self.command_order_script_path = os.path.join(
config.WOOEY_TEST_SCRIPTS, "command_order.py"
)
self.command_order_script = factories.generate_script(
self.command_order_script_path
)
self.translate_script_path = os.path.join(
config.WOOEY_TEST_SCRIPTS, "translate.py"
)

View File

@ -278,6 +278,114 @@ class WooeyViews(mixins.ScriptFactoryMixin, mixins.FileCleanupMixin, TestCase):
d = load_JSON_dict(response.content)
self.assertTrue(d["valid"], d)
def test_url_parameters_positional(self):
script_version = self.command_order_script
url = reverse("wooey:wooey_script", kwargs={"slug": script_version.script.slug})
request = self.factory.get(
url,
data={
"link": "abc",
},
)
request.user = AnonymousUser()
response = self.script_view_func(
request,
pk=script_version.script.pk,
)
self.assertEqual(response.status_code, 200)
context = response.resolve_context(response.context_data)
parser = list(context["form"]["parsers"].keys())[0]
self.assertEqual(
context["form"]["parsers"][parser][0]["form"]
.fields[f"{parser[0]}-link"]
.initial,
"abc",
)
def test_url_parameters_optional(self):
script_version = self.translate_script
url = reverse("wooey:wooey_script", kwargs={"slug": script_version.script.slug})
request = self.factory.get(
url,
data={
"sequence": "abc",
},
)
request.user = AnonymousUser()
response = self.script_view_func(
request,
pk=script_version.script.pk,
)
self.assertEqual(response.status_code, 200)
context = response.resolve_context(response.context_data)
parser = list(context["form"]["parsers"].keys())[0]
self.assertEqual(
context["form"]["parsers"][parser][0]["form"]
.fields[f"{parser[0]}-sequence"]
.initial,
"abc",
)
def test_url_parameters_multi_choice(self):
script_version = self.choice_script
url = reverse("wooey:wooey_script", kwargs={"slug": script_version.script.slug})
request = self.factory.get(
url,
data={
"one_choice": "0",
"two_choices": ["0", "1"],
},
)
request.user = AnonymousUser()
response = self.script_view_func(
request,
pk=script_version.script.pk,
)
self.assertEqual(response.status_code, 200)
context = response.resolve_context(response.context_data)
parser = list(context["form"]["parsers"].keys())[0]
self.assertEqual(
context["form"]["parsers"][parser][1]["form"]
.fields[f"{parser[0]}-one_choice"]
.initial,
"0",
)
self.assertEqual(
context["form"]["parsers"][parser][1]["form"]
.fields[f"{parser[0]}-two_choices"]
.initial,
["0", "1"],
)
def test_url_parameters_subparser(self):
script_version = self.subparser_script
url = reverse("wooey:wooey_script", kwargs={"slug": script_version.script.slug})
request = self.factory.get(url, data={"test_arg": "3.3", "sp1": "2"})
request.user = AnonymousUser()
response = self.script_view_func(
request,
pk=script_version.script.pk,
)
self.assertEqual(response.status_code, 200)
context = response.resolve_context(response.context_data)
main_parser, subparser1, subparser2 = list(context["form"]["parsers"].keys())
self.assertEqual(
context["form"]["parsers"][main_parser][0]["form"]
.fields[f"{main_parser[0]}-test_arg"]
.initial,
"3.3",
)
self.assertEqual(
context["form"]["parsers"][subparser1][0]["form"]
.fields[f"{subparser1[0]}-sp1"]
.initial,
"2",
)
def test_job_view_permissions(self):
# Make sure users cannot see jobs from other users
job = factories.generate_job(self.translate_script)

View File

@ -73,6 +73,17 @@ class WooeyScriptBase(DetailView):
"script_version", "script_iteration"
).last()
# Set parameter initial values by parsing the URL parameters
# and matching them to the script parameters.
for param in script_version.get_parameters():
if param.script_param in self.request.GET:
value = (
self.request.GET.getlist(param.script_param)
if param.multiple_choice
else self.request.GET.get(param.script_param)
)
initial[param.form_slug] = value
context["form"] = utils.get_form_groups(
script_version=script_version,
initial_dict=initial,