diff --git a/gallery_dl/extractor/pinterest.py b/gallery_dl/extractor/pinterest.py index 96f4afdb..526ca398 100644 --- a/gallery_dl/extractor/pinterest.py +++ b/gallery_dl/extractor/pinterest.py @@ -11,34 +11,83 @@ from .common import Extractor, Message from .. import text -class PinterestPinExtractor(Extractor): - """Extract an image from a single pin from https://www.pinterest.com""" +class PinterestExtractor(Extractor): + """Base class for pinterest extractors""" category = "pinterest" - subcategory = "pin" directory_fmt = ["{category}"] - filename_fmt = "{category}_{id}.{extension}" - pattern = [r"(?:https?://)?(?:www\.)?pinterest\.com/pin/([^/]+)"] + filename_fmt = "{category}_{pin-id}.{extension}" - def __init__(self, match): + def __init__(self): Extractor.__init__(self) - self.pin_id = match.group(1) self.api = PinterestAPI(self.session) - def items(self): - pin = self.api.pin(self.pin_id) + def data_from_pin(self, pin): + """Get image url and metadata from a pin-object""" img = pin["image"]["original"] + url = img["url"] data = { "category": self.category, "subcategory": self.subcategory, - "id": pin["id"], + "pin-id": pin["id"], "note": pin["note"], "width": img["width"], "height": img["height"], } - text.nameext_from_url(img["url"], data) + return url, text.nameext_from_url(url, data) + + +class PinterestPinExtractor(PinterestExtractor): + """Extract an image from a single pin from https://www.pinterest.com""" + subcategory = "pin" + pattern = [r"(?:https?://)?(?:www\.)?pinterest\.com/pin/([^/]+)"] + + def __init__(self, match): + PinterestExtractor.__init__(self) + self.pin_id = match.group(1) + + def items(self): + pin = self.api.pin(self.pin_id) + url, data = self.data_from_pin(pin) yield Message.Version, 1 yield Message.Directory, data - yield Message.Url, img["url"], data + yield Message.Url, url, data + + +class PinterestBoardExtractor(PinterestExtractor): + """Extract an image from a single pin from https://www.pinterest.com""" + category = "pinterest" + subcategory = "board" + directory_fmt = ["{category}", "{user}", "{board}"] + pattern = [r"(?:https?://)?(?:www\.)?pinterest\.com/(?!pin/)([^/]+)/([^/]+)"] + + def __init__(self, match): + PinterestExtractor.__init__(self) + self.user, self.board = match.groups() + + def items(self): + board = self.api.board(self.user, self.board) + data = self.data_from_board(board) + num = data["count"] + yield Message.Version, 1 + yield Message.Directory, data + for pin in self.api.board_pins(self.user, self.board): + url, pdata = self.data_from_pin(pin) + data.update(pdata) + data["num"] = num + num -= 1 + yield Message.Url, url, data + + def data_from_board(self, board): + """Get metadata from a board-object""" + data = { + "category": self.category, + "subcategory": self.subcategory, + "user": self.user, + "board-id": board["id"], + "board": board["name"], + "count": board["counts"]["pins"], + } + return data class PinterestAPI(): @@ -48,7 +97,7 @@ class PinterestAPI(): self.session = session self.session.params["access_token"] = access_token - def pin(self, pin_id, fields="image,note"): + def pin(self, pin_id, fields="id,image,note"): """Query information about a pin""" params = {"fields": fields} response = self.session.get( @@ -57,7 +106,16 @@ class PinterestAPI(): ) return self._parse(response)["data"] - def board_pins(self, user, board, fields="image,note"): + def board(self, user, board, fields="id,name,counts"): + """Query information about a board""" + params = {"fields": fields} + response = self.session.get( + "https://api.pinterest.com/v1/boards/{user}/{board}/" + .format(user=user, board=board), params=params + ) + return self._parse(response)["data"] + + def board_pins(self, user, board, fields="id,image,note"): """Yield all pins of a specific board""" params = {"fields": fields} url = ("https://api.pinterest.com/v1/boards/{user}/{board}/pins/"