Esempio n. 1
0
    async def __aenter__(self):
        while any([
                getattr(context, varname).locked
                for context, varname in self.vars
        ]):
            for context, varname in self.vars:
                var = getattr(context, varname)
                if var.locked:
                    # WARN_MSG("Variable %s locked, transaction %s waiting for unlock..." % (varname, self))
                    try:
                        await asyncio.wait_for(var.waitforunlock(), 2)
                    except asyncio.TimeoutError:
                        ERROR_MSG(
                            "Variable %s locked by %s more for 5 seconds! Check your code for nested transactions with the same variables"
                            % (varname, var.locker),
                            depth=1)
                        # raise TransactionError("Variables locked too long")

        INFO_MSG("Entered %s with %s" % (self, (self.vars, )), depth=1)

        for context, varname in self.vars:
            var = getattr(context, varname)
            await var.lock(self)

        self.savepoint()
        return Replication.__enter__(self)
Esempio n. 2
0
    async def enqueue_player(self, session):
        """ Добавить в очередь игрока
            Запускает матч, если список игроков заполнен
            @param session: сессия игрока
            @param character_id: ИД персонажа
        """
        INFO_MSG(f"Enqueueing player {session}")
        request_result = EReqGameResponse.Wait
        if self.fulfilled:
            WARN_MSG(f"Can't enqueue {session}. Game is fulfilled")
            return EReqGameResponse.Denied
        self.players[session] = GamePlayerInfo(session=session)
        session.ue4client.add_lost_callback(
            partial(self.on_client_dropped, session))
        # Начать выполнение матча. Можно только если команда заполнена и матч на данный момент не выполняется
        if self.fulfilled and not self.performing:
            asyncio.Task(self.perform())

        # Допустить игрока (дополнительного игрока, для восполнения) в матч (можно только если уже начат)
        if self.started:
            await self.accept_player_to_started_game(session,
                                                     self.players[session])
            request_result = EReqGameResponse.Success

        return request_result
Esempio n. 3
0
    async def __ainit__(self,
                        match_making,
                        id=0,
                        ip="0.0.0.0",
                        port=0,
                        dedicated_server=None,
                        players=None,
                        map_name=None,
                        started=False,
                        max_players=0,
                        teams_assigned=False):
        await GameBase.__ainit__(self,
                                 match_making,
                                 id,
                                 max_players,
                                 started=started,
                                 players=players,
                                 teams_assigned=teams_assigned)
        await Entity.__ainit__(self)

        self.ip = ip  # ip dedicated server'а
        self.port = port  # порт вступления в dedicated server
        self.dedicated_server: 'UE4App' = dedicated_server  # мейлбокс dedicated server'а
        self.map_name = map_name  # имя выбранной карты
        self.state = EMatchState.Idle  # состояние матча
        self.on_game_done = None
        self.empty_match_timer_handle = None
        INFO_MSG(f"Created and prepared new match {self}")
Esempio n. 4
0
    async def perform(self):
        """ Запуск текущего матча """
        INFO_MSG(f"Performing match {self}")
        if self.dedicated_server:            return \
ERROR_MSG(f"The match {self} already performing")
        self.performing = True

        self.update_state(EMatchState.Preparing)

        try:
            await self.wake_up_dedicated_server_for_match()
        except WakeupError:
            self.rollback()
            raise MatchMakingError(
                "Unable to wakeup dedicated server for match")

        await self.dedicated_server.SetupGame(self.max_players)

        self.assign_teams()
        self.started = True

        for player_info in self.players.values():
            await self.register_player_info(player_info)

        self.update_state(EMatchState.InGame)
        self.dedicated_server.MatchStart(self.id)

        self.handle_start()

        for session, player_info in self.players.items():
            player_info.join(self.ip, self.port)
Esempio n. 5
0
 async def async_set_value(self, value):
     INFO_MSG("saving", self.owner_dbid, self.owner_class_name, self.owner_property_name, self.prop_info.prop_type.get_type_name())
     from Core.BaseEntity import BaseEntity
     if isinstance(value, BaseEntity):
         from Core.LocalDatatypes import int32
         await self.db.UpdateEntityVariable(self.owner_dbid, self.owner_class_name, self.owner_property_name, 'int32', int32(value.dbid).serialize())
     else:
         await self.db.UpdateEntityVariable(self.owner_dbid, self.owner_class_name, self.owner_property_name, self.prop_info.prop_type.get_type_name(), value.serialize())
Esempio n. 6
0
 def done_game(self, game_id, winners, winner_team_id):
     """ Конец матча
         @param game_id: идентификатор игры
         @param winners: победители
     """
     INFO_MSG(f"Done game id={game_id}, winners={winners}, winner_team_id={winner_team_id}")
     for games in self.games.values():
         for game in games:
             INFO_MSG(f"game: {game}")
             if game.id == game_id:
                 asyncio.Task(game.done(winners, winner_team_id))
                 games.remove(game)
                 for player_session in game.players:
                     self.free_player(player_session)
                 break
             if game.is_subgame_id(game_id):
                 asyncio.Task(game.done_subgame(winners, winner_team_id))
                 break
Esempio n. 7
0
 def request_player_exit_from_game(self, session):
     """ Запрос выхода игрока из матча
         @param session: сессия игрока
     """
     INFO_MSG(f"{session}")
     for games in self.games.values():
         for game in games:
             if game.conditional_dequeue_player(session):
                 self.free_player(session)
Esempio n. 8
0
 def handle_empty_match(self):
     INFO_MSG(
         f"Closing and exiting game  {self} [second chance (todo)]")  # todo
     self.empty_match_timer_handle = None
     if not len(self.players):
         self.close_game()
         if self.dedicated_server.dedicated_server:
             asyncio.Task(self.dedicated_server.ExecuteCode("quit"))
         self.match_making.destroy_game(self)
Esempio n. 9
0
 async def __ainit__(self, dbid, username):
     await super().__ainit__(dbid)
     self.username = self.Username = username
     self.client = None
     self.checker_time = None
     self.access_token = ""
     self.login_date = datetime.datetime.now()
     self.currently_in_game = False
     INFO_MSG("Hi!")
Esempio n. 10
0
    async def subscribe_connection(self, endpoint_or_connection_or_mailbox):
        INFO_MSG("Subscribing")
        endpoint_or_connection = endpoint_or_connection_or_mailbox
        if isinstance(endpoint_or_connection_or_mailbox, Mailbox):
            endpoint_or_connection = endpoint_or_connection_or_mailbox.client_connection

        client_connection, _ = await self.get_connection_and_endpoint_with_lost_callback(
            endpoint_or_connection)
        self.clients_connections.append(client_connection)
Esempio n. 11
0
    def work(city,
             building_name: str,
             citizens_ids: List[int32],
             ability_type_name: str,
             amount: int = 1,
             **kwargs) -> WorkingResult:
        result = WorkingResult()
        if city.Citizens.locked or amount == 0:
            citizens_by_abilities = get_citizens_with_ability_names_by_ids_and_ability_type(
                city, citizens_ids, ability_type_name, building_name)
            for ability_name, citizens in citizens_by_abilities.items():
                ability_info = CitizenAbilities.get_by("Name", ability_name)
                for citizen in citizens:
                    current_experince = citizen.Abilities[ability_name]
                    multiplier = ability_info['ExperienceMultiplier']
                    ability_level = get_ability_level(current_experince,
                                                      multiplier)
                    leveled_ability_info = CitizenAbilitiesLeveling.get_by(
                        "Level", ability_level)
                    parameters = deepcopy(ability_info['BaseParameters'])
                    if leveled_ability_info:
                        for parameter_name in parameters.keys():
                            if parameter_name in ability_info[
                                    'BaseParameters']:
                                if isinstance(parameters[parameter_name],
                                              (int, float)):
                                    parameters[
                                        parameter_name] += leveled_ability_info[
                                            'Parameters'][
                                                parameter_name] * ability_info[
                                                    'LeveledParametersMultipliers'][
                                                        parameter_name]
                                else:
                                    if parameter_name in leveled_ability_info[
                                            'Parameters']:
                                        parameters[
                                            parameter_name] = leveled_ability_info[
                                                'Parameters'][parameter_name]

                    func = getattr(CityCitizens, ability_type_name, None)
                    if func is not None:
                        INFO_MSG(
                            f"Working {ability_type_name} in {building_name} with citizen {citizen}"
                        )
                        try:
                            func(result, **parameters, **kwargs)
                        except Exception as e:
                            ERROR_MSG(
                                f"Something went wrong in CityCitizens::{ability_type_name}"
                            )
                            print_exc()
                    else:
                        ERROR_MSG(f"Ability {ability_type_name} not released")
                    if amount > 0:
                        citizen.Abilities[ability_name] += amount
        return result
Esempio n. 12
0
 async def empty_database(self):
     INFO_MSG("Clear database")
     await self.driver.exec_raw("""  DROP TABLE IF EXISTS public.users;
                                     DROP TABLE IF EXISTS public.entities;
                                     DROP TABLE IF EXISTS public.classes;
                                     DROP TABLE IF EXISTS public.users_uncofirmed;
                                     DROP TABLE IF EXISTS public.types;
                                     DROP TABLE IF EXISTS public.statistics;
                                     --- DROP TABLE IF EXISTS public.storages;
                                """)
Esempio n. 13
0
    async def enqueue_player(self, session):
        result = await super().enqueue_player(session)

        if result != EReqGameResponse.Denied and not self.timeout_timer and len(
                self.players) >= SURVIVAL_MIN_PLAYERS:
            INFO_MSG("Timeout started")
            if not self.fulfilled and not self.performing and not self.started:
                self.timeout_timer = self.call_later(self.perform,
                                                     SURVIVAL_TIMEOUT)

        return result
Esempio n. 14
0
 async def get_connection_and_endpoint_with_lost_callback(
         self, endpoint_or_connection):
     INFO_MSG("endpoint_or_connection")
     if isinstance(endpoint_or_connection, TCPClient):
         endpoint = endpoint_or_connection.endpoint
         client_connection = endpoint_or_connection
         client_connection.add_lost_callback(self.on_connection_lost)
     else:
         endpoint = endpoint_or_connection
         client_connection = await self.service.create_client_connection(
             tuple(endpoint_or_connection), on_lost=self.on_connection_lost)
     return client_connection, endpoint
Esempio n. 15
0
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        do_not_raise_exc = True

        if exc_type is None:
            new_variables = TArray[FPropertyInfo]()
            for context, varname in self.vars:
                var = getattr(context, varname)
                info = FPropertyInfo(EntityDBID=context.dbid,
                                     EntityClass=context.__class__.__name__,
                                     PropertyName=var.property_name,
                                     PropertyTypeName=var.get_type_name(),
                                     SerializedValue=var.serialize())
                new_variables.append(info)
            success = await Globals.this_service.db.UpdateVariablesTransactionally(
                self.old_variables, new_variables)
            if success:
                self.unlock_all()
                INFO_MSG("%s done" % self, depth=1)
                Replication.__exit__(self, exc_type, exc_val, exc_tb)
            else:
                self.rollback("DB error")
                self.unlock_all()
                ERROR_MSG(
                    "%s failed, because values in database not actual. Variables rolled back"
                    % self,
                    depth=1)
                raise TransactionError("Variables changed outside transaction")
        elif exc_type == TransactionExitException:
            self.rollback("Interrupted")
            self.unlock_all()
            do_not_raise_exc = True
            WARN_MSG(
                "Transaction %s interrupted from code. Variables rolled back" %
                self,
                depth=1)
        else:
            self.rollback("Code error")
            self.unlock_all()
            do_not_raise_exc = False
            ERROR_MSG(
                "%s failed, because errors in code. Variables rolled back" %
                self,
                depth=1)

        # for context, varname in self.vars:
        #     var = getattr(context, varname)
        #     if var.locked:
        #         var.unlock()

        return do_not_raise_exc
Esempio n. 16
0
 async def UploadStorages(self):
     """ Загрузить хранилища """
     for storage in storage_list:
         with open("Configs/storage_%s.json" % storage.name.lower()) as f:
             try:
                 d = json.loads(f.read())
                 queries = list()
                 for entry in d:
                     s = [str(pg_str(v)) for v in entry.values()]
                     queries.append("""INSERT INTO "storage_{0}" ({1}) VALUES ({2});
                                    """.format(storage.name.lower(), ", ".join([f'"{key}"' for key in entry.keys()]), ", ".join([str(pg_str(v)) for v in entry.values()])) )
                 await self.driver.exec_raw(""" DELETE FROM storage_{0}; 
                                                {1}
                                            """.format(storage.name.lower(), "\n".join(queries)))
             except json.JSONDecodeError:
                 INFO_MSG("Storage:%s",storage)
Esempio n. 17
0
    def destroy_game(self, game_to_destroy):
        INFO_MSG(f"{game_to_destroy}")
        for games in self.games.values():
            for game in games:
                if game.is_subgame(game_to_destroy):
                    game.reset()
                    for player_session in game_to_destroy.players:
                        self.free_player(player_session)
                    return

            if game_to_destroy in games:
                games.remove(game_to_destroy)
                for player_session in game_to_destroy.players:
                    self.free_player(player_session)
                return
        WARN_MSG(f"Cannot destroy game {game_to_destroy}, not found")
Esempio n. 18
0
    def dequeue_player(self, session):
        """
        Убрать игрока
        @param session: сессия игрока
        @return:
        """
        # session.ue4client.RunConsoleCommand("disconnect")
        if self.dedicated_server:
            self.dedicated_server.UnregisterPlayer(session.access_token)
        super().dequeue_player(session)

        if not len(self.players):
            if self.empty_match_timer_handle:
                self.empty_match_timer_handle.cancel()
            INFO_MSG(f"Preparing to close and exit game {self}")
            self.empty_match_timer_handle = self.call_later(
                self.handle_empty_match, 120.0)
Esempio n. 19
0
 async def TellPID(self, connection, pid: int32):
     """
     Сообщить PID этому сервису
     @param pid: идентификатор процесса
     """
     if pid in self.processes and not self.processes[pid]['future'].done():
         INFO_MSG(
             f"{connection} ({self.processes[pid]['name']}) tells pid {pid} in {round(time() - self.processes[pid]['opened_at'], 6)} seconds"
         )
         self.processes[pid]['future'].set_result(
             await
             self.create_client_connection(self.processes[pid]['endpoint']))
     else:
         ERROR_MSG(
             "Failed to tell PID! "
             f"There are no processes runned with pid {pid} or this process already told PID."
             "Probably you run process which lanuched child process (be sure if this is UE4 dedicated server, "
             "check the right path, not a PROJECTNAME.exe in root dir)")
Esempio n. 20
0
 async def create_client_connection(self, endpoint, on_lost=None):
     INFO_MSG(f"{endpoint}")
     if endpoint not in self.tcp_server.clients:
         _, connection = await create_connection(
             endpoint, on_lost=on_lost
         )  #  await TCPClient(endpoint, ClientConnectionHandler, do_open_connection=True)
         if is_valid(connection):
             self.tcp_server.clients[endpoint] = connection
             connection.add_lost_callback(
                 partial(self.on_lost_client, endpoint))
         return connection
     else:
         self.tcp_server.clients[endpoint].add_lost_callback(on_lost)
     connection = self.tcp_server.clients[endpoint]
     connection.add_lost_callback(partial(self.on_lost_client, endpoint))
     if not is_valid(connection):
         del self.tcp_server.clients[endpoint]
     return connection
Esempio n. 21
0
    async def ConfirmUser(self, digest: FString) -> (Bool, FString):
        unconfirmeds = await self.driver.exec_raw(""" SELECT * FROM public.users_uncofirmed WHERE digest=%s; """, digest)

        for unconfirmed_user in unconfirmeds:
            id, digest = get_rows(unconfirmed_user, 2)

            users = await self.driver.exec_raw(""" SELECT unique_name FROM public.users WHERE id=%s; """, id)

            for user in users:
                await self.driver.exec_raw(""" UPDATE public.users 
                                               SET confirmed = TRUE 
                                               WHERE id=%s; 
                                               
                                               DELETE FROM users_uncofirmed WHERE id=%s; 
                                           """, id, id)
                username = user[0]
                INFO_MSG(f"User {username} confirmed")
                return True, username
            else:
                WARN_MSG(f"No user with id={id} and digest={digest}")
        return False, ""
Esempio n. 22
0
    async def async_wakeup_service_locally(self,
                                           service_path,
                                           arguments,
                                           port,
                                           is_python_process=True,
                                           index=0,
                                           name=None):
        INFO_MSG(
            f"{service_path}, {arguments}, {port}, {is_python_process}, {index}, {name}"
        )
        if arguments is None:
            arguments = dict()
        access_token = Access().generate(AccessLevel.Internal)

        # WARN_MSG(f"Opening (causer {self.exposed_ip}")
        proc = self.open_process(service_path,
                                 is_python_process=is_python_process,
                                 service_port=port,
                                 causer_ip=self.endpoint[0],
                                 causer_exposed_ip=self.exposed_ip,
                                 causer_port=self.endpoint[1],
                                 postfix=('[%i]' % index) if index else "",
                                 region=self.config.get_region(),
                                 **arguments,
                                 access_token=access_token,
                                 is_child_process=True)
        future_data = self.processes[proc.pid] = {
            'future': asyncio.Future(loop=asyncio.get_event_loop()),
            'endpoint': (self.endpoint[0], port),
            'opened_at': time(),
            'name': name
        }

        try:
            service_connection = await future_data['future']
        except Exception as e:
            ERROR_MSG("Something went wrong in future", e)
            return None

        return service_connection, proc
Esempio n. 23
0
    def open_process(self,
                     service_path,
                     arguments=list(),
                     is_python_process=True,
                     extented_param=None,
                     **kwargs):
        cmd_kwargs = list()

        kwargs['no_color_patterns'] = CommandLine.get_arguments(
        ).no_color_patterns

        for key, value in kwargs.items():
            if CommandLine.has_arg(key):
                arg_type = CommandLine.get_arg_type(key)
                kwarg = "-%s=%s" % (key, arg_type(value))
                cmd_kwargs.append(kwarg)
            else:
                ERROR_MSG(
                    "Unable to pass %s parameter, not exists in CommandLine.py: Arguments class"
                    % key)

        # cmd_kwargs = ["-%s=%s" % (key, value) for key, value in kwargs.items()]
        cmd_args = list()
        python_executable_name = ConfigGlobals.PythonExecutable
        if is_python_process:
            cmd_args.append(python_executable_name)
        cmd_args.extend(service_path) if isinstance(
            service_path, list) else cmd_args.append(service_path)
        if extented_param is not None:
            cmd_args.append(extented_param)
        cmd_args.extend(cmd_kwargs)
        cmd_args.extend(arguments)

        process = subprocess.Popen(cmd_args, shell=False)

        INFO_MSG(f"Opening process {process.pid}", cmd_args)
        # print(cmd_args)
        return process
Esempio n. 24
0
    async def create_prepared(cls, match_making, game_type, extra=None):
        """
        Создаёт новый инстанс матча
        @param match_making:
        @param game_type:
        @return:
        """
        maps_by_type = Maps.get_all_by("Type", game_type)
        INFO_MSG("Maps: %s" % maps_by_type)

        if not maps_by_type:
            raise RuntimeError("Gameplay maps list is empty")

        selected_map: FMapInfo = random.choice(maps_by_type)

        if isinstance(extra, dict):
            if extra.get('force_use_map', None):
                selected_map = Maps.get_by("Name", extra['force_use_map'])

        return await cls(match_making,
                         id=match_making.new_id(),
                         map_name=selected_map.Name,
                         max_players=selected_map.PlayersMax)
Esempio n. 25
0
    async def __ainit__(self,
                        context_name,
                        entity_typename,
                        endpoint_or_connection,
                        remote_id,
                        existent_endpoint_and_connection=None):
        INFO_MSG("")
        self.remote_id = remote_id
        self.client_connection: TCPClient

        if existent_endpoint_and_connection is None:
            self.client_connection, self.endpoint = await self.get_connection_and_endpoint_with_lost_callback(
                endpoint_or_connection)
        else:
            self.client_connection, self.endpoint = existent_endpoint_and_connection

        self.initialized_flag = True

        self.context_name = context_name
        self.entity_typename = entity_typename
        self.entity_info = ConfigurationGenerator(
        ).generated_entities_info.get_by_name(entity_typename)
        self.lost_callbacks = []
Esempio n. 26
0
    async def __ainit__(self):
        await super().__ainit__()
        self.started_time = time()
        args = self.get_args()

        self.next_service_port = self.child_service_port_start

        cls_name = self.__class__.__name__

        config: AppConfigType = Configuration()[cls_name]

        if not config:
            ERROR_MSG("Failed to read config! There is no section for %s" %
                      cls_name)
        self.config = config

        Globals.no_logging = self.config.DisableLog

        # INFO_MSG('~')
        if self.config.Kind in [AppKind.Single, AppKind.Static]:
            self.endpoint = self.config.get_endpoint()
            self.exposed_ip = self.config.get_exposed_ip()

        # INFO_MSG("Test")
        if args.service_port is not None:
            self.endpoint = self.endpoint[0], args.service_port

        # ERROR_MSG(f"T {args.causer_exposed_ip}")
        if not args.causer_exposed_ip or args.causer_exposed_ip == '0.0.0.0':
            try:
                self.exposed_ip = self.config.get_exposed_ip()
            except NotImplementedError:
                self.exposed_ip = '...'

        serving = not self.config.NoServer
        self.tcp_server = await create_server(self.endpoint, serving)

        Globals.disabled_log_categories = ConfigGlobals.DisabledLogs

        if not self.get_args().silent:
            INFO_MSG("%s started! with %s" % (cls_name, self.get_args()))
            INFO_MSG("%s started at %s (%s)" %
                     (cls_name, self.endpoint if serving else "None",
                      self.get_region()))
            INFO_MSG("Version: %s, generator signature: %s" %
                     (Globals.version, Globals.generator_signature))
            INFO_MSG("Description: %s" % self.config.Description)

        self.processes = dict()

        self.postfix = self.get_args().postfix

        if args.causer_exposed_ip and args.causer_exposed_ip != '0.0.0.0':
            self.exposed_ip = args.causer_exposed_ip
            INFO_MSG(f"Causer exposed {self.exposed_ip}")

        await self.start()

        self.dedicated_servers = list()

        if args.causer_ip is not None and args.causer_port is not None:
            INFO_MSG(f"Call to causer: {args.causer_ip}:{args.causer_port}")
            mbox = await Service.make_mailbox(
                "base", "Service", (args.causer_ip, args.causer_port))
            await mbox.TellPID(os.getpid())
Esempio n. 27
0
    async def async_wakeup_dedicated_server_locally(self,
                                                    service_path,
                                                    map_name,
                                                    base_ip,
                                                    base_port,
                                                    ue4_arguments,
                                                    arguments,
                                                    keyword_arguments,
                                                    port,
                                                    is_python_process=True,
                                                    index=0,
                                                    name=None):
        if len(self.dedicated_servers) >= self.max_dedicated_servers:
            raise WakeupError(
                "Unable to wakeup dedicated server. Out of limit")

        if keyword_arguments is None:
            keyword_arguments = dict()

        extented_param = None
        if ue4_arguments is not None:
            extented_param = map_name
            for idx, (key, value) in enumerate(ue4_arguments.items()):
                extented_param += ("?" if idx == 0 else
                                   "&") + "%s=%s" % (key, value)

        INFO_MSG("Opening '%s' '%s'" % (service_path, extented_param))

        access_token = Access().generate(AccessLevel.Internal)
        custom_local_network_version = Configuration(
        )['UE4App'].CustomLocalNetworkVersion
        custom_local_network_version = custom_local_network_version if custom_local_network_version else 0

        proc = self.open_process(
            service_path,
            is_python_process=is_python_process,
            service_port=port,
            causer_exposed_ip=self.exposed_ip,
            causer_ip=self.endpoint[0],
            causer_port=self.endpoint[1],
            base_ip=base_ip,
            base_port=base_port,
            postfix=('[%i]' % index) if index else "[0]",
            local_network_version=custom_local_network_version,
            arguments=arguments,
            **keyword_arguments,
            access_token=access_token,
            is_child_process=True,
            extented_param=extented_param)
        future_data = self.processes[proc.pid] = {
            'future': asyncio.Future(loop=asyncio.get_event_loop()),
            'endpoint': (self.endpoint[0], port),
            'opened_at': time(),
            'name': name
        }

        try:
            service_connection = await future_data['future']
            self.dedicated_servers.append(service_connection)
            service_connection.add_lost_callback(
                lambda conn: self.dedicated_servers.remove(conn))
            INFO_MSG("Total dedicated servers %i" %
                     len(self.dedicated_servers))
        except Exception as e:
            ERROR_MSG("Something went wrong in future", e)
            return None

        return service_connection, proc
Esempio n. 28
0
 def sigterm_handler(self, signal, frame):
     INFO_MSG(
         f"sigterm_handler {self.get_class_name()} going to be stopped")
     self.terminate()
Esempio n. 29
0
async def generate_bugreport(username, title, description, image):
    """
    Создаёт автоматический отчёт об ошибке в редмайне с картинкой и текстом

    @param username:
    @param title:
    @param description:
    @param image:
    @return:
    """

    redmine_config = ConfigGlobals.Redmine

    if not redmine_config:
        ERROR_MSG("redmine bugtracker not configured")
        return False

    redmine_host = redmine_config.get("host", None)
    if not redmine_host:
        ERROR_MSG("redmine host not configured")
        return False

    api_access_key = redmine_config.get("api_access_key", None)  # 'd41d39caf172705b8b63b290cec7c577b780cd11'
    if not api_access_key:
        ERROR_MSG("redmine api_access_key not configured")
        return False

    project_id = redmine_config.get("project_id", 1)

    async with aiohttp.ClientSession() as session:
        url = redmine_host + '/uploads.json'
        headers = {'content-type': 'application/octet-stream',
                   'X-Redmine-API-Key': api_access_key}
        token = ""
        result = await session.post(url, data=image, headers=headers)

        async with result as resp:
            try:
                response_json = await resp.json()
                INFO_MSG("Getting token")
                token = response_json.get("upload", {}).get("token", None)
            except Exception as e:
                print_exc()

        url = redmine_host + '/issues.json'

        data = f"""
                        <?xml version="1.0"?>
                        <issue>
                        <project_id>{project_id}</project_id>
                        <subject>[AUTO] {title}</subject>
                        <description>
h2. Баг от пользователя +{username}+

сгенерирован автоматически

h1. Проблема:

{description}
                        </description>
                        <priority_id>4</priority_id>
                        <category_id>1</category_id>

                        <uploads type="array">
                          <upload>
                            <token>{token}</token>
                            <filename>image.jpg</filename>
                            <description>Screenshot</description>
                            <content_type>image/jpeg</content_type>
                          </upload>
                        </uploads>

                        </issue>
                        """

        headers = {'content-type': 'application/xml',
                   'X-Redmine-API-Key': api_access_key}

        result = await session.post(url, data=data, headers=headers)

        async with result as resp:
            response_json = await resp.json()
            issue = response_json['issue']
            issue_id = issue['id']
            INFO_MSG(f"Bug report generated by {username} at {redmine_host}/issues/{issue_id}")


        return True
Esempio n. 30
0
 def InternalLogout(self, base: TBaseMailbox('BaseApp'), user_id: int32):
     INFO_MSG(f"User {user_id} logout")
     del self.loggedin_users[user_id]
     self.supervisor.Relax(base)