Skip to content

Commit

Permalink
Fix media uploads
Browse files Browse the repository at this point in the history
  • Loading branch information
LilSpazJoekp committed Oct 1, 2023
1 parent d16f73f commit f7e2f3e
Show file tree
Hide file tree
Showing 17 changed files with 1,555 additions and 4,805 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Expand Up @@ -6,6 +6,10 @@ PRAW follows `semantic versioning <http://semver.org/>`_.
Unreleased
----------

**Fixed**

- An issue where submitting a post with media would fail due to an API change.

**Added**

- :meth:`~.SubredditLinkFlairTemplates.reorder` to reorder a subreddit's link flair
Expand Down
32 changes: 14 additions & 18 deletions praw/models/reddit/subreddit.py
Expand Up @@ -862,16 +862,18 @@ def _read_and_post_media(self, media_path, upload_url, upload_data): # noqa: AN
)

def _submit_media(
self, *, data: dict[Any, Any], timeout: int, websocket_url: str | None = None
self, *, data: dict[Any, Any], timeout: int, without_websockets: bool
):
"""Submit and return an ``image``, ``video``, or ``videogif``.
This is a helper method for submitting posts that are not link posts or self
posts.
"""
response = self._reddit.post(API_PATH["submit"], data=data)
websocket_url = response["json"]["data"]["websocket_url"]
connection = None
if websocket_url is not None:
if websocket_url is not None and not without_websockets:
try:
connection = websocket.create_connection(websocket_url, timeout=timeout)
except (
Expand All @@ -882,8 +884,6 @@ def _submit_media(
msg = "Error establishing websocket connection."
raise WebSocketException(msg, ws_exception) from None

self._reddit.post(API_PATH["submit"], data=data)

if connection is None:
return None

Expand Down Expand Up @@ -912,7 +912,7 @@ def _upload_inline_media(
self._validate_inline_media(inline_media)
inline_media.media_id = self._upload_media(
media_path=inline_media.path, upload_type="selfpost"
)[0]
)
return inline_media

def _upload_media(
Expand Down Expand Up @@ -975,11 +975,11 @@ def _upload_media(
except HTTPError as err:
raise ServerError(response=err.response) from None

websocket_url = upload_response["asset"]["websocket_url"]
upload_response["asset"]["websocket_url"]

if upload_type == "link":
return f"{upload_url}/{upload_data['key']}", websocket_url
return upload_response["asset"]["asset_id"], websocket_url
return f"{upload_url}/{upload_data['key']}"
return upload_response["asset"]["asset_id"]

def post_requirements(self) -> dict[str, str | int | bool]:
"""Get the post requirements for a subreddit.
Expand Down Expand Up @@ -1386,7 +1386,7 @@ def submit_gallery(
expected_mime_prefix="image",
media_path=image["image_path"],
upload_type="gallery",
)[0],
),
}
)
response = self._reddit.request(
Expand Down Expand Up @@ -1505,14 +1505,12 @@ def submit_image(
if value is not None:
data[key] = value

image_url, websocket_url = self._upload_media(
image_url = self._upload_media(
expected_mime_prefix="image", media_path=image_path
)
data.update(kind="image", url=image_url)
if without_websockets:
websocket_url = None
return self._submit_media(
data=data, timeout=timeout, websocket_url=websocket_url
data=data, timeout=timeout, without_websockets=without_websockets
)

@_deprecate_args(
Expand Down Expand Up @@ -1730,19 +1728,17 @@ def submit_video(
if value is not None:
data[key] = value

video_url, websocket_url = self._upload_media(
video_url = self._upload_media(
expected_mime_prefix="video", media_path=video_path
)
data.update(
kind="videogif" if videogif else "video",
url=video_url,
# if thumbnail_path is None, it uploads the PRAW logo
video_poster_url=self._upload_media(media_path=thumbnail_path)[0],
video_poster_url=self._upload_media(media_path=thumbnail_path),
)
if without_websockets:
websocket_url = None
return self._submit_media(
data=data, timeout=timeout, websocket_url=websocket_url
data=data, timeout=timeout, without_websockets=without_websockets
)

@_deprecate_args("other_subreddits")
Expand Down
787 changes: 485 additions & 302 deletions tests/integration/cassettes/TestSubreddit.test_submit_image.json

Large diffs are not rendered by default.

Large diffs are not rendered by default.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Large diffs are not rendered by default.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

12 changes: 11 additions & 1 deletion tests/integration/models/reddit/test_subreddit.py
Expand Up @@ -1539,7 +1539,7 @@ def test_submit_gallery__flair(self, image_path, reddit):
@mock.patch(
"websocket.create_connection",
new=MagicMock(
return_value=WebsocketMock("k5rhpg", "k5rhsu", "k5rhx3")
return_value=WebsocketMock("16xb01r", "16xb06z", "16xb0aa")
), # update with cassette
)
def test_submit_image(self, image_path, reddit):
Expand Down Expand Up @@ -1619,6 +1619,7 @@ def patch_request(url, *args, **kwargs):
@mock.patch(
"websocket.create_connection", new=MagicMock(side_effect=BlockingIOError)
) # happens with timeout=0
@pytest.mark.cassette_name("TestSubreddit.test_submit_image__timeout")
def test_submit_image__timeout_1(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1633,6 +1634,7 @@ def test_submit_image__timeout_1(self, image_path, reddit):
# happens with timeout=0.00001
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_image__timeout")
def test_submit_image__timeout_2(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1648,6 +1650,7 @@ def test_submit_image__timeout_2(self, image_path, reddit):
), # happens with timeout=0.1
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_image__timeout")
def test_submit_image__timeout_3(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1663,6 +1666,7 @@ def test_submit_image__timeout_3(self, image_path, reddit):
), # could happen, and PRAW should handle it
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_image__timeout")
def test_submit_image__timeout_4(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1678,6 +1682,7 @@ def test_submit_image__timeout_4(self, image_path, reddit):
), # from issue #1124
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_image__timeout")
def test_submit_image__timeout_5(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand Down Expand Up @@ -1838,6 +1843,7 @@ def test_submit_video__thumbnail(self, image_path, reddit):
@mock.patch(
"websocket.create_connection", new=MagicMock(side_effect=BlockingIOError)
) # happens with timeout=0
@pytest.mark.cassette_name("TestSubreddit.test_submit_video__timeout")
def test_submit_video__timeout_1(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1852,6 +1858,7 @@ def test_submit_video__timeout_1(self, image_path, reddit):
# happens with timeout=0.00001
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_video__timeout")
def test_submit_video__timeout_2(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1867,6 +1874,7 @@ def test_submit_video__timeout_2(self, image_path, reddit):
), # happens with timeout=0.1
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_video__timeout")
def test_submit_video__timeout_3(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1882,6 +1890,7 @@ def test_submit_video__timeout_3(self, image_path, reddit):
), # could happen, and PRAW should handle it
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_video__timeout")
def test_submit_video__timeout_4(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand All @@ -1897,6 +1906,7 @@ def test_submit_video__timeout_4(self, image_path, reddit):
), # from issue #1124
),
)
@pytest.mark.cassette_name("TestSubreddit.test_submit_video__timeout")
def test_submit_video__timeout_5(self, image_path, reddit):
reddit.read_only = False
subreddit = reddit.subreddit(pytest.placeholders.test_subreddit)
Expand Down
2 changes: 1 addition & 1 deletion tests/utils.py
Expand Up @@ -31,7 +31,7 @@ def ensure_environment_variables():

def ensure_integration_test(cassette):
if cassette.is_recording():
is_integration_test = not cassette.is_empty()
is_integration_test = cassette.interactions
action = "record"
else:
is_integration_test = any(
Expand Down

0 comments on commit f7e2f3e

Please sign in to comment.