Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update discord bot #1149

Merged
merged 2 commits into from
Oct 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,8 @@ DISCORD_TOKEN=
DISCORD_DISABLE_SEARCH=false
DISCORD_SIGNAL_CHAR=!

# Publicly available data folder
PUBLIC_DATA_PATH=
PUBLIC_ADDRESS=http://18.218.187.242/

# Cloud drives for upload | Options: [GOFILE, GOOGLE_DRIVE] | Default: GOFILE
CLOUD_DRIVE=GOFILE

# Gofile config. Token is optional.
GOFILE_TOKEN=kRgxIJe0D724Sdq0U12Hy0KwGhY10b1z
GOFILE_FOLDER_ID=1247451e-2730-46b3-8dd8-8cff8cb18a5c
# Cloud drives for upload | Options: [ANONFILES, GOFILE, GOOGLE_DRIVE] | Default: ANONFILES
CLOUD_DRIVE=ANONFILES

# Google Drive Config
GOOGLE_DRIVE_CREDENTIAL_FILE=mycreds.txt
Expand Down
6 changes: 3 additions & 3 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
"value": "false"
},
"CLOUD_DRIVE": {
"description": "Available: GOFILE, GOOGLE_DRIVE",
"description": "Available: GOFILE, GOOGLE_DRIVE, ANONFILES",
"required": false,
"value": "GOFILE"
"value": "ANONFILES"
},
"GOOGLE_DRIVE_CREDENTIAL_FILE": {
"description": "Google Drive service credentials to use",
Expand All @@ -65,4 +65,4 @@
"url": "https://github.com/NNTin/heroku-buildpack-calibre"
}
]
}
}
2 changes: 2 additions & 0 deletions lncrawl/bots/console/resume_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ def resume_session():
# end if

app = load_session_from_metadata(metadata)
assert isinstance(app.crawler, Crawler)

print('Resuming', app.crawler.novel_title)
print('Output path:', app.output_path)

Expand Down
37 changes: 29 additions & 8 deletions lncrawl/bots/discord/config.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
# -*- coding: utf-8 -*-
import os
import logging
import logging.config
import os

from colorama import Fore
from ...core.arguments import get_args

# The special signal character for crawler commands
from lncrawl.core.arguments import get_args

shard_id = get_args().shard_id
shard_count = get_args().shard_count
signal = os.getenv('DISCORD_SIGNAL_CHAR') or '!'
max_workers = int(os.getenv('DISCORD_MAX_WORKERS', 10))
discord_token = os.getenv('DISCORD_TOKEN')
disable_search = os.getenv('DISCORD_DISABLE_SEARCH') == 'true'
session_retain_time_in_seconds = 4 * 3600
max_active_handles = 5

# The public ip and path of the server to put files in
public_ip = os.getenv('PUBLIC_ADDRESS', None)
public_path = os.getenv('PUBLIC_DATA_PATH', None)
vip_users_ids = set([
'1822',
])

available_formats = [
'epub',
'text',
'web',
'mobi',
#'pdf',
#'fb2',
]

os.makedirs('logs', exist_ok=True)
logging.config.dictConfig({
Expand Down Expand Up @@ -41,7 +56,7 @@
'file': {
'formatter': 'file',
'class': 'logging.handlers.RotatingFileHandler',
'filename': 'logs/discord-bot_%s.log' % (get_args().shard_id),
'filename': f'logs/discord-bot_{shard_id}.log',
'maxBytes': 10 * 1024 * 1024, # 10 MB
'backupCount': 5,
'encoding': 'utf8',
Expand All @@ -54,3 +69,9 @@
},
},
})

logger = logging.getLogger(f'discord-{shard_id}')

if not discord_token:
raise Exception('Discord token is not found')

59 changes: 30 additions & 29 deletions lncrawl/bots/discord/discord_bot.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
# -*- coding: utf-8 -*-
import logging
import logging.config
import os
import random
import subprocess
from datetime import datetime
from typing import Dict

import discord

from ...core.arguments import get_args
from .config import signal
from . import config as C
from .config import logger
from .message_handler import MessageHandler

logger = logging.getLogger(__name__)


def get_bot_version():
try:
Expand All @@ -28,26 +24,27 @@ class DiscordBot(discord.Client):
bot_version = get_bot_version()

def __init__(self, *args, loop=None, **options):
options['shard_id'] = get_args().shard_id
options['shard_count'] = get_args().shard_count
options['shard_id'] = C.shard_id
options['shard_count'] = C.shard_count
options['heartbeat_timeout'] = 300
options['guild_subscriptions'] = False
options['fetch_offline_members'] = False
self.handlers: Dict[str, MessageHandler] = {}
super().__init__(*args, loop=loop, **options)
# end def

def start_bot(self):
self.bot_is_ready = False
os.environ['debug_mode'] = 'yes'
self.run(os.getenv('DISCORD_TOKEN'))
self.run(C.discord_token)
# end def

async def on_ready(self):
# Reset handler cache
self.handlers = {}

print('Discord bot in online!')
activity = discord.Activity(name='for 🔥%s🔥 (%s)' % (signal, self.bot_version),
activity = discord.Activity(name='for 🔥%s🔥 (%s)' % (C.signal, self.bot_version),
type=discord.ActivityType.watching)
await self.change_presence(activity=activity,
status=discord.Status.online)
Expand All @@ -69,14 +66,13 @@ async def on_message(self, message):
text = message.content
if isinstance(message.channel, discord.abc.PrivateChannel):
await self.handle_message(message)
elif text.startswith(signal) and len(text.split(signal)) == 2:
uid = message.author.id
elif text.startswith(C.signal) and len(text.split(C.signal)) == 2:
uid = str(message.author.id)
if uid in self.handlers:
self.handlers[uid].destroy()
# end if
await self.send_public_text(message, random.choice([
"Sending you a private message",
]))
with message.channel.typing():
await message.channel.send(f"Sending you a private message <@{uid}>")
await self.handle_message(message)
# end if
except IndexError as ex:
Expand All @@ -86,29 +82,34 @@ async def on_message(self, message):
# end try
# end def

async def send_public_text(self, message, text):
async with message.channel.typing():
await message.channel.send(text + (" <@%s>" % str(message.author.id)))
# end def

async def handle_message(self, message):
if self.is_closed():
return
# end if
try:
uid = str(message.author.id)
logger.info("Processing message from %s", message.author.name)
if uid not in self.handlers:
self.handlers[uid] = MessageHandler(self)
discriminator = message.author.discriminator
logger.info("Processing message from %s#%s", message.author.name, discriminator)
if uid in self.handlers:
self.handlers[uid].process(message)
elif len(self.handlers) > C.max_active_handles or discriminator not in C.vip_users_ids:
await message.author.trigger_typing()
await message.author.send(
"Sorry! I am too busy processing requests of other users.\n"
"Please knock me here later!"
)
else:
self.handlers[uid] = MessageHandler(uid, self)
logger.info("New handler for %s#%s [%s]", message.author.name, discriminator, uid)
await message.author.trigger_typing()
await message.author.send(
'-' * 25 + '\n' +
('Hello %s\n' % message.author.name) +
f'Hello <@{uid}>\n' +
'-' * 25 + '\n'
)
logger.info("New handler for %s", message.author.name)
self.handlers[uid].process(message)
# end if
self.handlers[uid].process(message)
except Exception as err:
except Exception:
logger.exception('While handling this message: %s', message)
# end try
# end def
Expand All @@ -118,7 +119,7 @@ def cleanup_handlers(self):
cur_time = datetime.now()
for handler in self.handlers.values():
last_time = getattr(handler, 'last_activity', cur_time)
if (cur_time - last_time).days > 1:
if (cur_time - last_time).seconds > C.session_retain_time_in_seconds:
handler.destroy()
# end if
# end for
Expand Down
Loading