2020-11-09 19:41:01 +00:00
|
|
|
__filename__ = "webapp_media.py"
|
|
|
|
__author__ = "Bob Mottram"
|
|
|
|
__license__ = "AGPL3+"
|
2021-01-26 10:07:42 +00:00
|
|
|
__version__ = "1.2.0"
|
2020-11-09 19:41:01 +00:00
|
|
|
__maintainer__ = "Bob Mottram"
|
|
|
|
__email__ = "bob@freedombone.net"
|
|
|
|
__status__ = "Production"
|
2021-06-26 11:27:14 +00:00
|
|
|
__module_group__ = "Timeline"
|
2020-11-09 19:41:01 +00:00
|
|
|
|
2020-12-24 10:18:34 +00:00
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
|
|
def loadPeertubeInstances(baseDir: str, peertubeInstances: []) -> None:
|
|
|
|
"""Loads peertube instances from file into the given list
|
|
|
|
"""
|
|
|
|
peertubeList = None
|
|
|
|
peertubeInstancesFilename = baseDir + '/accounts/peertube.txt'
|
|
|
|
if os.path.isfile(peertubeInstancesFilename):
|
|
|
|
with open(peertubeInstancesFilename, 'r') as fp:
|
|
|
|
peertubeStr = fp.read()
|
|
|
|
if peertubeStr:
|
|
|
|
peertubeStr = peertubeStr.replace('\r', '')
|
|
|
|
peertubeList = peertubeStr.split('\n')
|
2020-12-24 11:42:23 +00:00
|
|
|
if not peertubeList:
|
|
|
|
return
|
|
|
|
for url in peertubeList:
|
|
|
|
if url in peertubeInstances:
|
|
|
|
continue
|
|
|
|
peertubeInstances.append(url)
|
|
|
|
|
|
|
|
|
2020-12-22 18:06:23 +00:00
|
|
|
def _addEmbeddedVideoFromSites(translate: {}, content: str,
|
2020-12-23 23:59:49 +00:00
|
|
|
peertubeInstances: [],
|
2020-12-22 18:06:23 +00:00
|
|
|
width=400, height=300) -> str:
|
2020-11-09 19:41:01 +00:00
|
|
|
"""Adds embedded videos
|
|
|
|
"""
|
|
|
|
if '>vimeo.com/' in content:
|
|
|
|
url = content.split('>vimeo.com/')[1]
|
|
|
|
if '<' in url:
|
|
|
|
url = url.split('<')[0]
|
|
|
|
content = \
|
|
|
|
content + "<center>\n<iframe loading=\"lazy\" " + \
|
|
|
|
"src=\"https://player.vimeo.com/video/" + \
|
|
|
|
url + "\" width=\"" + str(width) + \
|
|
|
|
"\" height=\"" + str(height) + \
|
|
|
|
"\" frameborder=\"0\" allow=\"autoplay; " + \
|
|
|
|
"fullscreen\" allowfullscreen></iframe>\n</center>\n"
|
|
|
|
return content
|
|
|
|
|
|
|
|
videoSite = 'https://www.youtube.com'
|
|
|
|
if '"' + videoSite in content:
|
|
|
|
url = content.split('"' + videoSite)[1]
|
|
|
|
if '"' in url:
|
|
|
|
url = url.split('"')[0].replace('/watch?v=', '/embed/')
|
|
|
|
if '&' in url:
|
|
|
|
url = url.split('&')[0]
|
2021-01-14 09:38:51 +00:00
|
|
|
if '?utm_' in url:
|
|
|
|
url = url.split('?utm_')[0]
|
2020-11-09 19:41:01 +00:00
|
|
|
content = \
|
|
|
|
content + "<center>\n<iframe loading=\"lazy\" src=\"" + \
|
|
|
|
videoSite + url + "\" width=\"" + str(width) + \
|
|
|
|
"\" height=\"" + str(height) + \
|
|
|
|
"\" frameborder=\"0\" allow=\"autoplay; fullscreen\" " + \
|
|
|
|
"allowfullscreen></iframe>\n</center>\n"
|
|
|
|
return content
|
|
|
|
|
2020-12-23 22:48:19 +00:00
|
|
|
invidiousSites = ('https://invidious.snopyta.org',
|
2020-12-23 22:50:21 +00:00
|
|
|
'https://yewtu.be',
|
|
|
|
'https://tube.connect.cafe',
|
|
|
|
'https://invidious.kavin.rocks',
|
|
|
|
'https://invidiou.site',
|
|
|
|
'https://invidious.tube',
|
|
|
|
'https://invidious.xyz',
|
|
|
|
'https://invidious.zapashcanon.fr',
|
2020-11-09 19:41:01 +00:00
|
|
|
'http://c7hqkpkpemu6e7emz5b4vy' +
|
|
|
|
'z7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion',
|
|
|
|
'http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4' +
|
|
|
|
'bzzsg2ii4fv2iid.onion')
|
|
|
|
for videoSite in invidiousSites:
|
|
|
|
if '"' + videoSite in content:
|
|
|
|
url = content.split('"' + videoSite)[1]
|
|
|
|
if '"' in url:
|
|
|
|
url = url.split('"')[0].replace('/watch?v=', '/embed/')
|
|
|
|
if '&' in url:
|
|
|
|
url = url.split('&')[0]
|
2021-01-14 09:38:51 +00:00
|
|
|
if '?utm_' in url:
|
|
|
|
url = url.split('?utm_')[0]
|
2020-11-09 19:41:01 +00:00
|
|
|
content = \
|
|
|
|
content + "<center>\n<iframe loading=\"lazy\" src=\"" + \
|
|
|
|
videoSite + url + "\" width=\"" + \
|
|
|
|
str(width) + "\" height=\"" + str(height) + \
|
|
|
|
"\" frameborder=\"0\" allow=\"autoplay; fullscreen\" " + \
|
|
|
|
"allowfullscreen></iframe>\n</center>\n"
|
|
|
|
return content
|
|
|
|
|
|
|
|
videoSite = 'https://media.ccc.de'
|
|
|
|
if '"' + videoSite in content:
|
|
|
|
url = content.split('"' + videoSite)[1]
|
|
|
|
if '"' in url:
|
|
|
|
url = url.split('"')[0]
|
|
|
|
if not url.endswith('/oembed'):
|
|
|
|
url = url + '/oembed'
|
|
|
|
content = \
|
|
|
|
content + "<center>\n<iframe loading=\"lazy\" src=\"" + \
|
|
|
|
videoSite + url + "\" width=\"" + \
|
|
|
|
str(width) + "\" height=\"" + str(height) + \
|
|
|
|
"\" frameborder=\"0\" allow=\"fullscreen\" " + \
|
|
|
|
"allowfullscreen></iframe>\n</center>\n"
|
|
|
|
return content
|
|
|
|
|
|
|
|
if '"https://' in content:
|
2020-12-23 23:59:49 +00:00
|
|
|
if peertubeInstances:
|
|
|
|
peerTubeSites = peertubeInstances
|
|
|
|
else:
|
2020-12-24 10:13:21 +00:00
|
|
|
# A default selection of the current larger peertube sites,
|
2020-12-24 12:37:13 +00:00
|
|
|
# mostly French and German language.
|
|
|
|
# These have only been semi-vetted, and so should be under
|
|
|
|
# continuous review.
|
2020-12-24 10:13:21 +00:00
|
|
|
# Also see https://peertube_isolation.frama.io/list/ for
|
|
|
|
# adversarial instances. Nothing in that list should be
|
|
|
|
# in the defaults below.
|
2020-12-24 12:37:13 +00:00
|
|
|
peerTubeSites = ('share.tube',
|
|
|
|
'tube.22decembre.eu',
|
2020-12-23 23:59:49 +00:00
|
|
|
'libre.video',
|
2020-12-24 12:37:13 +00:00
|
|
|
'peertube.linuxrocks.online',
|
|
|
|
'spacepub.space',
|
|
|
|
'tube.tchncs.de',
|
2020-12-23 23:59:49 +00:00
|
|
|
'video.irem.univ-paris-diderot.fr',
|
2020-12-24 12:37:13 +00:00
|
|
|
'peertube.openstreetmap.fr',
|
|
|
|
'video.antopie.org',
|
|
|
|
'scitech.video',
|
2020-12-23 23:59:49 +00:00
|
|
|
'video.ploud.fr',
|
2020-12-24 12:37:13 +00:00
|
|
|
'diode.zone',
|
|
|
|
'visionon.tv',
|
|
|
|
'peertube.fr',
|
|
|
|
'peertube.live',
|
|
|
|
'kolektiva.media',
|
2020-12-23 23:59:49 +00:00
|
|
|
'betamax.video',
|
2020-12-24 12:37:13 +00:00
|
|
|
'peertube.social',
|
|
|
|
'videos.lescommuns.org',
|
|
|
|
'video.tedomum.net',
|
|
|
|
'tilvids.com',
|
|
|
|
'exode.me',
|
|
|
|
'peertube.video')
|
2020-11-09 19:41:01 +00:00
|
|
|
for site in peerTubeSites:
|
2020-12-24 13:57:02 +00:00
|
|
|
site = site.strip()
|
|
|
|
if not site:
|
|
|
|
continue
|
|
|
|
if len(site) < 5:
|
|
|
|
continue
|
|
|
|
if '.' not in site:
|
|
|
|
continue
|
2020-12-24 12:37:13 +00:00
|
|
|
siteStr = site
|
2020-12-24 13:13:03 +00:00
|
|
|
if site.startswith('http://'):
|
|
|
|
site = site.replace('http://', '')
|
|
|
|
elif site.startswith('https://'):
|
|
|
|
site = site.replace('https://', '')
|
|
|
|
if site.endswith('.onion') or site.endswith('.i2p'):
|
|
|
|
siteStr = 'http://' + site
|
|
|
|
else:
|
2020-12-24 12:37:13 +00:00
|
|
|
siteStr = 'https://' + site
|
|
|
|
siteStr = '"' + siteStr
|
|
|
|
if siteStr in content:
|
|
|
|
url = content.split(siteStr)[1]
|
2020-11-09 19:41:01 +00:00
|
|
|
if '"' in url:
|
|
|
|
url = url.split('"')[0].replace('/watch/', '/embed/')
|
|
|
|
content = \
|
|
|
|
content + "<center>\n<iframe loading=\"lazy\" " + \
|
|
|
|
"sandbox=\"allow-same-origin " + \
|
|
|
|
"allow-scripts\" src=\"https://" + \
|
|
|
|
site + url + "\" width=\"" + str(width) + \
|
|
|
|
"\" height=\"" + str(height) + \
|
|
|
|
"\" frameborder=\"0\" allow=\"autoplay; " + \
|
|
|
|
"fullscreen\" allowfullscreen></iframe>\n</center>\n"
|
|
|
|
return content
|
|
|
|
return content
|
|
|
|
|
|
|
|
|
2020-12-22 18:06:23 +00:00
|
|
|
def _addEmbeddedAudio(translate: {}, content: str) -> str:
|
2020-11-09 19:41:01 +00:00
|
|
|
"""Adds embedded audio for mp3/ogg
|
|
|
|
"""
|
|
|
|
if not ('.mp3' in content or '.ogg' in content):
|
|
|
|
return content
|
|
|
|
|
|
|
|
if '<audio ' in content:
|
|
|
|
return content
|
|
|
|
|
|
|
|
extension = '.mp3'
|
|
|
|
if '.ogg' in content:
|
|
|
|
extension = '.ogg'
|
|
|
|
|
|
|
|
words = content.strip('\n').split(' ')
|
|
|
|
for w in words:
|
|
|
|
if extension not in w:
|
|
|
|
continue
|
|
|
|
w = w.replace('href="', '').replace('">', '')
|
|
|
|
if w.endswith('.'):
|
|
|
|
w = w[:-1]
|
|
|
|
if w.endswith('"'):
|
|
|
|
w = w[:-1]
|
|
|
|
if w.endswith(';'):
|
|
|
|
w = w[:-1]
|
|
|
|
if w.endswith(':'):
|
|
|
|
w = w[:-1]
|
|
|
|
if not w.endswith(extension):
|
|
|
|
continue
|
|
|
|
|
|
|
|
if not (w.startswith('http') or w.startswith('dat:') or
|
|
|
|
w.startswith('hyper:') or w.startswith('i2p:') or
|
|
|
|
w.startswith('gnunet:') or
|
|
|
|
'/' in w):
|
|
|
|
continue
|
|
|
|
url = w
|
|
|
|
content += '<center>\n<audio controls>\n'
|
|
|
|
content += \
|
|
|
|
'<source src="' + url + '" type="audio/' + \
|
|
|
|
extension.replace('.', '') + '">'
|
|
|
|
content += \
|
|
|
|
translate['Your browser does not support the audio element.']
|
|
|
|
content += '</audio>\n</center>\n'
|
|
|
|
return content
|
|
|
|
|
|
|
|
|
2021-03-07 12:09:46 +00:00
|
|
|
def _addEmbeddedVideo(translate: {}, content: str) -> str:
|
2020-11-09 19:41:01 +00:00
|
|
|
"""Adds embedded video for mp4/webm/ogv
|
|
|
|
"""
|
|
|
|
if not ('.mp4' in content or '.webm' in content or '.ogv' in content):
|
|
|
|
return content
|
|
|
|
|
|
|
|
if '<video ' in content:
|
|
|
|
return content
|
|
|
|
|
|
|
|
extension = '.mp4'
|
|
|
|
if '.webm' in content:
|
|
|
|
extension = '.webm'
|
|
|
|
elif '.ogv' in content:
|
|
|
|
extension = '.ogv'
|
|
|
|
|
|
|
|
words = content.strip('\n').split(' ')
|
|
|
|
for w in words:
|
|
|
|
if extension not in w:
|
|
|
|
continue
|
|
|
|
w = w.replace('href="', '').replace('">', '')
|
|
|
|
if w.endswith('.'):
|
|
|
|
w = w[:-1]
|
|
|
|
if w.endswith('"'):
|
|
|
|
w = w[:-1]
|
|
|
|
if w.endswith(';'):
|
|
|
|
w = w[:-1]
|
|
|
|
if w.endswith(':'):
|
|
|
|
w = w[:-1]
|
|
|
|
if not w.endswith(extension):
|
|
|
|
continue
|
|
|
|
if not (w.startswith('http') or w.startswith('dat:') or
|
|
|
|
w.startswith('hyper:') or w.startswith('i2p:') or
|
|
|
|
w.startswith('gnunet:') or
|
|
|
|
'/' in w):
|
|
|
|
continue
|
|
|
|
url = w
|
|
|
|
content += \
|
2021-03-07 12:06:01 +00:00
|
|
|
'<center><figure id="videoContainer" ' + \
|
|
|
|
'data-fullscreen="false">\n' + \
|
|
|
|
' <video id="video" controls ' + \
|
|
|
|
'preload="metadata">\n'
|
2020-11-09 19:41:01 +00:00
|
|
|
content += \
|
|
|
|
'<source src="' + url + '" type="video/' + \
|
|
|
|
extension.replace('.', '') + '">\n'
|
|
|
|
content += \
|
|
|
|
translate['Your browser does not support the video element.']
|
2021-03-07 12:06:01 +00:00
|
|
|
content += '</video>\n</figure>\n</center>\n'
|
2020-11-09 19:41:01 +00:00
|
|
|
return content
|
|
|
|
|
|
|
|
|
2020-12-23 23:59:49 +00:00
|
|
|
def addEmbeddedElements(translate: {}, content: str,
|
|
|
|
peertubeInstances: []) -> str:
|
2020-11-09 19:41:01 +00:00
|
|
|
"""Adds embedded elements for various media types
|
|
|
|
"""
|
2020-12-23 23:59:49 +00:00
|
|
|
content = _addEmbeddedVideoFromSites(translate, content,
|
|
|
|
peertubeInstances)
|
2020-12-22 18:06:23 +00:00
|
|
|
content = _addEmbeddedAudio(translate, content)
|
|
|
|
return _addEmbeddedVideo(translate, content)
|