[patreon] filter duplicate files per post (#590)

This commit is contained in:
Mike Fährmann
2020-02-05 22:47:20 +01:00
parent b38cf59711
commit 109f6c8685

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2019 Mike Fährmann # Copyright 2019-2020 Mike Fährmann
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as # it under the terms of the GNU General Public License version 2 as
@@ -12,6 +12,7 @@ from .common import Extractor, Message
from .. import text, exception from .. import text, exception
from ..cache import memcache from ..cache import memcache
import collections import collections
import itertools
import json import json
@@ -33,43 +34,60 @@ class PatreonExtractor(Extractor):
PatreonExtractor._warning = False PatreonExtractor._warning = False
for post in self.posts(): for post in self.posts():
ids = set()
post["num"] = 0 post["num"] = 0
content = post.get("content") hashes = set()
postfile = post.get("post_file")
yield Message.Directory, post yield Message.Directory, post
yield Message.Metadata, text.nameext_from_url( yield Message.Metadata, text.nameext_from_url(
post["creator"].get("image_url", ""), post) post["creator"].get("image_url", ""), post)
for image in post["images"]: for kind, url, name in itertools.chain(
url = image.get("download_url") self._postfile(post),
if not url: self._images(post),
continue self._attachments(post),
ids.add(url.split("/")[-2]) self._content(post),
name = image.get("file_name") or self._filename(url) or url ):
fhash = url.rsplit("/", 2)[1]
post["num"] += 1 if fhash not in hashes:
post["type"] = "image" hashes.add(fhash)
yield Message.Url, url, text.nameext_from_url(name, post) post["hash"] = fhash
post["type"] = kind
if postfile and postfile["url"].split("/")[-2] not in ids:
post["num"] += 1
post["type"] = "postfile"
text.nameext_from_url(postfile["name"], post)
yield Message.Url, postfile["url"], post
for attachment in post["attachments"]:
post["num"] += 1
post["type"] = "attachment"
text.nameext_from_url(attachment["name"], post)
yield Message.Url, attachment["url"], post
if content:
for url in text.extract_iter(content, 'src="', '"'):
post["num"] += 1 post["num"] += 1
post["type"] = "content" yield Message.Url, url, text.nameext_from_url(name, post)
yield Message.Url, url, text.nameext_from_url(url, post)
@staticmethod
def _postfile(post):
postfile = post.get("post_file")
if postfile:
return (("postfile", postfile["url"], postfile["name"]),)
return ()
def _images(self, post):
for image in post["images"]:
url = image.get("download_url")
if url:
name = image.get("file_name") or self._filename(url) or url
yield "image", url, name
def _attachments(self, post):
for attachment in post["attachments"]:
url = self.request(
attachment["url"], method="HEAD",
allow_redirects=False, fatal=False,
).headers.get("Location")
if url:
yield "attachment", url, attachment["name"]
@staticmethod
def _content(post):
content = post.get("content")
if content:
for img in text.extract_iter(
content, '<img data-media-id="', '>'):
url = text.extract(img, 'src="', '"')[0]
if url:
yield "content", url, url
def posts(self): def posts(self):
"""Return all relevant post objects""" """Return all relevant post objects"""
@@ -238,11 +256,13 @@ class PatreonPostExtractor(PatreonExtractor):
subcategory = "post" subcategory = "post"
pattern = r"(?:https?://)?(?:www\.)?patreon\.com/posts/([^/?&#]+)" pattern = r"(?:https?://)?(?:www\.)?patreon\.com/posts/([^/?&#]+)"
test = ( test = (
# postfile + attachments
("https://www.patreon.com/posts/precious-metal-23563293", { ("https://www.patreon.com/posts/precious-metal-23563293", {
"count": 4, "count": 4,
}), }),
("https://www.patreon.com/posts/er1-28201153", { # postfile + content
"count": 1, ("https://www.patreon.com/posts/19987002", {
"count": 4,
}), }),
("https://www.patreon.com/posts/not-found-123", { ("https://www.patreon.com/posts/not-found-123", {
"exception": exception.NotFoundError, "exception": exception.NotFoundError,