diff --git a/example_config.yaml b/example_config.yaml
index dafac10..eb86d17 100644
--- a/example_config.yaml
+++ b/example_config.yaml
@@ -11,16 +11,36 @@ config:
storage_chat: -1001222674489
storage_message_id: 1367
send_to_chats:
- - goodanimemes:
- - goodanimemes
- - -1001327025649:
- - ProgrammerAnimemes
- - memes10k:
- - linuxmemes
- - dankmemes
- - memes
- - ShitPostCrusaders
+ gooanimemes:
+ subreddits:
+ - goodanimemes
+ cron_duration: 0 * * * *
+ allow_selfposts: true
+ 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
+ - dankmemes
+ - memes
+ - ShitPostCrusaders
+ cron_duration: "*/30 * * * *"
+ allow_selfposts: false
+ allow_nsfw: true
+ allow_spoilers: true
+ show_nsfw_warning: true
+ show_spoilers_warning: true
bot_admins:
- thekneesocks
- 214416808
- cron_duration: 0 * * * *
diff --git a/redditbot.py b/redditbot.py
index a781a5d..66a86be 100644
--- a/redditbot.py
+++ b/redditbot.py
@@ -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'{html.escape(random_post.title)}'
+ 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 {html.escape(random_post.title)})'
+ 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 - tests sending submission'), parse_mode=None)
+ '/test [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: