# 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/bucket.py
# class Bucket(PCDict):
#     """
#     namedtuple('Bucket', 'id threshold total top_reports first_seen')
#     Data class for buckets. Contains two identifiers:
#      - id: The bucket's ID;
#      - total: how many reports are currently in the bucket.
#     """
#     __slots__ = tuple()
#     
#     canonical_fields = {
#         'id': key_type,
#         'threshold': mustbe_threshold,
#         'first_seen': mustbe_date,
#         'last_seen': mustbe_date,
#         'total': mustbe_int,
#     }
#         
#     #def __init__(self, *args, **kwargs):
#         #super(Bucket, self).__init__(*args, **kwargs)
#         #assert 'id' in self
#         #assert 'threshold' in self
#     
#     @classmethod
#     def new(cls, threshold, **kwargs):
#         kwargs['threshold'] = threshold
#         assert 'id' not in kwargs
#         kwargs['id'] = random_bucketid()
#         return Bucket(**kwargs)
#     
#     def jsonify(self):
#         return self.as_dict()
# 
# Path: partycrasher/api/report_bucket.py
# class ReportBucket(Bucket):
#     __slots__ = ('reports',)
#     
#     def __init__(self, search, from_=None, size=None, **kwargs):
#         super(ReportBucket, self).__init__(kwargs)
#         self.reports = ReportBucketSearch(search=search,
#                         bucket_id=self['id'],
#                         threshold=self['threshold'],
#                         from_=from_,
#                         size=size
#                         )
#     
#     def restify(self):
#         d = copy(self._d)
#         d['reports'] = self.reports
#         return d


import logging
from copy import copy
from partycrasher.threshold import Threshold
from partycrasher.bucket import Bucket
from partycrasher.api.search import Page, Search
from partycrasher.api.report_bucket import ReportBucket
from partycrasher.pc_encoder import pretty
        else:
            size = total
        
        first_page = self.new_first_page()
        
        buckets = [ReportBucket(
                        search=first_page, 
                        id=bucket['key'], 
                        project=self['project'],
                        type=self['type'],
                        threshold=self['threshold'],
                        total=bucket['doc_count'],
                        first_seen=bucket['first_seen']['value_as_string'],
                        last_seen=bucket['last_seen']['value_as_string'],
                        )
                   for bucket in top_buckets]
        
        assert self['threshold'] is not None
        r = BucketPage(
                       buckets=buckets,
                       total=total,
                       search=self,
                       from_=from_,
                       size=size
                       )
        return r
    
class ReportThreshold(Threshold):
    def __init__(self, search, result, from_=None, size=None):
        super(ReportThreshold, self).__init__(result)

# 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/bucket.py
# class Bucket(PCDict):
#     """
#     namedtuple('Bucket', 'id threshold total top_reports first_seen')
#     Data class for buckets. Contains two identifiers:
#      - id: The bucket's ID;
#      - total: how many reports are currently in the bucket.
#     """
#     __slots__ = tuple()
#     
#     canonical_fields = {
#         'id': key_type,
#         'threshold': mustbe_threshold,
#         'first_seen': mustbe_date,
#         'last_seen': mustbe_date,
#         'total': mustbe_int,
#     }
#         
#     #def __init__(self, *args, **kwargs):
#         #super(Bucket, self).__init__(*args, **kwargs)
#         #assert 'id' in self
#         #assert 'threshold' in self
#     
#     @classmethod
#     def new(cls, threshold, **kwargs):
#         kwargs['threshold'] = threshold
#         assert 'id' not in kwargs
#         kwargs['id'] = random_bucketid()
#         return Bucket(**kwargs)
#     
#     def jsonify(self):
#         return self.as_dict()
# 
# Path: partycrasher/api/report_bucket.py
# class ReportBucket(Bucket):
#     __slots__ = ('reports',)
#     
#     def __init__(self, search, from_=None, size=None, **kwargs):
#         super(ReportBucket, self).__init__(kwargs)
#         self.reports = ReportBucketSearch(search=search,
#                         bucket_id=self['id'],
#                         threshold=self['threshold'],
#                         from_=from_,
#                         size=size
#                         )
#     
#     def restify(self):
#         d = copy(self._d)
#         d['reports'] = self.reports
#         return d


# Path: partycrasher/api/report_threshold.py
import logging
from copy import copy
from partycrasher.threshold import Threshold
from partycrasher.bucket import Bucket
from partycrasher.api.search import Page, Search
from partycrasher.api.report_bucket import ReportBucket
from partycrasher.pc_encoder import pretty

        else:
            size = total
        
        first_page = self.new_first_page()
        
        buckets = [ReportBucket(
                        search=first_page, 
                        id=bucket['key'], 
                        project=self['project'],
                        type=self['type'],
                        threshold=self['threshold'],
                        total=bucket['doc_count'],
                        first_seen=bucket['first_seen']['value_as_string'],
                        last_seen=bucket['last_seen']['value_as_string'],
                        )
                   for bucket in top_buckets]
        
        assert self['threshold'] is not None
        r = BucketPage(
                       buckets=buckets,
                       total=total,
                       search=self,
                       from_=from_,
                       size=size
                       )
        return r
    
class ReportThreshold(Threshold):
    def __init__(self, search, result, from_=None, size=None):
        super(ReportThreshold, self).__init__(result)

        search = BucketSearch(search=search, threshold=Threshold(self))