| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  | __filename__ = "video.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2024-12-22 23:37:30 +00:00
										 |  |  | __version__ = "1.6.0" | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@libreserver.org" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							|  |  |  | __module_group__ = "Timeline" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-09 14:18:24 +00:00
										 |  |  | from utils import get_url_from_post | 
					
						
							| 
									
										
										
										
											2023-07-12 11:08:02 +00:00
										 |  |  | from utils import remove_html | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  | from utils import get_full_domain | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  | from utils import get_nickname_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-27 19:05:25 +00:00
										 |  |  | from utils import get_domain_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-27 11:20:57 +00:00
										 |  |  | from utils import remove_id_ending | 
					
						
							| 
									
										
										
										
											2023-09-26 20:25:53 +00:00
										 |  |  | from utils import get_attributed_to | 
					
						
							| 
									
										
										
										
											2023-10-29 13:24:52 +00:00
										 |  |  | from utils import get_content_from_post | 
					
						
							| 
									
										
										
										
											2023-10-29 18:08:35 +00:00
										 |  |  | from utils import dangerous_markup | 
					
						
							| 
									
										
										
										
											2023-10-29 20:20:55 +00:00
										 |  |  | from utils import license_link_from_name | 
					
						
							| 
									
										
										
										
											2023-10-29 22:00:04 +00:00
										 |  |  | from utils import get_media_url_from_video | 
					
						
							| 
									
										
										
										
											2024-01-27 17:04:21 +00:00
										 |  |  | from utils import resembles_url | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from blocking import is_blocked | 
					
						
							|  |  |  | from filters import is_filtered | 
					
						
							| 
									
										
										
										
											2024-10-06 19:20:47 +00:00
										 |  |  | from conversation import post_id_to_convthread_id | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def convert_video_to_note(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                           system_language: str, | 
					
						
							| 
									
										
										
										
											2023-10-29 13:24:52 +00:00
										 |  |  |                           post_json_object: {}, blocked_cache: {}, | 
					
						
							| 
									
										
										
										
											2024-02-09 22:09:18 +00:00
										 |  |  |                           block_federated: [], | 
					
						
							| 
									
										
										
										
											2023-10-29 13:24:52 +00:00
										 |  |  |                           languages_understood: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |     """Converts a PeerTube Video ActivityPub(ish) object into
 | 
					
						
							|  |  |  |     a Note, so that it can then be displayed in a timeline | 
					
						
							| 
									
										
										
										
											2023-10-29 18:08:35 +00:00
										 |  |  |     https://docs.joinpeertube.org/api/activitypub#video | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     # check that the required fields are present | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     required_fields = ( | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         'type', '@context', 'id', 'published', 'to', 'cc', | 
					
						
							|  |  |  |         'attributedTo', 'commentsEnabled', 'content', 'sensitive', | 
					
						
							|  |  |  |         'name', 'url' | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     for field_name in required_fields: | 
					
						
							|  |  |  |         if not post_json_object.get(field_name): | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if post_json_object['type'] != 'Video': | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # who is this attributed to ? | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     attributed_to = None | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if isinstance(post_json_object['attributedTo'], str): | 
					
						
							| 
									
										
										
										
											2023-09-26 20:25:53 +00:00
										 |  |  |         attributed_to = get_attributed_to(post_json_object['attributedTo']) | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     if not attributed_to: | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # get the language of the video | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     post_language = system_language | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if post_json_object.get('language'): | 
					
						
							|  |  |  |         if isinstance(post_json_object['language'], dict): | 
					
						
							|  |  |  |             if post_json_object['language'].get('identifier'): | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |                 post_language = post_json_object['language']['identifier'] | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # check that the attributed actor is not blocked | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     post_nickname = get_nickname_from_actor(attributed_to) | 
					
						
							|  |  |  |     if not post_nickname: | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     post_domain, post_domain_port = get_domain_from_actor(attributed_to) | 
					
						
							|  |  |  |     if not post_domain: | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     post_domain_full = get_full_domain(post_domain, post_domain_port) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     if is_blocked(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2024-02-09 22:09:18 +00:00
										 |  |  |                   post_nickname, post_domain_full, | 
					
						
							|  |  |  |                   blocked_cache, block_federated): | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # check that the content is valid | 
					
						
							| 
									
										
										
										
											2022-09-25 17:26:11 +00:00
										 |  |  |     if is_filtered(base_dir, nickname, domain, post_json_object['name'], | 
					
						
							|  |  |  |                    system_language): | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-09-25 17:26:11 +00:00
										 |  |  |     if is_filtered(base_dir, nickname, domain, post_json_object['content'], | 
					
						
							|  |  |  |                    system_language): | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # get the content | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     content = '<p><b>' + post_json_object['name'] + '</b></p>' | 
					
						
							|  |  |  |     if post_json_object.get('license'): | 
					
						
							|  |  |  |         if isinstance(post_json_object['license'], dict): | 
					
						
							|  |  |  |             if post_json_object['license'].get('name'): | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                 if is_filtered(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-09-25 17:26:11 +00:00
										 |  |  |                                post_json_object['license']['name'], | 
					
						
							|  |  |  |                                system_language): | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |                     return None | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |                 content += '<p>' + post_json_object['license']['name'] + '</p>' | 
					
						
							| 
									
										
										
										
											2023-10-29 14:54:00 +00:00
										 |  |  |     content += \ | 
					
						
							| 
									
										
										
										
											2023-10-29 13:24:52 +00:00
										 |  |  |         get_content_from_post(post_json_object, system_language, | 
					
						
							|  |  |  |                               languages_understood, "content") | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     conversation_id = remove_id_ending(post_json_object['id']) | 
					
						
							| 
									
										
										
										
											2024-10-06 19:20:47 +00:00
										 |  |  |     conversation_id = post_id_to_convthread_id(conversation_id, | 
					
						
							|  |  |  |                                                post_json_object['published']) | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 22:00:04 +00:00
										 |  |  |     media_type, media_url, media_torrent, media_magnet = \ | 
					
						
							|  |  |  |         get_media_url_from_video(post_json_object) | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     if not media_url: | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     attachment = [{ | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |             'mediaType': media_type, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             'name': post_json_object['content'], | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |             'type': 'Document', | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |             'url': media_url | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |     }] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     if media_torrent or media_magnet: | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         content += '<p>' | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |         if media_torrent: | 
					
						
							|  |  |  |             content += '<a href="' + media_torrent + '">⇓</a> ' | 
					
						
							|  |  |  |         if media_magnet: | 
					
						
							|  |  |  |             content += '<a href="' + media_magnet + '">🧲</a>' | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         content += '</p>' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-12 11:08:02 +00:00
										 |  |  |     new_post_id2 = remove_html(post_json_object['id']) | 
					
						
							|  |  |  |     new_post_id = remove_id_ending(new_post_id2) | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     new_post = { | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |         '@context': post_json_object['@context'], | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |         'id': new_post_id + '/activity', | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         'type': 'Create', | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |         'actor': attributed_to, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |         'published': post_json_object['published'], | 
					
						
							|  |  |  |         'to': post_json_object['to'], | 
					
						
							|  |  |  |         'cc': post_json_object['cc'], | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |         'object': { | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |             'id': new_post_id, | 
					
						
							|  |  |  |             'conversation': conversation_id, | 
					
						
							| 
									
										
										
										
											2023-01-09 11:38:05 +00:00
										 |  |  |             'context': conversation_id, | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |             'type': 'Note', | 
					
						
							|  |  |  |             'summary': None, | 
					
						
							|  |  |  |             'inReplyTo': None, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             'published': post_json_object['published'], | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |             'url': new_post_id, | 
					
						
							|  |  |  |             'attributedTo': attributed_to, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             'to': post_json_object['to'], | 
					
						
							|  |  |  |             'cc': post_json_object['cc'], | 
					
						
							|  |  |  |             'sensitive': post_json_object['sensitive'], | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |             'atomUri': new_post_id, | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |             'inReplyToAtomUri': None, | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |             'commentsEnabled': post_json_object['commentsEnabled'], | 
					
						
							|  |  |  |             'rejectReplies': not post_json_object['commentsEnabled'], | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |             'mediaType': 'text/html', | 
					
						
							|  |  |  |             'content': content, | 
					
						
							|  |  |  |             'contentMap': { | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |                 post_language: content | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |             }, | 
					
						
							|  |  |  |             'attachment': attachment, | 
					
						
							|  |  |  |             'tag': [], | 
					
						
							|  |  |  |             'replies': { | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |                 'id': new_post_id + '/replies', | 
					
						
							| 
									
										
										
										
											2025-03-31 11:23:56 +00:00
										 |  |  |                 'repliesOf': new_post_id, | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |                 'type': 'Collection', | 
					
						
							|  |  |  |                 'first': { | 
					
						
							|  |  |  |                     'type': 'CollectionPage', | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |                     'partOf': new_post_id + '/replies', | 
					
						
							| 
									
										
										
										
											2021-09-13 11:34:56 +00:00
										 |  |  |                     'items': [] | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 18:08:35 +00:00
										 |  |  |     if post_json_object.get('support'): | 
					
						
							| 
									
										
										
										
											2023-10-29 20:00:43 +00:00
										 |  |  |         support_str = post_json_object['support'] | 
					
						
							|  |  |  |         if isinstance(support_str, str): | 
					
						
							|  |  |  |             if not dangerous_markup(support_str, False, []): | 
					
						
							|  |  |  |                 if not is_filtered(base_dir, nickname, domain, support_str, | 
					
						
							| 
									
										
										
										
											2023-10-29 19:41:09 +00:00
										 |  |  |                                    system_language): | 
					
						
							| 
									
										
										
										
											2023-10-29 20:00:43 +00:00
										 |  |  |                     new_post['object']['support'] = support_str | 
					
						
							|  |  |  |                     # if this is a link | 
					
						
							| 
									
										
										
										
											2024-01-27 17:04:21 +00:00
										 |  |  |                     if resembles_url(support_str): | 
					
						
							| 
									
										
										
										
											2023-10-29 20:00:43 +00:00
										 |  |  |                         # add a buy link | 
					
						
							|  |  |  |                         new_post['object']['attachment'].append({ | 
					
						
							|  |  |  |                             'type': 'Link', | 
					
						
							| 
									
										
										
										
											2023-10-29 20:01:40 +00:00
										 |  |  |                             'mediaType': 'text/html', | 
					
						
							| 
									
										
										
										
											2023-10-29 20:00:43 +00:00
										 |  |  |                             'href': support_str, | 
					
						
							|  |  |  |                             'rel': 'support', | 
					
						
							|  |  |  |                             'name': 'Support' | 
					
						
							|  |  |  |                         }) | 
					
						
							| 
									
										
										
										
											2023-10-29 18:08:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 20:20:55 +00:00
										 |  |  |     if post_json_object.get('license'): | 
					
						
							|  |  |  |         if isinstance(post_json_object['license'], dict): | 
					
						
							|  |  |  |             if post_json_object['license'].get('name'): | 
					
						
							|  |  |  |                 if isinstance(post_json_object['license']['name'], str): | 
					
						
							|  |  |  |                     license_str = post_json_object['license']['name'] | 
					
						
							|  |  |  |                     content_license_url = \ | 
					
						
							|  |  |  |                         license_link_from_name(license_str) | 
					
						
							|  |  |  |                     if content_license_url: | 
					
						
							|  |  |  |                         new_post['object']['attachment'].append({ | 
					
						
							|  |  |  |                             "type": "PropertyValue", | 
					
						
							|  |  |  |                             "name": "license", | 
					
						
							|  |  |  |                             "value": content_license_url | 
					
						
							|  |  |  |                         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-29 20:48:27 +00:00
										 |  |  |     if post_json_object.get('subtitleLanguage'): | 
					
						
							|  |  |  |         if isinstance(post_json_object['subtitleLanguage'], list): | 
					
						
							|  |  |  |             for lang in post_json_object['subtitleLanguage']: | 
					
						
							|  |  |  |                 if not isinstance(lang, dict): | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 if not lang.get('identifier'): | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 if not isinstance(lang['identifier'], str): | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 if not lang.get('url'): | 
					
						
							|  |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2023-12-09 14:18:24 +00:00
										 |  |  |                 url_str = get_url_from_post(lang['url']) | 
					
						
							|  |  |  |                 if not url_str: | 
					
						
							| 
									
										
										
										
											2023-10-29 20:48:27 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2023-12-09 14:18:24 +00:00
										 |  |  |                 if not url_str.endswith('.vtt'): | 
					
						
							| 
									
										
										
										
											2023-10-29 20:48:27 +00:00
										 |  |  |                     continue | 
					
						
							|  |  |  |                 for understood in languages_understood: | 
					
						
							|  |  |  |                     if understood in lang['identifier']: | 
					
						
							|  |  |  |                         new_post['object']['attachment'].append({ | 
					
						
							| 
									
										
										
										
											2023-10-29 20:53:26 +00:00
										 |  |  |                             "type": "Document", | 
					
						
							|  |  |  |                             "name": understood, | 
					
						
							| 
									
										
										
										
											2023-10-29 20:48:27 +00:00
										 |  |  |                             "mediaType": "text/vtt", | 
					
						
							| 
									
										
										
										
											2023-12-09 14:18:24 +00:00
										 |  |  |                             "url": url_str | 
					
						
							| 
									
										
										
										
											2023-10-29 20:48:27 +00:00
										 |  |  |                         }) | 
					
						
							|  |  |  |                         break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 19:14:30 +00:00
										 |  |  |     return new_post |