Convert map links within post location into an embedded OSM map

main
Bob Mottram 2022-05-21 12:36:53 +01:00
parent 55fc047686
commit bb64125391
3 changed files with 269 additions and 6 deletions

235
maps.py 100644
View File

@ -0,0 +1,235 @@
__filename__ = "maps.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.3.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@libreserver.org"
__status__ = "Production"
__module_group__ = "Core"
def _geocoords_from_osm_link(url: str, osm_domain: str) -> (int, float, float):
"""Returns geocoordinates from an OSM map link
"""
if osm_domain + '/#map=' not in url:
return None, None, None
coords_str = url.split('openstreetmap.org/#map=')[1]
if '/' not in coords_str:
return None, None, None
coords = coords_str.split('/')
if len(coords) != 3:
return None, None, None
zoom = coords[0]
if not zoom.isdigit():
return None, None, None
latitude = coords[1]
if not latitude.isdigit():
return None, None, None
longitude = coords[2]
if not longitude.isdigit():
return None, None, None
zoom = int(zoom)
latitude = float(latitude)
longitude = float(longitude)
return zoom, latitude, longitude
def _geocoords_from_gmaps_link(url: str) -> (int, float, float):
"""Returns geocoordinates from a Gmaps link
"""
if '/maps/@' not in url:
return None, None, None
coords_str = url.split('/maps/@')[1]
if ',' not in coords_str:
return None, None, None
coords = coords_str.split(',')
if len(coords) != 3:
return None, None, None
zoom = coords[2].replace('z', '')
if not zoom.isdigit():
return None, None, None
latitude = coords[0]
if not latitude.isdigit():
return None, None, None
longitude = coords[1]
if not longitude.isdigit():
return None, None, None
zoom = int(zoom)
latitude = float(latitude)
longitude = float(longitude)
return zoom, latitude, longitude
def _geocoords_from_bmaps_link(url: str) -> (int, float, float):
"""Returns geocoordinates from a bing map link
"""
prefixes = ('/maps?cp=', '/maps/directions?cp=')
map_prefix = None
for prefix in prefixes:
if prefix in url:
map_prefix = prefix
break
if not map_prefix:
return None, None, None
coords_str = url.split(map_prefix)[1]
if '~' not in coords_str:
return None, None, None
orig_coords_str = coords_str
if '&' in coords_str:
coords_str = coords_str.split('&')[0]
if ';' in coords_str:
coords_str = coords_str.split(';')[0]
coords = coords_str.split('~')
if len(coords) != 2:
return None, None, None
latitude = coords[0]
if not latitude.isdigit():
return None, None, None
longitude = coords[1]
if not longitude.isdigit():
return None, None, None
zoom = 17
if 'lvl=' in orig_coords_str:
zoom = orig_coords_str.split('lvl=')[1]
if '&' in zoom:
zoom = zoom.split('&')[0]
if ';' in zoom:
zoom = zoom.split(';')[0]
if not zoom.isdigit():
return None, None, None
zoom = int(zoom)
latitude = float(latitude)
longitude = float(longitude)
return zoom, latitude, longitude
def _geocoords_from_waze_link(url: str) -> (int, float, float):
"""Returns geocoordinates from a waze map link
"""
prefixes = ['/ul?ll=']
map_prefix = None
for prefix in prefixes:
if prefix in url:
map_prefix = prefix
break
if not map_prefix:
return None, None, None
coords_str = url.split(map_prefix)[1]
orig_coords_str = coords_str
if '&' in coords_str:
coords_str = coords_str.split('&')[0]
if '%2C' not in coords_str and ',' not in coords_str:
return None, None, None
if '%2C' in coords_str:
coords = coords_str.split('%2C')
else:
coords = coords_str.split(',')
if len(coords) != 2:
return None, None, None
latitude = coords[0]
if not latitude.isdigit():
return None, None, None
longitude = coords[1]
if not longitude.isdigit():
return None, None, None
zoom = 17
if 'zoom=' in orig_coords_str:
zoom = orig_coords_str.split('zoom=')[1]
if '&' in zoom:
zoom = zoom.split('&')[0]
if not zoom.isdigit():
return None, None, None
zoom = int(zoom)
latitude = float(latitude)
longitude = float(longitude)
return zoom, latitude, longitude
def _geocoords_from_wego_link(url: str) -> (int, float, float):
"""Returns geocoordinates from a wego map link
"""
prefixes = ['/?map=']
map_prefix = None
for prefix in prefixes:
if prefix in url:
map_prefix = prefix
break
if not map_prefix:
return None, None, None
coords_str = url.split(map_prefix)[1]
if ',' not in coords_str:
return None, None, None
coords = coords_str.split(',')
if len(coords) < 3:
return None, None, None
latitude = coords[0]
if not latitude.isdigit():
return None, None, None
longitude = coords[1]
if not longitude.isdigit():
return None, None, None
zoom = coords[2]
if not zoom.isdigit():
return None, None, None
zoom = int(zoom)
latitude = float(latitude)
longitude = float(longitude)
return zoom, latitude, longitude
def _geocoords_from_map_link(url: str, osm_domain: str) -> (int, float, float):
"""Returns geocoordinates from a map link url
"""
if osm_domain in url:
return _geocoords_from_osm_link(url, osm_domain)
elif '.google.co' in url:
return _geocoords_from_gmaps_link(url)
elif '.bing.co' in url:
return _geocoords_from_bmaps_link(url)
elif '.waze.co' in url:
return _geocoords_from_waze_link(url)
elif 'wego.here.co' in url:
return _geocoords_from_wego_link(url)
return None, None, None
def html_open_street_map(url: str,
bounding_box_degrees: float,
translate: {}) -> str:
"""Returns embed html for an OSM link
"""
osm_domain = 'openstreetmap.org'
zoom, latitude, longitude = _geocoords_from_map_link(url, osm_domain)
if not latitude:
return ''
if not longitude:
return ''
if not zoom:
return ''
html_str = \
'<iframe width="425" height="350" frameborder="0" ' + \
'scrolling="no" marginheight="0" marginwidth="0" ' + \
'src="https://www.' + osm_domain + '/export/embed.html?' + \
'bbox=' + str(longitude - bounding_box_degrees) + \
'%2C' + \
str(latitude - bounding_box_degrees) + \
'%2C' + \
str(longitude + bounding_box_degrees) + \
'%2C' + \
str(latitude + bounding_box_degrees) + \
'&amp;layer=mapnik" style="border: 1px solid black"></iframe>' + \
'<br/><small><a href="https://www.' + osm_domain + '/#map=' + \
zoom + '/' + latitude + '/' + longitude + \
'">' + translate['View Larger Map'] + '</a></small>\n'
return html_str

View File

@ -682,7 +682,8 @@ def html_new_post(css_cache: {}, media_instance: bool, translate: {},
date_and_location += date_and_time_str
date_and_location += \
edit_text_field(translate['Location'], 'location', '')
edit_text_field(translate['Location'], 'location',
'https://www.openstreetmap.org/#map=')
date_and_location += end_edit_section()
instance_title = get_config_param(base_dir, 'instanceTitle')

View File

@ -93,6 +93,21 @@ from languages import auto_translate_post
from blocking import is_blocked
from blocking import add_cw_from_lists
from reaction import html_emoji_reactions
from maps import html_open_street_map
def _get_location_from_tags(tags: []) -> str:
"""Returns the location from the tags list
"""
for tag_item in tags:
if not tag_item.get('type'):
continue
if tag_item['type'] != 'Place':
continue
if not tag_item.get('name'):
continue
return tag_item['name'].replace('\n', ' ')
return None
def _html_post_metadata_open_graph(domain: str, post_json_object: {},
@ -2128,11 +2143,23 @@ def individual_post_as_html(signing_priv_key_pem: str,
_log_post_timing(enable_timing_log, post_start_time, '17')
if post_json_object['object'].get('tag') and not is_patch:
content_str = \
replace_emoji_from_tags(session, base_dir, content_str,
post_json_object['object']['tag'],
'content', False, True)
if post_json_object['object'].get('tag'):
if not is_patch:
content_str = \
replace_emoji_from_tags(session, base_dir, content_str,
post_json_object['object']['tag'],
'content', False, True)
# show embedded map if the location contains a map url
location_str = \
_get_location_from_tags(post_json_object['object']['tag'])
if location_str:
if '://' in location_str and '.' in location_str:
bounding_box_degrees = 0.01
content_str += \
html_open_street_map(location_str,
bounding_box_degrees,
translate)
if is_muted:
content_str = ''