'compress one file into an archive (e.g. zip, tar, tar.gz, 7z)
:param file_path: path to file to compress
:type file_path: str
:param file_name: name of file in archive (defaults to retrieving name from file_path)
:type file_name: str
:param archive_path: **optional** full path to archive (e.g. "/tmp/sample51.zip")
:type archive_path: str
:param cls_name: **optional** name of Compressor class to use
:type cls_name: str
:param password: **optional** password to use
:type password: str
:param kwargs: keyword arguments (e.g for special flags)
:returns True if successful, otherwise False'

def compress(self, file_path, file_name=None, archive_path=None, cls_name=None, password=None, **kwargs):

    if (not os.path.isfile(file_path)):
        self.err = 'invalid    file_path    (file    does    not    exist):    {}'.format(file_path)
        log.error(self.err)
        return False
    if (not file_name):
        (_, file_name) = os.path.split(file_path)
    archive_basename = None
    archive_ext = self.default_ext
    if (not archive_path):
        archive_dir = tempfile.mkdtemp(prefix='viper_tmp_')
        log.debug('created    output    directory:    {}'.format(archive_dir))
    else:
        (archive_dir, archive_name) = os.path.split(archive_path)
        if archive_name:
            (archive_basename, archive_ext) = self.auto_discover_ext(archive_name)
        if (not os.path.exists(archive_dir)):
            os.makedirs(archive_dir)
            log.debug('created    output    directory:    {}'.format(archive_dir))
    if cls_name:
        log.debug('Compressor    specified    by    caller')
        try:
            sub = self.compressors[cls_name]
        except KeyError:
            self.err = 'invalid    Compressor:    {}    (check    for    missing    dependencies)'.format(cls_name)
            log.error(self.err)
            return False
        if (not archive_path):
            archive_ext = sub.supports_extensions[0]
    else:
        if archive_basename:
            (_, _res_auto_discover_ext) = self.auto_discover_ext(archive_basename)
            if (not _res_auto_discover_ext):
                self.err = 'unable    to    discover    extension'
                log.error(self.err)
                return False
            else:
                archive_ext = _res_auto_discover_ext
        try:
            sub = self.compressors_by_extension[archive_ext][0]
            if password:
                for item in self.compressors_by_extension[archive_ext]:
                    if item.supports_password:
                        sub = item
                        break
                    else:
                        sub = self.compressors_by_extension[archive_ext][0]
        except KeyError:
            self.err = 'no    available    Extractor    supports    extension:    {}    (check    for    missing    dependencies)'.format(cls_name)
            log.error(self.err)
            return False
    if (not archive_basename):
        archive_basename = self.default_basename
    if archive_ext:
        if (archive_ext in sub.supports_extensions):
            archive_name = '{}.{}'.format(archive_basename, archive_ext)
        else:
            archive_name = '{}.{}.{}'.format(archive_basename, archive_ext, sub.supports_extensions[0])
    else:
        archive_name = '{}.{}'.format(archive_basename, sub.supports_extensions[0])
    output_path = os.path.join(archive_dir, archive_name)
    if os.path.isfile(output_path):
        self.err = 'file    exists    -    will    not    overwrite:    {}'.format(output_path)
        log.error(self.err)
        return False
    sub.input_tuple_list = [(file_path, file_name)]
    sub.output_archive_path = output_path
    sub.output_archive_name = archive_name
    (sub.output_archive_basename, sub.output_archive_ext) = self.auto_discover_ext(archive_name)
    if (password and (not sub.supports_password)):
        self.err = 'password    provided    but    modules    does    not    support    encryption:    {}'.format(sub.cls_name)
        log.error(self.err)
        return False
    if sub.supports_password:
        ret = sub.run(password=password, **kwargs)
    else:
        ret = sub.run(**kwargs)
    if ret:
        self.output_archive_path = sub.output_archive_path
        log.info(self.output_archive_path)
        return True
    else:
        self.err = sub.err
        log.error(self.err)
        return False
