~tsileo/microblog.pub

e611d61739813ac6175e7051b6955c3ec875d1cc — Thomas Sileo 8 months ago cf983ca
Add "location" support (embed a tag with a Place object)
4 files changed, 93 insertions(+), 1 deletions(-)

M blueprints/api.py
M templates/new.html
M templates/utils.html
M utils/template_filters.py
M blueprints/api.py => blueprints/api.py +36 -1
@@ 1,3 1,4 @@
import logging
import mimetypes
from datetime import datetime
from datetime import timedelta


@@ 50,6 51,8 @@ from core.tasks import Tasks
from utils import emojis
from utils import now

_logger = logging.getLogger(__name__)

blueprint = flask.Blueprint("api", __name__)




@@ 450,6 453,7 @@ def api_new_note() -> _Response:

    source = None
    summary = None
    place_tags = []

    # Basic Micropub (https://www.w3.org/TR/micropub/) "create" support
    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"]:
            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
        if _user_api_arg("type", default=None):
            _logger.info(f"Micropub request: {request.json}")
            try:
                source = request.json["properties"]["content"][0]
            except (ValueError, KeyError):


@@ 493,6 513,21 @@ def api_new_note() -> _Response:
    if summary is None:
        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)
    _reply, reply = None, None
    try:


@@ 507,7 542,7 @@ def api_new_note() -> _Response:
    content, tags = parse_markdown(source)

    # Check for custom emojis
    tags = tags + emojis.tags(content)
    tags = tags + emojis.tags(content) + place_tags

    to: List[str] = []
    cc: List[str] = []

M templates/new.html => templates/new.html +21 -0
@@ 49,6 49,15 @@
<input type="text" name="file_description" placeholder="attachment description (optional)">
</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" %}
<div style="margin-top:20px;">
    <p>Open for: <select name="open_for">


@@ 114,4 123,16 @@ var items = document.getElementsByClassName("ji")
for (var i = 0; i < items.length; i++) {
    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 %}

M templates/utils.html => templates/utils.html +5 -0
@@ 208,6 208,11 @@
    {% else %}
	{{ obj.content | clean | replace_custom_emojis(obj) | code_highlight | safe }}
    {% endif %}

    {% if obj | has_place %}
    <p>Location: {{ obj | get_place | safe }}</p>
    {% endif %}

	</div>

	{% if obj.attachment and obj | has_type('Note') %}

M utils/template_filters.py => utils/template_filters.py +31 -0
@@ 241,6 241,37 @@ def get_actor(url):


@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()
def poll_answer_key(choice: str) -> str:
    return _answer_key(choice)