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