# Path: partycrasher/threshold.py
# class Threshold(object):
#     """
#     A wrapper for a bucket threshold value. Ensures proper serialization
#     between ElasticSearch and the JSON API eloggingndpoints.
#     """
#     __slots__ = ('_value',)
#     
#     def __init__(self, value):
#         if isinstance(value, Threshold):
#             assert isinstance(value._value, Decimal)
#             # Clone the other Threshold.
#             self._value = value._value
#             return
#         elif isinstance(value, Decimal):
#             self._value = value
#             return
#         elif isinstance(value, string_types):
#             value = value.replace('_', '.')
#         elif isinstance(value, float):
#             pass
#         else:
#             raise TypeError("Expected type %s but got %s" % (text_type, repr(value)))
# 
#         self._value = Decimal(value).quantize(Decimal('0.1'))
# 
#     def __str__(self):
#         result = str(self._value)
#         assert '_' not in result
#         # Ensure that rounded values are always displayed with at least one
#         # decimal, for aesthetics.
#         if '.' not in result:
#             return result + '.0'
#         return result
# 
#     def __repr__(self):
#         return "Threshold('" + str(self) + "')"
# 
#     def to_float(self):
#         return float(self)
# 
#     def __float__(self):
#         """
#         Convert the threshold to a floating point number, for comparisons.
#         Note that this should NOT be converted back to a threshold, as there
#         may be a loss of data by doing the round trip.
#         """
#         return float(self._value)
# 
#     def __getattr__(self, attr):
#         # Delegate everything (i.e, comparisons) to the actual Threshold
#         # value.
#         return getattr(self._value, attr)
# 
#     def __hash__(self):
#         return self._value.__hash__()+1
# 
#     def __eq__(self, otter):
#         if not isinstance(otter, Threshold):
#             return False
#         return self._value == otter._value
# 
#     def to_elasticsearch(self):
#         """
#         Converts the threshold to a string, suitable for serialization as an
#         ElasticSearch field name. Note that full stops ('.') are verbotten in
#         ElasticSearch field names.
#         """        #elif isinstance(o, Bucket):
#             #o.check()
#             #return o.as_dict()
#         #elif isinstance(o, TopMatch):
#             #return o.as_dict()
# 
#         str_value = str(self)
#         assert isinstance(self._value, Decimal)
#         assert str_value.count('.') == 1, 'Invalid decimal number'
#         return str_value.replace('.', '_')
#     
#     def __lt__(self, other):
#         return float(self._value) < float(other._value)
#     
#     def __deepcopy__(self, memo):
#         return Threshold(copy(self._value))
#     
#     def jsonify(self):
#         return text_type(self._value)
# 
# Path: partycrasher/more_like_this.py
# class MoreLikeThis(MoreLikeThisSearcher):
#     """ Class to setup MLT search config. """
#     def __init__(self, index, config):
#         always_remove_fields = [r'^database_id',
#                          r'^buckets',
#                          r'force_bucket',
#                          r'stacktrace\.depth',
#                          r'^date',
#                          r'logdf']
#         filterer = CrashFilter(config.remove_fields+always_remove_fields,
#                                config.keep_fields)
#         rescore_filterer = CrashFilter(config.rescore_remove_fields+always_remove_fields,
#                                config.rescore_keep_fields)
#         super(MoreLikeThis,self).__init__(
#             index=index,
#             max_query_terms=config.max_query_terms,
#             terminate_after=config.terminate_after,
#             min_score=config.min_score,
#             filterer=filterer,
#             rescore_filterer=rescore_filterer,
#             rescore_window_size=config.rescore_window_size,
#             rescore_weight=config.rescore_weight,
#             search_weight=config.search_weight
#             )
# 
# Path: partycrasher/pc_exceptions.py
# class ESError(PartyCrasherError):
#     """
#     ElasticSearch returned an unexpected/unhandled error.
#     """
#     def __init__(self, ex, **kwargs):
#         (t, v, tb) = sys.exc_info()
#         message = ('ElasticSearch Exception: '
#                        '%s.' % str(ex))
#         super(PartyCrasherError, self).__init__(message, **kwargs)
#         self.original_traceback = tb
#         self.original_type = repr(t)
#         self.original_value = repr(v)
#         if isinstance(ex, TransportError):
#             self.es_status_code = ex.status_code
#             self.es_error = ex.error
#             self.es_info = ex.info
#             self.es_description = str(ex)


from six import string_types
from elasticsearch import TransportError
from elasticsearch import ElasticsearchException
from partycrasher.threshold import Threshold
from partycrasher.more_like_this import MoreLikeThis
from partycrasher.es.elastify import elastify
from partycrasher.pc_exceptions import ESError
import logging
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

#  Copyright (C) 2016, 2017 Joshua Charles Campbell

#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

from __future__ import print_function, division


logger = logging.getLogger(__name__)
error = logger.error

# Path: partycrasher/threshold.py
# class Threshold(object):
#     """
#     A wrapper for a bucket threshold value. Ensures proper serialization
#     between ElasticSearch and the JSON API eloggingndpoints.
#     """
#     __slots__ = ('_value',)
#     
#     def __init__(self, value):
#         if isinstance(value, Threshold):
#             assert isinstance(value._value, Decimal)
#             # Clone the other Threshold.
#             self._value = value._value
#             return
#         elif isinstance(value, Decimal):
#             self._value = value
#             return
#         elif isinstance(value, string_types):
#             value = value.replace('_', '.')
#         elif isinstance(value, float):
#             pass
#         else:
#             raise TypeError("Expected type %s but got %s" % (text_type, repr(value)))
# 
#         self._value = Decimal(value).quantize(Decimal('0.1'))
# 
#     def __str__(self):
#         result = str(self._value)
#         assert '_' not in result
#         # Ensure that rounded values are always displayed with at least one
#         # decimal, for aesthetics.
#         if '.' not in result:
#             return result + '.0'
#         return result
# 
#     def __repr__(self):
#         return "Threshold('" + str(self) + "')"
# 
#     def to_float(self):
#         return float(self)
# 
#     def __float__(self):
#         """
#         Convert the threshold to a floating point number, for comparisons.
#         Note that this should NOT be converted back to a threshold, as there
#         may be a loss of data by doing the round trip.
#         """
#         return float(self._value)
# 
#     def __getattr__(self, attr):
#         # Delegate everything (i.e, comparisons) to the actual Threshold
#         # value.
#         return getattr(self._value, attr)
# 
#     def __hash__(self):
#         return self._value.__hash__()+1
# 
#     def __eq__(self, otter):
#         if not isinstance(otter, Threshold):
#             return False
#         return self._value == otter._value
# 
#     def to_elasticsearch(self):
#         """
#         Converts the threshold to a string, suitable for serialization as an
#         ElasticSearch field name. Note that full stops ('.') are verbotten in
#         ElasticSearch field names.
#         """        #elif isinstance(o, Bucket):
#             #o.check()
#             #return o.as_dict()
#         #elif isinstance(o, TopMatch):
#             #return o.as_dict()
# 
#         str_value = str(self)
#         assert isinstance(self._value, Decimal)
#         assert str_value.count('.') == 1, 'Invalid decimal number'
#         return str_value.replace('.', '_')
#     
#     def __lt__(self, other):
#         return float(self._value) < float(other._value)
#     
#     def __deepcopy__(self, memo):
#         return Threshold(copy(self._value))
#     
#     def jsonify(self):
#         return text_type(self._value)
# 
# Path: partycrasher/more_like_this.py
# class MoreLikeThis(MoreLikeThisSearcher):
#     """ Class to setup MLT search config. """
#     def __init__(self, index, config):
#         always_remove_fields = [r'^database_id',
#                          r'^buckets',
#                          r'force_bucket',
#                          r'stacktrace\.depth',
#                          r'^date',
#                          r'logdf']
#         filterer = CrashFilter(config.remove_fields+always_remove_fields,
#                                config.keep_fields)
#         rescore_filterer = CrashFilter(config.rescore_remove_fields+always_remove_fields,
#                                config.rescore_keep_fields)
#         super(MoreLikeThis,self).__init__(
#             index=index,
#             max_query_terms=config.max_query_terms,
#             terminate_after=config.terminate_after,
#             min_score=config.min_score,
#             filterer=filterer,
#             rescore_filterer=rescore_filterer,
#             rescore_window_size=config.rescore_window_size,
#             rescore_weight=config.rescore_weight,
#             search_weight=config.search_weight
#             )
# 
# Path: partycrasher/pc_exceptions.py
# class ESError(PartyCrasherError):
#     """
#     ElasticSearch returned an unexpected/unhandled error.
#     """
#     def __init__(self, ex, **kwargs):
#         (t, v, tb) = sys.exc_info()
#         message = ('ElasticSearch Exception: '
#                        '%s.' % str(ex))
#         super(PartyCrasherError, self).__init__(message, **kwargs)
#         self.original_traceback = tb
#         self.original_type = repr(t)
#         self.original_value = repr(v)
#         if isinstance(ex, TransportError):
#             self.es_status_code = ex.status_code
#             self.es_error = ex.error
#             self.es_info = ex.info
#             self.es_description = str(ex)


# Path: partycrasher/es/index.py
from six import string_types
from elasticsearch import TransportError
from elasticsearch import ElasticsearchException
from partycrasher.threshold import Threshold
from partycrasher.more_like_this import MoreLikeThis
from partycrasher.es.elastify import elastify
from partycrasher.pc_exceptions import ESError
import logging

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

#  Copyright (C) 2016, 2017 Joshua Charles Campbell

#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

from __future__ import print_function, division


logger = logging.getLogger(__name__)
error = logger.error

warn = logger.warn