Add actions to feed view

This commit is contained in:
Tim Van Baak 2023-06-01 17:03:30 -07:00
parent 1b16a48f31
commit dd114ab0ae
4 changed files with 32 additions and 21 deletions

View File

@ -5,7 +5,7 @@ import time
from flask import Flask, render_template, request, jsonify, abort, redirect, url_for
from intake.source import LocalSource
from intake.source import LocalSource, execute_action
# Globals
app = Flask(__name__)
@ -126,6 +126,13 @@ def mass_deactivate():
return jsonify({})
@app.post("/action/<string:source_name>/<string:item_id>/<string:action>")
def action(source_name, item_id, action):
source = LocalSource(intake_data_dir(), source_name)
item = execute_action(source, item_id, action)
return jsonify(item)
def wsgi():
# init_default_logging()
return app

View File

@ -75,7 +75,7 @@ class LocalSource:
yield json.loads(filepath.read_text(encoding="utf8"))
def read_stdout(process: Popen, output: list):
def _read_stdout(process: Popen, output: list) -> None:
"""
Read the subprocess's stdout into memory.
This prevents the process from blocking when the pipe fills up.
@ -89,7 +89,7 @@ def read_stdout(process: Popen, output: list):
break
def read_stderr(process: Popen):
def _read_stderr(process: Popen) -> None:
"""
Read the subprocess's stderr stream and pass it to logging.
This prevents the process from blocking when the pipe fills up.
@ -102,12 +102,12 @@ def read_stderr(process: Popen):
break
def execute_source_action(
def _execute_source_action(
source: LocalSource, action: str, input: str, timeout: timedelta
):
) -> List[str]:
"""
Execute the action from a given source. If stdin is specified, pass it
along to the process.
along to the process. Returns lines from stdout.
"""
# Gather the information necessary to launch the process
config = source.get_config()
@ -141,9 +141,9 @@ def execute_source_action(
# Kick off monitoring threads
output = []
t_stdout: Thread = Thread(target=read_stdout, args=(process, output), daemon=True)
t_stdout: Thread = Thread(target=_read_stdout, args=(process, output), daemon=True)
t_stdout.start()
t_stderr: Thread = Thread(target=read_stderr, args=(process,), daemon=True)
t_stderr: Thread = Thread(target=_read_stderr, args=(process,), daemon=True)
t_stderr.start()
# Send input to the process, if provided
@ -168,7 +168,7 @@ def execute_source_action(
return output
def fetch_items(source: LocalSource, timeout: int = 60):
def fetch_items(source: LocalSource, timeout: int = 60) -> List[dict]:
"""
Execute the feed source and return the current feed items.
Returns a list of feed items on success.
@ -176,7 +176,7 @@ def fetch_items(source: LocalSource, timeout: int = 60):
"""
items = []
output = execute_source_action(source, "fetch", None, timedelta(timeout))
output = _execute_source_action(source, "fetch", None, timedelta(timeout))
for line in output:
try:
@ -188,13 +188,17 @@ def fetch_items(source: LocalSource, timeout: int = 60):
return items
def execute_action(source: LocalSource, item_id: str, action: str, timeout: int = 60):
def execute_action(
source: LocalSource, item_id: str, action: str, timeout: int = 60
) -> dict:
"""
Execute the action for a feed source.
"""
item = source.get_item(item_id)
output = execute_source_action(source, action, json.dumps(item), timedelta(timeout))
output = _execute_source_action(
source, action, json.dumps(item), timedelta(timeout)
)
if not output:
raise SourceUpdateException("no item")

View File

@ -99,14 +99,13 @@ var mdeactivate = function (items) {
location.reload();
});
};
var callback = function (source, itemid) {
document.getElementById(source + "-" + itemid + "-callback").disabled = true;
fetch('/callback/', {
var doAction = function (source, itemid, action) {
document.getElementById(`${source}-${itemid}-action-${action}`).disabled = true;
fetch(`/action/${source}/${itemid}/${action}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: JSON.stringify({source: source, itemid: itemid}),
})
.then(function (data) {
location.reload()
@ -130,15 +129,15 @@ var callback = function (source, itemid) {
{% endif %}
{# The item title is a clickable <summary> if there is body content #}
{% if item.body or item.callback %}
{% if item.body or item.action %}
<details>
<summary><span class="item-title">{{item.title}}</span></summary>
{% if item.body %}
<p>{{item.body|safe}}</p>
{% endif %}
{% if item.callback %}
<p><button id="{{item.source}}-{{item.id}}-callback" onclick="javascript:callback('{{item.source}}', '{{item.id}}')">Callback</button></p>
{% endif %}
{% for action in item.action %}
<p><button id="{{item.source}}-{{item.id}}-action-{{action}}" onclick="javascript:doAction('{{item.source}}', '{{item.id}}', '{{action}}')">{{action}}</button></p>
{% endfor %}
</details>
{% else %}
<span class="item-title">{{item.title}}</span><br>

View File

@ -20,5 +20,6 @@ if args.action == "increment":
item = sys.stdin.readline()
item = json.loads(item)
item["action"]["increment"] += 1
item["body"] = f"<p>{item['action']['increment']}</p>"
print(json.dumps(item))
pass