2021-09-13 11:34:56 +00:00
|
|
|
__filename__ = "video.py"
|
|
|
|
__author__ = "Bob Mottram"
|
|
|
|
__license__ = "AGPL3+"
|
2024-01-21 19:01:20 +00:00
|
|
|
__version__ = "1.5.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
|
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'])
|
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',
|
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
|