def pin(self, board_id, image_url, description='', link='', share_facebook=False, share_twitter=False): self.login_required() url = self.home_page + 'resource/PinResource/create/' data = url_encode({ 'source_url': '/pin/find/?url=%s' % url_encode(image_url), 'data': json.dumps({ 'options': { "board_id": board_id, "image_url": image_url, "description": description, "link": link if link else image_url, "scrape_metric": { "source": "www_url_scrape" }, "method": "scraped", "share_facebook": share_facebook, "share_twitter": share_twitter }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: pin = {'id': result['resource_response']['data']['id']} return pin return None
def __upload_image(self, image_file): self.login_required() file_name = os.path.basename(image_file) mime_type = mimetypes.guess_type(image_file)[0] if mime_type is None: extension = os.path.splitext(image_file)[1][1:] if extension == 'jpg': mime_type = 'image/jpeg' else: mime_type = 'image/%s' % extension m = MultipartEncoder( fields={ 'qquuid': '%s' % uuid.uuid4(), 'qqfilename': file_name, 'img': ('%s' % file_name, open(image_file, 'rb'), mime_type) }) headers = { 'Content-Length': '%s' % m.len, 'Content-Type': m.content_type, 'X-UPLOAD-SOURCE': 'pinner_uploader' } url = 'https://www.pinterest.com/upload-image/?img=%s' % url_encode( file_name) result = self.post(url=url, data=m, headers=headers, ajax=True).json() return result
def __search_next_page(self, scope, query): q = url_encode({ 'source_url': '/search/%s/?q=%s' % (scope, query), 'data': json.dumps({ 'options': { 'bookmarks': [self.next_book_marks[scope][query]], 'query': query, 'scope': scope }, "context": {} }).replace(' ', ''), '_': '%s' % int(time.time() * 1000) }) url = 'https://www.pinterest.com/resource/SearchResource/get/?%s' % q r = self.get(url=url, ajax=True).json() results = [] try: if r['resource_response']['error'] is not None: error = r['resource_response']['error'] raise PinterestException('[%s] %s' % (error['http_status'], error['message'])) results = r['resource_response']['data'] bookmarks = r['resource']['options']['bookmarks'] if isinstance(bookmarks, basestring): self.next_book_marks[scope][query] = bookmarks else: self.next_book_marks[scope][query] = bookmarks[0] except KeyError: pass return results
def upload_pin(self, board_id, image_file, description='', share_facebook=False, share_twitter=False): self.login_required() url = 'https://www.pinterest.com/resource/PinResource/create/' uploaded_image = self.__upload_image(image_file) if uploaded_image['success'] is True: image_url = uploaded_image['image_url'] data = url_encode({ 'source_url': '/%s/' % self.user['username'], 'data': json.dumps({ 'options': { "board_id": board_id, "image_url": image_url, "description": description, "upload_metric": {"source": "pinner_upload_standalone"}, "method": "uploaded", "share_facebook": share_facebook, "share_twitter": share_twitter}, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: pin = {'id': result['resource_response']['data']['id']} return pin return None
def boards(self): """ Return all boards of logged in user :rtype: list """ self.login_required() data = url_encode({ 'source_url': '/%s/pins/' % self.user['username'], 'data': json.dumps({ 'options': {"filter": "all", "field_set_key": "board_picker", "allow_stale": "true", "from": "app"}, "context": {} }).replace(' ', ''), '_': '%s' % int(time.time() * 1000) }) url = 'https://www.pinterest.com/resource/BoardPickerBoardsResource/get/?%s' % data r = self.get(url=url, ajax=True) result = r.json() boards = [] try: if result['resource_response']['data']['all_boards']: all_boards = result['resource_response']['data']['all_boards'] for board in all_boards: boards.append({ 'id': board.get('id'), 'name': board.get('name'), 'privacy': board.get('privacy') }) except KeyError: pass return boards
def delete_invite(self, board_id, board_url, invited_user_id, also_block=False): self.login_required() url = 'https://www.pinterest.com/resource/BoardInviteResource/delete/' data = url_encode({ 'source_url': board_url, 'data': json.dumps({ 'options': { "ban": also_block, "board_id": board_id, "field_set_key": "boardEdit", "invited_user_id": invited_user_id }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['status'] == "success": return True return False
def login(self): """ Login to pinterest site. If OK return True :rtype: bool """ r = self.get(self.home_page) self.user = self.extract_user_data(r.content) if self.user: self.is_logged_in = True else: time.sleep(2) login_page = 'https://www.pinterest.com/login/?referrer=home_page' self.get(login_page) time.sleep(3) data = url_encode({ 'source_url': '/login/?referrer=home_page', 'data': json.dumps({ 'options': {'username_or_email': self.username_or_email, 'password': self.password}, "context": {} }).replace(' ', '') }) url = 'https://www.pinterest.com/resource/UserSessionResource/create/' result = self.post(url=url, data=data, ajax=True).json() error = result['resource_response']['error'] if error is None: self.user = self.extract_user_data(self.get(self.home_page).content) self.is_logged_in = True else: raise PinterestLoginFailedException('[%s Login failed] %s' % (error['http_status'], error['message'])) return self.is_logged_in
def delete_invite(self, board_id, board_url, invited_user_id, also_block=False): self.login_required() url = self.home_page + 'resource/BoardInviteResource/delete/' data = url_encode({ 'source_url': board_url, 'data': json.dumps({ 'options': { "ban": also_block, "board_id": board_id, "field_set_key": "boardEdit", "invited_user_id": invited_user_id }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: return True return False
def create_board(self, name, description='', category='other', privacy='public', layout='default'): self.login_required() url = 'https://www.pinterest.com/resource/BoardResource/create/' data = url_encode({ 'source_url': '/%s/boards/' % self.user['username'], 'data': json.dumps({ 'options': { "name": name, "description": description, "category": category, "privacy": privacy, "layout": layout, "collab_board_email": 'true', "collaborator_invites_enabled": 'true' }, "context": {} }).replace(' ', '') }) r = self.post(url=url, data=data, ajax=True) result = r.json() if result['resource_response']['status'] == "success": board = result['resource_response']['data'] return board return None
def repin(self, board_id, pin_id, link='', title='', description='', share_facebook=False, share_twitter=False): """ Save this Pin to a Board. For 'save button' """ self.login_required() url = 'https://www.pinterest.com/resource/RepinResource/create/' data = url_encode({ 'source_url': '/pin/%s/' % pin_id, 'data': json.dumps({ 'options': { "board_id": board_id, "pin_id": pin_id, "link": link, "title": title, "description": description, "is_buyable_pin": False, "share_facebook": share_facebook, "share_twitter": share_twitter }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: pin = {'id': result['resource_response']['data']['id']} return pin return None
def search(self, scope, query, next_page=False): if next_page is True and self.next_book_marks[scope].get(query): return self.__search_next_page(scope, query) q = url_encode({'q': query, '_': '%s' % int(time.time() * 1000)}) url = 'https://www.pinterest.com/search/%s/?%s' % (scope, q) r = self.get(url=url) html = r.content[r.content.find('application/json'.encode('utf-8')):] html = html[html.find('{'.encode('utf-8')):html.find('</script>'. encode('utf-8'))] search_result = json.loads(html) results = [] try: if len(search_result['resources']['data'] ['BaseSearchResource']) > 0: for firstKey in search_result['resources']['data'][ 'BaseSearchResource'].keys(): search_resource = search_result['resources']['data'][ 'BaseSearchResource'][firstKey] results = search_resource['data']['results'] self.next_book_marks[scope][query] = search_resource[ 'nextBookmark'] break except KeyError: pass return results
def pins_board(self, tablero): """ Return all pines from a board (not from the sections) """ self.login_required() bookmarks = [] pins = [] while True: data = url_encode({ 'source_url': '/%s/%s/' % (self.user['username'], tablero['name']), 'data': json.dumps({ 'options': { 'bookmarks': bookmarks, 'isPrefetch': 'False', 'board_id': tablero['id'], 'board_url': '/%s/%s/' % (self.user['username'], tablero['name']), 'filter_section_pins': 'true', 'redux_normalize_feed': 'true' }, "context": {} }).replace(' ', ''), '_': '%s' % int(time.time() * 1000) }) url = self.home_page + 'resource/BoardFeedResource/get/?%s' % data r = self.get(url=url, ajax=True) result = r.json() try: if result['resource_response']['data']: for pin in result['resource_response']['data']: pins.append({ 'id': pin['id'], 'description': pin['description'], 'image': pin['images']['orig']['url'], 'link': pin['link'], 'title': pin['title'] }) except KeyError: pass bookmarks = result['resource']['options']['bookmarks'] if bookmarks[0] == '-end-': break return pins
def unfollow_user(self, user_id, username): self.login_required() url = 'https://www.pinterest.com/resource/UserFollowResource/delete/' data = url_encode({ 'source_url': '/%s/' % username, 'data': json.dumps({ 'options': {"user_id": user_id}, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: return True return False
def delete_comment(self, pin_id, comment_id): self.login_required() url = 'https://www.pinterest.com/resource/PinCommentResource/delete/' data = url_encode({ 'source_url': '/pin/%s/' % pin_id, 'data': json.dumps({ 'options': {"pin_id": pin_id, "comment_id": comment_id}, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: return True return False
def invite(self, board_id, board_url, user_id): self.login_required() url = 'https://www.pinterest.com/resource/BoardInviteResource/create/' data = url_encode({ 'source_url': board_url, 'data': json.dumps({ 'options': {"board_id": board_id, "invited_user_ids": [user_id]}, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: return True return False
def pin(self, board_id, image_url, title='', description='', link='', share_facebook=False, share_twitter=False): self.login_required() url = 'https://www.pinterest.com/resource/PinResource/create/' data = url_encode({ 'source_url': '/pin/find/?url=%s' % url_encode(image_url), 'data': json.dumps({ 'options': { "board_id": board_id, "image_url": image_url, "title": title, "description": description, "link": link if link else image_url, "scrape_metric": { "source": "www_url_scrape" }, "method": "scraped", "share_facebook": share_facebook, "share_twitter": share_twitter }, "context": {} }) }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['status'] == "success": pin = {'id': result['resource_response']['data']['id']} return pin return None
def sections(self, tablero): """ Return all sections from a board """ self.login_required() bookmarks = [] sections = [] while True: data = url_encode({ 'source_url': '/%s/%s/' % (self.user['username'], tablero['name']), 'data': json.dumps({ 'options': { 'bookmarks': bookmarks, 'isPrefetch': 'False', 'board_id': tablero['id'], 'redux_normalize_feed': 'true' }, "context": {} }).replace(' ', ''), '_': '%s' % int(time.time() * 1000) }) url = self.home_page + 'resource/BoardSectionsResource/get/?%s' % data r = self.get(url=url, ajax=True) result = r.json() try: if result['resource_response']['data']: for section in result['resource_response']['data']: sections.append({ 'id': section['id'], 'title': section['title'], 'slug': section['slug'] }) except KeyError: pass bookmarks = result['resource']['options']['bookmarks'] if bookmarks[0] == '-end-': break return sections
def delete_pin(self, pin_id): self.login_required() url = self.home_page + 'resource/PinResource/delete/' data = url_encode({ 'source_url': '/pin/%s/' % pin_id, 'data': json.dumps({ 'options': { "id": pin_id }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: return True return False
def unfollow_board(self, board_id, board_url): self.login_required() url = 'https://www.pinterest.com/resource/BoardFollowResource/delete/' data = url_encode({ 'source_url': board_url, 'data': json.dumps({ 'options': { "board_id": board_id }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['status'] == "success": return True return False
def delete_pin(self, pin_id): self.login_required() url = 'https://www.pinterest.com/resource/PinResource/delete/' data = url_encode({ 'source_url': '/pin/%s/' % pin_id, 'data': json.dumps({ 'options': { "id": pin_id }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['status'] == "success": return True return False
def unfollow_board(self, board_id, board_url): self.login_required() url = self.home_page + 'resource/BoardFollowResource/delete/' data = url_encode({ 'source_url': board_url, 'data': json.dumps({ 'options': { "board_id": board_id }, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: return True return False
def comment(self, pin_id, text): self.login_required() url = 'https://www.pinterest.com/resource/PinCommentResource/create/' data = url_encode({ 'source_url': '/pin/%s/' % pin_id, 'data': json.dumps({ 'options': {"pin_id": "657384876829999984", "text": text}, "context": {} }).replace(' ', '') }) result = self.post(url=url, data=data, ajax=True).json() if result['resource_response']['error'] is None: comment = { 'id': result['resource_response']['data']['id'], 'text': result['resource_response']['data']['text'], 'created_at': result['resource_response']['data']['created_at'] } return comment return None
def search(self, scope, query, next_page=False): if next_page is True and self.next_book_marks[scope].get(query): return self.__search_next_page(scope, query) q = url_encode({'q': query, '_': '%s' % int(time.time() * 1000)}) url = self.home_page + 'search/%s/?%s' % (scope, q) r = self.get(url=url) html = r.content[r.content.find(b'application/json'):] html = html[html.find(b'{'):html.find(b'</script>')] search_result = json.loads(html) results = [] try: if search_result['resources']['data']['BaseSearchResource']: print(search_result['resources']['data'] ['BaseSearchResource'].values()) search_resource = list(search_result['resources'] \ ['data']['BaseSearchResource'].values())[0] results = search_resource['data']['results'] self.next_book_marks[scope][query] = search_resource[ 'nextBookmark'] except KeyError: pass return results
def logout(self): """ Logout from pinterest site. If OK return False :rtype: bool """ r = self.get(self.home_page) self.user = self.extract_user_data(r.content) if self.user: self.is_logged_in = True time.sleep(3) data = url_encode({ 'source_url': '/login/?referrer=home_page', 'data': json.dumps({ 'options': { 'username_or_email': True }, "context": {} }).replace(' ', '') }) url = self.home_page + 'resource/UserSessionResource/delete/' result = self.post(url=url, data=data, ajax=True).json() # By using get avoid KeyError if "error" key is not present error = result['resource_response'].get('error') if error is None: self.user = self.extract_user_data( self.get(self.home_page).content) self.is_logged_in = True else: raise PinterestLoginFailedException( '[%s Login failed] %s' % (error['http_status'], error['message'])) self.is_logged_in = False return self.is_logged_in