<commit_before>#!/usr/bin/env python

import logging
import multiprocessing
import os.path
import time
import traceback

import browser
import kcsapi
import kcsapi_util
import logenv
import manipulator_util
import proxy_util
import server


COMMAND_REQUEST_OBJECT = 'request_object'
COMMAND_CLICK = 'click'
COMMAND_RELOAD_KCSAPI = 'reload_kcsapi'
COMMAND_RELOAD_MANIPULATORS = 'reload_manipulators'
COMMAND_MANIPULATE = 'manipulate'
COMMAND_TAKE_SCREENSHOT = 'take_screenshot'
COMMAND_SET_PREFERENCES = 'set_preferences'


class DummyProcess(object):

    def join(self):
        pass


def load_preferences(args, logger):
    if not args.preferences:
        logger.info('Preferences file is not specified. Using default.')
        logger.info('If you want to have one, set the value of the flag '
                    '--preferences properly.')
        preferences = kcsapi.prefs.Preferences()
        preferences.initialize()
        return preferences
    elif os.path.isfile(args.preferences):
        logger.info(
            'Prefenreces file found at {}. Loading.'.format(args.preferences))
        with open(args.preferences, 'r') as preferences_file:
            preferences = kcsapi.prefs.Preferences.parse_text(
                preferences_file.read())
            preferences.initialize()
            return preferences
    else:
        logger.info(
            'Prefenreces file not found at {}. Creating one with default.'
            .format(args.preferences))
        preferences = kcsapi.prefs.Preferences()
        preferences.initialize()
        save_preferences(args, logger, preferences)
        return preferences


def save_preferences(args, logger, preferences):
    with open(args.preferences, 'w') as preferences_file:
        preferences_string = preferences.json(
            indent=2, separators=(',', ': '), sort_keys=True,
            ensure_ascii=False).encode('utf8')
        preferences_file.write(preferences_string)


def control(args, to_exit):
    # It seems that uncaught exceptions are silently buffered after creating
    # another multiprocessing.Process.
    ps = DummyProcess()
    pk = DummyProcess()
    pc = DummyProcess()
    kcsapi_handler = None
    try:
        logenv.setup_logger(args.debug, args.log_file, args.log_level)
        logger = logging.getLogger('kcaa.controller')
        preferences = load_preferences(args, logger)
        har_manager = proxy_util.HarManager(args, 3.0)
        controller_conn, server_conn = multiprocessing.Pipe()
        object_queue = multiprocessing.Queue()
        ps = multiprocessing.Process(target=server.handle_server,
                                     args=(args, to_exit, controller_conn,
                                           object_queue))
        ps.start()
        object_queue.put((True, preferences.object_type, preferences.json()))
        if not server_conn.poll(3.0):
            logger.error('Server is not responding. Shutting down.')
            to_exit.set()
            return
        root_url = server_conn.recv()
        controller_conn_for_browser, browser_conn = multiprocessing.Pipe()
        pk = multiprocessing.Process(target=browser.setup_kancolle_browser,
                                     args=(args, controller_conn_for_browser,
                                           to_exit))
        pc = multiprocessing.Process(target=browser.setup_kcaa_browser,
                                     args=(args, root_url, to_exit))
        pk.start()
        pc.start()
        kcsapi_handler = kcsapi_util.KCSAPIHandler(
            har_manager, args.journal_basedir, args.debug)
        kcsapi_handler.update_preferences(preferences)
        manipulator_manager = manipulator_util.ManipulatorManager(
            browser_conn, kcsapi_handler.objects, preferences, time.time())
        while True:
            time.sleep(args.backend_update_interval)
            if to_exit.wait(0.0):
                logger.info('Controller got an exit signal. Shutting down.')
                break
            while server_conn.poll():
                command_type, command_args = server_conn.recv()
                if command_type == COMMAND_REQUEST_OBJECT:
                    try:
                        requestable = kcsapi_handler.request(command_args)
                        if requestable:
                            if isinstance(requestable, str):
                                server_conn.send(requestable)
                            else:
                                server_conn.send(requestable.json())
                        else:
                            server_conn.send(None)
                    except:
                        logger.error(traceback.format_exc())
                        server_conn.send(None)
                elif command_type == COMMAND_CLICK:
                    # This command is currently dead. If there is a reasonable
                    # means to get the clicked position in the client, this is
                    # supposed to feed that information to the fake client
                    # owned by the controller to better guess the current
                    # screen.
                    browser_conn.send((browser.COMMAND_CLICK, command_args))
                elif command_type == COMMAND_RELOAD_KCSAPI:
                    kcsapi_handler.save_journals(args.journal_basedir)
                    serialized_objects = kcsapi_handler.serialize_objects()
                    reload(kcsapi_util)
                    kcsapi_util.reload_modules()
                    kcsapi_handler = kcsapi_util.KCSAPIHandler(
                        har_manager, args.journal_basedir, args.debug)
                    kcsapi_handler.deserialize_objects(serialized_objects)
                    manipulator_manager.reset_objects(kcsapi_handler.objects)
                elif command_type == COMMAND_RELOAD_MANIPULATORS:
                    reload(manipulator_util)
                    manipulator_util.reload_modules()
                    manipulator_manager = manipulator_util.ManipulatorManager(
                        browser_conn, kcsapi_handler.objects, preferences,
                        time.time())
                elif command_type == COMMAND_MANIPULATE:
                    try:
                        manipulator_manager.dispatch(command_args)
                    except:
                        logger.error(traceback.format_exc())
                elif command_type == COMMAND_SET_PREFERENCES:
                    preferences = kcsapi.prefs.Preferences.parse_text(<commit_msg>Possibly fix the preferences cleared out bug.<commit_after>#!/usr/bin/env python

import logging
import multiprocessing
import os.path
import time
import traceback

import browser
import kcsapi
import kcsapi_util
import logenv
import manipulator_util
import proxy_util
import server


COMMAND_REQUEST_OBJECT = 'request_object'
COMMAND_CLICK = 'click'
COMMAND_RELOAD_KCSAPI = 'reload_kcsapi'
COMMAND_RELOAD_MANIPULATORS = 'reload_manipulators'
COMMAND_MANIPULATE = 'manipulate'
COMMAND_TAKE_SCREENSHOT = 'take_screenshot'
COMMAND_SET_PREFERENCES = 'set_preferences'


class DummyProcess(object):

    def join(self):
        pass


def load_preferences(args, logger):
    if not args.preferences:
        logger.info('Preferences file is not specified. Using default.')
        logger.info('If you want to have one, set the value of the flag '
                    '--preferences properly.')
        preferences = kcsapi.prefs.Preferences()
        preferences.initialize()
        return preferences
    elif os.path.isfile(args.preferences):
        logger.info(
            'Prefenreces file found at {}. Loading.'.format(args.preferences))
        with open(args.preferences, 'r') as preferences_file:
            preferences = kcsapi.prefs.Preferences.parse_text(
                preferences_file.read())
            preferences.initialize()
            return preferences
    else:
        logger.info(
            'Prefenreces file not found at {}. Creating one with default.'
            .format(args.preferences))
        preferences = kcsapi.prefs.Preferences()
        preferences.initialize()
        save_preferences(args, logger, preferences)
        return preferences


def save_preferences(args, logger, preferences):
    with open(args.preferences, 'w') as preferences_file:
        preferences_string = preferences.json(
            indent=2, separators=(',', ': '), sort_keys=True,
            ensure_ascii=False).encode('utf8')
        preferences_file.write(preferences_string)


def control(args, to_exit):
    # It seems that uncaught exceptions are silently buffered after creating
    # another multiprocessing.Process.
    ps = DummyProcess()
    pk = DummyProcess()
    pc = DummyProcess()
    kcsapi_handler = None
    try:
        logenv.setup_logger(args.debug, args.log_file, args.log_level)
        logger = logging.getLogger('kcaa.controller')
        preferences = load_preferences(args, logger)
        har_manager = proxy_util.HarManager(args, 3.0)
        controller_conn, server_conn = multiprocessing.Pipe()
        object_queue = multiprocessing.Queue()
        ps = multiprocessing.Process(target=server.handle_server,
                                     args=(args, to_exit, controller_conn,
                                           object_queue))
        ps.start()
        object_queue.put((True, preferences.object_type, preferences.json()))
        if not server_conn.poll(3.0):
            logger.error('Server is not responding. Shutting down.')
            to_exit.set()
            return
        root_url = server_conn.recv()
        controller_conn_for_browser, browser_conn = multiprocessing.Pipe()
        pk = multiprocessing.Process(target=browser.setup_kancolle_browser,
                                     args=(args, controller_conn_for_browser,
                                           to_exit))
        pc = multiprocessing.Process(target=browser.setup_kcaa_browser,
                                     args=(args, root_url, to_exit))
        pk.start()
        pc.start()
        kcsapi_handler = kcsapi_util.KCSAPIHandler(
            har_manager, args.journal_basedir, args.debug)
        kcsapi_handler.update_preferences(preferences)
        manipulator_manager = manipulator_util.ManipulatorManager(
            browser_conn, kcsapi_handler.objects, preferences, time.time())
        while True:
            time.sleep(args.backend_update_interval)
            if to_exit.wait(0.0):
                logger.info('Controller got an exit signal. Shutting down.')
                break
            while server_conn.poll():
                command_type, command_args = server_conn.recv()
                if command_type == COMMAND_REQUEST_OBJECT:
                    try:
                        requestable = kcsapi_handler.request(command_args)
                        if requestable:
                            if isinstance(requestable, str):
                                server_conn.send(requestable)
                            else:
                                server_conn.send(requestable.json())
                        else:
                            server_conn.send(None)
                    except:
                        logger.error(traceback.format_exc())
                        server_conn.send(None)
                elif command_type == COMMAND_CLICK:
                    # This command is currently dead. If there is a reasonable
                    # means to get the clicked position in the client, this is
                    # supposed to feed that information to the fake client
                    # owned by the controller to better guess the current
                    # screen.
                    browser_conn.send((browser.COMMAND_CLICK, command_args))
                elif command_type == COMMAND_RELOAD_KCSAPI:
                    kcsapi_handler.save_journals(args.journal_basedir)
                    serialized_objects = kcsapi_handler.serialize_objects()
                    reload(kcsapi_util)
                    kcsapi_util.reload_modules()
                    kcsapi_handler = kcsapi_util.KCSAPIHandler(
                        har_manager, args.journal_basedir, args.debug)
                    kcsapi_handler.deserialize_objects(serialized_objects)
                    manipulator_manager.reset_objects(kcsapi_handler.objects)
                    # TODO: Refactor!
                    preferences = kcsapi_handler.objects['Preferences']
                    manipulator_manager.preferences = preferences
                elif command_type == COMMAND_RELOAD_MANIPULATORS:
                    reload(manipulator_util)
                    manipulator_util.reload_modules()
                    manipulator_manager = manipulator_util.ManipulatorManager(
                        browser_conn, kcsapi_handler.objects, preferences,
                        time.time())
                elif command_type == COMMAND_MANIPULATE:
                    try:
                        manipulator_manager.dispatch(command_args)
                    except:
                        logger.error(traceback.format_exc())
                elif command_type == COMMAND_SET_PREFERENCES:
                    preferences = kcsapi.prefs.Preferences.parse_text(
{'fraction_non_alphanumeric': 0.0732661350985407, 'fraction_numerical': 0.001203550473897999, 'mean_word_length': 1.927769213829553, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1429707', 'n_tokens_mistral': 3479, 'n_tokens_neox': 3365, 'n_words': 695}