Display NSFW and spoiler warnings, and allow filtering by self post, NSFW, and spoilers

This commit is contained in:
blank X 2020-09-06 03:23:38 +07:00
parent a1216f1273
commit e4f8b37b75
2 changed files with 137 additions and 46 deletions

View File

@ -11,16 +11,36 @@ config:
storage_chat: -1001222674489 storage_chat: -1001222674489
storage_message_id: 1367 storage_message_id: 1367
send_to_chats: send_to_chats:
- goodanimemes: gooanimemes:
subreddits:
- goodanimemes - goodanimemes
- -1001327025649: cron_duration: 0 * * * *
- ProgrammerAnimemes allow_selfposts: true
- memes10k: allow_nsfw: true
allow_spoilers: true
show_nsfw_warning: true
show_spoilers_warning: true
-1001284025455:
subreddits:
- HentaiMemes
cron_duration: 0 * * * *
allow_selfposts: true
allow_nsfw: true
allow_spoilers: true
show_nsfw_warning: false
show_spoilers_warning: true
memes10k:
subreddits:
- linuxmemes - linuxmemes
- dankmemes - dankmemes
- memes - memes
- ShitPostCrusaders - ShitPostCrusaders
cron_duration: "*/30 * * * *"
allow_selfposts: false
allow_nsfw: true
allow_spoilers: true
show_nsfw_warning: true
show_spoilers_warning: true
bot_admins: bot_admins:
- thekneesocks - thekneesocks
- 214416808 - 214416808
cron_duration: 0 * * * *

View File

@ -32,20 +32,26 @@ reddit_client_secret = config_data['reddit']['client_secret']
storage_chat = config_data['config'].get('storage_chat') storage_chat = config_data['config'].get('storage_chat')
storage_msg_id = config_data['config'].get('storage_message_id') storage_msg_id = config_data['config'].get('storage_message_id')
_bkup_subreddits = config_data['config'].get('subreddits') _bkup_subreddits = config_data['config'].get('subreddits')
_send_to_chats = config_data['config']['send_to_chats'] _send_to_chats = send_to_chats = config_data['config']['send_to_chats']
send_to_chats = dict() if isinstance(_send_to_chats, list):
for chat in _send_to_chats: send_to_chats = dict()
subs = None for i in _send_to_chats:
if isinstance(chat, dict): j = None
subs = tuple(chat.values())[0] if isinstance(i, dict):
chat = tuple(chat.keys())[0] j = tuple(i.values())[0]
send_to_chats[chat] = subs i = tuple(i.keys())[0]
if isinstance(j, list) or not j:
j = {'subreddits': j, 'cron_duration': config_data['config']['cron_duration'],
'allow_selfposts': True, 'allow_nsfw': True,
'allow_spoilers': True, 'show_nsfw_warning': True,
'show_spoilers_warning': True}
send_to_chats[i] = j
bot_admins = config_data['config']['bot_admins'] bot_admins = config_data['config']['bot_admins']
cron_duration = config_data['config']['cron_duration']
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
async def main(): async def main():
zws = '\u200b' zws = '\u200b'
_added_chats = []
client = await TelegramClient('redditbot', tg_api_id, tg_api_hash).start(bot_token=bot_token) client = await TelegramClient('redditbot', tg_api_id, tg_api_hash).start(bot_token=bot_token)
client.parse_mode = 'html' client.parse_mode = 'html'
session = aiohttp.ClientSession() session = aiohttp.ClientSession()
@ -63,55 +69,99 @@ async def main():
seen_posts = {'version': 0, 'chats': {'global': []}} seen_posts = {'version': 0, 'chats': {'global': []}}
# chat dict: {chatid: [array of submission ids]} # chat dict: {chatid: [array of submission ids]}
uploading_lock = asyncio.Lock()
async def write_seen_posts(): async def write_seen_posts():
with open('redditbot.json', 'w') as file: with open('redditbot.json', 'w') as file:
json.dump(seen_posts, file) json.dump(seen_posts, file)
if storage_chat and storage_msg_id: if storage_chat and storage_msg_id:
async with uploading_lock:
await client.edit_message(storage_chat, storage_msg_id, file='redditbot.json') await client.edit_message(storage_chat, storage_msg_id, file='redditbot.json')
@aiocron.crontab(cron_duration) async def add_chat(chat, chat_data):
async def start_post(): global_sp = chat_sp = seen_posts['chats']['global']
global_sp = seen_posts['chats']['global'] subreddits = chat_data['subreddits']
for chat in send_to_chats: if subreddits:
uses_bkupsub = False
subreddits = send_to_chats[chat]
if not subreddits:
subreddits = _bkup_subreddits
uses_bkupsub = True
chat = await client.get_peer_id(chat) chat = await client.get_peer_id(chat)
if str(chat) not in seen_posts['chats']: if str(chat) not in seen_posts['chats']:
seen_posts['chats'][str(chat)] = [] seen_posts['chats'][str(chat)] = []
chat_sp = global_sp if uses_bkupsub else seen_posts['chats'][str(chat)] chat_sp = seen_posts['chats'][str(chat)]
else:
subreddits = _bkup_subreddits.copy()
cron_duration = chat_data['cron_duration']
allow_selfposts = chat_data['allow_selfposts']
allow_nsfw = chat_data['allow_nsfw']
allow_spoilers = chat_data['allow_spoilers']
show_nsfw_warning = chat_data['show_nsfw_warning']
show_spoilers_warning = chat_data['show_spoilers_warning']
@aiocron.crontab(cron_duration)
async def start_post():
while True: while True:
random.shuffle(subreddits) random.shuffle(subreddits)
to_break = False
for subreddit_name in subreddits: for subreddit_name in subreddits:
subreddit = reddit.subreddit(subreddit_name) subreddit = reddit.subreddit(subreddit_name)
while True: while True:
random_post = subreddit.random() random_post = subreddit.random()
cpid = None cpid = cpp = None
if random_post is None: if random_post is None:
for submission in subreddit.hot(): for submission in subreddit.hot():
cpid = getattr(submission, 'crosspost_parent', None) cpid = getattr(submission, 'crosspost_parent', None)
if cpid: if cpid and getattr(random_post, 'crosspost_parent_list', None):
cpid = cpid[3:] cpid = cpid[3:]
if submission.id in chat_sp + global_sp or cpid in chat_sp + global_sp: if submission.id in chat_sp + global_sp or cpid in chat_sp + global_sp:
continue continue
if not (allow_selfposts and allow_nsfw and allow_spoilers):
is_self = submission.is_self
nsfw = submission.over_18
spoilers = submission.spoiler
if cpid:
cpp = reddit.submission(cpid)
if not allow_selfposts:
is_self = cpp.is_self
if not (nsfw and allow_nsfw):
nsfw = cpp.over_18
if not (spoilers and allow_spoilers):
nsfw = cpp.spoiler
if is_self and not allow_selfposts:
continue
if nsfw and not allow_nsfw:
continue
if spoilers and not allow_spoilers:
continue
random_post = submission random_post = submission
break break
cpid = getattr(random_post, 'crosspost_parent', None) cpid = getattr(random_post, 'crosspost_parent', None)
if cpid: if cpid and getattr(random_post, 'crosspost_parent_list', None):
cpid = cpid[3:] cpid = cpid[3:]
if random_post.id in chat_sp + global_sp or cpid in chat_sp + global_sp: if random_post.id in chat_sp + global_sp or cpid in chat_sp + global_sp:
continue continue
if not (allow_selfposts and allow_nsfw and allow_spoilers):
is_self = random_post.is_self
nsfw = random_post.over_18
spoilers = random_post.spoiler
if cpid and not cpp:
cpp = reddit.submission(cpid)
if cpid:
if not allow_selfposts:
is_self = cpp.is_self
if not (nsfw and allow_nsfw):
nsfw = cpp.over_18
if not (spoilers and allow_spoilers):
nsfw = cpp.spoiler
if is_self and not allow_selfposts:
continue
if nsfw and not allow_nsfw:
continue
if spoilers and not allow_spoilers:
continue
chat_sp.append(cpid or random_post.id) chat_sp.append(cpid or random_post.id)
print(random_post.id, random_post.shortlink) print(random_post.id, random_post.shortlink)
to_break = True
break break
if to_break: else:
continue
break break
try: try:
await _actual_start_post(random_post, [chat]) await _actual_start_post(random_post, [chat], cpp, show_nsfw_warning, show_spoilers_warning)
except Exception: except Exception:
logging.exception(random_post.id) logging.exception(random_post.id)
for i in bot_admins: for i in bot_admins:
@ -120,6 +170,12 @@ async def main():
break break
await write_seen_posts() await write_seen_posts()
_added_chats.append(start_post)
for chat in send_to_chats:
print(chat, send_to_chats[chat])
await add_chat(chat, send_to_chats[chat])
async def _start_broadcast(text, file, chats): async def _start_broadcast(text, file, chats):
uploaded_files = [] uploaded_files = []
for i in file or []: for i in file or []:
@ -162,12 +218,24 @@ async def main():
ext = '.' + ext ext = '.' + ext
return ext return ext
async def _actual_start_post(random_post, chats): async def _actual_start_post(random_post, chats, cpp=None, snw=None, ssw=None):
text = f'<a href="{random_post.shortlink}">{html.escape(random_post.title)}</a>' text = f'<a href="{random_post.shortlink}">{html.escape(random_post.title)}</a>'
nsfw = random_post.over_18
spoilers = random_post.spoiler
cpid = getattr(random_post, 'crosspost_parent', None) cpid = getattr(random_post, 'crosspost_parent', None)
if cpid and getattr(random_post, 'crosspost_parent_list', None): if cpid and getattr(random_post, 'crosspost_parent_list', None) and not cpp:
random_post = reddit.submission(cpid[3:]) cpp = reddit.submission(cpid[3:])
if cpp:
random_post = cpp
if snw and not nsfw:
nsfw = random_post.over_18
if ssw and not spoilers:
spoilers = random_post.spoiler
text += f' (crosspost of <a href="{random_post.shortlink}">{html.escape(random_post.title)}</a>)' text += f' (crosspost of <a href="{random_post.shortlink}">{html.escape(random_post.title)}</a>)'
if spoilers and ssw:
text = '🙈🙈🙈 SPOILERS 🙈🙈🙈\n' + text
if nsfw and snw:
text = '🔞🔞🔞 18+ / NSFW 🔞🔞🔞\n' + text
if not random_post.is_self: if not random_post.is_self:
with tempfile.TemporaryDirectory() as tempdir: with tempfile.TemporaryDirectory() as tempdir:
url = random_post.url url = random_post.url
@ -333,20 +401,23 @@ async def main():
await e.reply(('/start - /help\n' await e.reply(('/start - /help\n'
'/help - /start\n' '/help - /start\n'
'/poweroff - shuts down bot\n' '/poweroff - shuts down bot\n'
'/test <submission id> - tests sending submission'), parse_mode=None) '/test <submission id> [ns] - tests sending submission'), parse_mode=None)
@register('/poweroff') @register('/poweroff')
async def poweroff(e): async def poweroff(e):
await e.reply('ok') await e.reply('ok')
await e.client.disconnect() await e.client.disconnect()
@register('/test (.+)') @register(r'/test (\S+)(?: ([ns]+))?')
async def test_post(e): async def test_post(e):
await e.reply('ok') await e.reply('ok')
post = reddit.submission(e.pattern_match.group(1)) post = reddit.submission(e.pattern_match.group(1))
await _actual_start_post(post, [e.chat_id]) flags = e.pattern_match.group(2) or ''
snw = 'n' in flags
ssw = 's' in flags
await _actual_start_post(post, [e.chat_id], None, snw, ssw)
# await start_post.func() # await asyncio.gather(*[i.func() for i in _added_chats])
try: try:
await client.run_until_disconnected() await client.run_until_disconnected()
finally: finally: