# Path: user_metrics/etl/aggregator.py
# METRIC_AGG_METHOD_FLAG = 'metric_agg_flag'
# 
# METRIC_AGG_METHOD_NAME = 'metric_agg_name'
# 
# METRIC_AGG_METHOD_HEAD = 'metric_agg_head'
# 
# METRIC_AGG_METHOD_KWARGS = 'metric_agg_kwargs'
# 
# Path: user_metrics/etl/aggregator.py
# def decorator_builder(header):
#     """
#         Decorator method to annotate aggregation methods to ensure the correct
#         data model is exposed by::
# 
#             metric_agg = decorator_builder(Metric.header())(metric_agg)
#     """
#     def eval_data_model(f):
#         def wrapper(metric, **kwargs):
#             if hasattr(metric, 'header'):
#                 header_arg = metric.header()
#                 if all(
#                         header_arg[i] == header[i]
#                         for i in range(len(header)-1)):
#                     return f(metric, **kwargs)
#             else:
#                 raise AggregatorError('This aggregator (%s) does not operate '
#                                       'on this data type.' % f.__name__)
#         return wrapper
#     return eval_data_model
# 
# def boolean_rate(iter, **kwargs):
#     """
#         Computes the fraction of rows meeting a comparison criteria defined
#         by `cmp_method`.  The index containing the value is passed as a kwarg
#         (`bool_idx`).
# 
#         Useful aggregator for boolean metrics: threshold, survival,
#                 live_accounts
#     """
# 
#     def cmp_method_default(x):
#         return x > 0
# 
#     val_idx = kwargs['val_idx'] if 'val_idx' in kwargs else 1
#     cmp_method = kwargs['cmp_method'] if 'cmp_method' in kwargs \
#         else cmp_method_default
# 
#     total = 0
#     pos = 0
#     for r in iter.__iter__():
#         try:
#             if cmp_method(r[val_idx]):
#                 pos += 1
#             total += 1
#         except IndexError:
#             continue
#         except TypeError:
#             continue
#     if total:
#         return [total, pos, float(pos) / total]
#     else:
#         return [total, pos, 0.0]
# 
# def build_numpy_op_agg(agg_meta_list, metric_header, method_handle):
#     """
#         Builder method for ``numpy_op`` aggregator.
#     """
#     agg_method = numpy_op
#     agg_method = decorator_builder(metric_header)(agg_method)
#     agg_meta_header = [o.field_name for o in agg_meta_list]
# 
#     setattr(agg_method, METRIC_AGG_METHOD_FLAG, True)
#     setattr(agg_method, METRIC_AGG_METHOD_NAME, method_handle)
#     setattr(agg_method, METRIC_AGG_METHOD_HEAD, agg_meta_header)
#     setattr(agg_method, METRIC_AGG_METHOD_KWARGS,
#             {
#                 'agg_meta': agg_meta_list
#             }
#             )
#     return agg_method
# 
# def build_agg_meta(op_list, field_prefix_names):
#     """
#         Builder helper method for building module aggregators via
#         ``build_numpy_op_agg``.
#     """
#     return [AggregatorMeta(name + op.__name__, index, op)
#             for name, index in field_prefix_names.iteritems()
#             for op in op_list]


from user_metrics.config import logging
from collections import namedtuple
from user_metrics.etl.aggregator import METRIC_AGG_METHOD_FLAG,\
    METRIC_AGG_METHOD_NAME, METRIC_AGG_METHOD_HEAD, METRIC_AGG_METHOD_KWARGS
from user_metrics.etl.aggregator import decorator_builder, boolean_rate, \
    build_numpy_op_agg, build_agg_meta
from numpy import mean
from user_metrics.metrics import query_mod
from user_metrics.metrics.users import UMP_MAP
from user_metrics.utils import format_mediawiki_timestamp
import user_metric as um
import os
import user_metrics.utils.multiprocessing_wrapper as mpw
# ==========================

metric_header = RevertRate.header()

field_prefixes = \
    {
        'reverted_': 1,
        'reverts_': 2,
        'revisions_': 3,
    }

# Build "stats" aggregator
op_list = [sum, mean]
revert_stats_agg = build_numpy_op_agg(build_agg_meta(op_list, field_prefixes),
                                      metric_header,
                                      'revert_stats_agg')

agg_kwargs = getattr(revert_stats_agg, METRIC_AGG_METHOD_KWARGS)
setattr(revert_stats_agg, METRIC_AGG_METHOD_KWARGS, agg_kwargs)

# Build proportion aggregator
revert_prop_agg = boolean_rate
revert_prop_agg = decorator_builder(RevertRate.header())(
    revert_prop_agg)

setattr(revert_prop_agg, METRIC_AGG_METHOD_FLAG, True)
setattr(revert_prop_agg, METRIC_AGG_METHOD_NAME, 'revert_prop_agg')
setattr(revert_prop_agg, METRIC_AGG_METHOD_HEAD, ['total_users',
                                                     'total_reverted',
                                                     'rate', ])

# Path: user_metrics/etl/aggregator.py
# METRIC_AGG_METHOD_FLAG = 'metric_agg_flag'
# 
# METRIC_AGG_METHOD_NAME = 'metric_agg_name'
# 
# METRIC_AGG_METHOD_HEAD = 'metric_agg_head'
# 
# METRIC_AGG_METHOD_KWARGS = 'metric_agg_kwargs'
# 
# Path: user_metrics/etl/aggregator.py
# def decorator_builder(header):
#     """
#         Decorator method to annotate aggregation methods to ensure the correct
#         data model is exposed by::
# 
#             metric_agg = decorator_builder(Metric.header())(metric_agg)
#     """
#     def eval_data_model(f):
#         def wrapper(metric, **kwargs):
#             if hasattr(metric, 'header'):
#                 header_arg = metric.header()
#                 if all(
#                         header_arg[i] == header[i]
#                         for i in range(len(header)-1)):
#                     return f(metric, **kwargs)
#             else:
#                 raise AggregatorError('This aggregator (%s) does not operate '
#                                       'on this data type.' % f.__name__)
#         return wrapper
#     return eval_data_model
# 
# def boolean_rate(iter, **kwargs):
#     """
#         Computes the fraction of rows meeting a comparison criteria defined
#         by `cmp_method`.  The index containing the value is passed as a kwarg
#         (`bool_idx`).
# 
#         Useful aggregator for boolean metrics: threshold, survival,
#                 live_accounts
#     """
# 
#     def cmp_method_default(x):
#         return x > 0
# 
#     val_idx = kwargs['val_idx'] if 'val_idx' in kwargs else 1
#     cmp_method = kwargs['cmp_method'] if 'cmp_method' in kwargs \
#         else cmp_method_default
# 
#     total = 0
#     pos = 0
#     for r in iter.__iter__():
#         try:
#             if cmp_method(r[val_idx]):
#                 pos += 1
#             total += 1
#         except IndexError:
#             continue
#         except TypeError:
#             continue
#     if total:
#         return [total, pos, float(pos) / total]
#     else:
#         return [total, pos, 0.0]
# 
# def build_numpy_op_agg(agg_meta_list, metric_header, method_handle):
#     """
#         Builder method for ``numpy_op`` aggregator.
#     """
#     agg_method = numpy_op
#     agg_method = decorator_builder(metric_header)(agg_method)
#     agg_meta_header = [o.field_name for o in agg_meta_list]
# 
#     setattr(agg_method, METRIC_AGG_METHOD_FLAG, True)
#     setattr(agg_method, METRIC_AGG_METHOD_NAME, method_handle)
#     setattr(agg_method, METRIC_AGG_METHOD_HEAD, agg_meta_header)
#     setattr(agg_method, METRIC_AGG_METHOD_KWARGS,
#             {
#                 'agg_meta': agg_meta_list
#             }
#             )
#     return agg_method
# 
# def build_agg_meta(op_list, field_prefix_names):
#     """
#         Builder helper method for building module aggregators via
#         ``build_numpy_op_agg``.
#     """
#     return [AggregatorMeta(name + op.__name__, index, op)
#             for name, index in field_prefix_names.iteritems()
#             for op in op_list]


# Path: user_metrics/metrics/revert_rate.py
from user_metrics.config import logging
from collections import namedtuple
from user_metrics.etl.aggregator import METRIC_AGG_METHOD_FLAG,\
    METRIC_AGG_METHOD_NAME, METRIC_AGG_METHOD_HEAD, METRIC_AGG_METHOD_KWARGS
from user_metrics.etl.aggregator import decorator_builder, boolean_rate, \
    build_numpy_op_agg, build_agg_meta
from numpy import mean
from user_metrics.metrics import query_mod
from user_metrics.metrics.users import UMP_MAP
from user_metrics.utils import format_mediawiki_timestamp
import user_metric as um
import os
import user_metrics.utils.multiprocessing_wrapper as mpw

# ==========================

metric_header = RevertRate.header()

field_prefixes = \
    {
        'reverted_': 1,
        'reverts_': 2,
        'revisions_': 3,
    }

# Build "stats" aggregator
op_list = [sum, mean]
revert_stats_agg = build_numpy_op_agg(build_agg_meta(op_list, field_prefixes),
                                      metric_header,
                                      'revert_stats_agg')

agg_kwargs = getattr(revert_stats_agg, METRIC_AGG_METHOD_KWARGS)
setattr(revert_stats_agg, METRIC_AGG_METHOD_KWARGS, agg_kwargs)

# Build proportion aggregator
revert_prop_agg = boolean_rate
revert_prop_agg = decorator_builder(RevertRate.header())(
    revert_prop_agg)

setattr(revert_prop_agg, METRIC_AGG_METHOD_FLAG, True)
setattr(revert_prop_agg, METRIC_AGG_METHOD_NAME, 'revert_prop_agg')
setattr(revert_prop_agg, METRIC_AGG_METHOD_HEAD, ['total_users',
                                                     'total_reverted',
                                                     'rate', ])

setattr(revert_prop_agg, METRIC_AGG_METHOD_KWARGS, {'val_idx': 1})