[fansly] add 'creator-media' extractor (#4401)
This commit is contained in:
@@ -292,7 +292,7 @@ Consider all listed sites to potentially be NSFW.
|
|||||||
<tr id="fansly" title="fansly">
|
<tr id="fansly" title="fansly">
|
||||||
<td>Fansly</td>
|
<td>Fansly</td>
|
||||||
<td>https://fansly.com/</td>
|
<td>https://fansly.com/</td>
|
||||||
<td>Creator Posts, Home Feed, Lists, Account Lists, Posts</td>
|
<td>Creator Media, Creator Posts, Home Feed, Lists, Account Lists, Posts</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr id="fantia" title="fantia">
|
<tr id="fantia" title="fantia">
|
||||||
|
|||||||
@@ -191,13 +191,20 @@ class FanslyCreatorPostsExtractor(FanslyExtractor):
|
|||||||
example = "https://fansly.com/CREATOR/posts"
|
example = "https://fansly.com/CREATOR/posts"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
creator = self.groups[0]
|
account = self.api.account(self.groups[0])
|
||||||
if creator.startswith("id:"):
|
return self.api.timeline_new(
|
||||||
account = self.api.account_by_id(creator[3:])
|
account["id"], account["walls"][0]["id"])
|
||||||
else:
|
|
||||||
account = self.api.account(creator)
|
|
||||||
wall_id = account["walls"][0]["id"]
|
class FanslyCreatorMediaExtractor(FanslyExtractor):
|
||||||
return self.api.timeline_new(account["id"], wall_id)
|
subcategory = "creator-media"
|
||||||
|
pattern = rf"{BASE_PATTERN}/([^/?#]+)/media"
|
||||||
|
example = "https://fansly.com/CREATOR/media"
|
||||||
|
|
||||||
|
def posts(self):
|
||||||
|
account = self.api.account(self.groups[0])
|
||||||
|
return self.api.mediaoffers_location(
|
||||||
|
account["id"], account["walls"][0]["id"])
|
||||||
|
|
||||||
|
|
||||||
class FanslyAPI():
|
class FanslyAPI():
|
||||||
@@ -217,7 +224,12 @@ class FanslyAPI():
|
|||||||
else:
|
else:
|
||||||
self.extractor.log.warning("No 'token' provided")
|
self.extractor.log.warning("No 'token' provided")
|
||||||
|
|
||||||
def account(self, username):
|
def account(self, creator):
|
||||||
|
if creator.startswith("id:"):
|
||||||
|
return self.account_by_id(creator[3:])
|
||||||
|
return self.account_by_username(creator)
|
||||||
|
|
||||||
|
def account_by_username(self, username):
|
||||||
endpoint = "/v1/account"
|
endpoint = "/v1/account"
|
||||||
params = {"usernames": username}
|
params = {"usernames": username}
|
||||||
return self._call(endpoint, params)[0]
|
return self._call(endpoint, params)[0]
|
||||||
@@ -252,6 +264,20 @@ class FanslyAPI():
|
|||||||
}
|
}
|
||||||
return self._pagination(endpoint, params)
|
return self._pagination(endpoint, params)
|
||||||
|
|
||||||
|
def mediaoffers_location(self, account_id, wall_id):
|
||||||
|
endpoint = "/v1/mediaoffers/location"
|
||||||
|
params = {
|
||||||
|
"locationId": wall_id,
|
||||||
|
"locationType": "1002",
|
||||||
|
"accountId": account_id,
|
||||||
|
"mediaType": "",
|
||||||
|
"before": "",
|
||||||
|
"after" : "0",
|
||||||
|
"limit" : "30",
|
||||||
|
"offset": "0",
|
||||||
|
}
|
||||||
|
return self._pagination_media(endpoint, params)
|
||||||
|
|
||||||
def post(self, post_id):
|
def post(self, post_id):
|
||||||
endpoint = "/v1/post"
|
endpoint = "/v1/post"
|
||||||
params = {"ids": post_id}
|
params = {"ids": post_id}
|
||||||
@@ -319,6 +345,19 @@ class FanslyAPI():
|
|||||||
|
|
||||||
return posts
|
return posts
|
||||||
|
|
||||||
|
def _update_media(self, items, response):
|
||||||
|
posts = {
|
||||||
|
post["id"]: post
|
||||||
|
for post in response["posts"]
|
||||||
|
}
|
||||||
|
|
||||||
|
response["posts"] = [
|
||||||
|
posts[item["correlationId"]]
|
||||||
|
for item in items
|
||||||
|
]
|
||||||
|
|
||||||
|
return self._update_posts(response)
|
||||||
|
|
||||||
def _update_items(self, items):
|
def _update_items(self, items):
|
||||||
ids = [item["id"] for item in items]
|
ids = [item["id"] for item in items]
|
||||||
accounts = {
|
accounts = {
|
||||||
@@ -353,3 +392,13 @@ class FanslyAPI():
|
|||||||
posts = self._update_posts(response)
|
posts = self._update_posts(response)
|
||||||
yield from posts
|
yield from posts
|
||||||
params["before"] = min(p["id"] for p in posts)
|
params["before"] = min(p["id"] for p in posts)
|
||||||
|
|
||||||
|
def _pagination_media(self, endpoint, params):
|
||||||
|
while True:
|
||||||
|
response = self._call(endpoint, params)
|
||||||
|
|
||||||
|
data = response["data"]
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
yield from self._update_media(data, response["aggregationData"])
|
||||||
|
params["before"] = data[-1]["id"]
|
||||||
|
|||||||
@@ -591,7 +591,7 @@ def subcategory_text(bc, c, sc):
|
|||||||
sc = f"{sc[:-1]}ies"
|
sc = f"{sc[:-1]}ies"
|
||||||
elif sc.endswith("h"):
|
elif sc.endswith("h"):
|
||||||
sc = f"{sc}es"
|
sc = f"{sc}es"
|
||||||
elif not sc.endswith("s"):
|
elif not sc.endswith("s") and not sc.endswith("edia"):
|
||||||
sc = f"{sc}s"
|
sc = f"{sc}s"
|
||||||
return sc
|
return sc
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ __tests__ = (
|
|||||||
"#class" : fansly.FanslyCreatorPostsExtractor,
|
"#class" : fansly.FanslyCreatorPostsExtractor,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"#url" : "https://fansly.com/Oliviaus/media",
|
||||||
|
"#class" : fansly.FanslyCreatorMediaExtractor,
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"#url" : "https://fansly.com/home",
|
"#url" : "https://fansly.com/home",
|
||||||
"#class" : fansly.FanslyHomeExtractor,
|
"#class" : fansly.FanslyHomeExtractor,
|
||||||
|
|||||||
Reference in New Issue
Block a user