small cleanups
Browse files- pytube/__main__.py +1 -1
- pytube/captions.py +1 -1
- pytube/contrib/playlist.py +11 -11
- pytube/helpers.py +10 -1
- pytube/streams.py +2 -6
pytube/__main__.py
CHANGED
@@ -61,7 +61,7 @@ class YouTube:
|
|
61 |
|
62 |
# the url to vid info, parsed from watch html
|
63 |
self.vid_info_url: Optional[str] = None
|
64 |
-
self.vid_info_raw = None # content fetched by vid_info_url
|
65 |
self.vid_info: Optional[Dict] = None # parsed content of vid_info_raw
|
66 |
|
67 |
self.watch_html: Optional[str] = None # the html of /watch?v=<video_id>
|
|
|
61 |
|
62 |
# the url to vid info, parsed from watch html
|
63 |
self.vid_info_url: Optional[str] = None
|
64 |
+
self.vid_info_raw: Optional[str] = None # content fetched by vid_info_url
|
65 |
self.vid_info: Optional[Dict] = None # parsed content of vid_info_raw
|
66 |
|
67 |
self.watch_html: Optional[str] = None # the html of /watch?v=<video_id>
|
pytube/captions.py
CHANGED
@@ -25,7 +25,7 @@ class Caption:
|
|
25 |
self.code = caption_track["languageCode"]
|
26 |
|
27 |
@property
|
28 |
-
def xml_captions(self):
|
29 |
"""Download the xml caption tracks."""
|
30 |
return request.get(self.url)
|
31 |
|
|
|
25 |
self.code = caption_track["languageCode"]
|
26 |
|
27 |
@property
|
28 |
+
def xml_captions(self) -> str:
|
29 |
"""Download the xml caption tracks."""
|
30 |
return request.get(self.url)
|
31 |
|
pytube/contrib/playlist.py
CHANGED
@@ -40,19 +40,19 @@ class Playlist:
|
|
40 |
return self.playlist_url
|
41 |
|
42 |
@staticmethod
|
43 |
-
def
|
44 |
"""Given an html page or a fragment thereof, looks for
|
45 |
and returns the "load more" url if found.
|
46 |
"""
|
47 |
-
|
48 |
-
load_more_url = "https://www.youtube.com" + re.search(
|
49 |
r"data-uix-load-more-href=\"(/browse_ajax\?"
|
50 |
'action_continuation=.*?)"',
|
51 |
req,
|
52 |
-
)
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
56 |
|
57 |
def parse_links(self) -> List[str]:
|
58 |
"""Parse the video links from the page source, extracts and
|
@@ -69,8 +69,8 @@ class Playlist:
|
|
69 |
|
70 |
# The above only returns 100 or fewer links
|
71 |
# Simulating a browser request for the load more link
|
72 |
-
load_more_url = self.
|
73 |
-
while
|
74 |
logger.debug("load more url: %s", load_more_url)
|
75 |
req = request.get(load_more_url)
|
76 |
load_more = json.loads(req)
|
@@ -79,11 +79,11 @@ class Playlist:
|
|
79 |
)
|
80 |
# remove duplicates
|
81 |
link_list.extend(list(OrderedDict.fromkeys(videos)))
|
82 |
-
load_more_url = self.
|
83 |
|
84 |
return link_list
|
85 |
|
86 |
-
def populate_video_urls(self):
|
87 |
"""Construct complete links of all the videos in playlist and
|
88 |
populate video_urls list
|
89 |
|
|
|
40 |
return self.playlist_url
|
41 |
|
42 |
@staticmethod
|
43 |
+
def _find_load_more_url(req: str) -> Optional[str]:
|
44 |
"""Given an html page or a fragment thereof, looks for
|
45 |
and returns the "load more" url if found.
|
46 |
"""
|
47 |
+
match = re.search(
|
|
|
48 |
r"data-uix-load-more-href=\"(/browse_ajax\?"
|
49 |
'action_continuation=.*?)"',
|
50 |
req,
|
51 |
+
)
|
52 |
+
if match:
|
53 |
+
return "https://www.youtube.com" + match.group(1)
|
54 |
+
|
55 |
+
return None
|
56 |
|
57 |
def parse_links(self) -> List[str]:
|
58 |
"""Parse the video links from the page source, extracts and
|
|
|
69 |
|
70 |
# The above only returns 100 or fewer links
|
71 |
# Simulating a browser request for the load more link
|
72 |
+
load_more_url = self._find_load_more_url(req)
|
73 |
+
while load_more_url: # there is an url found
|
74 |
logger.debug("load more url: %s", load_more_url)
|
75 |
req = request.get(load_more_url)
|
76 |
load_more = json.loads(req)
|
|
|
79 |
)
|
80 |
# remove duplicates
|
81 |
link_list.extend(list(OrderedDict.fromkeys(videos)))
|
82 |
+
load_more_url = self._find_load_more_url(load_more["load_more_widget_html"], )
|
83 |
|
84 |
return link_list
|
85 |
|
86 |
+
def populate_video_urls(self) -> None:
|
87 |
"""Construct complete links of all the videos in playlist and
|
88 |
populate video_urls list
|
89 |
|
pytube/helpers.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""Various helper functions implemented by pytube."""
|
3 |
-
|
4 |
import logging
|
5 |
import pprint
|
6 |
import re
|
|
|
7 |
|
8 |
from pytube.exceptions import RegexMatchError
|
9 |
|
@@ -99,3 +100,11 @@ def create_logger(level: int = logging.ERROR) -> logging.Logger:
|
|
99 |
logger.addHandler(handler)
|
100 |
logger.setLevel(level)
|
101 |
return logger
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""Various helper functions implemented by pytube."""
|
3 |
+
import functools
|
4 |
import logging
|
5 |
import pprint
|
6 |
import re
|
7 |
+
from typing import TypeVar, Callable
|
8 |
|
9 |
from pytube.exceptions import RegexMatchError
|
10 |
|
|
|
100 |
logger.addHandler(handler)
|
101 |
logger.setLevel(level)
|
102 |
return logger
|
103 |
+
|
104 |
+
|
105 |
+
T = TypeVar('T')
|
106 |
+
|
107 |
+
|
108 |
+
def cache(func: Callable[..., T]) -> T:
|
109 |
+
return functools.lru_cache()(func) # type: ignore
|
110 |
+
|
pytube/streams.py
CHANGED
@@ -118,9 +118,7 @@ class Stream:
|
|
118 |
|
119 |
:rtype: bool
|
120 |
"""
|
121 |
-
|
122 |
-
return True
|
123 |
-
return self.type == "audio"
|
124 |
|
125 |
@property
|
126 |
def includes_video_track(self) -> bool:
|
@@ -128,9 +126,7 @@ class Stream:
|
|
128 |
|
129 |
:rtype: bool
|
130 |
"""
|
131 |
-
|
132 |
-
return True
|
133 |
-
return self.type == "video"
|
134 |
|
135 |
def parse_codecs(self) -> Tuple:
|
136 |
"""Get the video/audio codecs from list of codecs.
|
|
|
118 |
|
119 |
:rtype: bool
|
120 |
"""
|
121 |
+
return self.is_progressive or self.type == "audio"
|
|
|
|
|
122 |
|
123 |
@property
|
124 |
def includes_video_track(self) -> bool:
|
|
|
126 |
|
127 |
:rtype: bool
|
128 |
"""
|
129 |
+
return self.is_progressive or self.type == "video"
|
|
|
|
|
130 |
|
131 |
def parse_codecs(self) -> Tuple:
|
132 |
"""Get the video/audio codecs from list of codecs.
|