<commit_before>
from errno import EPIPE
from time import time, sleep
from io import BytesIO
import logging
import socket
import shlex

from fluxclient.robot.errors import RobotError, RobotSessionError
from fluxclient.utils.version import StrictVersion
from fluxclient.fcode.g_to_f import GcodeToFcode

from .control_base import control_base_mixin

logger = logging.getLogger("API.CONTROL")


STAGE_DISCOVER = '{"status": "connecting", "stage": "discover"}'
STAGE_ROBOT_CONNECTING = '{"status": "connecting", "stage": "connecting"}'
STAGE_CONNECTED = '{"status": "connected"}'
STAGE_TIMEOUT = '{"status": "error", "error": "TIMEOUT"}'


def control_api_mixin(cls):
    class ControlApi(control_base_mixin(cls)):
        _task = None
        raw_sock = None

        def __init__(self, *args, **kw):
            try:
                super().__init__(*args, **kw)
            except RobotError:
                pass

        def on_connected(self):
            self.set_hooks()

        def set_hooks(self):
            if self.remote_version < StrictVersion("1.0b13"):
                logger.warn("Remote version is too old, allow update fw only")
                self.cmd_mapping = {
                    "update_fw": self.update_fw,
                }
                return

            self.cmd_mapping = {
                # deprecated
                "ls": self.list_file,
                # deprecated
                "select": self.select_file,
                # deprecated
                "mkdir": self.mkdir,
                # deprecated
                "rmdir": self.rmdir,
                # deprecated
                "rmfile": self.rmfile,
                # deprecated
                "cpfile": self.cpfile,
                # deprecated
                "fileinfo": self.fileinfo,
                # deprecated
                "upload": self.upload_file,

                "update_fw": self.update_fw,
                "update_mbfw": self.update_mbfw,

                "deviceinfo": self.deviceinfo,
                "wait_status": self.wait_status,
                "kick": self.kick,

                "file": {
                    "ls": self.list_file,
                    "mkdir": self.mkdir,
                    "rmdir": self.rmdir,
                    "rm": self.rmfile,
                    "rmfile": self.rmfile,
                    "cp": self.cpfile,
                    "cpfile": self.cpfile,
                    "info": self.fileinfo,
                    "md5": self.filemd5,
                    "upload": self.upload_file,
                    "download": self.download,
                    "download2": self.download2,
                },

                "maintain": {<commit_msg>Update fileinfo command in control<commit_after>
from errno import EPIPE
from time import time, sleep
from io import BytesIO
import logging
import socket
import shlex

from fluxclient.robot.errors import RobotError, RobotSessionError
from fluxclient.utils.version import StrictVersion
from fluxclient.fcode.g_to_f import GcodeToFcode

from .control_base import control_base_mixin

logger = logging.getLogger("API.CONTROL")


STAGE_DISCOVER = '{"status": "connecting", "stage": "discover"}'
STAGE_ROBOT_CONNECTING = '{"status": "connecting", "stage": "connecting"}'
STAGE_CONNECTED = '{"status": "connected"}'
STAGE_TIMEOUT = '{"status": "error", "error": "TIMEOUT"}'


def control_api_mixin(cls):
    class ControlApi(control_base_mixin(cls)):
        _task = None
        raw_sock = None

        def __init__(self, *args, **kw):
            try:
                super().__init__(*args, **kw)
            except RobotError:
                pass

        def on_connected(self):
            self.set_hooks()

        def set_hooks(self):
            if self.remote_version < StrictVersion("1.0b13"):
                logger.warn("Remote version is too old, allow update fw only")
                self.cmd_mapping = {
                    "update_fw": self.update_fw,
                }
                return

            self.cmd_mapping = {
                # deprecated
                "ls": self.list_file,
                # deprecated
                "select": self.select_file,
                # deprecated
                "mkdir": self.mkdir,
                # deprecated
                "rmdir": self.rmdir,
                # deprecated
                "rmfile": self.rmfile,
                # deprecated
                "cpfile": self.cpfile,
                # deprecated
                "fileinfo": self.fileinfo,
                # deprecated
                "upload": self.upload_file,

                "update_fw": self.update_fw,
                "update_mbfw": self.update_mbfw,

                "deviceinfo": self.deviceinfo,
                "wait_status": self.wait_status,
                "kick": self.kick,

                "file": {
                    "ls": self.list_file,
                    "mkdir": self.mkdir,
                    "rmdir": self.rmdir,
                    "rm": self.rmfile,
                    "rmfile": self.rmfile,
                    "cp": self.cpfile,
                    "cpfile": self.cpfile,
                    "info": self.fileinfo,
                    "fileinfo": self.fileinfo,
                    "md5": self.filemd5,
                    "upload": self.upload_file,
                    "download": self.download,
                    "download2": self.download2,
                },

                "maintain": {
{'fraction_non_alphanumeric': 0.10513761467889908, 'fraction_numerical': 0.0029357798165137615, 'mean_word_length': 1.489041095890411, 'pattern_counts': {'":': 71, '<': 5, '<?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': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3066580', 'n_tokens_mistral': 1568, 'n_tokens_neox': 1438, 'n_words': 320}