Skip to content

Commit

Permalink
Fix uploading, and move it to Client.upload (making it public again)
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Mar 11, 2020
1 parent e6ec5c5 commit 6660fd0
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 42 deletions.
4 changes: 2 additions & 2 deletions examples/interract.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@

# Will send the image located at `<image path>`
with open("<image path>", "rb") as f:
files = session._upload([("image_name.png", f, "image/png")])
files = client.upload([("image_name.png", f, "image/png")])
thread.send_text(text="This is a local image", files=files)

# Will download the image at the URL `<image url>`, and then send it
r = requests.get("<image url>")
files = session._upload([("image_name.png", r.content, "image/png")])
files = client.upload([("image_name.png", r.content, "image/png")])
thread.send_files(files) # Alternative to .send_text


Expand Down
37 changes: 36 additions & 1 deletion fbchat/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from ._common import log, attrs_default
from . import _exception, _util, _graphql, _session, _threads, _models

from typing import Sequence, Iterable, Tuple, Optional, Set
from typing import Sequence, Iterable, Tuple, Optional, Set, BinaryIO


@attrs_default
Expand Down Expand Up @@ -500,6 +500,41 @@ def get_emails(self) -> Sequence[str]:
data = self._get_private_data()
return [j["display_email"] for j in data["all_emails"]]

def upload(
self, files: Iterable[Tuple[str, BinaryIO, str]], voice_clip: bool = False
) -> Sequence[Tuple[str, str]]:
"""Upload files to Facebook.
`files` should be a list of files that requests can upload, see
`requests.request <https://docs.python-requests.org/en/master/api/#requests.request>`_.
Example:
>>> with open("file.txt", "rb") as f:
... (file,) = client.upload([("file.txt", f, "text/plain")])
...
>>> file
("1234", "text/plain")
Return:
Tuples with a file's ID and mimetype.
This result can be passed straight on to `ThreadABC.send_files`, or used in
`Group.set_image`.
"""
file_dict = {"upload_{}".format(i): f for i, f in enumerate(files)}

data = {"voice_clip": voice_clip}

j = self.session._payload_post(
"https://upload.facebook.com/ajax/mercury/upload.php", data, files=file_dict
)

if len(j["metadata"]) != len(file_dict):
raise _exception.ParseError("Some files could not be uploaded", data=j)

return [
(str(item[_util.mimetype_to_key(item["filetype"])]), item["filetype"])
for item in j["metadata"]
]

def mark_as_delivered(self, message: _models.Message):
"""Mark a message as delivered.
Expand Down
39 changes: 4 additions & 35 deletions fbchat/_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from ._common import log, kw_only
from . import _graphql, _util, _exception

from typing import Optional, Tuple, Mapping, BinaryIO, Sequence, Iterable, Callable
from typing import Optional, Tuple, Mapping, Callable

FB_DTSG_REGEX = re.compile(r'name="fb_dtsg" value="(.*?)"')

Expand All @@ -31,7 +31,9 @@ def base36encode(number: int) -> str:


def prefix_url(url: str) -> str:
return "https://www.facebook.com" + url
if url.startswith("/"):
return "https://www.facebook.com" + url
return url


def generate_message_id(now: datetime.datetime, client_id: str) -> str:
Expand Down Expand Up @@ -397,39 +399,6 @@ def _graphql_requests(self, *queries):
}
return self._post("/api/graphqlbatch/", data, as_graphql=True)

def _upload(
self, files: Iterable[Tuple[str, BinaryIO, str]], voice_clip: bool = False
) -> Sequence[Tuple[str, str]]:
"""Upload files to Facebook.
`files` should be a list of files that requests can upload, see
`requests.request <https://docs.python-requests.org/en/master/api/#requests.request>`_.
Example:
>>> with open("file.txt", "rb") as f:
... (file,) = session._upload([("file.txt", f, "text/plain")])
...
>>> file
("1234", "text/plain")
Return:
Tuples with a file's ID and mimetype.
"""
file_dict = {"upload_{}".format(i): f for i, f in enumerate(files)}

data = {"voice_clip": voice_clip}

j = self._payload_post(
"https://upload.facebook.com/ajax/mercury/upload.php", data, files=file_dict
)

if len(j["metadata"]) != len(file_dict):
raise _exception.ParseError("Some files could not be uploaded", data=j)

return [
(data[_util.mimetype_to_key(data["filetype"])], data["filetype"])
for data in j["metadata"]
]

def _do_send_request(self, data):
now = datetime.datetime.utcnow()
offline_threading_id = _util.generate_offline_threading_id()
Expand Down
7 changes: 4 additions & 3 deletions fbchat/_threads/_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ def send_text(
Args:
text: Text to send
mentions: Optional mentions
files: Optional tuples, each containing an uploaded file's ID and mimetype
files: Optional tuples, each containing an uploaded file's ID and mimetype.
See `ThreadABC.send_files` for an example.
reply_to_id: Optional message to reply to
Example:
Expand Down Expand Up @@ -223,9 +224,9 @@ def send_files(self, files: Iterable[Tuple[str, str]]):
Upload and send a video to a thread.
>>> with open("video.mp4", "rb") as f:
... files = session._upload([("video.mp4", f, "video/mp4")])
... files = client.upload([("video.mp4", f, "video/mp4")])
>>>
>>> thread.send_files(files=files)
>>> thread.send_files(files)
"""
return self.send_text(text=None, files=files)

Expand Down
2 changes: 1 addition & 1 deletion fbchat/_threads/_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def set_image(self, image_id: str):
Upload an image, and use it as the group image.
>>> with open("image.png", "rb") as f:
... (file,) = session._upload([("image.png", f, "image/png")])
... (file,) = client.upload([("image.png", f, "image/png")])
...
>>> group.set_image(file[0])
"""
Expand Down

0 comments on commit 6660fd0

Please sign in to comment.