Add actions to feed view
This commit is contained in:
parent
1b16a48f31
commit
dd114ab0ae
|
@ -5,7 +5,7 @@ import time
|
||||||
|
|
||||||
from flask import Flask, render_template, request, jsonify, abort, redirect, url_for
|
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
|
# Globals
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
@ -70,7 +70,7 @@ def source_feed(source_name):
|
||||||
if count_arg.isdigit() and page_arg.isdigit():
|
if count_arg.isdigit() and page_arg.isdigit():
|
||||||
count = int(count_arg)
|
count = int(count_arg)
|
||||||
page = int(page_arg)
|
page = int(page_arg)
|
||||||
sorted_items = sorted_items[count * page:count * page + count]
|
sorted_items = sorted_items[count * page : count * page + count]
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"feed.jinja2",
|
"feed.jinja2",
|
||||||
|
@ -126,6 +126,13 @@ def mass_deactivate():
|
||||||
return jsonify({})
|
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():
|
def wsgi():
|
||||||
# init_default_logging()
|
# init_default_logging()
|
||||||
return app
|
return app
|
||||||
|
|
|
@ -75,7 +75,7 @@ class LocalSource:
|
||||||
yield json.loads(filepath.read_text(encoding="utf8"))
|
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.
|
Read the subprocess's stdout into memory.
|
||||||
This prevents the process from blocking when the pipe fills up.
|
This prevents the process from blocking when the pipe fills up.
|
||||||
|
@ -89,7 +89,7 @@ def read_stdout(process: Popen, output: list):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def read_stderr(process: Popen):
|
def _read_stderr(process: Popen) -> None:
|
||||||
"""
|
"""
|
||||||
Read the subprocess's stderr stream and pass it to logging.
|
Read the subprocess's stderr stream and pass it to logging.
|
||||||
This prevents the process from blocking when the pipe fills up.
|
This prevents the process from blocking when the pipe fills up.
|
||||||
|
@ -102,12 +102,12 @@ def read_stderr(process: Popen):
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def execute_source_action(
|
def _execute_source_action(
|
||||||
source: LocalSource, action: str, input: str, timeout: timedelta
|
source: LocalSource, action: str, input: str, timeout: timedelta
|
||||||
):
|
) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Execute the action from a given source. If stdin is specified, pass it
|
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
|
# Gather the information necessary to launch the process
|
||||||
config = source.get_config()
|
config = source.get_config()
|
||||||
|
@ -141,9 +141,9 @@ def execute_source_action(
|
||||||
|
|
||||||
# Kick off monitoring threads
|
# Kick off monitoring threads
|
||||||
output = []
|
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_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()
|
t_stderr.start()
|
||||||
|
|
||||||
# Send input to the process, if provided
|
# Send input to the process, if provided
|
||||||
|
@ -168,7 +168,7 @@ def execute_source_action(
|
||||||
return output
|
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.
|
Execute the feed source and return the current feed items.
|
||||||
Returns a list of feed items on success.
|
Returns a list of feed items on success.
|
||||||
|
@ -176,7 +176,7 @@ def fetch_items(source: LocalSource, timeout: int = 60):
|
||||||
"""
|
"""
|
||||||
items = []
|
items = []
|
||||||
|
|
||||||
output = execute_source_action(source, "fetch", None, timedelta(timeout))
|
output = _execute_source_action(source, "fetch", None, timedelta(timeout))
|
||||||
|
|
||||||
for line in output:
|
for line in output:
|
||||||
try:
|
try:
|
||||||
|
@ -188,13 +188,17 @@ def fetch_items(source: LocalSource, timeout: int = 60):
|
||||||
return items
|
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.
|
Execute the action for a feed source.
|
||||||
"""
|
"""
|
||||||
item = source.get_item(item_id)
|
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:
|
if not output:
|
||||||
raise SourceUpdateException("no item")
|
raise SourceUpdateException("no item")
|
||||||
|
|
||||||
|
|
|
@ -99,14 +99,13 @@ var mdeactivate = function (items) {
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var callback = function (source, itemid) {
|
var doAction = function (source, itemid, action) {
|
||||||
document.getElementById(source + "-" + itemid + "-callback").disabled = true;
|
document.getElementById(`${source}-${itemid}-action-${action}`).disabled = true;
|
||||||
fetch('/callback/', {
|
fetch(`/action/${source}/${itemid}/${action}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json; charset=UTF-8',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({source: source, itemid: itemid}),
|
|
||||||
})
|
})
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
location.reload()
|
location.reload()
|
||||||
|
@ -130,15 +129,15 @@ var callback = function (source, itemid) {
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# The item title is a clickable <summary> if there is body content #}
|
{# 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>
|
<details>
|
||||||
<summary><span class="item-title">{{item.title}}</span></summary>
|
<summary><span class="item-title">{{item.title}}</span></summary>
|
||||||
{% if item.body %}
|
{% if item.body %}
|
||||||
<p>{{item.body|safe}}</p>
|
<p>{{item.body|safe}}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.callback %}
|
{% for action in item.action %}
|
||||||
<p><button id="{{item.source}}-{{item.id}}-callback" onclick="javascript:callback('{{item.source}}', '{{item.id}}')">Callback</button></p>
|
<p><button id="{{item.source}}-{{item.id}}-action-{{action}}" onclick="javascript:doAction('{{item.source}}', '{{item.id}}', '{{action}}')">{{action}}</button></p>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
</details>
|
</details>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="item-title">{{item.title}}</span><br>
|
<span class="item-title">{{item.title}}</span><br>
|
||||||
|
|
|
@ -20,5 +20,6 @@ if args.action == "increment":
|
||||||
item = sys.stdin.readline()
|
item = sys.stdin.readline()
|
||||||
item = json.loads(item)
|
item = json.loads(item)
|
||||||
item["action"]["increment"] += 1
|
item["action"]["increment"] += 1
|
||||||
|
item["body"] = f"<p>{item['action']['increment']}</p>"
|
||||||
print(json.dumps(item))
|
print(json.dumps(item))
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in New Issue