Skip to content

Commit

Permalink
[utilities] Relax from hard dependency of python3-magic
Browse files Browse the repository at this point in the history
For compatibility reasons on some distros, sos should not have a hard
dependency on 'magic' python library. It should attempt to use it for
detection of binary file content, but should fall back to previous "read
the very first byte" method otherwise.

Resolves: sosreport#3025
Relates: sosreport#3021

Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
  • Loading branch information
pmoravec committed Sep 13, 2022
1 parent 10fdd40 commit c9861b2
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 16 deletions.
1 change: 0 additions & 1 deletion requirements.txt
Expand Up @@ -2,5 +2,4 @@ pycodestyle>=2.4.0
coverage>=4.0.3
Sphinx>=1.3.5
pexpect>=4.0.0
python_magic>=0.4.20
pyyaml
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -107,7 +107,7 @@ def copy_file (self, filename, dirname):
],
cmdclass=cmdclass,
command_options=command_options,
requires=['pexpect', 'python_magic', 'pyyaml']
requires=['pexpect', 'pyyaml']
)


Expand Down
2 changes: 1 addition & 1 deletion sos.spec
Expand Up @@ -16,7 +16,7 @@ Requires: python3-rpm
Requires: tar
Requires: xz
Requires: python3-pexpect
Requires: python3-magic
Recommends: python3-magic
Recommends: python3-pyyaml
Obsoletes: sos-collector <= 1.9

Expand Down
50 changes: 37 additions & 13 deletions sos/utilities.py
Expand Up @@ -19,11 +19,26 @@
import threading
import time
import io
import magic

from contextlib import closing
from collections import deque

# try loading magic>=0.4.20 which implements detect_from_filename method
magic_mod = False
try:
import magic
magic.detect_from_filename(__file__)
magic_mod = True
except ImportError, AttributeError:
log = logging.getLogger('sos')
from textwrap import fill
msg = ("""\
WARNING: Failed to load 'magic' module version >= 0.4.20 which sos aims to \
use for detecting binary files. A less effective method will be used. It is \
recommended to install proper python3-magic package with the module.
""")
log.warn('\n' + fill(msg, 72, replace_whitespace=False) + '\n')


TIMEOUT_DEFAULT = 300


Expand Down Expand Up @@ -75,17 +90,26 @@ def file_is_binary(fname):
:returns: True if binary, else False
:rtype: ``bool``
"""
try:
_ftup = magic.detect_from_filename(fname)
_mimes = ['text/', 'inode/']
return (
_ftup.encoding == 'binary' and not
any(_ftup.mime_type.startswith(_mt) for _mt in _mimes)
)
except Exception:
# if for some reason this check fails, don't blindly remove all files
# but instead rely on other checks done by the component
return False
if magic_mod:
try:
_ftup = magic.detect_from_filename(fname)
_mimes = ['text/', 'inode/']
return (
_ftup.encoding == 'binary' and not
any(_ftup.mime_type.startswith(_mt) for _mt in _mimes)
)
except Exception:
pass
# if for some reason the above check fails or magic>=0.4.20 is not present,
# fail over to checking the very first byte of the file content
with open(fname, 'tr') as tfile:
try:
# when opened as above (tr), reading binary content will raise
# an exception
tfile.read(1)
return False
except UnicodeDecodeError:
return True


def find(file_pattern, top_dir, max_depth=None, path_pattern=None):
Expand Down

0 comments on commit c9861b2

Please sign in to comment.