diff --git a/newswire.py b/newswire.py index 698487740..dd04c1a9c 100644 --- a/newswire.py +++ b/newswire.py @@ -19,6 +19,7 @@ from datetime import timezone from collections import OrderedDict from utils import valid_post_date from categories import set_hashtag_category +from utils import get_domain_from_actor from utils import valid_hash_tag from utils import dangerous_svg from utils import get_fav_filename_from_url @@ -452,10 +453,35 @@ def _get_podcast_categories(xml_item: str, xml_str: str) -> str: return podcast_categories -def xml_podcast_to_dict(xml_item: str, xml_str: str) -> {}: +def _valid_podcast_entry(base_dir: str, key: str, entry: {}) -> bool: + """Is the given podcast namespace entry valid? + https://github.com/Podcastindex-org/podcast-namespace/ + blob/main/proposal-docs/social/social.md#socialinteract-element + """ + if key == 'socialInteract': + if not entry.get('protocol'): + return False + if not entry.get('text'): + return False + if entry['protocol'].tolower() != 'activitypub': + return False + post_url = entry['text'] + if '://' not in post_url: + return False + post_domain, post_port = get_domain_from_actor(post_url) + if not post_domain: + return False + if is_blocked_domain(base_dir, post_domain): + return False + return True + + +def xml_podcast_to_dict(base_dir: str, xml_item: str, xml_str: str) -> {}: """podcasting extensions for RSS feeds See https://github.com/Podcastindex-org/podcast-namespace/ blob/main/docs/1.0.md + https://github.com/Podcastindex-org/podcast-namespace/ + blob/main/proposal-docs/social/social.md#socialinteract-element """ if ' {}: "soundbites": [], "transcripts": [], "valueRecipients": [], - "trailers": [] + "trailers": [], + "socialInteract": [] } pod_lines = xml_item.split(' {}: 'url', 'geo', 'osm', 'type', 'method', 'group', 'owner', 'srcset', 'img', 'role', 'address', 'suggested', 'startTime', 'duration', 'href', 'name', 'pubdate', - 'length', 'season', 'email' + 'length', 'season', 'email', 'platform', 'protocol', + 'accountId', 'priority' ) pod_entry = {} for pod_field in pod_fields: @@ -509,13 +537,16 @@ def xml_podcast_to_dict(xml_item: str, xml_str: str) -> {}: if pod_text: pod_entry['text'] = pod_text + appended = False if pod_key + 's' in podcast_properties: if isinstance(podcast_properties[pod_key + 's'], list): podcast_properties[pod_key + 's'].append(pod_entry) - else: - podcast_properties[pod_key] = pod_entry - else: - podcast_properties[pod_key] = pod_entry + appended = True + if not appended: + # if there are repeated keys then only use the first one + if not podcast_properties.get(pod_key): + if _valid_podcast_entry(base_dir, pod_key, pod_entry): + podcast_properties[pod_key] = pod_entry ctr += 1 # get the image for the podcast, if it exists @@ -687,7 +718,8 @@ def _xml2str_to_dict(base_dir: str, domain: str, xml_str: str, if _valid_feed_date(pub_date_str): post_filename = '' votes_status = [] - podcast_properties = xml_podcast_to_dict(rss_item, xml_str) + podcast_properties = \ + xml_podcast_to_dict(base_dir, rss_item, xml_str) if podcast_properties: podcast_properties['linkMimeType'] = link_mime_type _add_newswire_dict_entry(base_dir, domain, @@ -783,7 +815,8 @@ def _xml1str_to_dict(base_dir: str, domain: str, xml_str: str, if _valid_feed_date(pub_date_str): post_filename = '' votes_status = [] - podcast_properties = xml_podcast_to_dict(rss_item, xml_str) + podcast_properties = \ + xml_podcast_to_dict(base_dir, rss_item, xml_str) if podcast_properties: podcast_properties['linkMimeType'] = link_mime_type _add_newswire_dict_entry(base_dir, domain, @@ -867,7 +900,8 @@ def _atom_feed_to_dict(base_dir: str, domain: str, xml_str: str, if _valid_feed_date(pub_date_str): post_filename = '' votes_status = [] - podcast_properties = xml_podcast_to_dict(atom_item, xml_str) + podcast_properties = \ + xml_podcast_to_dict(base_dir, atom_item, xml_str) if podcast_properties: podcast_properties['linkMimeType'] = link_mime_type _add_newswire_dict_entry(base_dir, domain, @@ -1068,7 +1102,8 @@ def _atom_feed_yt_to_dict(base_dir: str, domain: str, xml_str: str, if _valid_feed_date(pub_date_str): post_filename = '' votes_status = [] - podcast_properties = xml_podcast_to_dict(atom_item, xml_str) + podcast_properties = \ + xml_podcast_to_dict(base_dir, atom_item, xml_str) if podcast_properties: podcast_properties['linkMimeType'] = 'video/youtube' _add_newswire_dict_entry(base_dir, domain, diff --git a/tests.py b/tests.py index a3561b77a..886552c7f 100644 --- a/tests.py +++ b/tests.py @@ -6412,7 +6412,7 @@ def _test_get_actor_from_in_reply_to() -> None: assert reply_actor is None -def _test_xml_podcast_dict() -> None: +def _test_xml_podcast_dict(base_dir: str) -> None: print('test_xml_podcast_dict') xml_str = \ '\n' + \ @@ -6473,7 +6473,7 @@ def _test_xml_podcast_dict() -> None: 'address="someaddress2" split="99" />\n' + \ '\n' + \ '' - podcast_properties = xml_podcast_to_dict(xml_str, xml_str) + podcast_properties = xml_podcast_to_dict(base_dir, xml_str, xml_str) assert podcast_properties # pprint(podcast_properties) assert podcast_properties.get('valueRecipients') @@ -6575,7 +6575,7 @@ def run_all_tests(): _test_functions() _test_safe_webtext() _test_get_link_from_rss_item() - _test_xml_podcast_dict() + _test_xml_podcast_dict(base_dir) _test_get_actor_from_in_reply_to() _test_valid_emoji_content() _test_add_cw_lists(base_dir) diff --git a/translations/ar.json b/translations/ar.json index 43e8c65b0..68926de5d 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -504,5 +504,7 @@ "Encryption Keys": "مفاتيح التشفير", "Filtered words within bio": "كلمات مفلترة داخل السيرة الذاتية", "Write your news report": "اكتب تقريرك الإخباري", - "Dyslexic font": "الخط المعسر القراءة" + "Dyslexic font": "الخط المعسر القراءة", + "Leave a comment": "اترك تعليقا", + "View comments": "تعليقات عرض" } diff --git a/translations/ca.json b/translations/ca.json index 1b2342ef2..ecc8834cf 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -504,5 +504,7 @@ "Encryption Keys": "Claus de xifratge", "Filtered words within bio": "Paraules filtrades dins de la biografia", "Write your news report": "Escriu la teva notícia", - "Dyslexic font": "Tipus de lletra dislèxic" + "Dyslexic font": "Tipus de lletra dislèxic", + "Leave a comment": "Deixa un comentari", + "View comments": "Veure comentaris" } diff --git a/translations/cy.json b/translations/cy.json index 23d6a5e9c..523f22f64 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -504,5 +504,7 @@ "Encryption Keys": "Allweddi Amgryptio", "Filtered words within bio": "Geiriau wedi'u hidlo o fewn cofiant", "Write your news report": "Ysgrifennwch eich adroddiad newyddion", - "Dyslexic font": "Ffont dyslecsig" + "Dyslexic font": "Ffont dyslecsig", + "Leave a comment": "Gadael sylw", + "View comments": "Gweld sylwadau" } diff --git a/translations/de.json b/translations/de.json index 7e5fceb83..330719c08 100644 --- a/translations/de.json +++ b/translations/de.json @@ -504,5 +504,7 @@ "Encryption Keys": "Verschlüsselungsschlüssel", "Filtered words within bio": "Gefilterte Wörter in der Biografie", "Write your news report": "Schreiben Sie Ihren Nachrichtenbericht", - "Dyslexic font": "Schriftart für Legastheniker" + "Dyslexic font": "Schriftart für Legastheniker", + "Leave a comment": "Hinterlasse einen Kommentar", + "View comments": "Kommentare ansehen" } diff --git a/translations/en.json b/translations/en.json index 3ffa0c475..8987d97b5 100644 --- a/translations/en.json +++ b/translations/en.json @@ -504,5 +504,7 @@ "Encryption Keys": "Encryption Keys", "Filtered words within bio": "Filtered words within bio", "Write your news report": "Write your news report", - "Dyslexic font": "Dyslexic font" + "Dyslexic font": "Dyslexic font", + "Leave a comment": "Leave a comment", + "View comments": "View comments" } diff --git a/translations/es.json b/translations/es.json index 46990fcba..8ba1e78ab 100644 --- a/translations/es.json +++ b/translations/es.json @@ -504,5 +504,7 @@ "Encryption Keys": "Claves de cifrado", "Filtered words within bio": "Palabras filtradas dentro de la biografía", "Write your news report": "Escribe tu informe de noticias", - "Dyslexic font": "Fuente disléxica" + "Dyslexic font": "Fuente disléxica", + "Leave a comment": "Deja un comentario", + "View comments": "Ver comentarios" } diff --git a/translations/fr.json b/translations/fr.json index 275da9027..33705a762 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -504,5 +504,7 @@ "Encryption Keys": "Clés de cryptage", "Filtered words within bio": "Mots filtrés dans la biographie", "Write your news report": "Rédigez votre reportage", - "Dyslexic font": "Police dyslexique" + "Dyslexic font": "Police dyslexique", + "Leave a comment": "Laissez un commentaire", + "View comments": "Voir les commentaires" } diff --git a/translations/ga.json b/translations/ga.json index 3a1734dd7..b8815bde2 100644 --- a/translations/ga.json +++ b/translations/ga.json @@ -504,5 +504,7 @@ "Encryption Keys": "Eochracha Criptithe", "Filtered words within bio": "Focail scagtha laistigh den bheathaisnéis", "Write your news report": "Scríobh do thuairisc nuachta", - "Dyslexic font": "Cló disléicseach" + "Dyslexic font": "Cló disléicseach", + "Leave a comment": "Fág trácht", + "View comments": "Féach ar thuairimí" } diff --git a/translations/hi.json b/translations/hi.json index b255d624c..f4df47b07 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -504,5 +504,7 @@ "Encryption Keys": "एन्क्रिप्शन कुंजी", "Filtered words within bio": "जीवनी के भीतर फ़िल्टर किए गए शब्द", "Write your news report": "अपनी समाचार रिपोर्ट लिखें", - "Dyslexic font": "डिस्लेक्सिक फ़ॉन्ट" + "Dyslexic font": "डिस्लेक्सिक फ़ॉन्ट", + "Leave a comment": "एक टिप्पणी छोड़ें", + "View comments": "टिप्पणियाँ देखें" } diff --git a/translations/it.json b/translations/it.json index 5b3e69552..f9d23ef67 100644 --- a/translations/it.json +++ b/translations/it.json @@ -504,5 +504,7 @@ "Encryption Keys": "Chiavi di crittografia", "Filtered words within bio": "Parole filtrate all'interno della biografia", "Write your news report": "Scrivi il tuo reportage", - "Dyslexic font": "Carattere dislessico" + "Dyslexic font": "Carattere dislessico", + "Leave a comment": "Lascia un commento", + "View comments": "Visualizza commenti" } diff --git a/translations/ja.json b/translations/ja.json index d59daf636..49099f533 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -504,5 +504,7 @@ "Encryption Keys": "暗号化キー", "Filtered words within bio": "伝記内のフィルタリングされた単語", "Write your news report": "ニュースレポートを書く", - "Dyslexic font": "失読症フォント" + "Dyslexic font": "失読症フォント", + "Leave a comment": "コメントを残す", + "View comments": "コメントを見る" } diff --git a/translations/ku.json b/translations/ku.json index e4355fc2e..4beb4e9f5 100644 --- a/translations/ku.json +++ b/translations/ku.json @@ -504,5 +504,7 @@ "Encryption Keys": "Bişkojkên Şîfrekirinê", "Filtered words within bio": "Peyvên fîlterkirî di hundurê biyografiyê de", "Write your news report": "Rapora xwe ya nûçeyan binivîsin", - "Dyslexic font": "Font Dyslexic" + "Dyslexic font": "Font Dyslexic", + "Leave a comment": "Bihêle şîroveyek", + "View comments": "Binêre şîroveyan" } diff --git a/translations/oc.json b/translations/oc.json index 25a6f04bd..9bc44b52e 100644 --- a/translations/oc.json +++ b/translations/oc.json @@ -500,5 +500,7 @@ "Encryption Keys": "Encryption Keys", "Filtered words within bio": "Filtered words within bio", "Write your news report": "Write your news report", - "Dyslexic font": "Dyslexic font" + "Dyslexic font": "Dyslexic font", + "Leave a comment": "Leave a comment", + "View comments": "View comments" } diff --git a/translations/pt.json b/translations/pt.json index 4bb1e17f0..0d7fec957 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -504,5 +504,7 @@ "Encryption Keys": "Chaves de criptografia", "Filtered words within bio": "Palavras filtradas na biografia", "Write your news report": "Escreva sua reportagem", - "Dyslexic font": "Fonte disléxica" + "Dyslexic font": "Fonte disléxica", + "Leave a comment": "Deixe um comentário", + "View comments": "Ver comentários" } diff --git a/translations/ru.json b/translations/ru.json index a2ec2fab9..9050608c0 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -504,5 +504,7 @@ "Encryption Keys": "Ключи шифрования", "Filtered words within bio": "Отфильтрованные слова в биографии", "Write your news report": "Напишите свой новостной репортаж", - "Dyslexic font": "Дислексический шрифт" + "Dyslexic font": "Дислексический шрифт", + "Leave a comment": "Оставить комментарий", + "View comments": "Посмотреть комментарии" } diff --git a/translations/sw.json b/translations/sw.json index 51ba6667f..d305f2446 100644 --- a/translations/sw.json +++ b/translations/sw.json @@ -504,5 +504,7 @@ "Encryption Keys": "Vifunguo vya Usimbaji", "Filtered words within bio": "Maneno yaliyochujwa ndani ya wasifu", "Write your news report": "Andika ripoti yako ya habari", - "Dyslexic font": "Fonti ya Dyslexic" + "Dyslexic font": "Fonti ya Dyslexic", + "Leave a comment": "Acha maoni", + "View comments": "Tazama maoni" } diff --git a/translations/zh.json b/translations/zh.json index f11fe1d46..06e1efc27 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -504,5 +504,7 @@ "Encryption Keys": "加密密钥", "Filtered words within bio": "传记中的过滤词", "Write your news report": "写你的新闻报道", - "Dyslexic font": "阅读障碍字体" + "Dyslexic font": "阅读障碍字体", + "Leave a comment": "发表评论", + "View comments": "查看评论" } diff --git a/webapp_podcast.py b/webapp_podcast.py index bf80112d6..3dedca232 100644 --- a/webapp_podcast.py +++ b/webapp_podcast.py @@ -21,6 +21,31 @@ from webapp_utils import html_footer from webapp_utils import html_keyboard_navigation +def _html_podcast_social_interactions(podcast_properties: {}, + translate: {}, + nickname: str) -> str: + """Returns html for social interactions with a podcast + """ + if not podcast_properties: + return '' + if not podcast_properties.get('socialInteract'): + return '' + if not podcast_properties['socialInteract'].get('text'): + return '' + post_url = podcast_properties['socialInteract']['text'] + podcast_str = \ + '
\n' + \ + ' 💬 ' + \ + translate['Leave a comment'] + '\n' + \ + ' ' + \ + translate['View comments'] + '\n' + \ + '
\n' + return podcast_str + + def _html_podcast_performers(podcast_properties: {}) -> str: """Returns html for performers of a podcast """ @@ -243,6 +268,9 @@ def html_podcast_episode(css_cache: {}, translate: {}, podcast_str += tags_str.strip() + '

\n' podcast_str += _html_podcast_performers(podcast_properties) + podcast_str += \ + _html_podcast_social_interactions(podcast_properties, translate, + nickname) podcast_str += ' \n' podcast_str += '\n'