Merge branch 'main' of gitlab.com:bashrc2/epicyon

merge-requests/30/head
Bob Mottram 2022-05-21 13:58:20 +01:00
commit dc0ba8457d
29 changed files with 592 additions and 31 deletions

238
maps.py 100644
View File

@ -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 = \
'<iframe width="725" height="650" 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=' + \
str(zoom) + '/' + str(latitude) + '/' + str(longitude) + \
'">' + translate['View Larger Map'] + '</a></small>\n'
return html_str

240
media.py
View File

@ -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
"""

View File

@ -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 = {}

View File

@ -554,5 +554,6 @@
"shrug": "هز كتفيه",
"DM warning": "لا يتم تشفير الرسائل المباشرة من طرف إلى طرف. لا تشارك أي معلومات حساسة للغاية هنا.",
"Transcript": "نص",
"Color contrast is too low": "تباين الألوان منخفض جدًا"
"Color contrast is too low": "تباين الألوان منخفض جدًا",
"View Larger Map": "عرض خريطة أكبر"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -554,5 +554,6 @@
"shrug": "σήκωμα των ώμων",
"DM warning": "Τα άμεσα μηνύματα δεν είναι κρυπτογραφημένα από άκρο σε άκρο. Μην μοιράζεστε καμία εξαιρετικά ευαίσθητη πληροφορία εδώ.",
"Transcript": "Αντίγραφο",
"Color contrast is too low": "Η χρωματική αντίθεση είναι πολύ χαμηλή"
"Color contrast is too low": "Η χρωματική αντίθεση είναι πολύ χαμηλή",
"View Larger Map": "Δείτε Μεγαλύτερο Χάρτη"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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ó"
}

View File

@ -554,5 +554,6 @@
"shrug": "कंधे उचकाने की क्रिया",
"DM warning": "डायरेक्ट मैसेज एंड-टू-एंड एन्क्रिप्टेड नहीं होते हैं। यहां कोई अति संवेदनशील जानकारी साझा न करें।",
"Transcript": "प्रतिलिपि",
"Color contrast is too low": "रंग कंट्रास्ट बहुत कम है"
"Color contrast is too low": "रंग कंट्रास्ट बहुत कम है",
"View Larger Map": "बड़ा नक्शा देखें"
}

View File

@ -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"
}

View File

@ -554,5 +554,6 @@
"shrug": "肩をすくめる",
"DM warning": "ダイレクトメッセージはエンドツーエンドで暗号化されません。 ここでは機密性の高い情報を共有しないでください。",
"Transcript": "トランスクリプト",
"Color contrast is too low": "色のコントラストが低すぎる"
"Color contrast is too low": "色のコントラストが低すぎる",
"View Larger Map": "大きな地図を見る"
}

View File

@ -554,5 +554,6 @@
"shrug": "어깨를 으쓱하다",
"DM warning": "다이렉트 메시지는 종단 간 암호화되지 않습니다. 여기에 매우 민감한 정보를 공유하지 마십시오.",
"Transcript": "성적 증명서",
"Color contrast is too low": "색상 대비가 너무 낮습니다."
"Color contrast is too low": "색상 대비가 너무 낮습니다.",
"View Larger Map": "큰 지도 보기"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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ę"
}

View File

@ -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"
}

View File

@ -554,5 +554,6 @@
"shrug": "пожимание плечами",
"DM warning": "Прямые сообщения не подвергаются сквозному шифрованию. Не делитесь здесь особо конфиденциальной информацией.",
"Transcript": "Стенограмма",
"Color contrast is too low": "Цветовой контраст слишком низкий"
"Color contrast is too low": "Цветовой контраст слишком низкий",
"View Larger Map": "Посмотреть увеличенную карту"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -554,5 +554,6 @@
"shrug": "знизати плечима",
"DM warning": "Прямі повідомлення не наскрізне шифруються. Не публікуйте тут дуже конфіденційну інформацію.",
"Transcript": "Стенограма",
"Color contrast is too low": "Колірна контрастність надто низька"
"Color contrast is too low": "Колірна контрастність надто низька",
"View Larger Map": "Переглянути більшу карту"
}

View File

@ -554,5 +554,6 @@
"shrug": "שעפּן זיך",
"DM warning": "דירעקט אַרטיקלען זענען נישט ענקריפּטיד פון סוף צו סוף. דו זאלסט נישט טיילן קיין העכסט שפּירעוודיק אינפֿאָרמאַציע דאָ.",
"Transcript": "טראַנסקריפּט",
"Color contrast is too low": "קאָליר קאַנטראַסט איז אויך נידעריק"
"Color contrast is too low": "קאָליר קאַנטראַסט איז אויך נידעריק",
"View Larger Map": "View גרעסערע מאַפּע"
}

View File

@ -554,5 +554,6 @@
"shrug": "耸耸肩",
"DM warning": "直接消息不是端到端加密的。 不要在这里分享任何高度敏感的信息。",
"Transcript": "成绩单",
"Color contrast is too low": "颜色对比度太低"
"Color contrast is too low": "颜色对比度太低",
"View Larger Map": "查看更大的地图"
}

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,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 = '<center>\n' + map_str + '</center>\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 + ' </div>\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 += ' </div>\n'
else:
post_html = gallery_str