1from __future__ import unicode_literals
2
3import json
4import os
5import shutil
6import time
7from random import randint
8
9from requests_toolbelt import MultipartEncoder
10
11from . import config
12from .api_photo import get_image_size, stories_shaper
13
14
15def download_story(self, filename, story_url, username):
16    path = "stories/{}".format(username)
17    if not os.path.exists(path):
18        os.makedirs(path)
19    fname = os.path.join(path, filename)
20    if os.path.exists(fname):  # already exists
21        self.logger.info("Stories already downloaded...")
22        return os.path.abspath(fname)
23    response = self.session.get(story_url, stream=True)
24    if response.status_code == 200:
25        with open(fname, "wb") as f:
26            response.raw.decode_content = True
27            shutil.copyfileobj(response.raw, f)
28        return os.path.abspath(fname)
29
30
31def upload_story_photo(self, photo, upload_id=None):
32    if upload_id is None:
33        upload_id = str(int(time.time() * 1000))
34    photo = stories_shaper(photo)
35    if not photo:
36        return False
37
38    with open(photo, "rb") as f:
39        photo_bytes = f.read()
40
41    data = {
42        "upload_id": upload_id,
43        "_uuid": self.uuid,
44        "_csrftoken": self.token,
45        "image_compression": '{"lib_name":"jt","lib_version":"1.3.0",'
46        + 'quality":"87"}',
47        "photo": (
48            "pending_media_%s.jpg" % upload_id,
49            photo_bytes,
50            "application/octet-stream",
51            {"Content-Transfer-Encoding": "binary"},
52        ),
53    }
54    m = MultipartEncoder(data, boundary=self.uuid)
55    self.session.headers.update(
56        {
57            "Accept-Encoding": "gzip, deflate",
58            "Content-type": m.content_type,
59            "Connection": "close",
60            "User-Agent": self.user_agent,
61        }
62    )
63    response = self.session.post(config.API_URL + "upload/photo/", data=m.to_string())
64
65    if response.status_code == 200:
66        upload_id = json.loads(response.text).get("upload_id")
67        if self.configure_story(upload_id, photo):
68            # self.expose()
69            return True
70    return False
71
72
73def configure_story(self, upload_id, photo):
74    (w, h) = get_image_size(photo)
75    data = self.json_data(
76        {
77            "source_type": 4,
78            "upload_id": upload_id,
79            "story_media_creation_date": str(int(time.time()) - randint(11, 20)),
80            "client_shared_at": str(int(time.time()) - randint(3, 10)),
81            "client_timestamp": str(int(time.time())),
82            "configure_mode": 1,  # 1 - REEL_SHARE, 2 - DIRECT_STORY_SHARE
83            "device": self.device_settings,
84            "edits": {
85                "crop_original_size": [w * 1.0, h * 1.0],
86                "crop_center": [0.0, 0.0],
87                "crop_zoom": 1.3333334,
88            },
89            "extra": {"source_width": w, "source_height": h},
90        }
91    )
92    return self.send_request("media/configure_to_story/?", data)
93