From 4a632c1c94ba771ac5a17df28d39bbfd20184ba6 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 20 May 2022 16:18:02 +0100 Subject: [PATCH 01/21] Convert ID3 metadata field on audio attachments into hashtags --- media.py | 32 ++++++++++++++++++++++++++++++++ posts.py | 20 ++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/media.py b/media.py index 1f84f7a10..c5c61b195 100644 --- a/media.py +++ b/media.py @@ -162,6 +162,38 @@ def _spoof_meta_data(base_dir: str, nickname: str, domain: str, return +def get_music_metadata(filename: str) -> {}: + """Returns metadata for a music file + """ + result = None + try: + result = subprocess.run(['exiftool', '-v3', filename], + stdout=subprocess.PIPE) + except BaseException as ex: + print('EX: get_music_metadata failed ' + str(ex)) + if not result: + return {} + if not result.stdout: + return {} + try: + id3_lines = result.stdout.decode('utf-8').split('\n') + except BaseException: + print('EX: get_music_metadata unable to decode output') + return {} + fieldnames = ( + 'Title', 'Artist', 'Genre', 'Track', 'Album', 'Length', 'Band' + ) + music_metadata = {} + for line in id3_lines: + for field in fieldnames: + if field + ' = ' in line: + field_value = line.split(field + ' = ')[1] + if '>' in field_value: + field_value = field_value.split('>')[0].strip() + music_metadata[field.lower()] = field_value + return music_metadata + + def convert_image_to_low_bandwidth(image_filename: str) -> None: """Converts an image to a low bandwidth version """ diff --git a/posts.py b/posts.py index 1780999d7..da64d85fd 100644 --- a/posts.py +++ b/posts.py @@ -32,6 +32,8 @@ from webfinger import webfinger_handle from httpsig import create_signed_header from siteactive import site_is_active from languages import understood_post_language +from utils import valid_hash_tag +from utils import get_audio_extensions from utils import get_summary_from_post from utils import get_user_paths from utils import invalid_ciphertext @@ -70,6 +72,7 @@ from utils import remove_html from utils import dangerous_markup from utils import acct_dir from utils import local_actor_url +from media import get_music_metadata from media import attach_media from media import replace_you_tube from media import replace_twitter @@ -1423,6 +1426,23 @@ def _create_post_base(base_dir: str, else: mentioned_recipients = '' + # add hashtags from audio file ID3 tags, such as Artist, Album, etc + if attach_image_filename and media_type: + audio_types = get_audio_extensions() + music_metadata = None + for ext in audio_types: + if ext in media_type: + music_metadata = get_music_metadata(attach_image_filename) + break + if music_metadata: + for audio_tag, audio_value in music_metadata.items(): + if audio_tag == 'title' or audio_tag == 'track': + continue + audio_value = audio_value.title().replace(' ', '') + if valid_hash_tag(audio_value) and \ + '#' + audio_value not in content: + content += ' #' + audio_value + tags = [] hashtags_dict = {} From 7907d79eaaa84808faadeacf3b275ff8a76b5c45 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 20 May 2022 16:55:02 +0100 Subject: [PATCH 02/21] Check if music file hashtag is blocked --- posts.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/posts.py b/posts.py index da64d85fd..86061af00 100644 --- a/posts.py +++ b/posts.py @@ -84,6 +84,7 @@ from content import add_html_tags from content import replace_emoji_from_tags from content import remove_text_formatting from auth import create_basic_auth_header +from blocking import is_blocked_hashtag from blocking import is_blocked from blocking import is_blocked_domain from filters import is_filtered @@ -1441,7 +1442,8 @@ def _create_post_base(base_dir: str, audio_value = audio_value.title().replace(' ', '') if valid_hash_tag(audio_value) and \ '#' + audio_value not in content: - content += ' #' + audio_value + if not is_blocked_hashtag(base_dir, audio_value): + content += ' #' + audio_value tags = [] hashtags_dict = {} From 240e7219cdad09ab94eae0ce0db71f7daad278e1 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 20 May 2022 17:16:58 +0100 Subject: [PATCH 03/21] Remove music metadata words containing colon --- media.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/media.py b/media.py index c5c61b195..66ad93063 100644 --- a/media.py +++ b/media.py @@ -190,6 +190,13 @@ def get_music_metadata(filename: str) -> {}: field_value = line.split(field + ' = ')[1] if '>' in field_value: field_value = field_value.split('>')[0].strip() + if ':' in field_value and ' ' in field_value: + words = field_value.split(' ') + new_value = '' + for wrd in words: + if ':' not in wrd: + new_value += wrd + ' ' + field_value = new_value.strip() music_metadata[field.lower()] = field_value return music_metadata From 372e1c8a48682c5c936c1bee28af0398e417074e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 20 May 2022 17:30:10 +0100 Subject: [PATCH 04/21] Tidying --- media.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/media.py b/media.py index 66ad93063..b5bc6a310 100644 --- a/media.py +++ b/media.py @@ -186,18 +186,19 @@ def get_music_metadata(filename: str) -> {}: music_metadata = {} for line in id3_lines: for field in fieldnames: - if field + ' = ' in line: - field_value = line.split(field + ' = ')[1] - if '>' in field_value: - field_value = field_value.split('>')[0].strip() - if ':' in field_value and ' ' in field_value: - words = field_value.split(' ') - new_value = '' - for wrd in words: - if ':' not in wrd: - new_value += wrd + ' ' - field_value = new_value.strip() - music_metadata[field.lower()] = field_value + if field + ' = ' not in line: + continue + field_value = line.split(field + ' = ')[1] + if '>' in field_value: + field_value = field_value.split('>')[0].strip() + if ':' in field_value and ' ' in field_value: + words = field_value.split(' ') + new_value = '' + for wrd in words: + if ':' not in wrd: + new_value += wrd + ' ' + field_value = new_value.strip() + music_metadata[field.lower()] = field_value return music_metadata From e21f34aab6913f3b0e16a08c2c567cb0b88bd73e Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 20 May 2022 18:01:12 +0100 Subject: [PATCH 05/21] Convert music genre numbers into text --- media.py | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) diff --git a/media.py b/media.py index b5bc6a310..046b824df 100644 --- a/media.py +++ b/media.py @@ -29,6 +29,203 @@ from shutil import move from city import spoof_geolocation +# music file ID3 v1 genres +music_genre = { + 0: "Blues", + 96: "Big Band", + 1: "Classic Rock", + 97: "Chorus", + 2: "Country", + 98: "Easy Listening", + 3: "Dance", + 99: "Acoustic", + 4: "Disco", + 100: "Humour", + 5: "Funk", + 101: "Speech", + 6: "Grunge", + 102: "Chanson", + 7: "Hip Hop", + 103: "Opera", + 8: "Jazz", + 104: "Chamber Music", + 9: "Metal", + 105: "Sonata", + 10: "New Age", + 106: "Symphony", + 11: "Oldies", + 107: "Booty Bass", + 12: "Other", + 108: "Primus", + 13: "Pop", + 109: "Porn Groove", + 14: "RnB", + 110: "Satire", + 15: "Rap", + 111: "Slow Jam", + 16: "Reggae", + 112: "Club", + 17: "Rock", + 113: "Tango", + 18: "Techno", + 114: "Samba", + 19: "Industrial", + 115: "Folklore", + 20: "Alternative", + 116: "Ballad", + 21: "Ska", + 117: "Power Ballad", + 22: "Death Metal", + 118: "Rhythmic Soul", + 23: "Pranks", + 119: "Freestyle", + 24: "Soundtrack", + 120: "Duet", + 25: "Euro-Techno", + 121: "Punk Rock", + 26: "Ambient", + 122: "Drum Solo", + 27: "Trip Hop", + 123: "A Cappella", + 28: "Vocal", + 124: "Euro House", + 29: "Jazz Funk", + 125: "Dance Hall", + 30: "Fusion", + 126: "Goa", + 31: "Trance", + 127: "Drum and Bass", + 32: "Classical", + 128: "Club House", + 33: "Instrumental", + 129: "Hardcore", + 34: "Acid", + 130: "Terror", + 35: "House", + 131: "Indie", + 36: "Game", + 132: "BritPop", + 37: "Sound Clip", + 133: "Negerpunk", + 38: "Gospel", + 134: "Polsk Punk", + 39: "Noise", + 135: "Beat", + 40: "AlternRock", + 136: "Christian Gangsta Rap", + 41: "Bass", + 137: "Heavy Metal", + 42: "Soul", + 138: "Black Metal", + 43: "Punk", + 139: "Crossover", + 44: "Space", + 140: "Contemporary Christian", + 45: "Meditative", + 141: "Christian Rock", + 46: "Instrumental Pop", + 142: "Merengue", + 47: "Instrumental Rock", + 143: "Salsa", + 48: "Ethnic", + 144: "Thrash Metal", + 49: "Gothic", + 145: "Anime", + 50: "Darkwave", + 146: "JPop", + 51: "Techno Industrial", + 147: "Synthpop", + 52: "Electronic", + 148: "Abstract", + 53: "Pop Folk", + 149: "Art Rock", + 54: "Eurodance", + 150: "Baroque", + 55: "Dream", + 151: "Bhangra", + 56: "Southern Rock", + 152: "Big Beat", + 57: "Comedy", + 153: "Breakbeat", + 58: "Cult", + 154: "Chillout", + 59: "Gangsta Rap", + 155: "Downtempo", + 60: "Top 40", + 156: "Dub", + 61: "Christian Rap", + 157: "EBM", + 62: "Pop Funk", + 158: "Eclectic", + 63: "Jungle", + 159: "Electro", + 64: "Native American", + 160: "Electroclash", + 65: "Cabaret", + 161: "Emo", + 66: "New Wave", + 162: "Experimental", + 67: "Psychedelic", + 163: "Garage", + 68: "Rave", + 164: "Global", + 69: "Showtunes", + 165: "IDM", + 70: "Trailer", + 166: "Illbient", + 71: "Lo Fi", + 167: "Industro Goth", + 72: "Tribal", + 168: "Jam Band", + 73: "Acid Punk", + 169: "Krautrock", + 74: "Acid Jazz", + 170: "Leftfield", + 75: "Polka", + 171: "Lounge", + 76: "Retro", + 172: "Math Rock", + 77: "Musical", + 173: "New Romantic", + 78: "Rock and Roll", + 174: "Nu-Breakz", + 79: "Hard Rock", + 175: "Post Punk", + 80: "Folk", + 176: "Post Rock", + 81: "Folk Rock", + 177: "Psytrance", + 82: "National Folk", + 178: "Shoegaze", + 83: "Swing", + 179: "Space Rock", + 84: "Fast Fusion", + 180: "Trop Rock", + 85: "Bebob", + 181: "World Music", + 86: "Latin", + 182: "Neoclassical", + 87: "Revival", + 183: "Audiobook", + 88: "Celtic", + 184: "Audio Theatre", + 89: "Bluegrass", + 185: "Neue Deutsche Welle", + 90: "Avantgarde", + 186: "Podcast", + 91: "Gothic Rock", + 187: "Indie Rock", + 92: "Progressive Rock", + 188: "G Funk", + 93: "Psychedelic Rock", + 189: "Dubstep", + 94: "Symphonic Rock", + 190: "Garage Rock", + 95: "Slow Rock", + 191: "Psybient" +} + + def _get_blur_hash() -> str: """You may laugh, but this is a lot less computationally intensive, especially on large images, while still providing some visual variety @@ -198,6 +395,9 @@ def get_music_metadata(filename: str) -> {}: if ':' not in wrd: new_value += wrd + ' ' field_value = new_value.strip() + if field == 'Genre' and field_value.isdigit(): + if music_genre.get(int(field_value)): + field_value = music_genre[int(field_value)] music_metadata[field.lower()] = field_value return music_metadata From 55fc0476862d81dc1676cd5a077b2c50fe741d8f Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 20 May 2022 21:02:08 +0100 Subject: [PATCH 06/21] Add comments --- posts.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/posts.py b/posts.py index 86061af00..5ee5649f1 100644 --- a/posts.py +++ b/posts.py @@ -1439,9 +1439,12 @@ def _create_post_base(base_dir: str, for audio_tag, audio_value in music_metadata.items(): if audio_tag == 'title' or audio_tag == 'track': continue + # capitalize and remove any spaces audio_value = audio_value.title().replace(' ', '') + # check that the tag is valid if valid_hash_tag(audio_value) and \ '#' + audio_value not in content: + # check that it hasn't been blocked if not is_blocked_hashtag(base_dir, audio_value): content += ' #' + audio_value From bb641253914e4f71d70451816075eb7651814b84 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 12:36:53 +0100 Subject: [PATCH 07/21] Convert map links within post location into an embedded OSM map --- maps.py | 235 ++++++++++++++++++++++++++++++++++++++++++ webapp_create_post.py | 3 +- webapp_post.py | 37 ++++++- 3 files changed, 269 insertions(+), 6 deletions(-) create mode 100644 maps.py diff --git a/maps.py b/maps.py new file mode 100644 index 000000000..5eac5207b --- /dev/null +++ b/maps.py @@ -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 = \ + '' + \ + '
' + translate['View Larger Map'] + '\n' + return html_str diff --git a/webapp_create_post.py b/webapp_create_post.py index 888b9e1c4..651c9d22b 100644 --- a/webapp_create_post.py +++ b/webapp_create_post.py @@ -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') diff --git a/webapp_post.py b/webapp_post.py index e7b95c5b9..0ea90e8d0 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -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 = '' From f55df8e5704ea3c8f816f2fcbfc7d7071c4108b6 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 12:45:07 +0100 Subject: [PATCH 08/21] Translations --- translations/ar.json | 3 ++- translations/ca.json | 3 ++- translations/cy.json | 3 ++- translations/de.json | 3 ++- translations/el.json | 3 ++- translations/en.json | 3 ++- translations/es.json | 3 ++- translations/fr.json | 3 ++- translations/ga.json | 3 ++- translations/hi.json | 3 ++- translations/it.json | 3 ++- translations/ja.json | 3 ++- translations/ko.json | 3 ++- translations/ku.json | 3 ++- translations/nl.json | 3 ++- translations/oc.json | 3 ++- translations/pl.json | 3 ++- translations/pt.json | 3 ++- translations/ru.json | 3 ++- translations/sw.json | 3 ++- translations/tr.json | 3 ++- translations/uk.json | 3 ++- translations/yi.json | 3 ++- translations/zh.json | 3 ++- 24 files changed, 48 insertions(+), 24 deletions(-) diff --git a/translations/ar.json b/translations/ar.json index b9e8d8cd2..1817ba74b 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -554,5 +554,6 @@ "shrug": "هز كتفيه", "DM warning": "لا يتم تشفير الرسائل المباشرة من طرف إلى طرف. لا تشارك أي معلومات حساسة للغاية هنا.", "Transcript": "نص", - "Color contrast is too low": "تباين الألوان منخفض جدًا" + "Color contrast is too low": "تباين الألوان منخفض جدًا", + "View Larger Map": "عرض خريطة أكبر" } diff --git a/translations/ca.json b/translations/ca.json index 1991807d4..acbfff5c4 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -554,5 +554,6 @@ "shrug": "arronsar les espatlles", "DM warning": "Els missatges directes no estan xifrats d'extrem a extrem. No compartiu cap informació molt sensible aquí.", "Transcript": "Transcripció", - "Color contrast is too low": "El contrast de color és massa baix" + "Color contrast is too low": "El contrast de color és massa baix", + "View Larger Map": "Veure mapa més gran" } diff --git a/translations/cy.json b/translations/cy.json index f99c7ed63..027f5b7bb 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -554,5 +554,6 @@ "shrug": "shrug", "DM warning": "Nid yw negeseuon uniongyrchol wedi'u hamgryptio o'r dechrau i'r diwedd. Peidiwch â rhannu unrhyw wybodaeth hynod sensitif yma.", "Transcript": "Trawsgrifiad", - "Color contrast is too low": "Mae cyferbyniad lliw yn rhy isel" + "Color contrast is too low": "Mae cyferbyniad lliw yn rhy isel", + "View Larger Map": "Gweld Map Mwy" } diff --git a/translations/de.json b/translations/de.json index e5b728fcd..f0d31d7b4 100644 --- a/translations/de.json +++ b/translations/de.json @@ -554,5 +554,6 @@ "shrug": "zucken", "DM warning": "Direktnachrichten sind nicht Ende-zu-Ende verschlüsselt. Geben Sie hier keine hochsensiblen Informationen weiter.", "Transcript": "Abschrift", - "Color contrast is too low": "Der Farbkontrast ist zu gering" + "Color contrast is too low": "Der Farbkontrast ist zu gering", + "View Larger Map": "größere Karte ansehen" } diff --git a/translations/el.json b/translations/el.json index 9cdf972e9..a51978878 100644 --- a/translations/el.json +++ b/translations/el.json @@ -554,5 +554,6 @@ "shrug": "σήκωμα των ώμων", "DM warning": "Τα άμεσα μηνύματα δεν είναι κρυπτογραφημένα από άκρο σε άκρο. Μην μοιράζεστε καμία εξαιρετικά ευαίσθητη πληροφορία εδώ.", "Transcript": "Αντίγραφο", - "Color contrast is too low": "Η χρωματική αντίθεση είναι πολύ χαμηλή" + "Color contrast is too low": "Η χρωματική αντίθεση είναι πολύ χαμηλή", + "View Larger Map": "Δείτε Μεγαλύτερο Χάρτη" } diff --git a/translations/en.json b/translations/en.json index cce3649f1..e4152c524 100644 --- a/translations/en.json +++ b/translations/en.json @@ -554,5 +554,6 @@ "shrug": "shrug", "DM warning": "Direct messages are not end-to-end encrypted. Do not share any highly sensitive information here.", "Transcript": "Transcript", - "Color contrast is too low": "Color contrast is too low" + "Color contrast is too low": "Color contrast is too low", + "View Larger Map": "View Larger Map" } diff --git a/translations/es.json b/translations/es.json index 6007430d8..b8399cde7 100644 --- a/translations/es.json +++ b/translations/es.json @@ -554,5 +554,6 @@ "shrug": "encogimiento de hombros", "DM warning": "Los mensajes directos no están cifrados de extremo a extremo. No comparta ninguna información altamente confidencial aquí.", "Transcript": "Transcripción", - "Color contrast is too low": "El contraste de color es demasiado bajo" + "Color contrast is too low": "El contraste de color es demasiado bajo", + "View Larger Map": "Ver mapa más grande" } diff --git a/translations/fr.json b/translations/fr.json index 7a471240a..8f3f2289a 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -554,5 +554,6 @@ "shrug": "hausser les épaules", "DM warning": "Les messages directs ne sont pas chiffrés de bout en bout. Ne partagez aucune information hautement sensible ici.", "Transcript": "Transcription", - "Color contrast is too low": "Le contraste des couleurs est trop faible" + "Color contrast is too low": "Le contraste des couleurs est trop faible", + "View Larger Map": "Agrandir le plan" } diff --git a/translations/ga.json b/translations/ga.json index 1a32a9b30..c64dabd22 100644 --- a/translations/ga.json +++ b/translations/ga.json @@ -554,5 +554,6 @@ "shrug": "shrug", "DM warning": "Níl teachtaireachtaí díreacha criptithe ó cheann go ceann. Ná roinn aon fhaisnéis an-íogair anseo.", "Transcript": "Athscríbhinn", - "Color contrast is too low": "Tá codarsnacht dath ró-íseal" + "Color contrast is too low": "Tá codarsnacht dath ró-íseal", + "View Larger Map": "Féach ar Léarscáil Níos Mó" } diff --git a/translations/hi.json b/translations/hi.json index ae9141fd0..09ad2d94e 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -554,5 +554,6 @@ "shrug": "कंधे उचकाने की क्रिया", "DM warning": "डायरेक्ट मैसेज एंड-टू-एंड एन्क्रिप्टेड नहीं होते हैं। यहां कोई अति संवेदनशील जानकारी साझा न करें।", "Transcript": "प्रतिलिपि", - "Color contrast is too low": "रंग कंट्रास्ट बहुत कम है" + "Color contrast is too low": "रंग कंट्रास्ट बहुत कम है", + "View Larger Map": "बड़ा नक्शा देखें" } diff --git a/translations/it.json b/translations/it.json index 5dc4845ed..a39ddbfc3 100644 --- a/translations/it.json +++ b/translations/it.json @@ -554,5 +554,6 @@ "shrug": "scrollare le spalle", "DM warning": "I messaggi diretti non sono crittografati end-to-end. Non condividere qui alcuna informazione altamente sensibile.", "Transcript": "Trascrizione", - "Color contrast is too low": "Il contrasto del colore è troppo basso" + "Color contrast is too low": "Il contrasto del colore è troppo basso", + "View Larger Map": "Visualizza mappa più grande" } diff --git a/translations/ja.json b/translations/ja.json index 6bb22327f..496d348b0 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -554,5 +554,6 @@ "shrug": "肩をすくめる", "DM warning": "ダイレクトメッセージはエンドツーエンドで暗号化されません。 ここでは機密性の高い情報を共有しないでください。", "Transcript": "トランスクリプト", - "Color contrast is too low": "色のコントラストが低すぎる" + "Color contrast is too low": "色のコントラストが低すぎる", + "View Larger Map": "大きな地図を見る" } diff --git a/translations/ko.json b/translations/ko.json index 123c26f42..0280c48c0 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -554,5 +554,6 @@ "shrug": "어깨를 으쓱하다", "DM warning": "다이렉트 메시지는 종단 간 암호화되지 않습니다. 여기에 매우 민감한 정보를 공유하지 마십시오.", "Transcript": "성적 증명서", - "Color contrast is too low": "색상 대비가 너무 낮습니다." + "Color contrast is too low": "색상 대비가 너무 낮습니다.", + "View Larger Map": "큰 지도 보기" } diff --git a/translations/ku.json b/translations/ku.json index 71ef6f0b1..6463ee261 100644 --- a/translations/ku.json +++ b/translations/ku.json @@ -554,5 +554,6 @@ "shrug": "şuştin", "DM warning": "Peyamên rasterast bi dawî-bi-dawî ne şîfrekirî ne. Li vir agahdariya pir hesas parve nekin.", "Transcript": "Transcript", - "Color contrast is too low": "Berevajî reng pir kêm e" + "Color contrast is too low": "Berevajî reng pir kêm e", + "View Larger Map": "Nexşeya Mezin bibînin" } diff --git a/translations/nl.json b/translations/nl.json index 59f01d702..4ee192a1b 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -554,5 +554,6 @@ "shrug": "schouderophalend", "DM warning": "Directe berichten zijn niet end-to-end versleuteld. Deel hier geen zeer gevoelige informatie.", "Transcript": "Vertaling", - "Color contrast is too low": "Kleurcontrast is te laag" + "Color contrast is too low": "Kleurcontrast is te laag", + "View Larger Map": "zie grotere kaart" } diff --git a/translations/oc.json b/translations/oc.json index 016cdbef9..30bc3511c 100644 --- a/translations/oc.json +++ b/translations/oc.json @@ -550,5 +550,6 @@ "shrug": "shrug", "DM warning": "Direct messages are not end-to-end encrypted. Do not share any highly sensitive information here.", "Transcript": "Transcript", - "Color contrast is too low": "Color contrast is too low" + "Color contrast is too low": "Color contrast is too low", + "View Larger Map": "View Larger Map" } diff --git a/translations/pl.json b/translations/pl.json index 077dd11a0..a35f320b5 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -554,5 +554,6 @@ "shrug": "wzruszać ramionami", "DM warning": "Wiadomości na czacie nie są szyfrowane metodą end-to-end. Nie udostępniaj tutaj żadnych wysoce wrażliwych informacji.", "Transcript": "Transkrypcja", - "Color contrast is too low": "Kontrast kolorów jest zbyt niski" + "Color contrast is too low": "Kontrast kolorów jest zbyt niski", + "View Larger Map": "Wyświetl Większą Mapę" } diff --git a/translations/pt.json b/translations/pt.json index eb594d052..1c4f23b0c 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -554,5 +554,6 @@ "shrug": "dar de ombros", "DM warning": "As mensagens diretas não são criptografadas de ponta a ponta. Não compartilhe nenhuma informação altamente sensível aqui.", "Transcript": "Transcrição", - "Color contrast is too low": "O contraste de cores é muito baixo" + "Color contrast is too low": "O contraste de cores é muito baixo", + "View Larger Map": "ver o mapa maior" } diff --git a/translations/ru.json b/translations/ru.json index f82cc2c70..06ebb2336 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -554,5 +554,6 @@ "shrug": "пожимание плечами", "DM warning": "Прямые сообщения не подвергаются сквозному шифрованию. Не делитесь здесь особо конфиденциальной информацией.", "Transcript": "Стенограмма", - "Color contrast is too low": "Цветовой контраст слишком низкий" + "Color contrast is too low": "Цветовой контраст слишком низкий", + "View Larger Map": "Посмотреть увеличенную карту" } diff --git a/translations/sw.json b/translations/sw.json index 4f8c99e2c..803c3dff4 100644 --- a/translations/sw.json +++ b/translations/sw.json @@ -554,5 +554,6 @@ "shrug": "piga mabega", "DM warning": "Ujumbe wa moja kwa moja haujasimbwa kutoka mwisho hadi mwisho. Usishiriki maelezo yoyote nyeti sana hapa.", "Transcript": "Nakala", - "Color contrast is too low": "Utofautishaji wa rangi uko chini sana" + "Color contrast is too low": "Utofautishaji wa rangi uko chini sana", + "View Larger Map": "Tazama Ramani Kubwa" } diff --git a/translations/tr.json b/translations/tr.json index d1ab905da..3257c2ebd 100644 --- a/translations/tr.json +++ b/translations/tr.json @@ -554,5 +554,6 @@ "shrug": "omuz silkmek", "DM warning": "Doğrudan mesajlar uçtan uca şifrelenmez. Son derece hassas bilgileri burada paylaşmayın.", "Transcript": "Transcript", - "Color contrast is too low": "Renk kontrastı çok düşük" + "Color contrast is too low": "Renk kontrastı çok düşük", + "View Larger Map": "Daha Büyük Haritayı Görüntüle" } diff --git a/translations/uk.json b/translations/uk.json index 559788e5d..ee50964ce 100644 --- a/translations/uk.json +++ b/translations/uk.json @@ -554,5 +554,6 @@ "shrug": "знизати плечима", "DM warning": "Прямі повідомлення не наскрізне шифруються. Не публікуйте тут дуже конфіденційну інформацію.", "Transcript": "Стенограма", - "Color contrast is too low": "Колірна контрастність надто низька" + "Color contrast is too low": "Колірна контрастність надто низька", + "View Larger Map": "Переглянути більшу карту" } diff --git a/translations/yi.json b/translations/yi.json index afe00dbb5..bd464abca 100644 --- a/translations/yi.json +++ b/translations/yi.json @@ -554,5 +554,6 @@ "shrug": "שעפּן זיך", "DM warning": "דירעקט אַרטיקלען זענען נישט ענקריפּטיד פון סוף צו סוף. דו זאלסט נישט טיילן קיין העכסט שפּירעוודיק אינפֿאָרמאַציע דאָ.", "Transcript": "טראַנסקריפּט", - "Color contrast is too low": "קאָליר קאַנטראַסט איז אויך נידעריק" + "Color contrast is too low": "קאָליר קאַנטראַסט איז אויך נידעריק", + "View Larger Map": "View גרעסערע מאַפּע" } diff --git a/translations/zh.json b/translations/zh.json index b5db64510..738e02a55 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -554,5 +554,6 @@ "shrug": "耸耸肩", "DM warning": "直接消息不是端到端加密的。 不要在这里分享任何高度敏感的信息。", "Transcript": "成绩单", - "Color contrast is too low": "颜色对比度太低" + "Color contrast is too low": "颜色对比度太低", + "View Larger Map": "查看更大的地图" } From f1c6471de769a2c4fbe33a191eba42e02959b703 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 12:47:26 +0100 Subject: [PATCH 09/21] Set placeholder --- webapp_create_post.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp_create_post.py b/webapp_create_post.py index 651c9d22b..38b7fcff9 100644 --- a/webapp_create_post.py +++ b/webapp_create_post.py @@ -682,7 +682,7 @@ 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() From 94dd07f98fffaba301948e95097b9bb547c54eab Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:05:23 +0100 Subject: [PATCH 10/21] Separate map string --- webapp_post.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/webapp_post.py b/webapp_post.py index 0ea90e8d0..476aafb06 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -2143,6 +2143,7 @@ def individual_post_as_html(signing_priv_key_pem: str, _log_post_timing(enable_timing_log, post_start_time, '17') + map_str = '' if post_json_object['object'].get('tag'): if not is_patch: content_str = \ @@ -2156,7 +2157,7 @@ def individual_post_as_html(signing_priv_key_pem: str, if location_str: if '://' in location_str and '.' in location_str: bounding_box_degrees = 0.01 - content_str += \ + map_str = \ html_open_street_map(location_str, bounding_box_degrees, translate) @@ -2197,7 +2198,8 @@ def individual_post_as_html(signing_priv_key_pem: str, ' ' + title_str + \ reply_avatar_image_in_post + ' \n' post_html += \ - content_str + citations_str + reaction_str + footer_str + '\n' + content_str + citations_str + map_str + \ + reaction_str + footer_str + '\n' post_html += ' \n' else: post_html = gallery_str From 66c7f3def1d86762eaf0934cc73b03b309d4b613 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:08:50 +0100 Subject: [PATCH 11/21] Check that location is a string --- webapp_post.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/webapp_post.py b/webapp_post.py index 476aafb06..ab5b99ed1 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -106,6 +106,8 @@ def _get_location_from_tags(tags: []) -> str: continue if not tag_item.get('name'): continue + if not isinstance(tag_item['name'], str): + continue return tag_item['name'].replace('\n', ' ') return None From c15696d98f8ded1ca8ef191b05f3c6c927792e07 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:23:29 +0100 Subject: [PATCH 12/21] Check float values in geocoords --- maps.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/maps.py b/maps.py index 5eac5207b..b9da5dc9c 100644 --- a/maps.py +++ b/maps.py @@ -8,13 +8,16 @@ __status__ = "Production" __module_group__ = "Core" +from utils import is_float + + 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] + coords_str = url.split(osm_domain + '/#map=')[1] if '/' not in coords_str: return None, None, None @@ -25,10 +28,10 @@ def _geocoords_from_osm_link(url: str, osm_domain: str) -> (int, float, float): if not zoom.isdigit(): return None, None, None latitude = coords[1] - if not latitude.isdigit(): + if not is_float(latitude): return None, None, None longitude = coords[2] - if not longitude.isdigit(): + if not is_float(longitude): return None, None, None zoom = int(zoom) latitude = float(latitude) @@ -53,10 +56,10 @@ def _geocoords_from_gmaps_link(url: str) -> (int, float, float): if not zoom.isdigit(): return None, None, None latitude = coords[0] - if not latitude.isdigit(): + if not is_float(latitude): return None, None, None longitude = coords[1] - if not longitude.isdigit(): + if not is_float(longitude): return None, None, None zoom = int(zoom) latitude = float(latitude) @@ -89,10 +92,10 @@ def _geocoords_from_bmaps_link(url: str) -> (int, float, float): if len(coords) != 2: return None, None, None latitude = coords[0] - if not latitude.isdigit(): + if not is_float(latitude): return None, None, None longitude = coords[1] - if not longitude.isdigit(): + if not is_float(longitude): return None, None, None zoom = 17 if 'lvl=' in orig_coords_str: @@ -135,10 +138,10 @@ def _geocoords_from_waze_link(url: str) -> (int, float, float): if len(coords) != 2: return None, None, None latitude = coords[0] - if not latitude.isdigit(): + if not is_float(latitude): return None, None, None longitude = coords[1] - if not longitude.isdigit(): + if not is_float(longitude): return None, None, None zoom = 17 if 'zoom=' in orig_coords_str: @@ -173,10 +176,10 @@ def _geocoords_from_wego_link(url: str) -> (int, float, float): if len(coords) < 3: return None, None, None latitude = coords[0] - if not latitude.isdigit(): + if not is_float(latitude): return None, None, None longitude = coords[1] - if not longitude.isdigit(): + if not is_float(longitude): return None, None, None zoom = coords[2] if not zoom.isdigit(): From d1d61ab14264c244809c6dd20c8f6123c8513c1d Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:26:58 +0100 Subject: [PATCH 13/21] String cast --- maps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maps.py b/maps.py index b9da5dc9c..5223bcb3c 100644 --- a/maps.py +++ b/maps.py @@ -233,6 +233,6 @@ def html_open_street_map(url: str, str(latitude + bounding_box_degrees) + \ '&layer=mapnik" style="border: 1px solid black">' + \ '
' + translate['View Larger Map'] + '\n' return html_str From ac2e45f0344c86acd44890d3744f37b30977616a Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:28:21 +0100 Subject: [PATCH 14/21] Smaller bounding box --- webapp_post.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp_post.py b/webapp_post.py index ab5b99ed1..1415a8894 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -2158,7 +2158,7 @@ def individual_post_as_html(signing_priv_key_pem: 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 + bounding_box_degrees = 0.001 map_str = \ html_open_street_map(location_str, bounding_box_degrees, From c80d5f25be45bbf04f6faba063fd6c3c16473566 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:34:20 +0100 Subject: [PATCH 15/21] Center the map --- webapp_post.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webapp_post.py b/webapp_post.py index 1415a8894..34ee0f6d7 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -2159,10 +2159,12 @@ def individual_post_as_html(signing_priv_key_pem: str, if location_str: if '://' in location_str and '.' in location_str: bounding_box_degrees = 0.001 - map_str = \ + map_str = \ html_open_street_map(location_str, bounding_box_degrees, translate) + if map_str: + map_str = '
\n' + map_str + '
\n' if is_muted: content_str = '' From 75d9c6c59c29ea4d3d77262d14a4cc1c944cc296 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:36:37 +0100 Subject: [PATCH 16/21] Tidying --- webapp_post.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp_post.py b/webapp_post.py index 34ee0f6d7..92678289b 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -2159,7 +2159,7 @@ def individual_post_as_html(signing_priv_key_pem: str, if location_str: if '://' in location_str and '.' in location_str: bounding_box_degrees = 0.001 - map_str = \ + map_str = \ html_open_street_map(location_str, bounding_box_degrees, translate) From 80c7254861cd676b1ed83034e17e662f700541c2 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sat, 21 May 2022 13:38:08 +0100 Subject: [PATCH 17/21] Frame width --- maps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maps.py b/maps.py index 5223bcb3c..fcd63b087 100644 --- a/maps.py +++ b/maps.py @@ -221,7 +221,7 @@ def html_open_street_map(url: str, return '' html_str = \ - '