Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Honeypot
mopidy-youtube
Commits
5f8ecc42
Commit
5f8ecc42
authored
Jan 31, 2017
by
Fjen Undso
Browse files
fix caching and add search for URLs
parent
70d7d6de
Changes
1
Hide whitespace changes
Inline
Side-by-side
mopidy_youtube/backend.py
View file @
5f8ecc42
...
...
@@ -21,8 +21,6 @@ session = requests.Session()
search_uri
=
'youtube:search'
ytdl_id
=
'ytdl_id'
cache
=
{}
cache_ids
=
[]
cache_max
=
50
...
...
@@ -34,7 +32,7 @@ def get_cache(y_id):
def
set_cache
(
tracks
):
for
track
in
tracks
:
y_id
=
track
.
album
.
name
y_id
=
':'
.
join
(
track
.
uri
.
split
(
':'
)[
1
:])
cache
[
y_id
]
=
track
cache_ids
.
append
(
y_id
)
if
len
(
cach_ids
)
>
cache_max
:
...
...
@@ -67,7 +65,7 @@ class YouTubeBackend(pykka.ThreadingActor, backend.Backend):
class
YouTubeLibraryProvider
(
backend
.
LibraryProvider
):
def
_get_duration
(
self
,
yttime
):
"""Convert
y
ou
t
ube time to milliseconds"""
"""Convert
Y
ou
T
ube time to milliseconds"""
# convert PT1H2M10S to 3730000
m
=
re
.
search
(
'PT((?P<hours>\d+)H)?'
+
'((?P<minutes>\d+)M)?'
+
...
...
@@ -78,7 +76,7 @@ class YouTubeLibraryProvider(backend.LibraryProvider):
int
(
m
.
group
(
'seconds'
)
or
0
))
*
1000
def
_get_tracks
(
self
,
ids
):
"""Process
y
ou
t
ube
id
s and return tracks"""
"""Process
Y
ou
T
ube
ID
s and return tracks"""
fancy_ids
=
' '
.
join
([
str
(
x
)
for
x
in
ids
])
logger
.
info
(
"Get tracks for ids: %s"
,
fancy_ids
)
query
=
{
...
...
@@ -106,7 +104,7 @@ class YouTubeLibraryProvider(backend.LibraryProvider):
return
tracks
def
_get_playlist
(
self
,
id
,
maxresults
=
100
):
"""Process
y
ou
t
ube playlist and return tracks"""
"""Process
Y
ou
T
ube playlist and return tracks"""
logger
.
info
(
"Get Playlist for '%s'"
,
str
(
id
))
page
=
''
video_ids
=
[]
...
...
@@ -127,7 +125,7 @@ class YouTubeLibraryProvider(backend.LibraryProvider):
return
self
.
_get_tracks
(
video_ids
)
def
_get_search
(
self
,
query
,
maxresults
=
20
):
"""Process
y
ou
t
ube search and return tracks"""
"""Process
Y
ou
T
ube search and return tracks"""
query
=
{
'part'
:
'id'
,
'fields'
:
'items(id)'
,
...
...
@@ -153,13 +151,14 @@ class YouTubeLibraryProvider(backend.LibraryProvider):
name
=
ytdl
[
'display_id'
],
images
=
thumbnail
),
uri
=
self
.
backend
.
uri_schemes
[
0
]
+
':'
+
ytdl
[
'webpage_url'
]
+
' '
+
ytdl
[
'url'
]
uri
=
self
.
backend
.
uri_schemes
[
0
]
+
':'
+
ytdl
[
'url'
]
)
return
track
def
_get_ytdl_tracks
(
self
,
uri
):
"""Return a list of tracks given an
a
ri based on ytdl
.
"""
"""Return a list of tracks given an
u
ri based on ytdl"""
if
uri
in
cache
:
logger
.
info
(
"Using cached track response"
)
return
get_cache
(
uri
)
try
:
yt_uri
=
call_ytdl
(
uri
)
...
...
@@ -176,7 +175,7 @@ class YouTubeLibraryProvider(backend.LibraryProvider):
def
lookup
(
self
,
uri
):
"""Process any uri supported by ytdl and return tracks"""
logger
.
info
(
"Looking up
I
nternet for '%s'"
,
uri
)
logger
.
info
(
"Looking up
i
nternet for '%s'"
,
uri
)
# drop scheme from uri
uri
=
':'
.
join
(
uri
.
split
(
':'
)[
1
:])
...
...
@@ -189,24 +188,34 @@ class YouTubeLibraryProvider(backend.LibraryProvider):
if
'v'
in
req
:
return
self
.
_get_tracks
([
req
.
get
(
'v'
)[
0
]])
elif
'http'
not
in
uri
:
logger
.
info
(
"Detected You
t
ube-ID"
)
logger
.
info
(
"Detected You
T
ube-ID"
)
return
self
.
_get_tracks
([
uri
])
elif
uri
.
startswith
(
ytdl_id
):
logger
.
info
(
"Detected YTDL-ID, using cache"
)
y_id
,
uri
=
uri
.
split
(
' '
)
return
self
.
_get_ytdl_tracks
(
uri
,
y_id
=
y_id
)
else
:
logger
.
info
(
"Invoke youtube-dl"
)
return
self
.
_get_ytdl_tracks
(
uri
)
def
search
(
self
,
query
=
None
,
uris
=
None
,
exact
=
False
):
"""Search
for query in
youtube and return tracks"""
"""Search
in YouTube or resolve URL with
youtube
-dl
and return tracks"""
# TODO Support exact search
if
not
query
:
logger
.
info
(
"Query could not be handled
.
"
)
logger
.
info
(
"Query could not be handled"
)
return
if
'uri'
in
query
:
search_query
=
''
.
join
(
query
[
'uri'
])
if
'youtube.com'
in
search_query
:
logger
.
info
(
"Searching URL in YouTube '%s'"
,
search_query
)
return
SearchResult
(
uri
=
search_uri
,
tracks
=
lookup
(
search_query
)
)
logger
.
info
(
"Searching with youtube-dl for URL '%s'"
,
search_query
)
return
SearchResult
(
uri
=
search_uri
,
tracks
=
self
.
_get_ytdl_tracks
(
search_query
)
)
if
'any'
in
query
:
search_query
=
' '
.
join
(
query
.
values
()[
0
])
logger
.
info
(
"Searching YouTube for query '%s'"
,
search_query
)
...
...
@@ -215,23 +224,22 @@ class YouTubeLibraryProvider(backend.LibraryProvider):
uri
=
search_uri
,
tracks
=
self
.
_get_search
(
search_query
)
)
return
None
class
YouTubePlaybackProvider
(
backend
.
PlaybackProvider
):
def
translate_uri
(
self
,
uri
):
"""Translate
y
ou
t
ube
video url or id
into ressource
url
if necessary.
"""Translate
Y
ou
T
ube
-ID
into ressource
URL
if necessary.
If already translated do nothing.
"""
logger
.
info
(
"Playing
YouTube id
: %s"
,
uri
)
logger
.
info
(
"Playing: %s"
,
uri
)
# drop scheme from uri
uri
=
':'
.
join
(
uri
.
split
(
':'
)[
1
:])
if
'http'
not
in
uri
:
uri
=
self
.
_resolve_url
(
uri
)
if
' '
in
uri
:
uri
=
' '
.
join
(
uri
.
split
(
' '
)[
1
:])
return
uri
def
_resolve_url
(
self
,
url
):
...
...
@@ -239,7 +247,7 @@ class YouTubePlaybackProvider(backend.PlaybackProvider):
yt_uri
=
call_ytdl
(
url
)
except
:
return
None
if
'entries'
in
yt_uri
:
# if playlist
if
'entries'
in
yt_uri
:
# if playlist
, play first track
trackList
=
yt_uri
[
'entries'
]
else
:
trackList
=
[
yt_uri
]
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment