Merge branch 'master' of github.com:gpodder/gpodder
This commit is contained in:
commit
975b0338ab
|
@ -219,4 +219,4 @@ check if the bug still appears to see if an extension causes the bug.
|
|||
- Homepage: http://gpodder.org/
|
||||
- Bug tracker: https://github.com/gpodder/gpodder/issues
|
||||
- Mailing list: http://freelists.org/list/gpodder
|
||||
- IRC channel: #gpodder on irc.freenode.net
|
||||
- IRC channel: #gpodder on irc.libera.chat
|
||||
|
|
504
po/cs_CZ.po
504
po/cs_CZ.po
File diff suppressed because it is too large
Load Diff
504
po/es_ES.po
504
po/es_ES.po
File diff suppressed because it is too large
Load Diff
504
po/es_MX.po
504
po/es_MX.po
File diff suppressed because it is too large
Load Diff
506
po/fa_IR.po
506
po/fa_IR.po
File diff suppressed because it is too large
Load Diff
504
po/id_ID.po
504
po/id_ID.po
File diff suppressed because it is too large
Load Diff
504
po/ko_KR.po
504
po/ko_KR.po
File diff suppressed because it is too large
Load Diff
504
po/messages.pot
504
po/messages.pot
File diff suppressed because it is too large
Load Diff
504
po/pt_BR.po
504
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
506
po/zh_CN.po
506
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
|
@ -116,6 +116,10 @@ class YoutubeCustomDownload(download.CustomDownload):
|
|||
break
|
||||
ext_filetype = mimetype_from_extension(dot_ext)
|
||||
if ext_filetype:
|
||||
# Youtube weba formats have a webm extension and get a video/webm mime-type
|
||||
# but audio content has no width or height, so change it to audio/webm for correct icon and player
|
||||
if ext_filetype.startswith('video/') and ('height' not in res or res['height'] is None):
|
||||
ext_filetype = ext_filetype.replace('video/', 'audio/')
|
||||
headers['content-type'] = ext_filetype
|
||||
return headers, res.get('url', self._url)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH GPO "1" "April 2021" "gpodder 3.10.19" "User Commands"
|
||||
.TH GPO "1" "June 2021" "gpodder 3.10.20" "User Commands"
|
||||
.SH NAME
|
||||
gpo \- Text mode interface of gPodder
|
||||
.SH SYNOPSIS
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.17.
|
||||
.TH GPODDER "1" "April 2021" "gpodder 3.10.19" "User Commands"
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.48.3.
|
||||
.TH GPODDER "1" "June 2021" "gpodder 3.10.20" "User Commands"
|
||||
.SH NAME
|
||||
gpodder \- Media aggregator and podcast client
|
||||
.SH SYNOPSIS
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
# This metadata block gets parsed by setup.py - use single quotes only
|
||||
__tagline__ = 'Media aggregator and podcast client'
|
||||
__author__ = 'Thomas Perl <thp@gpodder.org>'
|
||||
__version__ = '3.10.19'
|
||||
__date__ = '2021-04-15'
|
||||
__version__ = '3.10.20'
|
||||
__date__ = '2021-06-06'
|
||||
__copyright__ = '© 2005-2021 The gPodder Team'
|
||||
__license__ = 'GNU General Public License, version 3 or later'
|
||||
__url__ = 'http://gpodder.org/'
|
||||
|
|
|
@ -80,7 +80,7 @@ class gPodderChannel(BuilderWidget):
|
|||
|
||||
b = Gtk.TextBuffer()
|
||||
if self.channel._update_error:
|
||||
err = '\n\nERROR: {}'.format(self.channel._update_error)
|
||||
err = '\n\n' + (_('ERROR: %s') % self.channel._update_error)
|
||||
else:
|
||||
err = ''
|
||||
b.set_text(util.remove_html_tags(self.channel.description) + err)
|
||||
|
|
|
@ -289,8 +289,8 @@ def get_real_download_url(url, allow_partial, preferred_fmt_ids=None):
|
|||
fmt_id_url_map = dict(fmt_id_url_map)
|
||||
|
||||
for id in preferred_fmt_ids:
|
||||
if re.search(r'\+', str(id)):
|
||||
# skip formats that contain a + (136+140)
|
||||
if re.search(r'(^best|\+)', str(id)):
|
||||
# skip formats that contain 'best.*' or a + (136+140)
|
||||
continue
|
||||
id = int(id)
|
||||
if id in formats_available:
|
||||
|
@ -373,10 +373,15 @@ def get_real_channel_url(url):
|
|||
def get_channel_id_url(url):
|
||||
if 'youtube.com' in url:
|
||||
try:
|
||||
channel_url = ''
|
||||
raw_xml_data = io.BytesIO(util.urlopen(url).content)
|
||||
xml_data = xml.etree.ElementTree.parse(raw_xml_data)
|
||||
channel_id = xml_data.find("{http://www.youtube.com/xml/schemas/2015}channelId").text
|
||||
req = util.urlopen(url)
|
||||
# video page may contain corrupt HTML/XML, search for tag to avoid exception
|
||||
m = re.search(r'<meta itemprop="channelId" content="([^"]+)">', req.text)
|
||||
if m:
|
||||
channel_id = m.group(1)
|
||||
else:
|
||||
raw_xml_data = io.BytesIO(req.content)
|
||||
xml_data = xml.etree.ElementTree.parse(raw_xml_data)
|
||||
channel_id = xml_data.find("{http://www.youtube.com/xml/schemas/2015}channelId").text
|
||||
channel_url = 'https://www.youtube.com/channel/{}'.format(channel_id)
|
||||
return channel_url
|
||||
|
||||
|
@ -480,27 +485,34 @@ def parse_youtube_url(url):
|
|||
scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url)
|
||||
logger.debug("Analyzing URL: {}".format(" ".join([scheme, netloc, path, query, fragment])))
|
||||
|
||||
if 'youtube.com' in netloc and ('/user/' in path or '/channel/' in path or 'list=' in query):
|
||||
logger.debug("Valid Youtube URL detected. Parsing...")
|
||||
if 'youtube.com' in netloc:
|
||||
if '/user/' in path or '/channel/' in path or 'list=' in query:
|
||||
logger.debug("Valid Youtube URL detected. Parsing...")
|
||||
|
||||
if path.startswith('/user/'):
|
||||
user_id = path.split('/')[2]
|
||||
query = 'user={user_id}'.format(user_id=user_id)
|
||||
if path.startswith('/user/'):
|
||||
user_id = path.split('/')[2]
|
||||
query = 'user={user_id}'.format(user_id=user_id)
|
||||
|
||||
if path.startswith('/channel/'):
|
||||
channel_id = path.split('/')[2]
|
||||
query = 'channel_id={channel_id}'.format(channel_id=channel_id)
|
||||
if path.startswith('/channel/'):
|
||||
channel_id = path.split('/')[2]
|
||||
query = 'channel_id={channel_id}'.format(channel_id=channel_id)
|
||||
|
||||
if 'list=' in query:
|
||||
playlist_query = [query_value for query_value in query.split("&") if 'list=' in query_value][0]
|
||||
playlist_id = playlist_query[5:]
|
||||
query = 'playlist_id={playlist_id}'.format(playlist_id=playlist_id)
|
||||
if 'list=' in query:
|
||||
playlist_query = [query_value for query_value in query.split("&") if 'list=' in query_value][0]
|
||||
playlist_id = playlist_query[5:]
|
||||
query = 'playlist_id={playlist_id}'.format(playlist_id=playlist_id)
|
||||
|
||||
path = '/feeds/videos.xml'
|
||||
path = '/feeds/videos.xml'
|
||||
|
||||
new_url = urllib.parse.urlunsplit((scheme, netloc, path, query, fragment))
|
||||
logger.debug("New Youtube URL: {}".format(new_url))
|
||||
return new_url
|
||||
else:
|
||||
logger.debug("Not a valid Youtube URL: {}".format(url))
|
||||
return url
|
||||
new_url = urllib.parse.urlunsplit((scheme, netloc, path, query, fragment))
|
||||
logger.debug("New Youtube URL: {}".format(new_url))
|
||||
return new_url
|
||||
|
||||
# look for channel URL in page
|
||||
new_url = get_channel_id_url(url)
|
||||
if new_url:
|
||||
logger.debug("New Youtube URL: {}".format(new_url))
|
||||
return new_url
|
||||
|
||||
logger.debug("Not a valid Youtube URL: {}".format(url))
|
||||
return url
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# PyPI / pip requirements for Linux
|
||||
# For the benefit of e.g. flatpak-pip-generator.
|
||||
#
|
||||
mygpoclient==1.8
|
||||
podcastparser==0.6.6
|
||||
requests[socks]==2.25.1
|
||||
urllib3==1.26.5
|
||||
html5lib==1.1
|
||||
mutagen==1.45.1
|
||||
dbus-python
|
||||
youtube_dl
|
||||
# eyed3 is optional and pulls in a lot of dependencies, so disable by default
|
||||
# eyed3
|
|
@ -92,8 +92,8 @@ webencodings==0.5.1
|
|||
certifi==2020.11.8
|
||||
mutagen==1.45.1
|
||||
youtube_dl
|
||||
requests==2.25.0
|
||||
urllib3==1.26.4
|
||||
requests==2.25.1
|
||||
urllib3==1.26.5
|
||||
chardet==4.0.0
|
||||
idna==3.1
|
||||
PySocks==1.7.1
|
||||
|
|
Loading…
Reference in New Issue