# █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
# █▀█ █ █ █ █▀█ █▀▄ █
# © Copyright 2022
# https://t.me/hikariatama
#
# 🔒 Licensed under the GNU AGPLv3
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
# meta pic: https://static.dan.tatar/scrolller_icon.png
# meta banner: https://mods.hikariatama.ru/badges/scrolller.jpg
# meta developer: @hikarimods
# scope: hikka_only
# scope: hikka_min 1.2.10
import functools
import random
from typing import List, Union
import requests
from telethon.tl.types import Message
from telethon.utils import get_display_name
from .. import loader, utils
from ..inline.types import InlineQuery
async def photos(subreddit: str, quantity: int) -> List[str]:
"""Loads `quantity` photos from `subreddit` on scrolller.com"""
ans = (
await utils.run_sync(
requests.get,
"https://api.scrolller.com/api/v2/graphql",
json={
"query": (
" query SubredditQuery( $url: String! $filter: SubredditPostFilter"
" $iterator: String ) { getSubreddit(url: $url) { children("
f" limit: {quantity} iterator: $iterator filter: $filter"
" disabledHosts: null ) { iterator items {url subredditTitle"
" isNsfw mediaSources { url } } } } } "
),
"variables": {"url": subreddit, "filter": None, "hostsDown": None},
"authorization": None,
},
)
).json()
posts = ans["data"]["getSubreddit"]["children"]["items"]
return [post["mediaSources"][-1]["url"] for post in posts]
def caption(subreddit: dict) -> str:
return (
f"{'🔞' if subreddit['isNsfw'] else '👨👩👧'} {utils.escape_html(subreddit['secondaryTitle'])} ({utils.escape_html(subreddit['url'])})\n\n{utils.escape_html(subreddit['description'])}\n\nEnjoy!"
f" {utils.ascii_face()}"
)
async def search_subreddit(query: str) -> List[dict]:
"""Searches for subreddits using `query`"""
ans = (
await utils.run_sync(
requests.get,
"https://api.scrolller.com/api/v2/graphql",
json={
"query": (
" query SearchQuery($query: String!, $isNsfw: Boolean) {"
" searchSubreddits( query: $query isNsfw: $isNsfw limit: 500 ) {"
" __typename url title secondaryTitle description createdAt isNsfw"
" subscribers isComplete itemCount videoCount pictureCount"
" albumCount isFollowing } } "
),
"variables": {"query": query, "isNsfw": None},
"authorization": None,
},
)
).json()
res = ans["data"]["searchSubreddits"]
random.shuffle(res)
return res[:30]
async def fetch_multiple_subreddits(subreddits: List[str]) -> Union[List[str], bool]:
"""Fetches preview from multiple `subreddits`"""
args = [f"$url_{i}: String!" for i in range(len(subreddits))]
vals = {f"url_{i}": subreddit for i, subreddit in enumerate(subreddits)}
funcs = [
subreddit.split("/")[-1]
+ """: getSubreddit(url: $url_"""
+ str(i)
+ """) {children(limit: 1 iterator: $iterator filter: $filter disabledHosts: null ) {iterator items {url subredditTitle isNsfw mediaSources { url } } } }"""
for i, subreddit in enumerate(subreddits)
]
r = (
await utils.run_sync(
requests.get,
"https://api.scrolller.com/api/v2/graphql",
json={
"query": (
"""query SubredditQuery ("""
+ "\n".join(args)
+ """$filter: SubredditPostFilter $iterator: String ) {"""
+ "\n".join(funcs)
+ """} """
),
"variables": {**vals, "filter": None, "hostsDown": None},
"authorization": None,
},
)
).json()
try:
return [
i["children"]["items"][0]["mediaSources"][0]["url"]
for i in r["data"].values()
]
except KeyError:
return False
@loader.tds
class ScrolllerMod(loader.Module):
"""Sends pictures from scrolller.com via inline gallery"""
strings = {
"name": "Scrolller",
"sreddit404": "🚫 Subreddit not found",
"default_subreddit": "🙂 Set new default subreddit: {}",
}
strings_ru = {
"sreddit404": "🚫 Сабреддит не найден",
"default_subreddit": (
"🙂 Установил новый сабреддит по умолчанию: {}"
),
"_cmd_doc_gallery": (
"<сабреддит> [-n <количество | 1 по умолчанию>] - Отправляет случайную 18+"
" картинку"
),
"_cmd_doc_gallerycat": "<сабреддит> - Установить новый сабреддит по умолчанию",
"_cls_doc": "Отправляет изображения с scrolller.com в виде инлайн галереи",
}
async def gallerycmd(self, message: Message):
""" - Send inline gallery with photos from subreddit"""
args = utils.get_args_raw(message)
reply = await message.get_reply_message()
if reply:
for_ = (
"❤️ Special for"
f" {utils.escape_html(get_display_name(reply.sender))}"
)
else:
for_ = ""
if not args:
args = self.get("default_subreddit", "cat")
subreddit = f"/r/{args}"
ans = await utils.run_sync(
requests.get, f"https://api.scrolller.com{subreddit}"
)
if ans.status_code != 200:
await utils.answer(message, self.strings("sreddit404", message))
return
await self.inline.gallery(
message=message,
next_handler=functools.partial(photos, subreddit=subreddit, quantity=15),
caption=lambda: f"Enjoy this {subreddit} photos <3\n{utils.ascii_face()}\n\n{for_}",
always_allow=[reply.sender_id] if reply else [],
)
async def gallerycatcmd(self, message: Message):
""" - Set new default subreddit"""
args = utils.get_args_raw(message)
if not args:
args = "cat"
ans = await utils.run_sync(requests.get, f"https://api.scrolller.com/r/{args}")
if ans.status_code != 200:
await utils.answer(message, self.strings("sreddit404", message))
return
self.set("default_subreddit", args)
await utils.answer(
message, self.strings("default_subreddit", message).format(args)
)
async def gallery_inline_handler(self, query: InlineQuery):
"""
Search for Scrolller subreddits
"""
if not query.args:
query.args = self.get("default_subreddit", "cat")
subreddits = await search_subreddit(query.args)
thumbs = await fetch_multiple_subreddits([i["url"] for i in subreddits])
if not thumbs or not subreddits:
await query.e404()
return
await self.inline.query_gallery(
query,
[
{
"title": (
f"{'🔞' if subreddit['isNsfw'] else '👨👩👧'} {subreddit['secondaryTitle']} ({subreddit['url']})"
),
"description": subreddit["description"],
"next_handler": functools.partial(
photos,
subreddit=subreddit["url"],
quantity=15,
),
"thumb_handler": [thumbs[i]],
"caption": functools.partial(
caption,
subreddit=subreddit,
),
}
for i, subreddit in enumerate(subreddits)
],
)