From 99174266fd308f84f7705d3072363d2adf20506a Mon Sep 17 00:00:00 2001 From: RocksGarnett <74124595+RocksGarnett@users.noreply.github.com> Date: Fri, 27 Nov 2020 10:06:51 -0600 Subject: [PATCH] Adds visual search (#91) * added visual search * Update README.md Co-authored-by: spookslayer <74124595+spookslayer@users.noreply.github.com> --- README.md | 5 +++++ py3pin/Pinterest.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/README.md b/README.md index 47c3cc3..720a31c 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,12 @@ If username is not provided current user will be used Current pinterest scopes are: pins, buyable_pins, my_pins, videos, boards +### Visual Search +``` + pin_data = pinterest.load_pin(pin_id='pin_id') + search_batch = pinterest.visual_search(pin_data, x=10, y=50, w=100, h=100) +``` ## User interactions ### Invite to board diff --git a/py3pin/Pinterest.py b/py3pin/Pinterest.py index d28f402..a0d8ac9 100644 --- a/py3pin/Pinterest.py +++ b/py3pin/Pinterest.py @@ -37,6 +37,7 @@ PIN_COMMENT_RESOURCE = 'https://www.pinterest.com/resource/PinCommentResource/create/' BOARD_INVITE_RESOURCE = 'https://www.pinterest.com/_ngjs/resource/BoardInviteResource/create/' BOARD_DELETE_INVITE_RESOURCE = 'https://www.pinterest.com/_ngjs/resource/BoardCollaboratorResource/delete/' +VISUAL_LIVE_SEARCH_RESOURCE = 'https://www.pinterest.com/resource/VisualLiveSearchResource/get' SEARCH_RESOURCE = 'https://www.pinterest.com/resource/SearchResource/get' BOARD_RECOMMEND_RESOURCE = 'https://www.pinterest.com/_ngjs/resource/BoardContentRecommendationResource/get' PINNABLE_IMAGES_RESOURCE = 'https://www.pinterest.com/_ngjs/resource/FindPinImagesResource/get' @@ -625,6 +626,59 @@ def delete_invite(self, board_id, invited_user_id, also_block=False): data = self.req_builder.buildPost(options=options) return self.post(url=BOARD_DELETE_INVITE_RESOURCE, data=data) + def visual_search(self, pin_data, x = None, y = None, w = None, h = None, padding=10): + """ + Gives access to pinterest search api + This method is batched, meaning is needs to be called until empty list is returned. + :param pin_data: pin data + :param x: x position of the cropped part of the image used for searching + :param y: y position of the cropped part of the image used for searching + :param w: width of the cropped part of the image used for searching + :param h: height of the cropped part of the image used for searching + :param padding: Default padding for for cropped image. + + :return: python dict describing the pinterest response + """ + + orig = pin_data['images']['orig'] + width = orig['width'] + height = orig['height'] + image_signature = pin_data['image_signature'] + pin_id = pin_data['id'] + + x = padding if x is None else x + y = padding if y is None else y + w = width - padding * 2 if w is None else w + h = height - padding * 2 if h is None else h + + source_url = '/pin/{}/visual-search/?x={}&y={}&w={}&h={}'.format(pin_id, x, y, w, h) + + next_bookmark = self.bookmark_manager.get_bookmark(primary='visual_search', secondary=source_url) + if next_bookmark == '-end-': + return [] + + options = { + "isPrefetch": False, + "pin_id":pin_id, + "image_signature":image_signature, + "crop":{ + "x": x / width, + "y": y / height, + "w": w / width, + "h": h / height + }, + "bookmarks": [next_bookmark], + "no_fetch_context_on_resource": False + } + url = self.req_builder.buildGet(url=VISUAL_LIVE_SEARCH_RESOURCE, options=options, source_url=source_url) + resp = self.get(url=url).json() + + bookmark = resp['resource']['options']['bookmarks'][0] + + self.bookmark_manager.add_bookmark(primary='visual_search', secondary=source_url, bookmark=bookmark) + + return resp['resource_response']['data']['results'] + def search(self, scope, query, page_size=250): """ Gives access to pinterest search api