From ddbd669dc1f776d1a2f51384acd8cba8b453322a Mon Sep 17 00:00:00 2001 From: Peter Silva Date: Wed, 26 Jul 2023 23:14:15 -0400 Subject: [PATCH] issue #721 make magic an extra, degrade gracefully when missing. Also added *all* extra to install all extras. --- sarracenia/__init__.py | 20 ++++++++++++++------ sarracenia/flow/__init__.py | 9 ++++++--- setup.py | 6 +++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/sarracenia/__init__.py b/sarracenia/__init__.py index 14e3337dd..f8392678a 100755 --- a/sarracenia/__init__.py +++ b/sarracenia/__init__.py @@ -31,7 +31,6 @@ import datetime import importlib.util import logging -import magic import os import os.path import paramiko @@ -475,11 +474,15 @@ def fromFileData(path, o, lstat=None): if lstat : if os_stat.S_ISREG(lstat.st_mode): m.__computeIdentity(path, o) - try: - t = magic.from_file(path,mime=True) - m['contentType'] = t - except Exception as ex: - logging.info("trying to determine mime-type. Exception details:", exc_info=True) + if extras['filetypes']['present']: + try: + t = magic.from_file(path,mime=True) + m['contentType'] = t + except Exception as ex: + logging.info("trying to determine mime-type. Exception details:", exc_info=True) + #else: + # m['contentType'] = 'application/octet-stream' # https://www.rfc-editor.org/rfc/rfc2046.txt (default when clueless) + # I think setting a bad value is worse than none, so just omitting. elif os_stat.S_ISDIR(lstat.st_mode): m['contentType'] = 'text/directory' # source: https://www.w3.org/2002/12/cal/rfc2425.html elif os_stat.S_ISLNK(lstat.st_mode): @@ -804,6 +807,7 @@ def getContent(msg): amqp - ability to communicate with AMQP (rabbitmq) brokers mqtt - ability to communicate with MQTT brokers + filetypes - ability to ftppoll - ability to poll FTP servers vip - enable vip (Virtual IP) settings to implement singleton processing for high availability support. @@ -816,6 +820,7 @@ def getContent(msg): 'ftppoll' : { 'modules_needed': ['dateparser', 'pytz'], 'present': False, 'lament' : 'will not be able to poll with ftp' }, 'humanize' : { 'modules_needed': ['humanize' ], 'present': False, 'lament': 'humans will have to read larger, uglier numbers' }, 'mqtt' : { 'modules_needed': ['paho.mqtt.client'], 'present': False, 'lament': 'will not be able to connect to mqtt brokers' }, + 'filetypes' : { 'modules_needed': ['magic'], 'present': False, 'lament': 'will not be able to set content headers' }, 'vip' : { 'modules_needed': ['netifaces'] , 'present': False, 'lament': 'will not be able to use the vip option for high availability clustering' }, 'watch' : { 'modules_needed': ['watchdog'] , 'present': False, 'lament': 'cannot watch directories' } } @@ -837,6 +842,9 @@ def getContent(msg): # Some sort of graceful fallback, or good messaging for when dependencies are missing. +if extras['filetypes']['present']: + import magic + if extras['mqtt']['present']: import paho.mqtt.client if not hasattr( paho.mqtt.client, 'MQTTv5' ): diff --git a/sarracenia/flow/__init__.py b/sarracenia/flow/__init__.py index f3acbdc76..61f406ca8 100644 --- a/sarracenia/flow/__init__.py +++ b/sarracenia/flow/__init__.py @@ -1,7 +1,6 @@ import copy import importlib import logging -import magic import os import re @@ -58,6 +57,9 @@ 'vip': None } +if sarracenia.extras['filetypes']['present']: + import magic + if sarracenia.extras['vip']['present']: import netifaces @@ -1868,7 +1870,7 @@ def download(self, msg, options) -> bool: os.rename(new_inflight_path, new_file) # older versions don't include the contentType, so patch it here. - if 'contentType' not in msg: + if sarracenia.extras['filetypes']['present'] and 'contentType' not in msg: msg['contentType'] = magic.from_file(new_file,mime=True) self.metrics['flow']['transferRxBytes'] += len_written @@ -1957,7 +1959,8 @@ def send(self, msg, options): local_path = '/' + msg['relPath'] # older versions don't include the contentType, so patch it here. - if 'contentType' not in msg and not 'fileOp' in msg: + if sarracenia.extras['filetypes']['present'] and \ + ('contentType' not in msg) and (not 'fileOp' in msg): msg['contentType'] = magic.from_file(local_path,mime=True) local_dir = os.path.dirname(local_path).replace('\\', '/') diff --git a/setup.py b/setup.py index 10908b46c..0ac91eb82 100755 --- a/setup.py +++ b/setup.py @@ -83,13 +83,17 @@ def read(*parts): 'Topic :: System :: Logging', ], install_requires=[ - "appdirs", "humanfriendly", "humanize", "jsonpickle", "python-magic", "paramiko", + "appdirs", "humanfriendly", "humanize", "jsonpickle", "paramiko", "psutil>=5.3.0", "watchdog" ], extras_require = { 'amqp' : [ "amqp" ], + 'filetypes': [ "python-magic" ], 'ftppoll' : ['dateparser' ], 'mqtt': [ 'paho.mqtt>=1.5.1' ], 'vip': [ 'netifaces' ], 'redis': [ 'redis' ] }) + extras_require['all'] = list(itertools.chain.from_iterable(extras_require.values())) + +