mirror of
https://github.com/mikf/gallery-dl.git
synced 2024-11-26 04:32:51 +01:00
[subscribestar] add 'user' and 'post' extractors (#852)
This commit is contained in:
parent
4f16fd37fe
commit
821524e4ee
@ -1,5 +1,7 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
## 1.14.2 - 2020-06-27
|
## 1.14.2 - 2020-06-27
|
||||||
### Additions
|
### Additions
|
||||||
- [artstation] add `date` metadata field ([#839](https://github.com/mikf/gallery-dl/issues/839))
|
- [artstation] add `date` metadata field ([#839](https://github.com/mikf/gallery-dl/issues/839))
|
||||||
|
@ -120,6 +120,7 @@ SlickPic https://www.slickpic.com/ Albums, User Profiles
|
|||||||
SlideShare https://www.slideshare.net/ Presentations
|
SlideShare https://www.slideshare.net/ Presentations
|
||||||
SmugMug https://www.smugmug.com/ |smugmug-C| Optional (OAuth)
|
SmugMug https://www.smugmug.com/ |smugmug-C| Optional (OAuth)
|
||||||
Speaker Deck https://speakerdeck.com/ Presentations
|
Speaker Deck https://speakerdeck.com/ Presentations
|
||||||
|
Subscribestar https://www.subscribestar.com/ Posts, User Profiles
|
||||||
The /b/ Archive https://thebarchive.com/ Threads
|
The /b/ Archive https://thebarchive.com/ Threads
|
||||||
Tsumino https://www.tsumino.com/ Galleries, Search Results Optional
|
Tsumino https://www.tsumino.com/ Galleries, Search Results Optional
|
||||||
Tumblr https://www.tumblr.com/ Likes, Posts, Tag Searches, User Profiles Optional (OAuth)
|
Tumblr https://www.tumblr.com/ Likes, Posts, Tag Searches, User Profiles Optional (OAuth)
|
||||||
|
@ -108,6 +108,7 @@ modules = [
|
|||||||
"slideshare",
|
"slideshare",
|
||||||
"smugmug",
|
"smugmug",
|
||||||
"speakerdeck",
|
"speakerdeck",
|
||||||
|
"subscribestar",
|
||||||
"tsumino",
|
"tsumino",
|
||||||
"tumblr",
|
"tumblr",
|
||||||
"twitter",
|
"twitter",
|
||||||
|
185
gallery_dl/extractor/subscribestar.py
Normal file
185
gallery_dl/extractor/subscribestar.py
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2020 Mike Fährmann
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
|
||||||
|
"""Extractors for https://www.subscribestar.com/"""
|
||||||
|
|
||||||
|
from .common import Extractor, Message
|
||||||
|
from .. import text
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
BASE_PATTERN = r"(?:https?://)?(?:www\.)?subscribestar\.(com|adult)"
|
||||||
|
|
||||||
|
|
||||||
|
class SubscribestarExtractor(Extractor):
|
||||||
|
"""Base class for subscribestar extractors"""
|
||||||
|
category = "subscribestar"
|
||||||
|
root = "https://www.subscribestar.com"
|
||||||
|
directory_fmt = ("{category}", "{author_name}")
|
||||||
|
filename_fmt = "{post_id}_{id}.{extension}"
|
||||||
|
archive_fmt = "{id}"
|
||||||
|
|
||||||
|
def __init__(self, match):
|
||||||
|
tld, self.item = match.groups()
|
||||||
|
if tld == "adult":
|
||||||
|
self.root = "https://subscribestar.adult"
|
||||||
|
self.subcategory += "-adult"
|
||||||
|
Extractor.__init__(self, match)
|
||||||
|
self.metadata = self.config("metadata", False)
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
for post_html in self.posts():
|
||||||
|
media = self._media_from_post(post_html)
|
||||||
|
if not media:
|
||||||
|
continue
|
||||||
|
data = self._data_from_post(post_html)
|
||||||
|
yield Message.Directory, data
|
||||||
|
for item in media:
|
||||||
|
item.update(data)
|
||||||
|
url = item["url"]
|
||||||
|
yield Message.Url, url, text.nameext_from_url(url, item)
|
||||||
|
|
||||||
|
def posts(self):
|
||||||
|
"""Yield HTML content of all relevant posts"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _media_from_post(html):
|
||||||
|
gallery = text.extract(html, 'data-gallery="', '"')[0]
|
||||||
|
if gallery:
|
||||||
|
return [
|
||||||
|
item for item in json.loads(text.unescape(gallery))
|
||||||
|
if "/previews/" not in item["url"]
|
||||||
|
]
|
||||||
|
return ()
|
||||||
|
|
||||||
|
def _data_from_post(self, html):
|
||||||
|
extr = text.extract_from(html)
|
||||||
|
data = {
|
||||||
|
"post_id" : text.parse_int(extr('data-id="', '"')),
|
||||||
|
"author_id" : text.parse_int(extr('data-user-id="', '"')),
|
||||||
|
"author_name": text.unescape(extr('href="/', '"')),
|
||||||
|
"author_nick": text.unescape(extr('>', '<')),
|
||||||
|
"content" : (extr(
|
||||||
|
'<div class="post-content', '<div class="post-uploads')
|
||||||
|
.partition(">")[2]),
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.metadata:
|
||||||
|
url = "{}/posts/{}".format(self.root, data["post_id"])
|
||||||
|
page = self.request(url).text
|
||||||
|
data["date"] = self._parse_datetime(text.extract(
|
||||||
|
page, 'class="section-subtitle">', '<')[0])
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_datetime(dt):
|
||||||
|
date = text.parse_datetime(dt, "%B %d, %Y %H:%M")
|
||||||
|
if date is dt:
|
||||||
|
date = text.parse_datetime(dt + " 2020", "%d %b %H:%M %Y")
|
||||||
|
return date
|
||||||
|
|
||||||
|
|
||||||
|
class SubscribestarUserExtractor(SubscribestarExtractor):
|
||||||
|
"""Extractor for media from a subscribestar user"""
|
||||||
|
subcategory = "user"
|
||||||
|
pattern = BASE_PATTERN + r"/(?!posts/)([^/?&#]+)"
|
||||||
|
test = (
|
||||||
|
("https://www.subscribestar.com/subscribestar", {
|
||||||
|
"count": ">= 20",
|
||||||
|
"pattern": r"https://star-uploads.s\d+-us-west-\d+.amazonaws.com"
|
||||||
|
r"/uploads/users/11/",
|
||||||
|
"keyword": {
|
||||||
|
"author_id": 11,
|
||||||
|
"author_name": "subscribestar",
|
||||||
|
"author_nick": "SubscribeStar",
|
||||||
|
"content": str,
|
||||||
|
"height" : int,
|
||||||
|
"id" : int,
|
||||||
|
"pinned" : bool,
|
||||||
|
"post_id": int,
|
||||||
|
"type" : "re:image|video",
|
||||||
|
"url" : str,
|
||||||
|
"width" : int,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
("https://www.subscribestar.com/subscribestar", {
|
||||||
|
"options": (("metadata", True),),
|
||||||
|
"keyword": {"date": "type:datetime"},
|
||||||
|
"range": "1",
|
||||||
|
}),
|
||||||
|
("https://subscribestar.adult/kanashiipanda", {
|
||||||
|
"range": "21-40",
|
||||||
|
"count": 20,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
def posts(self):
|
||||||
|
needle_next_page = 'data-role="infinite_scroll-next_page" href="'
|
||||||
|
page = self.request("{}/{}".format(self.root, self.item)).text
|
||||||
|
|
||||||
|
while True:
|
||||||
|
posts = page.split('<div class="post ')[1:]
|
||||||
|
if not posts:
|
||||||
|
return
|
||||||
|
yield from posts
|
||||||
|
|
||||||
|
url = text.extract(posts[-1], needle_next_page, '"')[0]
|
||||||
|
if not url:
|
||||||
|
return
|
||||||
|
page = self.request(self.root + text.unescape(url)).json()["html"]
|
||||||
|
|
||||||
|
|
||||||
|
class SubscribestarPostExtractor(SubscribestarExtractor):
|
||||||
|
"""Extractor for media from a single subscribestar post"""
|
||||||
|
subcategory = "post"
|
||||||
|
pattern = BASE_PATTERN + r"/posts/(\d+)"
|
||||||
|
test = (
|
||||||
|
("https://www.subscribestar.com/posts/102468", {
|
||||||
|
"url": "612da5a98af056dd78dc846fbcfa705e721f6675",
|
||||||
|
"keyword": {
|
||||||
|
"author_id": 11,
|
||||||
|
"author_name": "subscribestar",
|
||||||
|
"author_nick": "SubscribeStar",
|
||||||
|
"content": "re:<h1>Brand Guidelines and Assets</h1>",
|
||||||
|
"date": "dt:2020-05-07 12:33:00",
|
||||||
|
"extension": "jpg",
|
||||||
|
"filename": "8ff61299-b249-47dc-880a-cdacc9081c62",
|
||||||
|
"group": "imgs_and_videos",
|
||||||
|
"height": 291,
|
||||||
|
"id": 203885,
|
||||||
|
"pinned": False,
|
||||||
|
"post_id": 102468,
|
||||||
|
"type": "image",
|
||||||
|
"width": 700,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
("https://subscribestar.adult/posts/22950", {
|
||||||
|
"url": "440d745a368e6b3e218415f593a5045f384afa0d",
|
||||||
|
"keyword": {"date": "dt:2019-04-28 07:32:00"},
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
def posts(self):
|
||||||
|
url = "{}/posts/{}".format(self.root, self.item)
|
||||||
|
self._page = self.request(url).text
|
||||||
|
return (self._page,)
|
||||||
|
|
||||||
|
def _data_from_post(self, html):
|
||||||
|
extr = text.extract_from(html)
|
||||||
|
return {
|
||||||
|
"post_id" : text.parse_int(extr('data-id="', '"')),
|
||||||
|
"author_name": text.unescape(extr('href="/', '"')),
|
||||||
|
"author_id" : text.parse_int(extr('data-user-id="', '"')),
|
||||||
|
"author_nick": text.unescape(extr('alt="', '"')),
|
||||||
|
"date" : self._parse_datetime(extr(
|
||||||
|
'class="section-subtitle">', '<')),
|
||||||
|
"content" : (extr(
|
||||||
|
'<div class="post-content', '<div class="post-uploads')
|
||||||
|
.partition(">")[2]),
|
||||||
|
}
|
@ -6,4 +6,4 @@
|
|||||||
# 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
|
||||||
# published by the Free Software Foundation.
|
# published by the Free Software Foundation.
|
||||||
|
|
||||||
__version__ = "1.14.2"
|
__version__ = "1.14.3-dev"
|
||||||
|
Loading…
Reference in New Issue
Block a user