diff --git a/maps.py b/maps.py new file mode 100644 index 000000000..c7e42f24a --- /dev/null +++ b/maps.py @@ -0,0 +1,238 @@ +__filename__ = "maps.py" +__author__ = "Bob Mottram" +__license__ = "AGPL3+" +__version__ = "1.3.0" +__maintainer__ = "Bob Mottram" +__email__ = "bob@libreserver.org" +__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(osm_domain + '/#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 is_float(latitude): + return None, None, None + longitude = coords[2] + if not is_float(longitude): + 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 is_float(latitude): + return None, None, None + longitude = coords[1] + if not is_float(longitude): + 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 is_float(latitude): + return None, None, None + longitude = coords[1] + if not is_float(longitude): + 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 is_float(latitude): + return None, None, None + longitude = coords[1] + if not is_float(longitude): + 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 is_float(latitude): + return None, None, None + longitude = coords[1] + if not is_float(longitude): + 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/media.py b/media.py index 1f84f7a10..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 @@ -162,6 +359,49 @@ 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 + ' = ' 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() + 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 + + 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..5ee5649f1 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 @@ -81,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 @@ -1423,6 +1427,27 @@ 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 + # 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 + tags = [] hashtags_dict = {} 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": "查看更大的地图" } diff --git a/webapp_create_post.py b/webapp_create_post.py index 888b9e1c4..38b7fcff9 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..92678289b 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -93,6 +93,23 @@ 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 + if not isinstance(tag_item['name'], str): + continue + return tag_item['name'].replace('\n', ' ') + return None def _html_post_metadata_open_graph(domain: str, post_json_object: {}, @@ -2128,11 +2145,26 @@ 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) + map_str = '' + 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.001 + 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 = '' @@ -2170,7 +2202,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