示例#1
0
 def __init__(self, websocket_client_entry: WebsocketConnectedClientEntry, worker_id: str,
              worker_instance_ref: Optional[AbstractWorker],
              command_timeout: float):
     # Throws ValueError if unable to connect!
     # catch in code using this class
     self.logger = get_origin_logger(get_logger(LoggerEnums.websocket), origin=worker_id)
     self.worker_instance_ref: Optional[AbstractWorker] = worker_instance_ref
     self.websocket_client_entry = websocket_client_entry
     self.__command_timeout: float = command_timeout
     self.__sendMutex = Lock()
示例#2
0
 def __init__(self, origin, application_args,
              mitm_mapper_parent: MitmMapper):
     self._id = origin
     self._logger = get_logger(LoggerEnums.mitm, name=self._id)
     self.__application_args = application_args
     self._level: int = 0
     self.__stats_collected: dict = {}
     self._stats_collector_start = True
     self._last_processed_timestamp = 0
     self._generate_stats = application_args.game_stats
     self.__mapping_mutex = Lock()
     self.__mitm_mapper_parent: MitmMapper = mitm_mapper_parent
     self._poke_stop_visits: int = 0
示例#3
0
    def __init__(self, num: int, form: int, atk: int, de: int, sta: int,
                 evolutions: list, ranklength: int):
        super(Pokemon, self).__init__()
        self.num = num
        self.form = form
        self.atk = atk
        self.de = de
        self.sta = sta
        self.evolutions = evolutions
        self.ranklength = ranklength
        self.logger = get_logger(LoggerEnums.plugin)

        self.products = {}
        self.greatPerfect, self.greatLowest = self._spreads(1500)
        self.ultraPerfect, self.ultraLowest = self._spreads(2500)
        self.logger.debug("Pokemon {}, form {} initialized".format(
            self.num, self.form))
示例#4
0
 def __init__(self, origin: str, worker_thread: Optional[Thread],
              worker_instance: Optional[AbstractWorker],
              websocket_client_connection: Optional[
                  websockets.WebSocketClientProtocol],
              loop_running: asyncio.AbstractEventLoop):
     self.origin: str = origin
     self.worker_thread: Optional[Thread] = worker_thread
     self.worker_instance: Optional[AbstractWorker] = worker_instance
     self.websocket_client_connection: Optional[
         websockets.WebSocketClientProtocol] = websocket_client_connection
     self.loop_running: asyncio.AbstractEventLoop = loop_running
     self.fail_counter: int = 0
     self.received_messages: Dict[int, ReceivedMessageEntry] = {}
     self.received_mutex: asyncio.Lock = asyncio.Lock()
     self.message_id_counter: int = 0
     self.message_id_mutex: asyncio.Lock = asyncio.Lock()
     self.logger = get_origin_logger(get_logger(LoggerEnums.websocket),
                                     origin=origin)
     # store a timestamp in order to cleanup (soft-states)
     self.last_message_received_at: float = 0
示例#5
0
import json
from typing import Optional, Dict, List, Tuple
from .resource import Resource
from ..dm_exceptions import UnknownIdentifier
from mapadroid.geofence.geofenceHelper import GeofenceHelper
from mapadroid.utils.logging import get_logger, LoggerEnums

logger = get_logger(LoggerEnums.data_manager)


class GeoFence(Resource):
    table = 'settings_geofence'
    name_field = 'name'
    primary_key = 'geofence_id'
    search_field = 'name'
    configuration = {
        "fields": {
            "name": {
                "settings": {
                    "type": "text",
                    "require": True,
                    "description": "Name of the geofence",
                    "expected": str
                }
            },
            "fence_type": {
                "settings": {
                    "type": "option",
                    "require": True,
                    "values": ['polygon'],
                    "description": "Type of the geofence",
示例#6
0
import json
import time
from typing import List, Optional

import requests

from mapadroid.db.DbWebhookReader import DbWebhookReader
from mapadroid.geofence.geofenceHelper import GeofenceHelper
from mapadroid.utils import MappingManager
from mapadroid.utils.gamemechanicutil import calculate_mon_level
from mapadroid.utils.logging import LoggerEnums, get_logger
from mapadroid.utils.madGlobals import terminate_mad
from mapadroid.utils.questGen import generate_quest
from mapadroid.utils.s2Helper import S2Helper

logger = get_logger(LoggerEnums.webhook)


class WebhookWorker:
    __IV_MON: List[int] = List[int]
    __excluded_areas = {}

    def __init__(self, args, data_manager, mapping_manager: MappingManager,
                 rarity, db_webhook_reader: DbWebhookReader):
        self.__worker_interval_sec = 10
        self.__args = args
        self.__data_manager = data_manager
        self.__db_wrapper = self.__data_manager.dbc
        self._db_reader = db_webhook_reader
        self.__rarity = rarity
        self.__last_check = int(time.time())
示例#7
0
    def perform_operation(self):

        # do not change this part ▽▽▽▽▽▽▽▽▽▽▽▽▽▽▽
        if not self._pluginconfig.getboolean(
                "plugin", "active", fallback=False):
            return False
        self._mad['madmin'].register_plugin(self._plugin)
        # do not change this part △△△△△△△△△△△△△△△

        # load your stuff now
        self._logger = get_logger(LoggerEnums.plugin, 'madqtt')

        # do not start plugin when in config mode
        if self._mad['args'].config_mode == True:
            self._logger.warning('not active while in configmode')
            return False

        self._logger.info('plugin is running')
        self._logger.debug('loading pluginconfig')
        self._config = {
            'topic': self._pluginconfig.get('mqtt', 'topic',
                                            fallback='madqtt'),
            'broker': {
                'host':
                self._pluginconfig.get('broker', 'host', fallback='localhost'),
                'port':
                int(self._pluginconfig.get('broker', 'port', fallback=1883)),
                'user':
                self._pluginconfig.get('broker', 'user', fallback=None),
                'pass':
                self._pluginconfig.get('broker', 'pass', fallback=None)
            },
            'timeouts': {
                'mitm':
                int(self._pluginconfig.get('timeouts', 'mitm', fallback=600)),
                'proto':
                int(self._pluginconfig.get('timeouts', 'proto', fallback=600)),
                'restart':
                int(self._pluginconfig.get('timeouts', 'restart',
                                           fallback=900)),
                'check':
                int(self._pluginconfig.get('timeouts', 'check', fallback=60))
            }
        }

        self._devices = []
        for item in self._mad['db_wrapper'].download_status():
            device = {}
            device['origin'] = item['name']
            device['state'] = None
            device['restart-time'] = int(time.time())
            self._devices.append(device)
        self.refresh_devices()

        mqttListener = Thread(name='MqttListener', target=self.mqttListener)
        mqttListener.daemon = True
        mqttListener.start()

        madqttRunner = Thread(name='MadqttRunner', target=self.madqttRunner)
        madqttRunner.daemon = True
        madqttRunner.start()

        return True
示例#8
0
import glob
import json
import os
import re
import time
from datetime import datetime, timedelta
from enum import Enum
from multiprocessing import Queue, Event
from queue import Empty
from threading import RLock, Thread
from mapadroid.utils.logging import get_logger, LoggerEnums
from mapadroid.mad_apk import AbstractAPKStorage, is_newer_version, APKType, file_generator, lookup_arch_enum, \
    APKPackage, APKArch, supported_pogo_version, MADPackages

logger = get_logger(LoggerEnums.utils)


class JobType(Enum):
    INSTALLATION = 0
    REBOOT = 1
    RESTART = 2
    STOP = 3
    PASSTHROUGH = 4
    START = 5
    SMART_UPDATE = 6
    CHAIN = 99


class JobReturn(Enum):
    UNKNOWN = 0
    SUCCESS = 1
from mapadroid.utils.logging import get_logger, LoggerEnums

logger = get_logger(LoggerEnums.routemanager)


def route_calc_impl(coords, route_name, num_processes=1):
    with logger.contextualize(origin=route_name):
        less_coords_array = []
        for i in range(len(coords)):
            less_coords_array.append(
                [coords[i][0].item(), coords[i][1].item()])

        length, path = tsp(less_coords_array)
        logger.info("Found {} long solution: ", length)

    return path


def tsp(data):
    logger.info("building the graph for a route of {}", len(data))
    # build a graph
    graph_data = build_graph(data)

    # build a minimum spanning tree
    logger.info("Building a min span tree..")
    min_span_tree = minimum_spanning_tree(graph_data)

    # find odd vertexes
    logger.info("Finding odd vertexes...")
    odd_vertexes = find_odd_vertexes(min_span_tree)
示例#10
0
from abc import ABC, abstractmethod

from mapadroid.utils.logging import LoggerEnums, get_logger
from mapadroid.websocket.AbstractCommunicator import AbstractCommunicator

logger = get_logger(LoggerEnums.worker)


class AbstractWorker(ABC):
    def __init__(self, origin: str, communicator: AbstractCommunicator):
        self.logger = get_logger(LoggerEnums.worker, identifier=str(origin))
        self._origin: str = origin
        self._communicator: AbstractCommunicator = communicator

    @abstractmethod
    def start_worker(self):
        pass

    @abstractmethod
    def stop_worker(self):
        pass

    @abstractmethod
    def is_stopping(self) -> bool:
        pass

    @abstractmethod
    def set_geofix_sleeptime(self, sleeptime: int) -> bool:
        pass

    @property
示例#11
0
from mapadroid.utils.walkerArgs import parse_args
from mapadroid.websocket.WebsocketServer import WebsocketServer
from mapadroid.utils.updater import DeviceUpdater
from mapadroid.data_manager import DataManager
from mapadroid.ocr.pogoWindows import PogoWindows
from mapadroid.webhook.webhookworker import WebhookWorker
from mapadroid.mad_apk import get_storage_obj, StorageSyncManager, AbstractAPKStorage
from mapadroid.madmin.madmin import MADmin
from mapadroid.utils.pluginBase import PluginCollection
import unittest
from mapadroid.utils.logging import init_logging, get_logger, LoggerEnums

args = parse_args()
os.environ['LANGUAGE'] = args.language
init_logging(args)
logger = get_logger(LoggerEnums.system)


# Patch to make exceptions in threads cause an exception.
def install_thread_excepthook():
    """
    Workaround for sys.excepthook thread bug
    (https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470).
    Call once from __main__ before creating any threads.
    If using psyco, call psycho.cannotcompile(threading.Thread.run)
    since this replaces a new-style class method.
    """
    run_thread_old = Thread.run
    run_process_old = Process.run

    def run_thread(*args, **kwargs):
示例#12
0
 def __setstate__(self, d):
     if 'logger' in d:
         d['logger'] = get_logger(LoggerEnums.plugin)
     self.__dict__.update(d)
     self.logger.debug4("{} object loaded from pickle file".format(
         type(self).__name__))
示例#13
0
    def __init__(self, mad):
        super().__init__(mad)

        self._rootdir = os.path.dirname(os.path.abspath(__file__))
        sys.path.append(self._rootdir)

        self._mad = mad
        self.db = self._mad["db_wrapper"]
        self.logger = get_logger(LoggerEnums.plugin)
        self.wh = self._mad["webhook_worker"]

        self.statusname = self._mad["args"].status_name
        self._pluginconfig.read(self._rootdir + "/plugin.ini")
        self._versionconfig.read(self._rootdir + "/version.mpl")
        self.author = self._versionconfig.get("plugin",
                                              "author",
                                              fallback="unknown")
        self.url = self._versionconfig.get("plugin",
                                           "url",
                                           fallback="https://www.maddev.eu")
        self.description = self._versionconfig.get("plugin",
                                                   "description",
                                                   fallback="unknown")
        self.version = self._versionconfig.get("plugin",
                                               "version",
                                               fallback="unknown")
        self.pluginname = self._versionconfig.get(
            "plugin", "pluginname", fallback="https://www.maddev.eu")
        self.staticpath = self._rootdir + "/static/"
        self.templatepath = self._rootdir + "/template/"

        # plugin specific
        if self.statusname in self._pluginconfig:
            self.logger.success("found statusname specific config!")
            settings = self.statusname
        else:
            settings = "settings"
        self.target = self._pluginconfig.get(settings, "target", fallback=None)
        self.interval = self._pluginconfig.getint(settings,
                                                  "interval",
                                                  fallback=30)
        self.ranklength = self._pluginconfig.getint(settings,
                                                    "ranklength",
                                                    fallback=100)

        self._routes = [
            ("/poraclePvpHelper_manual", self.manual),
        ]

        self._hotlink = [
            ("poraclePvpHelper Manual", "poraclePvpHelper_manual",
             "poraclePvpHelper Manual"),
        ]

        if self._pluginconfig.getboolean("plugin", "active", fallback=False):
            self._plugin = Blueprint(str(self.pluginname),
                                     __name__,
                                     static_folder=self.staticpath,
                                     template_folder=self.templatepath)

            for route, view_func in self._routes:
                self._plugin.add_url_rule(route,
                                          route.replace("/", ""),
                                          view_func=view_func)

            for name, link, description in self._hotlink:
                self._mad['madmin'].add_plugin_hotlink(
                    name, self._plugin.name + "." + link.replace("/", ""),
                    self.pluginname, self.description, self.author, self.url,
                    description, self.version)
示例#14
0
    def __init__(self, ranklength):
        super(PokemonData, self).__init__()
        self.logger = get_logger(LoggerEnums.plugin)
        self.logger.warning(
            "initializing PokemonData, this will take a while ...")
        self.ranklength = ranklength
        self.data = {}
        self.PokemonId = PokemonId
        self.Form = Form
        gmfile = requests.get(
            "https://raw.githubusercontent.com/pokemongo-dev-contrib/pokemongo-game-master/"
            "master/versions/1595879989869/GAME_MASTER.json")
        templates = gmfile.json()["itemTemplate"]

        i = 0
        for template in templates:
            if (template["templateId"]
                    and template["templateId"].startswith("V")
                    and not template["templateId"].startswith("VS")
                    and "POKEMON" in template["templateId"]):
                if i > 0 and i % 50 == 0:
                    self.logger.success(
                        "processed {} pokemon templates ...".format(i))
                i += 1
                try:
                    moninfo = template["pokemon"]
                    stats = moninfo["stats"]
                    evolution = []
                    try:
                        for evo in moninfo["evolutionBranch"]:
                            evoId = self.PokemonId[evo["evolution"]].value
                            try:
                                formId = self.Form[evo["form"]].value
                            except Exception:
                                formId = self.Form["{}_NORMAL".format(
                                    evo["evolution"])].value
                            evolution.append("{}-{}".format(evoId, formId))
                    except KeyError:
                        evolution = []
                    try:
                        form = self.Form[moninfo["form"]].value
                    except KeyError:
                        # handle Nidoran ...
                        name = moninfo["uniqueId"].replace("_FEMALE",
                                                           "").replace(
                                                               "_MALE", "")
                        form = self.Form["{}_NORMAL".format(name)].value
                    mon = Pokemon(self.PokemonId[moninfo["uniqueId"]].value,
                                  form, stats["baseAttack"],
                                  stats["baseDefense"], stats["baseStamina"],
                                  evolution, self.ranklength)
                    self.add(mon)
                    self.logger.debug("processed template {}".format(
                        template["templateId"]))
                except Exception as e:
                    self.logger.warning(
                        "Exception processing template {}: {} (this is probably ok)"
                        .format(template["templateId"], e))
                    continue
            else:
                continue
示例#15
0
from distutils.version import LooseVersion
from flask import Response, stream_with_context
import json
import requests
from typing import Tuple, Union, Generator
from .apk_enums import APKArch, APKType, APKPackage
from .abstract_apk_storage import AbstractAPKStorage
from .custom_types import MADapks, MADPackage, MADPackages
from mapadroid.utils.global_variables import CHUNK_MAX_SIZE, ADDRESSES_GITHUB
from mapadroid.utils.logging import get_logger, LoggerEnums

logger = get_logger(LoggerEnums.package_mgr)


def convert_to_backend(req_type: str,
                       req_arch: str) -> Tuple[APKType, APKArch]:
    """ Converts front-end input into backend enums

    Args:
        req_type (str): User-input for APKType
        req_arch (str): User-input for APKArch

    Returns (tuple):
        Returns a tuple of (APKType, APKArch) enums
    """
    backend_type: APKType = None
    backend_arch: APKArch = None
    try:
        if req_type is not None:
            backend_type = lookup_apk_enum(req_type)
    except (TypeError, ValueError):
示例#16
0
from mapadroid.data_manager import DataManager
from mapadroid.utils.logging import InterceptHandler, get_logger, LoggerEnums, get_origin_logger
import logging
from mapadroid.websocket.AbstractCommunicator import AbstractCommunicator
from mapadroid.websocket.WebsocketConnectedClientEntry import WebsocketConnectedClientEntry
from mapadroid.websocket.communicator import Communicator
from mapadroid.worker.AbstractWorker import AbstractWorker
from mapadroid.worker.WorkerFactory import WorkerFactory

logging.getLogger('websockets.server').setLevel(logging.DEBUG)
logging.getLogger('websockets.protocol').setLevel(logging.DEBUG)
logging.getLogger('websockets.server').addHandler(InterceptHandler(log_section=LoggerEnums.websocket))
logging.getLogger('websockets.protocol').addHandler(InterceptHandler(log_section=LoggerEnums.websocket))


logger = get_logger(LoggerEnums.websocket)


class WebsocketServer(object):
    def __init__(self, args, mitm_mapper: MitmMapper, db_wrapper: DbWrapper, mapping_manager: MappingManager,
                 pogo_window_manager: PogoWindows, data_manager: DataManager, event, enable_configmode: bool = False):
        self.__args = args
        self.__db_wrapper: DbWrapper = db_wrapper
        self.__mapping_manager: MappingManager = mapping_manager
        self.__pogo_window_manager: PogoWindows = pogo_window_manager
        self.__data_manager: DataManager = data_manager
        self.__mitm_mapper: MitmMapper = mitm_mapper
        self.__enable_configmode: bool = enable_configmode

        # Event to signal that the server is to be stopped. Used to not accept new connections for example
        self.__stop_server: Event = Event()
示例#17
0
from io import BytesIO
from threading import RLock
from typing import NoReturn, Optional

from mapadroid.utils import global_variables
from mapadroid.utils.logging import LoggerEnums, get_logger

from .abstract_apk_storage import AbstractAPKStorage
from .apk_enums import APKArch, APKType
from .custom_types import MADPackage, MADPackages
from .utils import generate_filename

logger = get_logger(LoggerEnums.storage)


class APKStorageDatabase(AbstractAPKStorage):
    """ Storage interface for using the database.  Implements AbstractAPKStorage for ease-of-use between different
        storage mediums

    Args:
        dbc: Database wrapper

    Attributes:
        dbc: Database wrapper
        file_lock (RLock): RLock to allow updates to be thread-safe
    """
    def __init__(self, dbc, token):
        logger.debug('Initializing Database storage')
        super(APKStorageDatabase, self).__init__(token)
        self.file_lock: RLock = RLock()
        self.dbc = dbc
示例#18
0
 def __init__(self, origin: str, communicator: AbstractCommunicator):
     self.logger = get_logger(LoggerEnums.worker, identifier=str(origin))
     self._origin: str = origin
     self._communicator: AbstractCommunicator = communicator
示例#19
0
import os

from mapadroid.mad_apk import APKArch, APKType
from mapadroid.tests.apk_base import APKTestBase
from mapadroid.tests.test_utils import filepath_rgc, get_rgc_bytes
from mapadroid.utils.logging import LoggerEnums, get_logger

logger = get_logger(LoggerEnums.system)


class EndpointTests(APKTestBase):
    def web_upload_rgc(self, method: str = 'octet'):
        response = None
        uri = '/api/mad_apk/{}/{}'.format(APKType.rgc.name, APKArch.noarch.name)
        with open(filepath_rgc, 'rb') as fh:
            filename = filepath_rgc.rsplit(os.sep, 1)[1]
            if method == 'octet':
                headers = {
                    'Content-Type': 'application/octet-stream',
                    'filename': filename
                }
                data = fh
                response = self.api.post(uri, data=data, headers=headers)
            else:
                files = {'file': (filename, fh)}
                response = self.api.post(uri, data={'filename': filename}, files=files)
        return response

    def test_upload(self):
        response = self.web_upload_rgc()
        self.assertTrue(response.status_code == 201)
示例#20
0
import datetime
import json
import os
import time
from math import floor
from multiprocessing import Lock
from pathlib import Path
from mapadroid.mitm_receiver import MitmMapper
from mapadroid.utils.logging import get_logger, LoggerEnums, get_origin_logger

logger = get_logger(LoggerEnums.mitm)


class PlayerStats(object):
    def __init__(self, origin, application_args,
                 mitm_mapper_parent: MitmMapper):
        self._id = origin
        self._logger = get_logger(LoggerEnums.mitm, name=self._id)
        self.__application_args = application_args
        self._level: int = 0
        self.__stats_collected: dict = {}
        self._stats_collector_start = True
        self._last_processed_timestamp = 0
        self._generate_stats = application_args.game_stats
        self.__mapping_mutex = Lock()
        self.__mitm_mapper_parent: MitmMapper = mitm_mapper_parent
        self._poke_stop_visits: int = 0

    def set_level(self, level: int):
        if self._level != level:
            self._logger.info('set level {}', level)
示例#21
0
import math
import os
import os.path
import time
from multiprocessing.pool import ThreadPool
from typing import Optional, List, Tuple
import cv2
import numpy as np
import pytesseract
from PIL import Image
from pytesseract import Output
from mapadroid.ocr.matching_trash import trash_image_matching
from mapadroid.ocr.screen_type import ScreenType
from mapadroid.utils.logging import get_logger, LoggerEnums, get_origin_logger

logger = get_logger(LoggerEnums.ocr)


class PogoWindows:
    def __init__(self, temp_dir_path, thread_count: int):
        if not os.path.exists(temp_dir_path):
            os.makedirs(temp_dir_path)
            logger.info('PogoWindows: Temp directory created')
        self.temp_dir_path = temp_dir_path
        self.__thread_pool = ThreadPool(processes=thread_count)

        # screendetection
        self._ScreenType: dict = {}
        self._ScreenType[1]: list = [
            'Geburtdatum', 'birth.', 'naissance.', 'date'
        ]
示例#22
0
from mapadroid.utils.logging import LoggerEnums, get_logger

from ._patch_base import PatchBase

logger = get_logger(LoggerEnums.patcher)


class Patch(PatchBase):
    name = 'Remove inventory_clear_item_amount_tap_duration'
    descr = 'Removes the setting defining how long the + button would be held during item deletion'

    def _execute(self):
        if self._schema_updater.check_column_exists(
                'settings_devicepool',
                'inventory_clear_item_amount_tap_duration'):
            sql = "ALTER TABLE settings_devicepool\n" \
                  "DROP COLUMN inventory_clear_item_amount_tap_duration;"
            self._db.execute(sql, raise_exc=False, suppress_log=True)
        if self._schema_updater.check_column_exists(
                'settings_device', 'inventory_clear_item_amount_tap_duration'):
            sql = "ALTER TABLE settings_device\n" \
                  "DROP COLUMN inventory_clear_item_amount_tap_duration;"
            self._db.execute(sql, raise_exc=False, suppress_log=True)
示例#23
0
import os
import re
from flask import (render_template, request, redirect, url_for, Response)
from flask_caching import Cache
from typing import List, Tuple
from mapadroid.data_manager import DataManagerException
from mapadroid.madmin.functions import auth_required
from mapadroid.utils.MappingManager import MappingManager
from mapadroid.utils.adb import ADBConnect
from mapadroid.utils.language import i8ln, open_json_file
from mapadroid.data_manager.dm_exceptions import (ModeNotSpecified,
                                                  ModeUnknown)
from mapadroid.data_manager.modules.pogoauth import PogoAuth
from mapadroid.utils.logging import get_logger, LoggerEnums

logger = get_logger(LoggerEnums.madmin)
cache = Cache(config={'CACHE_TYPE': 'simple'})


class MADminConfig(object):
    def __init__(self, db, args, logger, app, mapping_manager: MappingManager,
                 data_manager):
        self._db = db
        self._args = args
        if self._args.madmin_time == "12":
            self._datetimeformat = '%Y-%m-%d %I:%M:%S %p'
        else:
            self._datetimeformat = '%Y-%m-%d %H:%M:%S'
        self._adb_connect = ADBConnect(self._args)
        self._ws_connected_phones: list = []
        self._logger = logger
示例#24
0
import sys
from mapadroid.db.PooledQueryExecutor import PooledQueryExecutor
from . import madmin_conversion
from mapadroid.utils.logging import get_logger, LoggerEnums

logger = get_logger(LoggerEnums.database)


class DbSchemaUpdater:
    """
    Covers methods for database schema updates/additions. It also contains a few
    migrated classes and configurations for schema changes which have been added
    in the past.
    TODO: This needs more refactoring and alingment with `utils/version.py`, and
    it should include a way to create all RocketmapDB tables (basically migrate
    what `scripts/databasesetup.py` does with `scripts/SQL/rocketmap.sql`).
    Also, all SQL configuration should be pulled out.
    """

    table_adds = [
        # Spawn tables
        {
            "table":
            "trs_spawn",
            "spec":
            ("`spawnpoint` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL, "
             "`latitude` double NOT NULL, "
             "`longitude` double NOT NULL, "
             "`spawndef` int(11) NOT NULL DEFAULT 240, "
             "`earliest_unseen` int(6) NOT NULL, "
             "`last_scanned` datetime DEFAULT NULL, "
from mapadroid.madmin.functions import auth_required
import os
import sys
import time
import json
import logging
from threading import Thread
import pickle
import requests
import configparser
from mapadroid.utils.logging import get_logger, LoggerEnums, get_bind_name
sys.path.append(
    os.path.join(os.path.dirname(os.path.abspath(__file__)), "PogoPvpData"))
from pogopvpdata import PokemonData  # noqa: E402

logger = get_logger(LoggerEnums.plugin)


class PoracleInterceptHandler(logging.Handler):
    def __init__(self, *args, **kwargs):
        try:
            self.log_section = kwargs['log_section']
            del kwargs['log_section']
        except KeyError:
            self.log_section = LoggerEnums.unknown
        try:
            self.log_identifier = kwargs['log_identifier']
            del kwargs['log_identifier']
        except KeyError:
            self.log_identifier = LoggerEnums.unknown
        super().__init__(*args, **kwargs)