Example #1
0
class MinimalCommands:
    def __init__(self):
        # get kdfs config
        self.config = Config(ServerUtils.CONFIG_PATH)
        self.storage_path = self.config.get('storage', './')

    # ------------------------------------------------
    def _getAbsPath(self, pathi: str):
        return os.path.abspath("{}/{}".format(self.storage_path, pathi))

    # ------------------------------------------------
    def listCommand(self, params: dict):
        response = []
        # create absolute path with storage path
        absPath = self._getAbsPath(params['path'])
        # check for exist directory
        if not os.path.exists(absPath) or not os.path.isdir(absPath):
            return ('', "no such directory to retrive")
        # get list of files and dirs
        files = os.listdir(absPath)
        # iterate all files
        for filei in files:
            newPath = os.path.join(absPath, filei)
            sizei = os.stat(newPath).st_size
            # translate size humanly
            size = minimalUitls.convertBytesToHumanly(sizei)
            # append to response
            response.append({
                'name': filei,
                'size': size,
                'type': 'dir' if os.path.isdir(newPath) else 'file',
                'path': os.path.join(params['path'], filei)
            })

        return (response, '')

    # ------------------------------------------------
    def findCommand(self, params: dict):
        response = []
        # print("minimal:",params)
        # create absolute path with storage path
        absPath = self._getAbsPath(params['path'])
        # check for exist directory
        if not os.path.exists(absPath) or not os.path.isdir(absPath):
            return ('', "no such directory to retrive")
        # get list of files and dirs (can recursion)
        files = minimalUitls.getAllFilesList(
            absPath,
            is_recursion=(params['type'] == 'rec'),
            just_files=(params['type'] == 'file'))
        # get max items
        maxItems = self.config.getInteger('list_limit', 10)
        # print('final files:',files)
        # iterate all files
        for filei in files:
            # print('file to find:',filei)
            # get abs path
            newPath = os.path.join(absPath, filei)
            findCount = 0
            # if search in filename
            if params['mode'] == 'name':
                # search regex on filename
                findCount = len(
                    minimalUitls.searchTextByRegex(filei, params['regex']))
            elif params['mode'] == 'content':
                # check if directory
                if os.path.isdir(newPath): continue
                # check if file is binary
                if minimalUitls.checkIsBinaryFile(newPath): continue
                # open file and read line by line
                try:
                    with open(newPath, 'r', encoding='utf-8') as f:
                        for line in f:
                            # search regex on every line
                            findCount += len(
                                minimalUitls.searchTextByRegex(
                                    line, params['regex']))
                except:
                    pass

            # append to response
            if findCount > 0 and len(response) <= maxItems:
                response.append({
                    'name': filei,
                    'count': findCount,
                    'type': 'dir' if os.path.isdir(newPath) else 'file',
                    'path': os.path.join(params['path'], filei)
                })

        # print('response_minimal:',params,response)

        return (response, '')

    # ------------------------------------------------
    def existCommand(self, params: dict):
        # create absolute path with storage path
        absPath = self._getAbsPath(params['path'])
        # check for exist path
        if os.path.exists(absPath):
            return ("true", '')
        else:
            return ('false', '')

    # ------------------------------------------------
    def statCommand(self, params: dict):
        response = {}
        # create absolute path with storage path
        absPath = self._getAbsPath(params['path'])
        # check for exist directory or file
        if not os.path.exists(absPath):
            return ('', "no such file or directory to retrive")
        # get stat of absolute path
        (mode, ino, dev, nlink, uid, gid, sizei, atime, mtime,
         ctime) = os.stat(absPath)
        # fileStat = os.stat(newPath)
        # translate size humanly
        size = minimalUitls.convertBytesToHumanly(sizei)

        # append to response
        response = {
            'name': os.path.basename(absPath),
            'size': size,
            'type': 'dir' if os.path.isdir(absPath) else 'file',
            'kdfs_path': params['path'],
            'local_path': absPath,
            'last_access': time.ctime(atime),
            'last_modify': time.ctime(mtime),
            'owner': pwd.getpwuid(uid).pw_name
        }

        return (response, '')

    # ------------------------------------------------
    def identifyCommand(self, params: dict = {}):
        res: dict = {
            'macaddr':
            ServerUtils.getMacAddress(),
            'version':
            self.config.getInteger('version', 0),
            'os':
            platform.system(),
            'arch':
            platform.machine(),
            'hostname':
            platform.node(),
            'node_type':
            'queen' if self.config.getBoolean('is_queen', False) else 'node'
        }
        return (res, '')

    # ------------------------------------------------
    def upgradeCommand(self, params: dict):
        # if packet number is 1,then just return 'yes' or 'no'
        if params['packnumber'] == 1:
            # check if server can accept upgrades or not
            if self.config.getBoolean('accept_upgrades', True):
                KDFSProtocol.echo(
                    "Accept kdfs version {} upgrading...".format(
                        params['version']), 'upgrade')
                # check if upgrades folder is not exsit
                if not os.path.exists(ServerUtils.UPGRADE_PATH):
                    os.makedirs(ServerUtils.UPGRADE_PATH)
                # resturn accept response
                return ('yes', '')
            else:
                KDFSProtocol.echo("Refuse any upgrading", 'upgrade')
                # return refuse response
                return ('no', '')
        # if get file in next packet number, save it
        else:
            try:
                # save to file
                with open(ServerUtils.UPGRADE_ZIP_PATH.format(
                        params['version']),
                          mode='wb') as f:
                    f.write(bytearray(params['data']))
                # extract to min source
                with tarfile.open(
                        ServerUtils.UPGRADE_ZIP_PATH.format(params['version']),
                        'r:gz') as kdfsTar:
                    kdfsTar.extractall("./")
                # update kdfs version number
                self.config.updateItem('version', params['version'])
                KDFSProtocol.echo(
                    "saved kdfs version {} upgraded file in local".format(
                        params['version']), 'upgrade')
                # if os is linux, then run bash script
                if ServerUtils.detectOS() == 'linux':
                    os.system("sh ./upgrade.sh &")
                else:
                    pass
                    # TODO:

                return ('success', '')

            except Exception as e:
                return (e, '')

    # ------------------------------------------------
    def notifyCommand(self, params: dict):
        response = Notification(self.config.get('app_name', 'KDFS'),
                                params['text'], 30).send()
        if response:
            return ('success', '')
        else:
            return ('failed', '')

    # ------------------------------------------------
    def copyCommand(self, params: dict):
        # create absolute path with storage path
        absPath = self._getAbsPath(params['path'])
        # print('abspath:',absPath)
        # if type of copy is 'src'
        if params['mode'] == 'src':
            # check for exist directory or file
            if not os.path.exists(absPath):
                return ('', "no such file or directory to retrive")
            # if path is for file
            if os.path.isfile(absPath):
                content = KDFSProtocol.fileCompress(absPath)
                return (content, '')
            # if path is for directory
            elif os.path.isdir(absPath):
                content = KDFSProtocol.directoryCompress(absPath)
                return (content, '')
            else:
                return ('', "undefined path")

        # if type of copy is 'dest'
        elif params['mode'] == 'dest':
            if params['packnumber'] == 1:
                # check for exist parent directory of dest path
                if not os.path.exists(os.path.dirname(absPath)):
                    return ('', "no such parent directory to retrive")
                return ('success', '')
            else:

                # print("data file (copy):",params['data'])
                # save to file
                filename = KDFSProtocol.saveTempCompressedFile(params['data'])
                # extract to min source
                with tarfile.open(filename, 'r:gz') as kdfsTar:
                    kdfsTar.extractall(absPath)

                return ('success', '')