updated README, added test_deprecated
Browse files- README.md +6 -6
- pytube/helpers.py +3 -7
- pytube/query.py +16 -0
README.md
CHANGED
@@ -138,17 +138,17 @@ Conversely, if you only want to see the DASH streams (also referred to as "adapt
|
|
138 |
<Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus">]
|
139 |
```
|
140 |
|
|
|
|
|
141 |
You can also download a complete Youtube playlist:
|
142 |
|
143 |
```python
|
144 |
>>> from pytube import Playlist
|
145 |
-
>>>
|
146 |
-
>>>
|
147 |
-
>>>
|
148 |
-
>>> pl.download_all('/path/to/directory/')
|
149 |
```
|
150 |
-
This will download the highest progressive stream available (generally 720p) from the given playlist.
|
151 |
-
to choose video resolution.
|
152 |
|
153 |
### Filtering
|
154 |
|
|
|
138 |
<Stream: itag="251" mime_type="audio/webm" abr="160kbps" acodec="opus">]
|
139 |
```
|
140 |
|
141 |
+
### Playlists
|
142 |
+
|
143 |
You can also download a complete Youtube playlist:
|
144 |
|
145 |
```python
|
146 |
>>> from pytube import Playlist
|
147 |
+
>>> playlist = Playlist("https://www.youtube.com/playlist?list=PLynhp4cZEpTbRs_PYISQ8v_uwO0_mDg_X")
|
148 |
+
>>> for video in playlist.videos:
|
149 |
+
>>> video.streams.get_highest_resolution().download()
|
|
|
150 |
```
|
151 |
+
This will download the highest progressive stream available (generally 720p) from the given playlist.
|
|
|
152 |
|
153 |
### Filtering
|
154 |
|
pytube/helpers.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""Various helper functions implemented by pytube."""
|
3 |
import functools
|
4 |
-
import inspect
|
5 |
import logging
|
6 |
import pprint
|
7 |
import re
|
@@ -112,7 +111,7 @@ def cache(func: Callable[..., GenericType]) -> GenericType:
|
|
112 |
return functools.lru_cache()(func) # type: ignore
|
113 |
|
114 |
|
115 |
-
def deprecated(reason):
|
116 |
"""
|
117 |
This is a decorator which can be used to mark functions
|
118 |
as deprecated. It will result in a warning being emitted
|
@@ -120,16 +119,13 @@ def deprecated(reason):
|
|
120 |
"""
|
121 |
|
122 |
def decorator(func1):
|
123 |
-
|
124 |
-
fmt1 = "Call to deprecated class {name} ({reason})."
|
125 |
-
else:
|
126 |
-
fmt1 = "Call to deprecated function {name} ({reason})."
|
127 |
|
128 |
@functools.wraps(func1)
|
129 |
def new_func1(*args, **kwargs):
|
130 |
warnings.simplefilter("always", DeprecationWarning)
|
131 |
warnings.warn(
|
132 |
-
|
133 |
category=DeprecationWarning,
|
134 |
stacklevel=2,
|
135 |
)
|
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""Various helper functions implemented by pytube."""
|
3 |
import functools
|
|
|
4 |
import logging
|
5 |
import pprint
|
6 |
import re
|
|
|
111 |
return functools.lru_cache()(func) # type: ignore
|
112 |
|
113 |
|
114 |
+
def deprecated(reason: str) -> Callable:
|
115 |
"""
|
116 |
This is a decorator which can be used to mark functions
|
117 |
as deprecated. It will result in a warning being emitted
|
|
|
119 |
"""
|
120 |
|
121 |
def decorator(func1):
|
122 |
+
message = "Call to deprecated function {name} ({reason})."
|
|
|
|
|
|
|
123 |
|
124 |
@functools.wraps(func1)
|
125 |
def new_func1(*args, **kwargs):
|
126 |
warnings.simplefilter("always", DeprecationWarning)
|
127 |
warnings.warn(
|
128 |
+
message.format(name=func1.__name__, reason=reason),
|
129 |
category=DeprecationWarning,
|
130 |
stacklevel=2,
|
131 |
)
|
pytube/query.py
CHANGED
@@ -273,6 +273,22 @@ class StreamQuery:
|
|
273 |
.last()
|
274 |
)
|
275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
def first(self) -> Optional[Stream]:
|
277 |
"""Get the first :class:`Stream <Stream>` in the results.
|
278 |
|
|
|
273 |
.last()
|
274 |
)
|
275 |
|
276 |
+
def get_highest_resolution(self) -> Optional[Stream]:
|
277 |
+
"""Get highest resolution stream that is a progressive video.
|
278 |
+
|
279 |
+
:rtype: :class:`Stream <Stream>` or None
|
280 |
+
:returns:
|
281 |
+
The :class:`Stream <Stream>` matching the given itag or None if
|
282 |
+
not found.
|
283 |
+
|
284 |
+
"""
|
285 |
+
return (
|
286 |
+
self.filter(progressive=True)
|
287 |
+
.order_by("resolution")
|
288 |
+
.asc()
|
289 |
+
.last()
|
290 |
+
)
|
291 |
+
|
292 |
def first(self) -> Optional[Stream]:
|
293 |
"""Get the first :class:`Stream <Stream>` in the results.
|
294 |
|