erepublik-ebot/ebot/__main__.py
2022-07-04 10:44:45 +03:00

161 lines
5.3 KiB
Python

""" eBot
Copyright (C) 2022 Eriks K
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging
import os
import signal
import sys
import time
import warnings
from typing import Dict, List, Union
import httpx
import sentry_sdk
from erepublik import utils
from erepublik._logging import ErepublikFileHandler, ErepublikFormatter, ErepublikLogConsoleHandler
from ebot import __version__
from ebot.helpers import BotRestart, BotStop, EbotErrorHttpHandler
from ebot.main import main
from ebot.utils import parse_config, pid_alive
json = utils.json
logger = logging.getLogger("Player")
VERSION = __version__
EVERSION = utils.VERSION
sentry_sdk.init(
"https://8ae666ac1cc344b3ab4a8ba6d3d1c420@o334571.ingest.sentry.io/4686978",
release=f"{VERSION} (using eRepublik {EVERSION})",
with_locals=True,
auto_enabling_integrations=False,
)
sentry_sdk.set_tag("eRepublik", EVERSION)
sentry_sdk.set_tag("eBot", VERSION)
formatter = ErepublikFormatter()
file_handler = ErepublikFileHandler()
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
error_handler = EbotErrorHttpHandler()
error_handler.setFormatter(formatter)
error_handler.setLevel(logging.ERROR)
logger.addHandler(error_handler)
logger.setLevel(logging.INFO)
INTERACTIVE = True
CONFIG: Dict[str, Union[str, int, bool, List[str], Dict[str, Dict[str, Union[bool, List[int]]]]]] = {}
def def_sig(a, b): # noqa
raise BotStop()
signal.signal(signal.SIGINT, def_sig)
signal.signal(signal.SIGTERM, def_sig)
signal.signal(signal.SIGABRT, def_sig)
if sys.platform.startswith("win"):
signal.signal(signal.SIGBREAK, def_sig)
else:
signal.signal(signal.SIGUSR1, def_sig)
signal.signal(signal.SIGHUP, def_sig)
if __name__ == "__main__":
os.makedirs("log", exist_ok=True)
if not sys.version_info >= (3, 8):
raise AssertionError(
"This script requires Python version 3.8 and higher\n"
"But Your version is v{}.{}.{}".format(*sys.version_info)
)
try:
# os.chdir(os.path.dirname(os.path.realpath(__file__)))
if os.path.isfile("bot.pid"):
with open("bot.pid") as f:
old_pid = f.read()
if old_pid.isnumeric():
old_pid = int(old_pid)
try:
os.kill(old_pid, 15)
except: # noqa
pass
while pid_alive(old_pid) and not sys.platform.startswith("win"):
time.sleep(1)
with open("bot.pid", "w") as f:
f.write(f"{os.getpid()}")
config_location = "config.json"
if os.path.isfile(config_location):
with open(config_location, "r") as f:
CONFIG.update(json.load(f))
logger.info("Config file found. Checking...")
should_save = parse_config(CONFIG)
else:
try:
should_save = parse_config(CONFIG)
except EOFError:
logger.error("Unable to read input for config file!\nTerminating...")
raise BotStop()
if should_save:
with open(config_location, "w") as f:
json.dump(CONFIG, f, indent=True)
if CONFIG["interactive"]:
console_handler = ErepublikLogConsoleHandler()
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
if CONFIG.get("debug"):
logger.setLevel(logging.DEBUG)
for handler in logger.handlers:
if isinstance(handler, (ErepublikLogConsoleHandler, ErepublikFileHandler)):
handler.setLevel(logging.DEBUG)
warnings.simplefilter("default") # Change the filter in this process
os.environ["PYTHONWARNINGS"] = "default" # Also affect subprocesses
logger.info("To quit press [ctrl] + [c]")
logger.info(f"Version: {VERSION} (elib {EVERSION})")
while True:
try:
main(CONFIG)
except BotRestart:
continue
logger.error("Restarting after 1h")
try:
utils.interactive_sleep(60 * 60)
except (OSError, EOFError):
utils.silent_sleep(60 * 60)
except BotStop:
logger.info("Everything is done! Hope You enjoyed!")
utils.silent_sleep(1)
except httpx.ConnectError:
logger.critical("Connection Error! Can't continue, will quit!", exc_info=True)
utils.silent_sleep(1)
except Exception as e: # noqa
logger.critical(
f"Fatal error. {e}",
exc_info=True,
stack_info=True,
extra=dict(ebot_version=VERSION, erep_version=EVERSION),
)
sentry_sdk.capture_exception(e)
finally:
if os.path.isfile("bot.pid"):
os.unlink("bot.pid")
sys.exit(0)