Add "location" support (embed a tag with a Place object)

This commit is contained in:
Thomas Sileo 2019-10-27 19:05:42 +01:00
parent cf983ca9f3
commit e611d61739
4 changed files with 93 additions and 1 deletions

View file

@ -1,3 +1,4 @@
import logging
import mimetypes import mimetypes
from datetime import datetime from datetime import datetime
from datetime import timedelta from datetime import timedelta
@ -50,6 +51,8 @@ from core.tasks import Tasks
from utils import emojis from utils import emojis
from utils import now from utils import now
_logger = logging.getLogger(__name__)
blueprint = flask.Blueprint("api", __name__) blueprint = flask.Blueprint("api", __name__)
@ -450,6 +453,7 @@ def api_new_note() -> _Response:
source = None source = None
summary = None summary = None
place_tags = []
# Basic Micropub (https://www.w3.org/TR/micropub/) "create" support # Basic Micropub (https://www.w3.org/TR/micropub/) "create" support
is_micropub = False is_micropub = False
@ -463,8 +467,24 @@ def api_new_note() -> _Response:
if "jwt_payload" not in flask.g or "create" not in flask.g.jwt_payload["scope"]: if "jwt_payload" not in flask.g or "create" not in flask.g.jwt_payload["scope"]:
abort(403) abort(403)
# Handle location sent via form-data
# `geo:28.5,9.0,0.0`
location = _user_api_arg("location", default="")
if location.startswith("geo:"):
slat, slng, *_ = location[4:].split(",")
place_tags.append(
{
"type": ap.ActivityType.PLACE.value,
"url": "",
"name": "",
"latitude": float(slat),
"longitude": float(slng),
}
)
# Handle JSON microformats2 data # Handle JSON microformats2 data
if _user_api_arg("type", default=None): if _user_api_arg("type", default=None):
_logger.info(f"Micropub request: {request.json}")
try: try:
source = request.json["properties"]["content"][0] source = request.json["properties"]["content"][0]
except (ValueError, KeyError): except (ValueError, KeyError):
@ -493,6 +513,21 @@ def api_new_note() -> _Response:
if summary is None: if summary is None:
summary = _user_api_arg("summary", default="") summary = _user_api_arg("summary", default="")
if not place_tags:
if _user_api_arg("location_lat", default=None):
lat = float(_user_api_arg("location_lat"))
lng = float(_user_api_arg("location_lng"))
loc_name = _user_api_arg("location_name", default="")
place_tags.append(
{
"type": ap.ActivityType.PLACE.value,
"url": "",
"name": loc_name,
"latitude": lat,
"longitude": lng,
}
)
# All the following fields are specific to the API (i.e. not Micropub related) # All the following fields are specific to the API (i.e. not Micropub related)
_reply, reply = None, None _reply, reply = None, None
try: try:
@ -507,7 +542,7 @@ def api_new_note() -> _Response:
content, tags = parse_markdown(source) content, tags = parse_markdown(source)
# Check for custom emojis # Check for custom emojis
tags = tags + emojis.tags(content) tags = tags + emojis.tags(content) + place_tags
to: List[str] = [] to: List[str] = []
cc: List[str] = [] cc: List[str] = []

View file

@ -49,6 +49,15 @@
<input type="text" name="file_description" placeholder="attachment description (optional)"> <input type="text" name="file_description" placeholder="attachment description (optional)">
</p> </p>
<p>
<input type="text" name="location_lat" id="location_lat" placeholder="latitude (optional)">
<input type="text" name="location_lng" id="location_lng" placeholder="longitude (optional)">
<a href="#" class="location_autofill">ask browser for location</a>
</p>
<p>
<input type="text" name="location_name" placeholder="location name (optional)">
</p>
{% if request.args.get("question") == "1" %} {% if request.args.get("question") == "1" %}
<div style="margin-top:20px;"> <div style="margin-top:20px;">
<p>Open for: <select name="open_for"> <p>Open for: <select name="open_for">
@ -114,4 +123,16 @@ var items = document.getElementsByClassName("ji")
for (var i = 0; i < items.length; i++) { for (var i = 0; i < items.length; i++) {
items[i].addEventListener('click', ji); items[i].addEventListener('click', ji);
} }
var askForLocation = function(ev) {
ev.preventDefault();
navigator.geolocation.getCurrentPosition(function(position) {
document.getElementById("location_lat").value = position.coords.latitude;
document.getElementById("location_lng").value = position.coords.longitude;
});
}
var items = document.getElementsByClassName("location_autofill")
for (var i = 0; i < items.length; i++) {
items[i].addEventListener('click', askForLocation);
}
</script>{% endblock %} </script>{% endblock %}

View file

@ -208,6 +208,11 @@
{% else %} {% else %}
{{ obj.content | clean | replace_custom_emojis(obj) | code_highlight | safe }} {{ obj.content | clean | replace_custom_emojis(obj) | code_highlight | safe }}
{% endif %} {% endif %}
{% if obj | has_place %}
<p>Location: {{ obj | get_place | safe }}</p>
{% endif %}
</div> </div>
{% if obj.attachment and obj | has_type('Note') %} {% if obj.attachment and obj | has_type('Note') %}

View file

@ -240,6 +240,37 @@ def get_actor(url):
return f"Error<{url}/{exc!r}>" return f"Error<{url}/{exc!r}>"
@filters.app_template_filter()
def has_place(note):
for tag in note.get("tag", []):
if tag.get("type") == "Place":
return True
return False
@filters.app_template_filter()
def get_place(note):
for tag in note.get("tag", []):
if tag.get("type") == "Place":
lat = tag["latitude"]
lng = tag["longitude"]
out = ""
if tag.get("name"):
out += f"{tag['name']} "
out += (
'<span class="h-geo">'
f'<data class="p-latitude" value="{lat}"></data>'
f'<data class="p-longitude" value="{lng}"></data>'
f'<a href="https://www.openstreetmap.org/?mlat={lat}&mlon={lng}#map=16/{lat}/{lng}">{lat},{lng}</a>'
"</span>"
)
return out
return ""
@filters.app_template_filter() @filters.app_template_filter()
def poll_answer_key(choice: str) -> str: def poll_answer_key(choice: str) -> str:
return _answer_key(choice) return _answer_key(choice)