import numpy as np
from qti.aisw.converters.common.converter_ir.op_adapter import (
    ConstantOp,
    ElementwiseAndOp,
    ElementwiseDivOp,
    ElementwiseEqualOp,
    ElementwiseFloorDivOp,
    ElementwiseGreaterOp,
    ElementwiseGreaterEqualOp,
    ElementwiseLessOp,
    ElementwiseLessEqualOp,
    ElementwiseMaxOp,
    ElementwiseMinOp,
    ElementwiseNotEqualOp,
    ElementwiseOrOp,
    ElementwiseProductOp,
    ElementwiseSelectOp,
    ElementwiseSubOp,
    ElementwiseSumOp,
)
from qti.aisw.converters.tensorflow.common import LayerDescriptor, LayerResolver, LayerBuilder
from qti.aisw.converters.tensorflow.layers.constant import ConstantLayerResolver
from abc import ABC, abstractmethod
from qti.aisw.converters.tensorflow.graph_matcher import (
    ConverterSequenceNode,
    NonConsumableConverterSequenceNode,
    GraphSequence
)

class EltWiseBiasaddLayerResolver(LayerResolver):
    class Descriptor(LayerDescriptor):
        def __init__(self, name, nodes, bias_name, bias):
            super(EltWiseBiasaddLayerResolver.Descriptor, self).__init__('BiasAdd', name, nodes)
            self.bias_tensor = bias
            self.bias_name = bias_name

    def __init__(self):
        super(EltWiseBiasaddLayerResolver, self).__init__()

        self.sequence = GraphSequence([
            ConverterSequenceNode('root', ['BiasAdd']),
            NonConsumableConverterSequenceNode('bias', ['?']),
            NonConsumableConverterSequenceNode('input', ['?']),
        ])
        self.sequence.set_inputs('root', ['input', 'bias'])
        self.sequence.set_outputs(['root'])

    def resolve_layer(self, graph_matcher, graph_helper):
        descriptors = []
        for match in graph_matcher.match_sequence(self.sequence):
            eltwise_op = match['root']
            bias_op = match['bias']
            bias = graph_helper.evaluate_tensor_output(bias_op.outputs[0])
            descriptor = EltWiseBiasaddLayerResolver.Descriptor(str(eltwise_op.name),
                                                                match.consumed_nodes,
                                                                str(bias_op.name),
                                                                bias)
            descriptors.append(descriptor)

        return descriptors

class EltWiseBiasaddLayerBuilder(LayerBuilder):
    def build_layer(self, ir_graph, converter_context, descriptor, input_descriptors, output_descriptors):
        """
        :type ir_graph: converters.common.converter_ir.op_graph.IROpGraph
        :type converter_context: converters.tensorflow.converter.ConverterContext
        :type descriptor: EltWiseBiasaddResolver.Descriptor
        :type input_descriptors: [converters.tensorflow.common.LayerDescriptor]
        :type output_descriptors: [converters.tensorflow.common.LayerDescriptor]
        :rtype: int
        """
        input_names = self.get_input_names(converter_context, descriptor, input_descriptors)
        output_name = descriptor.output_names[0]

        return ir_graph.add(ElementwiseSumOp(descriptor.layer_name),
                            input_names,
                            output_name)

class EltWiseLayerResolver(LayerResolver, ABC, object):

    class Descriptor(LayerDescriptor):
        def __init__(self, op_type, name, nodes, output_names=None, unary=False):
            super(EltWiseLayerResolver.Descriptor, self).__init__(op_type, name, nodes, output_names=output_names)
            self.unary = unary

    def __init__(self, layer_type, op_type, descriptor_class):
        super(EltWiseLayerResolver, self).__init__()
        self._layer_type = layer_type
        self._op_type = op_type
        self._descriptor_class = descriptor_class

        self.sequence = GraphSequence([
            ConverterSequenceNode('root', self._op_type),
        ])
        self.sequence.set_outputs(['root'])

        # used for FRVSR
        self.sequence3 = GraphSequence([
            NonConsumableConverterSequenceNode('input1', ['Shape']),
            NonConsumableConverterSequenceNode('input2', ['?']),
            NonConsumableConverterSequenceNode('strided_slice_2', ['StridedSlice']),
            NonConsumableConverterSequenceNode('strided_slice_1', ['StridedSlice']),
            ConverterSequenceNode('range', ['Range']),
            ConverterSequenceNode('size', ['Size']),
            ConverterSequenceNode('size_1', ['Size']),
            ConverterSequenceNode('range1', ['Range']),
            ConverterSequenceNode('reshape', ['Reshape']),
            ConverterSequenceNode('packed', ['Pack']),
            ConverterSequenceNode('reshape1', ['Reshape']),
            ConverterSequenceNode('reshape2', ['Reshape']),
            ConverterSequenceNode('ones', ['Fill']),
            ConverterSequenceNode('reshape3', ['Reshape']),
            ConverterSequenceNode('mul', ['Mul']),
            ConverterSequenceNode('mul1', ['Mul']),
            ConverterSequenceNode('stack', ['Pack']),
            ConverterSequenceNode('cast', ['Cast']),
            ConverterSequenceNode('const_frvsr', ['ExpandDims']),
            ConverterSequenceNode('root', self._op_type),
            NonConsumableConverterSequenceNode('stub_19', ['?']),
            NonConsumableConverterSequenceNode('stub_20', ['?']),
            NonConsumableConverterSequenceNode('stub_21', ['?']),
            NonConsumableConverterSequenceNode('stub_22', ['?']),
            NonConsumableConverterSequenceNode('stub_23', ['?']),
            NonConsumableConverterSequenceNode('stub_24', ['?']),
            ConverterSequenceNode('stub_25', ['?']),
            ConverterSequenceNode('stub_26', ['?']),
            ConverterSequenceNode('stub_27', ['?']),
            ConverterSequenceNode('stub_28', ['?']),
            ConverterSequenceNode('stub_29', ['?']),
            ConverterSequenceNode('stub_30', ['?']),
            ConverterSequenceNode('stub_31', ['?']),
            ConverterSequenceNode('stub_32', ['?']),
            ConverterSequenceNode('stub_33', ['?']),
            ConverterSequenceNode('stub_34', ['?']),
        ])
        self.sequence3.set_inputs('strided_slice_2', ['input1', 'stub_19', 'stub_20', 'stub_21'])
        self.sequence3.set_inputs('range', ['stub_25', 'strided_slice_2', 'stub_26'])
        self.sequence3.set_inputs('reshape', ['range', 'stub_29'])
        self.sequence3.set_inputs('reshape2', ['reshape', 'stub_31'])
        self.sequence3.set_inputs('size', ['range'])
        self.sequence3.set_inputs('size_1', ['range1'])
        self.sequence3.set_inputs('packed', ['size_1', 'size'])
        self.sequence3.set_inputs('ones', ['packed', 'stub_32'])
        self.sequence3.set_inputs('mul', ['reshape2', 'ones'])
        self.sequence3.set_inputs('strided_slice_1', ['input1', 'stub_22', 'stub_23', 'stub_24'])
        self.sequence3.set_inputs('range1', ['stub_27', 'strided_slice_1', 'stub_28'])
        self.sequence3.set_inputs('reshape1', ['range1', 'stub_30'])
        self.sequence3.set_inputs('reshape3', ['reshape1', 'stub_33'])
        self.sequence3.set_inputs('mul1', ['reshape3', 'ones'])
        self.sequence3.set_inputs('stack', ['mul1', 'mul'])
        self.sequence3.set_inputs('cast', ['stack'])
        self.sequence3.set_inputs('const_frvsr', ['cast', 'stub_34'])
        self.sequence3.set_inputs('root', ['const_frvsr', 'input2'])
        self.sequence3.set_outputs(['root'])

        # used for FRVSR
        self.sequence4 = GraphSequence([
            NonConsumableConverterSequenceNode('input1', ['Shape']),
            NonConsumableConverterSequenceNode('input2', ['?']),
            ConverterSequenceNode('strided_slice', ['StridedSlice']),
            ConverterSequenceNode('stub_1', ['Const']),
            ConverterSequenceNode('stub_2', ['Const']),
            ConverterSequenceNode('stub_3', ['Const']),
            ConverterSequenceNode('const_frvsr', ['Cast']),
            ConverterSequenceNode('root', self._op_type),
        ])
        self.sequence4.set_inputs('strided_slice', ['input1', 'stub_1', 'stub_2', 'stub_3'])
        self.sequence4.set_inputs('const_frvsr', ['strided_slice'])
        self.sequence4.set_inputs('root', ['const_frvsr', 'input2'])
        self.sequence4.set_outputs(['root'])

        self.sequence5 = GraphSequence([
            ConverterSequenceNode('root', self._op_type),
            NonConsumableConverterSequenceNode('const_frvsr', ['StridedSlice']),
            NonConsumableConverterSequenceNode('begin', ['Const']),
            NonConsumableConverterSequenceNode('end', ['Const']),
            NonConsumableConverterSequenceNode('strides', ['Const']),
            NonConsumableConverterSequenceNode('input', ['Shape']),
            NonConsumableConverterSequenceNode('input1', ['?']),
        ])
        self.sequence5.set_inputs('const_frvsr', ['input', 'begin', 'end', 'strides'])
        self.sequence5.set_inputs('root', ['input1', 'const_frvsr'])
        self.sequence5.set_outputs(['root'])

        # used for FRVSR
        self.sequence6 = GraphSequence([
            NonConsumableConverterSequenceNode('input1', ['Shape']),
            NonConsumableConverterSequenceNode('input2', ['?']),
            ConverterSequenceNode('strided_slice', ['StridedSlice']),
            ConverterSequenceNode('stub_1', ['Const']),
            ConverterSequenceNode('stub_2', ['Const']),
            ConverterSequenceNode('stub_3', ['Const']),
            ConverterSequenceNode('sub', ['Sub']),
            ConverterSequenceNode('sub_const', ['Const']),
            ConverterSequenceNode('const_frvsr', ['Cast']),
            ConverterSequenceNode('root', self._op_type),
        ])
        self.sequence6.set_inputs('strided_slice', ['input1', 'stub_1', 'stub_2', 'stub_3'])
        self.sequence6.set_inputs('sub', ['sub_const', 'strided_slice'])
        self.sequence6.set_inputs('const_frvsr', ['sub'])
        self.sequence6.set_inputs('root', ['const_frvsr', 'input2'])
        self.sequence6.set_outputs(['root'])

        self.sequence7 = GraphSequence([
            NonConsumableConverterSequenceNode('input', ['Shape']),
            NonConsumableConverterSequenceNode('input1', ['?']),
            NonConsumableConverterSequenceNode('strided_slice_1', ['StridedSlice']),
            NonConsumableConverterSequenceNode('range', ['Range']),
            NonConsumableConverterSequenceNode('strided_slice', ['StridedSlice']),
            NonConsumableConverterSequenceNode('strided_slice_2', ['StridedSlice']),
            NonConsumableConverterSequenceNode('mul2', ['Mul']),
            NonConsumableConverterSequenceNode('pack', ['Pack']),
            NonConsumableConverterSequenceNode('mul3', ['Mul']),
            ConverterSequenceNode('const_frvsr', ['Reshape']),
            ConverterSequenceNode('root', self._op_type),
            NonConsumableConverterSequenceNode('stub_10', ['?']),
            NonConsumableConverterSequenceNode('stub_11', ['?']),
            NonConsumableConverterSequenceNode('stub_12', ['?']),
            NonConsumableConverterSequenceNode('stub_13', ['?']),
            NonConsumableConverterSequenceNode('stub_14', ['?']),
            NonConsumableConverterSequenceNode('stub_15', ['?']),
            NonConsumableConverterSequenceNode('stub_16', ['?']),
            NonConsumableConverterSequenceNode('stub_17', ['?']),
            NonConsumableConverterSequenceNode('stub_18', ['?']),
            NonConsumableConverterSequenceNode('stub_19', ['?']),
            NonConsumableConverterSequenceNode('stub_20', ['?']),
            NonConsumableConverterSequenceNode('stub_21', ['?']),
        ])
        self.sequence7.set_inputs('strided_slice', ['input', 'stub_15', 'stub_16', 'stub_17'])
        self.sequence7.set_inputs('range', ['strided_slice', 'stub_13', 'stub_14'])
        self.sequence7.set_inputs('strided_slice_1', ['input', 'stub_10', 'stub_11', 'stub_12'])
        self.sequence7.set_inputs('mul2', ['range', 'strided_slice_1'])
        self.sequence7.set_inputs('strided_slice_2', ['input', 'stub_18', 'stub_19', 'stub_20'])
        self.sequence7.set_inputs('mul3', ['mul2', 'strided_slice_2'])
        self.sequence7.set_inputs('pack', ['strided_slice', 'stub_21'])
        self.sequence7.set_inputs('const_frvsr', ['mul3', 'pack'])
        self.sequence7.set_inputs('root', ['const_frvsr', 'input1'])
        self.sequence7.set_outputs(['root'])

        self.sequence_with_identity = GraphSequence([
            ConverterSequenceNode('root', self._op_type),
            ConverterSequenceNode('identity', ['Identity']),
            NonConsumableConverterSequenceNode('input1', ['?']),
            NonConsumableConverterSequenceNode('input2', ['?'])
        ])
        self.sequence_with_identity.set_inputs('identity', ['root'])
        self.sequence_with_identity.set_inputs('root', ['input1', 'input2'])
        self.sequence_with_identity.set_outputs(['identity'])

        self.sequence_with_const_input = GraphSequence([
            ConverterSequenceNode('root', self._op_type),
            NonConsumableConverterSequenceNode('const', ['Const']),
            NonConsumableConverterSequenceNode('other', ['?'])
        ])

        self.sequence_with_const_input.set_inputs('root', ['const', 'other'])
        self.sequence_with_const_input.set_outputs(['root'])

        self.sequence_with_const_or_identity_input = GraphSequence([
            ConverterSequenceNode('root', self._op_type),
            NonConsumableConverterSequenceNode('const', ['Const', 'Identity']),
            NonConsumableConverterSequenceNode('other', ['?'])
        ])
        self.sequence_with_const_or_identity_input.set_inputs('root', ['const', 'other'])
        self.sequence_with_const_or_identity_input.set_outputs(['root'])

        self.sequence_with_const_input_and_identity = GraphSequence([
            ConverterSequenceNode('root', self._op_type),
            ConverterSequenceNode('identity', ['Identity']),
            NonConsumableConverterSequenceNode('const', ['Const', 'Identity']),
            NonConsumableConverterSequenceNode('other', ['?'])
        ])
        self.sequence_with_const_input_and_identity.set_inputs('root', ['const', 'other'])
        self.sequence_with_const_input_and_identity.set_inputs('identity', ['root'])
        self.sequence_with_const_input_and_identity.set_outputs(['identity'])

    def resolve_layer(self, graph_matcher, graph_helper):
        descriptors = []

        # Matches basic sequence with root and n-inputs
        for match in graph_matcher.match_sequence(self.sequence):
            eltwise_op = match['root']
            descriptor = self._descriptor_class(self._layer_type, str(eltwise_op.name), match.consumed_nodes,
                                                unary=(eltwise_op.inputs[0] == eltwise_op.inputs[1]))
            descriptors.append(descriptor)

        non_const_input_sequences = [self.sequence_with_identity]
        for sequence in non_const_input_sequences:
            for match in graph_matcher.match_sequence(sequence):
                eltwise_op = match['root']
                descriptor = self._descriptor_class(self._layer_type, str(eltwise_op.name), match.consumed_nodes)
                descriptors.append(descriptor)

        frvsr_sequences = [self.sequence3, self.sequence4, self.sequence5, self.sequence6, self.sequence7]
        for sequence in frvsr_sequences:
            for match in graph_matcher.match_sequence(sequence):
                eltwise_op = match['root']
                eltwise_descriptor = self._descriptor_class(self._layer_type, str(eltwise_op.name), [eltwise_op])
                descriptors.append(eltwise_descriptor)

                const_op = match['const_frvsr']
                consumed_nodes = match.consumed_nodes
                consumed_nodes.remove(eltwise_op)
                if len(consumed_nodes) == 0:
                    consumed_nodes.append(const_op)

                const_tensor = graph_helper.evaluate_tensor_output(const_op.outputs[0])

                # Sub RealDiv Mul Min Max Ops support dynamic broadcasting
                # Eltwise sum op is not broadcasted here. It is checked for squashing in optimizations step
                # If squash not possible the OP is broadcasted in OP graph optimizations
                eltwise_shape = graph_helper.get_op_output_shape(const_op)
                if not eltwise_shape:
                    eltwise_shape = [1]

                const_descriptor = ConstantLayerResolver.Descriptor(str(const_op.name), consumed_nodes,
                                                                    const_tensor, eltwise_shape, eltwise_descriptor)
                descriptors.append(const_descriptor)

        const_input_sequences = [self.sequence_with_const_input_and_identity, self.sequence_with_const_input, self.sequence_with_const_or_identity_input]
        for sequence in const_input_sequences:
            for match in graph_matcher.match_sequence(sequence):
                eltwise_op = match['root']
                eltwise_descriptor = self._descriptor_class(self._layer_type, str(eltwise_op.name),
                                                            match.consumed_nodes)
                descriptors.append(eltwise_descriptor)

                const_op = match['const']
                const_consumed_ops = [const_op]
                while const_op.type == 'Identity':
                    const_op = const_op.inputs[0].op
                    const_consumed_ops.append(const_op)

                if const_op.type != 'Const':
                    continue

                const_tensor = graph_helper.evaluate_tensor_output(const_op.outputs[0])

                # Sub RealDiv Mul Min Max Ops support dynamic broadcasting
                # Eltwise sum op is not broadcasted here. It is checked for squashing in optimizations step
                # If squash not possible the OP is broadcasted in OP graph optimizations
                for op_type in self._op_type:
                    eltwise_shape = graph_helper.get_op_output_shape(const_op)
                    if not eltwise_shape:
                        eltwise_shape = [1]

                const_descriptor = ConstantLayerResolver.Descriptor(str(const_op.name), const_consumed_ops,
                                                                    const_tensor, eltwise_shape, eltwise_descriptor)
                descriptors.append(const_descriptor)

        return descriptors

class EltWiseLayerBuilder(LayerBuilder, ABC):
    def build_layer(self, ir_graph, converter_context, descriptor, input_descriptors, output_descriptors):
        """
        :type ir_graph: converters.common.converter_ir.op_graph.IROpGraph
        :type input_descriptors: [converters.tensorflow.common.LayerDescriptor]
        :type output_descriptors: [converters.tensorflow.common.LayerDescriptor]
        :type converter_context: converters.tensorflow.converter.ConverterContext
        :type descriptor: EltWiseAndLayerResolver.Descriptor
        :rtype: int
        """
        input_names = self.get_input_names(converter_context, descriptor, input_descriptors)
        output_name = descriptor.output_names[0]

        # In case there is one input used twice, duplicate the input name
        if descriptor.unary:
            input_names = input_names * 2

        return ir_graph.add(self._op_class(descriptor.layer_name),
                            input_names,
                            output_name)

class EltWiseAndLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseAndLayerResolver, self).__init__('ElementWiseAnd', ['LogicalAnd'],
                                                      EltWiseAndLayerResolver.Descriptor)

class EltWiseAndLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseAndLayerBuilder, self).__init__()
        self._op_class = ElementwiseAndOp

class EltWiseEqualLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseEqualLayerResolver, self).__init__('ElementWiseEqual', ['Equal'],
                                                        EltWiseEqualLayerResolver.Descriptor)

class EltWiseFloorDivLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseFloorDivLayerBuilder, self).__init__()
        self._op_class = ElementwiseFloorDivOp

class EltWiseFloorDivLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseFloorDivLayerResolver, self).__init__('ElementWiseFloorDiv', ['FloorDiv'],
                                                           EltWiseFloorDivLayerResolver.Descriptor)

class EltWiseEqualLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseEqualLayerBuilder, self).__init__()
        self._op_class = ElementwiseEqualOp

class EltWiseGreaterLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseGreaterLayerResolver, self).__init__('ElementWiseGreater', ['Greater'],
                                                          EltWiseGreaterLayerResolver.Descriptor)

class EltWiseGreaterLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseGreaterLayerBuilder, self).__init__()
        self._op_class = ElementwiseGreaterOp

class EltWiseGreaterEqualLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseGreaterEqualLayerResolver, self).__init__('ElementWiseGreaterEqual', ['GreaterEqual'],
                                                               EltWiseGreaterEqualLayerResolver.Descriptor)

class EltWiseGreaterEqualLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseGreaterEqualLayerBuilder, self).__init__()
        self._op_class = ElementwiseGreaterEqualOp

class EltWiseLessLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseLessLayerResolver, self).__init__('ElementWiseLess', ['Less'], EltWiseLessLayerResolver.Descriptor)

class EltWiseLessLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseLessLayerBuilder, self).__init__()
        self._op_class = ElementwiseLessOp

class EltWiseLessEqualLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseLessEqualLayerResolver, self).__init__('ElementWiseLessEqual', ['LessEqual'],
                                                            EltWiseLessEqualLayerResolver.Descriptor)

class EltWiseLessEqualLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseLessEqualLayerBuilder, self).__init__()
        self._op_class = ElementwiseLessEqualOp

class EltWiseNotEqualLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseNotEqualLayerResolver, self).__init__('ElementWiseNotEqual', ['NotEqual'],
                                                           EltWiseNotEqualLayerResolver.Descriptor)

class EltWiseNotEqualLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseNotEqualLayerBuilder, self).__init__()
        self._op_class = ElementwiseNotEqualOp

class EltWiseOrLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseOrLayerResolver, self).__init__('ElementWiseOr', ['LogicalOr'],
                                                     EltWiseOrLayerResolver.Descriptor)

class EltWiseOrLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseOrLayerBuilder, self).__init__()
        self._op_class = ElementwiseOrOp

class EltWiseSelectLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseSelectLayerResolver, self).__init__('ElementWiseSelect', ['Select'],
                                                         EltWiseSelectLayerResolver.Descriptor)

class EltWiseSelectLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseSelectLayerBuilder, self).__init__()
        self._op_class = ElementwiseSelectOp

class EltWiseSumLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseSumLayerResolver, self).__init__('ElementWiseSum', ['Add', 'AddV2'],
                                                      EltWiseSumLayerResolver.Descriptor)

class EltWiseSumLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseSumLayerBuilder, self).__init__()
        self._op_class = ElementwiseSumOp

class EltWiseSubLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseSubLayerResolver, self).__init__('ElementWiseSub', ['Sub'], EltWiseSubLayerResolver.Descriptor)

class EltWiseSubLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseSubLayerBuilder, self).__init__()
        self._op_class = ElementwiseSubOp

class EltWiseMulLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseMulLayerResolver, self).__init__('ElementWiseMul', ['Mul'], EltWiseMulLayerResolver.Descriptor)

class EltWiseMulLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseMulLayerBuilder, self).__init__()
        self._op_class = ElementwiseProductOp

class EltWiseMaxLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseMaxLayerResolver, self).__init__('ElementWiseMax', ['Maximum'], EltWiseMaxLayerResolver.Descriptor)

class EltWiseMaxLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseMaxLayerBuilder, self).__init__()
        self._op_class = ElementwiseMaxOp

class EltWiseMinLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseMinLayerResolver, self).__init__('ElementWiseMin', ['Minimum'], EltWiseMinLayerResolver.Descriptor)

class EltWiseMinLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseMinLayerBuilder, self).__init__()
        self._op_class = ElementwiseMinOp

class EltWiseDivLayerResolver(EltWiseLayerResolver):
    class Descriptor(EltWiseLayerResolver.Descriptor):
        pass

    def __init__(self):
        super(EltWiseDivLayerResolver, self).__init__('ElementWiseDiv', ['RealDiv'], EltWiseDivLayerResolver.Descriptor)

class EltWiseDivLayerBuilder(EltWiseLayerBuilder):
    def __init__(self):
        super(EltWiseDivLayerBuilder, self).__init__()
        self._op_class = ElementwiseDivOp

    def transform_layer(self, ir_graph, converter_context, descriptor, input_descriptors, output_descriptors):

        constant_input_descriptor = [d for d in input_descriptors if isinstance(d, ConstantLayerResolver.Descriptor)]
        if len(constant_input_descriptor) == 1 and np.all(constant_input_descriptor[0].value == 1):
            descriptor.set_ignored(True)
            constant_input_descriptor[0].set_ignored(True)


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Fri May  4 19:07:34 2018

@author: abinaya
"""

import numpy as np
import matplotlib.pyplot as plt
import random

class Traveling_Salesmen_problem():

    def __init__(self, no_cities, T, cooling_function, max_iter):
        self.no_cities = no_cities
        self.T = T
        self.cooling_function = cooling_function
        self.max_iter = max_iter

    def generate_cities(self):
        return [random.sample(range(0,1000), 2) for x in range(self.no_cities)]

    def generate_initial_random_tour(self):
        return random.sample(range(self.no_cities),self.no_cities)

    def travel_cost(self, tour):
        cost = 0
        for i in range(0, self.no_cities-1):
            from_city_index = tour[i]
            to_city_index = tour[i+1]
            from_city = self.cities[from_city_index]
            to_city = self.cities[to_city_index]
            cost += np.linalg.norm(np.array(from_city) - np.array(to_city))
        return cost

    def return_iterTemp(self,n):
        if self.cooling_function == "Polynomial":
            return self.T * pow(n+1, -0.751)
        elif self.cooling_function == "Logarithmic":
            return self.T / np.log(n+1)
        elif self.cooling_function == "Exponential":
            return self.T / np.exp(n+1)
        elif self.cooling_function == "Other":
            return self.T * 0.99

    def generate_acceptance_probability(self, tour_cost, swapped_tour_cost, iterT):
        return np.exp((tour_cost - swapped_tour_cost) / iterT)

    def solve_problem(self):
        self.cities = self.generate_cities()
        tour = self.generate_initial_random_tour()
        initial_tour = tour[:]

        cost_to_plot = []

        for i in range(0,self.max_iter):
            swap_positions =  random.sample(range(self.no_cities),2)
            swapped_tour = tour[:]
            swapped_tour[swap_positions[0]] = tour[swap_positions[1]]
            swapped_tour[swap_positions[1]] = tour[swap_positions[0]]

            tour_cost = self.travel_cost(tour)
            swapped_tour_cost = self.travel_cost(swapped_tour)

            iterT = self.return_iterTemp(i)

            acceptance_probability = self.generate_acceptance_probability(tour_cost, swapped_tour_cost, iterT)
            if(np.random.uniform() <= acceptance_probability):
                tour = swapped_tour[:]
                cost_to_plot.append(swapped_tour_cost)

        return initial_tour,tour, cost_to_plot

no_cities = 400
tr_sa_pr = Traveling_Salesmen_problem(no_cities, 1, "Other", 5000)
initial_tour,tour, cost_to_plot = tr_sa_pr.solve_problem()
oldx = zip(*[tr_sa_pr.cities[initial_tour[i % no_cities]] for i in range(no_cities+1)])[0]
oldy = zip(*[tr_sa_pr.cities[initial_tour[i % no_cities]] for i in range(no_cities+1)])[1]
newx = zip(*[tr_sa_pr.cities[tour[i % no_cities]] for i in range(no_cities+1)])[0]
newy = zip(*[tr_sa_pr.cities[tour[i % no_cities]] for i in range(no_cities+1)])[1]

plt.figure()
plt.plot(oldx, oldy, marker='o', color='r')
plt.grid('on')
plt.title('Initial Random Tour: Number of Cities = '+str(no_cities))

plt.figure()
plt.plot(newx, newy, color='g', marker='*')
plt.grid('on')
plt.title('Optmized Tour: Number of Cities = '+str(no_cities))

plt.figure()
plt.plot(cost_to_plot)
plt.xlabel('Iteration')
plt.ylabel('Cost')
plt.title('Number of Cities = '+str(no_cities))


import discord
from discord.ext import commands
import aiohttp
import datetime
from PIL import Image, ImageDraw, ImageFont

from functools import partial

from io import BytesIO

from discord_components import (
    Button,
    ButtonStyle,
)

class ImageCog(commands.Cog):
    def __init__(self, bot: commands.Bot):
        self.bot = bot
        self.session = aiohttp.ClientSession(loop=bot.loop)

    # getting the album cover
    async def get_image(self, url) -> BytesIO:
        async with self.session.get(url) as response:
            image_bytes = await response.read()

        return image_bytes

    @staticmethod
    def imgen(delta1, delta2, title: str, artist: str, album: str, image_bytes: bytes) -> BytesIO:

        myFont3 = ImageFont.truetype("assets/Roboto-Regular.ttf", 19)

        if title.isascii==False or album.isascii==False or artist.isascii==False:
            myFont2 = ImageFont.truetype("assets/code2000.ttf", 28)
            myFont1 = ImageFont.truetype("assets/code2000.ttf", 41)
        else:
            myFont1 = ImageFont.truetype("assets/Roboto-Regular.ttf", 41)
            myFont2 = ImageFont.truetype("assets/Roboto-Regular.ttf", 28)

        m1 = divmod(delta1.seconds, 60)
        m2 = divmod(delta2.seconds, 60)

        # we must use BytesIO to load the image here as PIL expects a stream instead of
        # just raw bytes.
        with Image.open(BytesIO(image_bytes)) as im:
            with Image.open("assets/template.jpg") as background:
                img2 = im.resize((210, 210))
                background.paste(img2, (36, 36))
                draw = ImageDraw.Draw(background)

                # title
                draw.text((303, 36), "{}".format(
                    title[:23]), font=myFont1, fill="#befe00")

                #artist and album
                draw.text((303, 99), "{}".format(artist[:33]),
                          font=myFont2, fill="#FFFFFF")
                draw.text((303, 147), "{}".format(
                    album[:33]), font=myFont2, fill="#FFFFFF")

                # timestamps

                draw.text((303, 229), "{}:{}".format(str(m1[0]).zfill(
                    2), str(m1[1]).zfill(2)), font=myFont3, fill="#FFFFFF")
                draw.text((855, 229), "{}:{}".format(str(m2[0]).zfill(
                    2), str(m2[1]).zfill(2)), font=myFont3, fill="#FFFFFF")

                # total progress bar
                draw.rounded_rectangle(
                    (303, 211, 897, 221), radius=7, fill='#FFFFFF', outline=None, width=10
                )

                # current progress
                # some math
                xbar = int((delta1.seconds/delta2.seconds)*594)
                draw.rounded_rectangle(
                    (303, 211, 303+xbar, 221), radius=7, fill='#befe00', outline=None, width=10
                )
                # prepare the stream to save this image into
                final_buffer = BytesIO()

                # save into the stream, using png format.
                background.save(final_buffer, "png")

        # seek back to the start of the stream
        final_buffer.seek(0)

        return final_buffer

    @commands.command(name='spotify', aliases=['spot'])
    async def spotify(self, ctx, user: discord.Member = None):

        user = user or ctx.author
        if user.activities:
            for activity in user.activities:

                if isinstance(activity, discord.Spotify):

                    delta1 = datetime.datetime.utcnow() - activity.start
                    delta2 = activity.end - activity.start
                    title = activity.title
                    artist = activity.artist
                    album = activity.album
                    url = activity.album_cover_url
                    songid = activity.track_id
                    spoturl = 'https://open.spotify.com/track/{}'.format(
                        songid)
                    image_bytes = await self.get_image(url)

                    # create partial function so we don't have to stack the args in run_in_executor
                    fn = partial(self.imgen, delta1, delta2,
                                 title, artist, album, image_bytes)

                    final_buffer = await self.bot.loop.run_in_executor(None, fn)
                    file = discord.File(
                        filename="spotify.png", fp=final_buffer)

                    await ctx.reply(file=file,
                        components=[Button(
                            style=ButtonStyle.URL,
                            label="Play On Spotify",
                            url=spoturl)])
                    break
            else:

                spotify = discord.Embed(
                    title="Uh Oh!",
                description="Looks like {} isn't listening to **Spotify <:spotify:887426366818115585>** right now. \nPerhaps [give it a shot?](https://www.spotify.com/)".format(user),
                colour=discord.Colour.gold(),
            ).set_footer(
                text="Q-Loggr Bot"
            )

                await ctx.reply(embed=spotify)

        else:

            spotify = discord.Embed(
                title="Uh Oh!",
                description="Looks like {} isn't listening to **Spotify <:spotify:887426366818115585>** right now. \nPerhaps [give it a shot?](https://www.spotify.com/)".format(user),
                colour=discord.Colour.gold(),
            ).set_footer(
                text="Q-Loggr Bot"
            )

            await ctx.reply(embed=spotify)

# setup function so this can be loaded as an extension
def setup(bot: commands.Bot):
    bot.add_cog(ImageCog(bot))


import argparse
import os
import json
from colorama import Fore, Style, init
import traceback
from pytube import YouTube
from tqdm import tqdm
import datetime
import cv2
import argparse

# Setting argparse tools
parse = argparse.ArgumentParser(description='Download Youtube Video and cut to frame.')
parse.add_argument('--url', type=str, required=True, help='Paste Youtube URL')

# The center of path
main_path = os.path.dirname(os.path.abspath(__file__))

# Defualt setting
storage_folder_name = 'videos'
frame_folder_name = 'frames'
frame_path = os.path.join(main_path, frame_folder_name)
storage_path = os.path.join(main_path, storage_folder_name)
storage_files_by_videos = None
storage_folders_by_frames = None

youtube_record = 'youtube_record.json'
record_data = None

# setting colorama
init(autoreset=True)

def init_factory():
    global storage_files_by_videos
    global record_data
    global storage_folders_by_frames

    # Check videos storage path
    if os.path.isdir(storage_path):
        print('|- \"{}\" folder is exist !'.format(storage_folder_name))
        contents = os.listdir(storage_path)

        storage_files_by_videos = list(filter(lambda f: os.path.isfile(os.path.join(storage_path, f)), contents))

        print(Fore.CYAN+'|- {} video files'.format(len(storage_files_by_videos)))

    else:
        try:
            print(Fore.YELLOW+'|- \"{}\" folder did not exists. Make it right now....'.format(storage_folder_name))
            os.mkdir(storage_path)

            if os.path.isdir(storage_path):
                print(Fore.GREEN+'|- Done !')
        except:
            print(traceback.format_exc())

    # Check videos per frame storage path
    if os.path.isdir(frame_path):
        print('|- \"{}\" folder is exist !'.format(frame_folder_name))
        contents = os.listdir(frame_path)
        storage_folders_by_frames = list(filter(lambda f: os.path.isdir(os.path.join(frame_path, f)), contents))

        print(Fore.CYAN+'|- {} frames folders'.format(len(storage_folders_by_frames)))

    else:
        try:
            print(Fore.YELLOW+'|- \"{}\" folder did not exists. Make it right now....'.format(frame_folder_name))
            os.mkdir(frame_path)

            if os.path.isdir(frame_path):
                print(Fore.GREEN, '|- Done !')
        except:
            print(traceback.format_exc())

    print("-"*100)
    # Checking record file if exist
    if os.path.isfile(os.path.join(main_path, youtube_record)):
        print('|- Loading record data \"{}\"....'.format(youtube_record))
        with open(youtube_record, 'r') as jsFile:
            record_data = json.load(jsFile)

def file_name_factory():
    global record_data
    print('|- via naming factory')

    start_number = 0

    if record_data:
        sort_list = sorted(record_data.keys())
        return str(int(sort_list[-1])+1)
    else:
        return str(start_number)

def write_record_data(yt_title, yt_url, file_name):
    global record_data

    data = {}
    data.update({file_name : {'title': yt_title,
                              'url': yt_url}})

    print('|- Saving record....')
    if record_data:
        record_data.update(data)
        with open(youtube_record, 'w') as jfile:
            json.dump(record_data, jfile)
    else:
        record_data = data
        with open(youtube_record, 'w') as jfile:
            json.dump(record_data, jfile)

    print(Fore.GREEN,'|- Done!')

def download_youtube(yt_url, target_folder, file_name):
    try:
        print('|- Connecting Youtube ... ')
        yt = YouTube(yt_url)
        video = yt.streams.first()
        file_size = video.filesize
        yt_title = video.title

        print('-'*100+'|')
        print('|-Title : {} '.format(yt_title))
        print('-'*100+'|')
        print('|-URL : {} '.format(yt_url))
        print('-'*100+'|')
        print('|-File Size : {} KB'.format(file_size//(1024*1024)))
        print('-'*100+'|')
        print('|-Storage Path : {}'.format(target_folder))
        print('-'*100+'|')
        print('|-File Name : {}.mp4'.format(file_name))
        print('-'*100+'|')

        for _ in tqdm(yt.streams):
            video.download(target_folder, file_name)

        # save metadata
        write_record_data(yt_title, yt_url, file_name)

        now = datetime.datetime.now()
        print('-'*100+'|')
        print(Fore.GREEN+'|- {}.{}.{} {}:{} download successful!! '.format(now.year, now.month, now.day, now.hour, now.minute))

    except:
        print(traceback.format_exc())

def cut_video2frame(src_path, video_name):
    sec = 0
    frameRate = 1

    #FIXME : Check format
    video_format = '.mp4'
    frame_folder_name = 'video{}'.format(video_name)

    frames_folder = os.path.join(frame_path, frame_folder_name)

    if os.path.isdir(frames_folder):
        raise Exception('The frame by video folder already exist. Please check the target path({}) or the folder name({})'.format(frames_folder, frame_folder_name))
    else:
        print("|- Create \"{}\" folder ...".format(frame_folder_name))
        os.mkdir(frames_folder)

    def getFrame(sec):
        image_name = 'video{}_{}.jpg'.format(video_name, str(sec))
        vidcap.set(cv2.CAP_PROP_POS_MSEC, sec*1000)
        hasFrames, image = vidcap.read()
        if hasFrames:
            cv2.imwrite(os.path.join(frames_folder, image_name), image)
        return hasFrames

    print(Fore.GREEN+"|- Capture video {}".format(video_name+video_format))
    vidcap = cv2.VideoCapture(os.path.join(src_path, video_name+video_format))
    success = getFrame(sec)
    while success:
        sec = sec + frameRate
        success = getFrame(sec)

    print("|- Cutting video successful!!")

def main():
    args = parse.parse_args()
    yt_url = args.url

    init_factory()
    file_name = file_name_factory()
    download_youtube(yt_url, storage_path, file_name)
    cut_video2frame(storage_path, file_name)

if __name__ == '__main__':
    main()


import json
import time

import discord
from discord.ext import commands, tasks
from discord.utils import get

import Cogs._bot_logging as el

class Roster(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        with open("Cogs/request_case", "r") as f:
            self.requests = json.load(f)
        self.request_expire.start()

    @commands.command()
    async def roster(self, ctx, *, role):
        if not ctx.channel.name == "user-info":
            await ctx.send('`You can only use that command in user-info!`')
            return
        try:
            role = get(ctx.guild.roles, name=role)
            members = role.members
        except AttributeError:
            await ctx.send("`That role does not exist!`")
            return
        desc = f"**Roster of {role} ({len(members)} people)**" + "\n"
        num = 1
        for i in members:
            desc += str(num) + " **|** " + i.name + "#" + i.discriminator + "\n"
            num += 1
        try:
            await ctx.send(desc)
        except UnboundLocalError:
            await ctx.send("`No people belong to this role!`")

    @roster.error
    async def roster_error(self, ctx, error):
        await el.log_error(ctx, error, 'roster')

    @commands.group()
    async def tl(self, ctx):
        if ctx.invoked_subcommand is None:
            await ctx.send("`Please specify a subcommand!`")

    @tl.command()
    @commands.has_permissions(ban_members=True)
    async def add(self, ctx, target: discord.Member, team):
        role = discord.utils.get(ctx.guild.roles, name=team)
        try:
            team = discord.utils.get(ctx.guild.roles, name=team).id
        except AttributeError:
            await ctx.send('`Team does not exist!`')
            return
        if ctx.author.top_role <= role:
            await ctx.send('`You can\'t do that!`')
            return
        team_leaders = await self.bot.pg_con.fetch("SELECT * FROM Teams WHERE guild_id = $1 AND user_id = $2",
                                                   ctx.guild.id, target.id)
        if team_leaders:
            await ctx.send(f"{target.mention} is already a team leader!")
            return
        await self.bot.pg_con.fetch("INSERT INTO Teams (guild_id, user_id, team) VALUES ($1, $2, $3)",
                                    ctx.guild.id, target.id, team)
        await ctx.send('`Team Leader Added!`')

    @tl.command()
    @commands.has_permissions(ban_members=True)
    async def remove(self, ctx, target: discord.Member, team):
        role = discord.utils.get(ctx.guild.roles, name=team)
        team = discord.utils.get(ctx.guild.roles, name=team).id
        if ctx.author.top_role <= role:
            await ctx.send('`You can\'t do that!`')
            return
        await self.bot.pg_con.fetch("DELETE FROM Teams WHERE guild_id = $1 AND user_id = $2 AND team = $3",
                                    ctx.guild.id, target.id, team)
        await ctx.send('`Team Leader Removed!`')

    @tl.command()
    async def list(self, ctx, team):
        if not ctx.channel.name == "user-info":
            await ctx.send('`You can only use that command in user-info!`')
            return
        try:
            team1 = discord.utils.get(ctx.guild.roles, name=team).id
        except AttributeError:
            await ctx.send('`Team does not exist!`')
            return
        team_leaders = await self.bot.pg_con.fetch("SELECT * FROM Teams WHERE guild_id = $1 AND team = $2",
                                                   ctx.guild.id, team1)
        if not team_leaders:
            await ctx.send('`Team does not have any team leaders!`')
            return
        desc = f"**Team Leaders of {team}**" + "\n"
        num = 1
        for i in team_leaders:
            try:
                desc += str(num) + " **|** " + ctx.guild.get_member(i[1]).name + "#" \
                        + ctx.guild.get_member(i[1]).discriminator + "\n"
            except AttributeError:
                await self.bot.pg_con.fetch("DELETE FROM Teams WHERE guild_id = $1 AND user_id = $2",
                                            ctx.guild.id, i[1])
            num += 1
        await ctx.send(desc)

    @tl.command()
    async def listall(self, ctx):
        if not ctx.channel.name == "user-info":
            await ctx.send('`You can only use that command in user-info!`')
            return
        team_leaders = await self.bot.pg_con.fetch("SELECT * FROM Teams WHERE guild_id = $1",
                                                   ctx.guild.id)
        if not team_leaders:
            await ctx.send("No team leader exist!")
        desc = "**All Team Leaders**" + '\n'
        while team_leaders:
            name = str(ctx.guild.get_role(team_leaders[0][2]).name)
            control = team_leaders[0]
            desc += name + " **|** "
            for i in team_leaders:
                if ctx.guild.get_role(i[2]).name == name:
                    desc += self.bot.get_user(i[1]).name
                    desc += ', '
                    team_leaders.remove(i)
            desc += '\n'
            try:
                team_leaders.remove(control)
            except ValueError:
                pass

        await ctx.send(desc)

    @tl.command()
    @commands.has_permissions(administrator=True)
    async def clear(self, ctx):
        await self.bot.pg_con.fetch("DELETE FROM Teams WHERE guild_id = $1",
                                    ctx.guild.id)
        await ctx.send('`Team Leaders Cleared!`')

    @add.error
    async def add_error(self, ctx, error):
        await el.log_error(ctx, error, 'add')

    @remove.error
    async def remove_error(self, ctx, error):
        await el.log_error(ctx, error, 'remove')

    @list.error
    async def add_error(self, ctx, error):
        await el.log_error(ctx, error, 'list')

    @commands.group()
    async def team(self, ctx):
        if ctx.invoked_subcommand is None:
            await ctx.send("`Please specify a subcommand!`")

    @team.command()
    async def hire(self, ctx, target: discord.Member):
        role = await self.bot.pg_con.fetch("SELECT team FROM Teams WHERE guild_id = $1 AND user_id = $2",
                                           ctx.guild.id, ctx.author.id)
        if not role:
            await ctx.send('`You are not a team leader!`')
        role = int(role[0][0])
        user_id = target.id
        expiry = time.time() + 604800
        guild_id = ctx.guild.id
        if str(guild_id) not in self.requests:
            self.requests[str(guild_id)] = 1
        else:
            self.requests[str(guild_id)] += 1
        case = self.requests[str(guild_id)]
        await self.bot.pg_con.fetch("INSERT INTO Requests (case_id, expiry, user_id, guild_id, role) VALUES "
                                    "($1, $2, $3, $4, $5)", case, expiry, user_id, guild_id, role)
        with open("Cogs/request_case", "w") as f:
            json.dump(self.requests, f)
        await target.send(f"{ctx.guild.get_role(role)} has invited you to join them! Respond with `yes {case}`"
                          f" or `no {case}` to accept / deny their proposition. You have 7 days!")
        await ctx.send(f'`{target} invited!`')

    @team.command()
    async def fire(self, ctx, target: discord.Member):
        role = await self.bot.pg_con.fetch("SELECT * FROM Teams WHERE guild_id = $1 AND user_id = $2",
                                           ctx.guild.id, target.id)
        role = discord.utils.get(ctx.guild.roles, id=role[0][2])

        if not role:
            await ctx.send('`You are not a team leader!`')
            return
        await target.remove_roles(role)
        await ctx.send(f"`{target} removed!`")

    @commands.Cog.listener()
    async def on_message(self, message):
        if isinstance(message.channel, discord.DMChannel):
            message1 = message.content.split(" ")
            try:
                if message1[0] == 'yes':
                    request = await self.bot.pg_con.fetch("SELECT * FROM Requests WHERE case_id = $1 AND user_id = $2",
                                                          int(message1[1]), message.author.id)
                    if not request:
                        await message.author.send('Invalid case!')
                        return
                    guild = self.bot.get_guild(request[0][1])
                    member = guild.get_member(message.author.id)
                    role = guild.get_role(request[0][2])
                    await member.add_roles(role)
                    await self.bot.pg_con.fetch("DELETE FROM Requests WHERE case_id = $1 AND user_id = $2",
                                                int(message1[1]), message.author.id)
                    team_leaders = await self.bot.pg_con.fetch(
                        "SELECT user_id FROM Teams WHERE guild_id = $1 AND team = $2",
                        guild.id, request[0][2])
                    channel = discord.utils.get(guild.channels, name="team-leaders-lounge")
                    await message.author.send("Proposition accepted!")
                    await channel.send(f"{member.name} has accepted the offer to join {role.name}!"
                                       f" {[guild.get_member(i[0]).mention for i in team_leaders]}")
                if message1[0] == 'no':
                    await self.bot.pg_con.fetch("DELETE FROM Requests WHERE case_id = $1 AND user_id = $2",
                                                int(message1[1]), message.author.id)
                    await message.author.send('`Proposition declined!`')
            except AttributeError or ValueError:
                await message.author.send('`Something went wrong with your case where it could not be accepted!'
                                          'Check if you have inputted any nad information!`')

    @hire.error
    async def hire_error(self, ctx, error):
        await el.log_error(ctx, error, 'hire')

    @fire.error
    async def fire_error(self, ctx, error):
        await el.log_error(ctx, error, 'fire')

    @tasks.loop(hours=1)
    async def request_expire(self):
        try:
            await self.bot.pg_con.fetch("DELETE FROM Requests WHERE $1 > expiry", time.time())
        except Exception as e:
            print(e)

def setup(bot):
    bot.add_cog(Roster(bot))


import os

CORE_NUMBER = os.environ['CORE_NUMBER']
REQUEST_COST = os.environ['REQUEST_COST']
CURRENT_YEAR = os.environ['CURRENT_YEAR']

HEADERS = os.environ['HEADERS']

WEIGHTS_ORGANIC = os.environ['WEIGHTS_ORGANIC']

WEIGHTS_DIRECT = os.environ['WEIGHTS_DIRECT']

ABSURD_STEM_BREAKPOINT = 30

STANDART_IMPORTANCE = {
    'Возраст сайта': 0.4,
    'Стемирование': 0.3,
    'Объем статей': 0.1,
    'Ссылочное': 0.2,
}

ABSURD_IMPORTANCE = {
    'Возраст сайта': 0.15,
    'Стемирование': 0.7,
    'Объем статей': 0,
    'Ссылочное': 0.15,
}


from httpx import post, put
from pyogg import VorbisFile
from mutagen import File

class lol:
    def __init__(gay, token: str) -> None:
        gay.Token = token

    def attachment(gay, channel: int, filePath: str) -> dict:
        try:
            z = post(
                f'https://discord.com/api/v9/channels/{channel}/attachments',
                headers={'Authorization': gay.Token},
                json={
                      "files": [
                        {
                          "filename": "voice-message.ogg",
                          "file_size": VorbisFile(filePath).buffer_length,
                          "id": "6"
                        }
                      ]
                    }
            )
            if z.status_code == 200:
                return z.json()['attachments'][0]
            else:
                exit(z.text)
        except Exception as err:
            exit(err)

    def uploadToCloud(gay, upload_url: str, filePath: str) -> bool:
        try:
            with open(filePath, 'rb') as fobj:
                x = put(
                    upload_url,
                    data=fobj.read(),
                    headers={'Content-Type': 'audio/ogg'}
                    )
                if x.status_code == 200:
                    return True
                else:
                    exit(x.text)
        except Exception as err:
            exit(err)

    def uploadToDiscord(gay, channel: int, filePath: str) -> tuple:
        try:
            z = a.attachment(channel, filePath)
            n = gay.uploadToCloud(z['upload_url'], filePath)
            if n:
                y = post(
                    f'https://discord.com/api/v9/channels/{channel}/messages',
                    headers={
                        'Authorization': gay.Token,
                        'x-super-properties': 'eyJvcyI6IkFuZHJvaWQiLCJicm93c2VyIjoiRGlzY29yZCBBbmRyb2lkIiwiZGV2aWNlIjoiZHJlYW0ybHRla3MiLCJzeXN0ZW1fbG9jYWxlIjoiZnItRlIiLCJjbGllbnRfdmVyc2lvbiI6IjE3My4yMyAtIHJuIiwicmVsZWFzZV9jaGFubmVsIjoiZ29vZ2xlUmVsZWFzZSIsImRldmljZV92ZW5kb3JfaWQiOiI5M2RjMDRiOS04ODhkLTQ1NjMtYmI0OC1iMzA4NTNhYjNjOWMiLCJicm93c2VyX3VzZXJfYWdlbnQiOiIiLCJicm93c2VyX3ZlcnNpb24iOiIiLCJvc192ZXJzaW9uIjoiMjUiLCJjbGllbnRfYnVpbGRfbnVtYmVyIjoxNzMwMjMsImNsaWVudF9ldmVudF9zb3VyY2UiOm51bGwsImRlc2lnbl9pZCI6MH0=',
                        'user-agent': 'Discord-Android/173023;RNA',
                        'content-type': 'application/json'
                        },
                    json={
                          "content": "",
                          "channel_id": f"{channel}",
                          "type": 0,
                          "flags": 8192,
                          "attachments": [
                            {
                              "id": z['id'],
                              "filename": z['upload_filename'].split('/')[1],
                              "uploaded_filename": z['upload_filename'],
                              "duration_secs": File(filePath).info.length,
                              "waveform": "KBkKDRAKGBIWcnZ+o1xub6GUX6CITm0b"
                            }
                          ]
                        }
                )
                if y.status_code == 200:
                    return True, 'Successfully uploaded audio file !'
                else:
                    return False, y.json()
        except Exception as err:
            exit(err)

a = lol(
    input('Token >')
)

b = a.uploadToDiscord(
    int(input('Channel ID >')),
    input('.ogg audio file path > ') # './audio.ogg'
    )
print(b[1])


import os

import cv2
import tensorflow as tf

from args import opt

def _bytes_feature(value):
    """string / byte 型から byte_list を返す"""
    if isinstance(value, str):
        value = value.encode()

    if isinstance(value, type(tf.constant(0))):
        value = value.numpy()  # BytesList won't unpack a string from an EagerTensor.
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

def _float_feature(value):
    """float / double 型から float_list を返す"""
    return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))

def _int64_feature(value):
    """bool / enum / int / uint 型から Int64_list を返す"""
    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

def image_encode(path):
    image = cv2.imread(path)
    if path.endswith('.jpg'):
        encode_image = cv2.imencode('.jpg', image, (cv2.IMWRITE_JPEG_QUALITY, 100))[1].tobytes()
    elif path.endswith('.png'):
        encode_image = cv2.imencode('.png', image)[1].tobytes()
    return _bytes_feature(encode_image)

def make_serialize(path, label, filename, classname):
    image = cv2.imread(path)
    height, width = image.shape[:2]
    feature = {
        "image": image_encode(path),
        "width": _int64_feature(int(width)),
        "height": _int64_feature(int(height)),
        "label": _int64_feature(label),
        "filename": _bytes_feature(filename),
        "classname": _bytes_feature(classname),
    }
    example_proto = tf.train.Example(features=tf.train.Features(feature=feature))
    return example_proto.SerializeToString()

def main(args):
    print(args)
    for phase in ("train", "val"):
        tfrecord_path = f"{args.path2db}/{phase}.tfrecord"
        with tf.io.TFRecordWriter(tfrecord_path) as writer:
            classnames = os.listdir(os.path.join(args.path2db, phase))
            classnames.sort()
            for label, classname in enumerate(classnames):
                filenames = os.listdir(os.path.join(args.path2db, phase, classname))
                for i, filename in enumerate(filenames):
                    if i == 0:
                        print("{:03d}: {}".format(label, filename))
                    image_path = os.path.join(args.path2db, phase, classname, filename)
                    example = make_serialize(image_path, label, filename, classname)
                    writer.write(example)

if __name__ == '__main__':
    args = opt()
    main(args)


from models.basic.basic_model import BasicModel
from models.encoders.shufflenet import ShuffleNet
from layers.convolution import conv2d_transpose, conv2d, atrous_conv2d
from utils.misc import get_vars_underscope

import tensorflow as tf
import pdb

class FCN8sShuffleNet(BasicModel):
    """
    FCN8s with ShuffleNet as an encoder Model Architecture
    """

    def __init__(self, args):
        super().__init__(args)
        # init encoder
        self.encoder = None
        # init network layers

    def build(self):
        print("\nBuilding the MODEL...")
        self.init_input()
        self.init_network()
        self.init_output()
        self.init_train()
        self.init_summaries()
        print("The Model is built successfully\n")

    def init_network(self):
        """
        Building the Network here
        :return:
        """

        # Init ShuffleNet as an encoder
        self.encoder = ShuffleNet(x_input=self.x_pl, num_classes=self.params.num_classes,
                                  pretrained_path=self.args.pretrained_path, train_flag=self.is_training,
                                  batchnorm_enabled=self.args.batchnorm_enabled, num_groups=self.args.num_groups,
                                  weight_decay=self.args.weight_decay, bias=self.args.bias)

        # Build Encoding part
        self.encoder.build()

        # Build Decoding part
        with tf.name_scope('upscore_2s'):
            self.upscore2 = conv2d_transpose('upscore2', x=self.encoder.score_fr,
                                             output_shape=self.encoder.feed1.shape.as_list()[0:3] + [
                                                 self.params.num_classes], batchnorm_enabled=self.args.batchnorm_enabled, is_training= self.is_training,
                                             kernel_size=(4, 4), stride=(2, 2), l2_strength=self.encoder.wd, bias=self.args.bias)
#            currvars= get_vars_underscope(tf.get_variable_scope().name, 'upscore2')
#            for v in currvars:
#                tf.add_to_collection('decoding_trainable_vars', v)

            self.score_feed1 = conv2d('score_feed1', x=self.encoder.feed1, batchnorm_enabled=self.args.batchnorm_enabled, is_training= self.is_training,
                                      num_filters=self.params.num_classes, kernel_size=(1, 1), bias= self.args.bias,
                                      l2_strength=self.encoder.wd)
#            currvars= get_vars_underscope(tf.get_variable_scope().name, 'score_feed1')
#            for v in currvars:
#                tf.add_to_collection('decoding_trainable_vars', v)

            self.fuse_feed1 = tf.add(self.score_feed1, self.upscore2)

        with tf.name_scope('upscore_4s'):
            self.upscore4 = conv2d_transpose('upscore4', x=self.fuse_feed1,
                                             output_shape=self.encoder.feed2.shape.as_list()[0:3] + [
                                                 self.params.num_classes], batchnorm_enabled=self.args.batchnorm_enabled, is_training= self.is_training,
                                             kernel_size=(4, 4), stride=(2, 2), l2_strength=self.encoder.wd, bias=self.args.bias,
                                             )
#            currvars= get_vars_underscope(tf.get_variable_scope().name, 'upscore4')
#            for v in currvars:
#                tf.add_to_collection('decoding_trainable_vars', v)

            self.score_feed2 = conv2d('score_feed2', x=self.encoder.feed2, batchnorm_enabled=self.args.batchnorm_enabled, is_training= self.is_training,
                                      num_filters=self.params.num_classes, kernel_size=(1, 1), bias=self.args.bias,
                                      l2_strength=self.encoder.wd)
#            currvars= get_vars_underscope(tf.get_variable_scope().name, 'score_feed2')
#            for v in currvars:
#                tf.add_to_collection('decoding_trainable_vars', v)

            self.fuse_feed2 = tf.add(self.score_feed2, self.upscore4)

        with tf.name_scope('upscore_8s'):
            self.upscore8 = conv2d_transpose('upscore8', x=self.fuse_feed2,
                                             output_shape=self.x_pl.shape.as_list()[0:3] + [self.params.num_classes], is_training=self.is_training,
                                             kernel_size=(16, 16), stride=(8, 8), l2_strength=self.encoder.wd, bias=self.args.bias,
                                             )
#            currvars= get_vars_underscope(tf.get_variable_scope().name, 'upscore8')
#            for v in currvars:
#                tf.add_to_collection('decoding_trainable_vars', v)

        self.logits = self.upscore8


# for mesuring time
import time
# for plotting
import matplotlib.pyplot as plt

def fibonacci(n):
    fib = [0, 1]
    for i in range(2, n+1):
        fib.append(fib[i-1] + fib[i-2])
    return fib[n]

xdp=[]
for i in range(350):
    xdp.append(i+1)

ydp=[]

for i in range(350):
    start_time_dp = time.time()
    fibonacci(i)
    end_time_dp = time.time()
    ydp.append(end_time_dp - start_time_dp)

plt.plot(xdp, ydp, color='b', label='D.P')
plt.show()


# consist of vertexes and connections(edges)
# edges can be weighted and non-weighted
# edges can be directional and bidirectional
# adjacency matrix = if connection between two vertex = 1, else = 0
# adjacency list = { "A" : ["B", "E"] } ==  A connected to the vertexes  B and E
# BIG O of GRAPHS
    # adding a vertex to the matrix: an extra row and columns will be added to the matrix
    # so operation is eveluated with O(V^2)
    # adding a vertex to the adjacency JSON is O(1)
    #adding an edge == O(1)

class Graph:
    def __init__(self):
        self.adj_list = {}

    def add_vertex(self, vertex):
        if vertex not in self.adj_list.keys():
            self.adj_list[vertex] = []
            return True
        return False

    def print_graph(self):
        for vertex in self.adj_list.keys():
            print(vertex,":", self.adj_list[vertex])

    def add_edge(self, v1, v2):
        if v1 in self.adj_list.keys() and v2 in self.adj_list.keys():
            self.adj_list[v1].append(v2)
            self.adj_list[v2].append(v1)
            return True
        return False

    def remove_edge(self, v1, v2):
        if v1 in self.adj_list.keys() and v2 in self.adj_list.keys():
            try:
                self.adj_list[v1].remove(v2)
                self.adj_list[v2].remove(v1)
            except ValueError:
                pass
            return True
        return False

    def remove_vertex(self, vertex):
        if vertex in self.adj_list.keys():
            for edges in self.adj_list[vertex]:
                self.adj_list[edges].remove(vertex)
            del self.adj_list[vertex]
            return True
        return False

print("-----------------------  INIT / GRAPHS -----------------------")
my_graph = Graph()
print("-----------------------  ADD VERTEX / GRAPHS -----------------------")
my_graph.add_vertex(1)
my_graph.add_vertex(2)
my_graph.add_vertex(3)
my_graph.add_vertex(4)
print("-----------------------  PRINT GRAPH / GRAPHS -----------------------")
my_graph.print_graph()
print("-----------------------  ADD AN EDGE / GRAPHS -----------------------")
my_graph.add_edge(1, 2)
my_graph.add_edge(2, 3)
my_graph.add_edge(3, 1)
my_graph.print_graph()
print("-----------------------  REMOVE AN EDGE / GRAPHS -----------------------")
my_graph.remove_edge(1, 4)
my_graph.print_graph()
print("-----------------------  REMOVE A VERTEX / GRAPHS -----------------------")
my_graph.remove_vertex(2)
my_graph.remove_vertex(4)
my_graph.print_graph()


import matplotlib.pyplot as plt
import numpy as np

import os
import json

dir = '/home/buens/Desktop/MA_Evaluation/e4e_encoder_original/webcam_images/results/corrected_original_without_background'
lpips = []
ssim = []
fsim = []

for root, dirs, files in sorted(os.walk(dir)):
    for name in files:
        if name == 'metrics.json':
            id = sorted(dirs)[0]
            with open(os.path.join(dir, id, name)) as f:
                data = json.load(f)
                lpips.append(data['LPIPS'])
                ssim.append(data['SSIM'])
                fsim.append(data['FSIM'])

x = np.arange(1, 101, 1)

# Plotting both the curves simultaneously
plt.plot(x, lpips, color='r', label='LPIPS')
plt.plot(x, ssim, color='g', label='SSIM')
plt.plot(x, fsim, color='b', label='FSIM')

# Naming the x-axis, y-axis and the whole graph
plt.xlabel("Index")
plt.ylabel("Wert der Metrik")
plt.title("Beleuchtungskorrektur auf Webcam-Aufnahmen")

# Adding legend, which helps us recognize the curve according to it's color
plt.legend()

# To load the display window
plt.show()

lpips_arr = np.array(lpips)
outliers = np.where(lpips_arr > 0.10)
print(outliers)


from flask import abort

from ...services.orga_presence import service as orga_presence_service
from ...services.party import service as party_service
from ...util.framework.blueprint import create_blueprint
from ...util.templating import templated

from ..authorization.decorators import permission_required
from ..authorization.registry import permission_registry

from .authorization import OrgaPresencePermission

blueprint = create_blueprint('orga_presence', __name__)

permission_registry.register_enum(OrgaPresencePermission)

@blueprint.route('/<party_id>')
@permission_required(OrgaPresencePermission.list)
@templated
def view(party_id):
    """List orga presence and task time slots for that party."""
    party = party_service.find_party(party_id)

    if party is None:
        abort(404)

    presences = orga_presence_service.get_presences(party.id)
    tasks = orga_presence_service.get_tasks(party.id)

    hour_ranges = list(orga_presence_service.get_hour_ranges(party, tasks))

    days_and_hour_totals = list(orga_presence_service \
        .get_days_and_hour_totals(hour_ranges))

    return {
        'party': party,
        'days_and_hour_totals': days_and_hour_totals,
        'hour_ranges': hour_ranges,
        'presences': presences,
        'tasks': tasks,
    }


from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('add', views.newRecipe, name='addNew'),
    path('get', views.getAllRecipe, name='getRecipe'),
    path('search', views.search, name='searchRecipe'),
    path('getId/<int:id>', views.getRecipeById, name='searchRecipeById'),
    path('getIngredients/<int:id>', views.getIngredientsByRecipe, name='getIngredients'),
    path('getSteps/<int:id>', views.getStepsByRecipe, name='getSteps'),
    path('deleteRecipe', views.deleteRecipe, name='deleteRecipe')
]


import socketserver
import time
import sys
import threading
import glob
import re

import server.exploder as exploder
import server.config as config

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass

class SMTPHandler(socketserver.StreamRequestHandler):

    def send(self, what):
        self.request.sendall(bytes(what, 'utf-8'))

    def handle(self):

        cip = format(self.client_address[0])
        cport = int(format(self.client_address[1]))
        print ("Request from %s:%u" % (cip,cport) )

        line = self.rfile.readline().strip()
        listname = "dev@httpd.apache.org"
        recip = None
        match = re.match(r"GET /([^?]+)\??(.*) HTTP", str(line, 'utf-8'))
        if match:
            listname = match.group(1)
            recip = match.group(2)
        print("Got req for: %s" % listname)
        self.send("Checking whether %s is valid: " % listname)
        listdir = exploder.list_exists(listname)
        if listdir:
            self.send(listdir)
            self.send("\n")
            if recip:
                exploder.remove_recipient(listdir, recip)

            recips = exploder.get_recipients(listdir)
            if len(recips) > 0:
                self.send("Recipients are: ")
                self.send(", ".join(recips))
        else:
            self.send("No such list exists")

def start():
    bindHost = config.cconfig.get('SMTP', 'bindTo')
    bindPort = int(config.cconfig.get('SMTP', 'incomingPort'))

    # Create the server, binding to localhost on port 9999
    server = ThreadedTCPServer((bindHost, bindPort), SMTPHandler)

    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.daemon = True
    server_thread.start()


import argparse
from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np

from data_loader import load_data

substitutions = {
    "Algorithm": {
        "AuxIVA-IP (PCA)": "IP",
        "AuxIVA-ISS (PCA)": "ISS",
        "AuxIVA-IP2 (PCA)": "IP2",
        "AuxIVA-IPA (PCA)": "IPA",
        "FastIVA (PCA)": "FIVA",
    }
}

if __name__ == "__main__":

    parser = argparse.ArgumentParser(
        description="Load simulation data into a pandas frame"
    )
    parser.add_argument(
        "-p",
        "--pickle",
        action="store_true",
        help="Read the aggregated data table from a pickle cache",
    )
    parser.add_argument(
        "dirs",
        type=Path,
        nargs="+",
        metavar="DIR",
        help="The directory containing the simulation output files.",
    )
    args = parser.parse_args()

    dirs = args.dirs
    pickle = args.pickle

    df, final_val_tbl, conv_tbl, rt60, parameters = load_data(args.dirs, pickle=pickle)

    conv_tbl = conv_tbl.replace(substitutions)

    col_order = [
        "IP",
        "ISS",
        "IP2",
        "IPA",
        "FIVA",
    ]

    agg_func = np.median
    flt_fmt = "%.1f"

    print("Runtime Table:")
    pt_rt = conv_tbl.pivot_table(
        index=["Mics"], columns=["SINR", "Algorithm"], aggfunc=agg_func
    )["Runtime"]
    pt_rt = pt_rt.reindex(level=1, columns=col_order)
    print(pt_rt.to_latex(float_format=flt_fmt))

    print()

    print("Speed-up Factors:")
    for snr in [5, 15, 25]:
        print(f"SNR {snr}")
        print(pt_rt[snr].div(pt_rt[snr, "IPA"], axis=0))

    print()

    print("Iteration Table Table:")
    pt_it = conv_tbl.pivot_table(
        index=["Mics"], columns=["SINR", "Algorithm"], aggfunc=agg_func
    )["Iterations"]
    pt_it = pt_it.reindex(level=1, columns=col_order)
    print(pt_it.to_latex(float_format="%.0f"))


import re
from operator import itemgetter

dict = {}

def scoreCalculator(text):
    for line in text:
        fields = line.split(",")

        team1 = fields[0][0:(re.search("\d", fields[0])).start()].strip()
        team2 = fields[1][0:(re.search("\d", fields[1])).start()].strip()

        dict.setdefault(team1, 0)
        dict.setdefault(team2, 0)

        score1 = int(re.search(r'\d+', fields[0]).group(0))
        score2 = int(re.search(r'\d+', fields[1]).group(0))

        if score1 > score2:
            dict[team1] += 3
        elif (score1 == score2):
            dict[team1] += 1
            dict[team2] += 1
        else:
            dict[team2] += 3

    print("Rankings compiled!")

    # returning here just for the automated test.
    return dict

def compileRanking(outputFormat):
    s = sorted(dict.items(), key=itemgetter(0))
    rankings = sorted(s, key=itemgetter(1), reverse=True)
    createTable(rankings, outputFormat)

def createTable(rankings, outputFormat):
    prevScore = rankings[0][1]
    currentRank = 1
    sameRank = 0
    outputStr = ""

    for scoreItem in rankings:
        team = scoreItem[0]
        points = scoreItem[1]

        if points == prevScore:
            rank = currentRank
            sameRank = sameRank + 1
        elif points < prevScore:
            currentRank = currentRank + sameRank
            rank = currentRank
            prevScore = points
            sameRank = 1

        end = ""
        if points == 1:
            end = "pt"
        else:
            end = "pts"

        output = "%s. %s, %s %s\n" % (rank, team, points, end)
        outputStr = outputStr + output

    if outputFormat == "t" or outputFormat == "T":
        textFile = open("Output table.txt", "w")
        textFile.write(outputStr)
        textFile.close()
    else:
        print("Season Rankings: ")
        print()
        print(outputStr)

    # returning here just for the automated test.
    return outputStr


from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar, Union

import attr

from ..types import UNSET, Unset

if TYPE_CHECKING:
    from ..models.codat_data_contracts_datasets_account_ref import CodatDataContractsDatasetsAccountRef
    from ..models.codat_data_contracts_datasets_tracking import CodatDataContractsDatasetsTracking

T = TypeVar("T", bound="CodatDataContractsDatasetsJournalLine")

@attr.s(auto_attribs=True)
class CodatDataContractsDatasetsJournalLine:
    """
    Attributes:
        net_amount (float):
        description (Union[Unset, None, str]):
        currency (Union[Unset, None, str]):
        account_ref (Union[Unset, CodatDataContractsDatasetsAccountRef]):
        tracking (Union[Unset, CodatDataContractsDatasetsTracking]):
    """

    net_amount: float
    description: Union[Unset, None, str] = UNSET
    currency: Union[Unset, None, str] = UNSET
    account_ref: Union[Unset, "CodatDataContractsDatasetsAccountRef"] = UNSET
    tracking: Union[Unset, "CodatDataContractsDatasetsTracking"] = UNSET

    def to_dict(self) -> Dict[str, Any]:
        net_amount = self.net_amount
        description = self.description
        currency = self.currency
        account_ref: Union[Unset, Dict[str, Any]] = UNSET
        if not isinstance(self.account_ref, Unset):
            account_ref = self.account_ref.to_dict()

        tracking: Union[Unset, Dict[str, Any]] = UNSET
        if not isinstance(self.tracking, Unset):
            tracking = self.tracking.to_dict()

        field_dict: Dict[str, Any] = {}
        field_dict.update(
            {
                "netAmount": net_amount,
            }
        )
        if description is not UNSET:
            field_dict["description"] = description
        if currency is not UNSET:
            field_dict["currency"] = currency
        if account_ref is not UNSET:
            field_dict["accountRef"] = account_ref
        if tracking is not UNSET:
            field_dict["tracking"] = tracking

        return field_dict

    @classmethod
    def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T:
        from ..models.codat_data_contracts_datasets_account_ref import CodatDataContractsDatasetsAccountRef
        from ..models.codat_data_contracts_datasets_tracking import CodatDataContractsDatasetsTracking

        d = src_dict.copy()
        net_amount = d.pop("netAmount")

        description = d.pop("description", UNSET)

        currency = d.pop("currency", UNSET)

        _account_ref = d.pop("accountRef", UNSET)
        account_ref: Union[Unset, CodatDataContractsDatasetsAccountRef]
        if isinstance(_account_ref, Unset):
            account_ref = UNSET
        else:
            account_ref = CodatDataContractsDatasetsAccountRef.from_dict(_account_ref)

        _tracking = d.pop("tracking", UNSET)
        tracking: Union[Unset, CodatDataContractsDatasetsTracking]
        if isinstance(_tracking, Unset):
            tracking = UNSET
        else:
            tracking = CodatDataContractsDatasetsTracking.from_dict(_tracking)

        codat_data_contracts_datasets_journal_line = cls(
            net_amount=net_amount,
            description=description,
            currency=currency,
            account_ref=account_ref,
            tracking=tracking,
        )

        return codat_data_contracts_datasets_journal_line


from pyspark.sql import SparkSession
from pyspark.sql import functions as func
from pyspark.sql.types import StructField, StructType, IntegerType, StringType

spark = (
    SparkSession
    .builder
    .appName('MarvelSuperHeroe')
    .getOrCreate()
)

schema = StructType(
    [
        StructField('id', IntegerType(), True),
        StructField('name', StringType(), True),
    ]
)

names = (
    spark
    .read
    .schema(schema)
    .option('sep', ' ')
    .csv('./marvel-super-hero/data/Marvel+Names')
)

lines = spark.read.text('./marvel-super-hero/data/Marvel+Graph')

connections = (
    lines
    .withColumn('id', func.split(func.col('value'), ' ')[0])
    .withColumn('connections', func.size(func.split(func.col('value'), ' ')) - 1)
    .groupBy('id')
    .agg(func.sum('connections').alias('connections'))
)

hero_only_one_conn = (
    connections
    .filter(func.col('connections') == 1)
)
hero_only_one_conn_name = (
    hero_only_one_conn
    .join(names, 'id')
    .select('name', 'connections')
)
hero_only_one_conn_name.show(hero_only_one_conn_name.count())

min_connection = (
    connections
    .agg(func.min(func.col('connections')))
    .first()
)

print(f'the minimun number of connections is {min_connection[0]} connections')

spark.stop()


# Imports --
import os
from io import BytesIO
from time import sleep
import requests
import tweepy
import cv2
from PIL import Image
from PIL import ImageFile
import numpy as np

# PIL.ImageFile.ImageFile Class Constant -- Whether or not to load truncated image files
ImageFile.LOAD_TRUNCATED_IMAGES = True

# Loading twitter credentials
API_KEY = os.getenv("API_KEY")
API_SECRET = os.getenv("API_SECRET")
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN")
ACCESS_TOKEN_SECRET = os.getenv("ACCESS_TOKEN_SECRET")

# Authenticate to Twitter using Tweepy
auth = tweepy.OAuthHandler(API_KEY, API_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

# Connect to the TWITTER API
api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)

# This function opens the image using PIL library & then transforms it into a pencil sketch using 'sketch' function below.
# After that, it uploads the sketch image in reply to the tweet posted earlier.
def tweet_image(image, username, status_id):
    if image.status_code == 200:
        i = Image.open(BytesIO(image.content))
        sketch(i)
        response = api.media_upload('images/sketch.jpg')
        api.update_status(status='@{0}'.format(username), in_reply_to_status_id=status_id, media_ids=[response.media_id])
    else:
        print("image app fail!")

# Below functions help transform the image into a pencil sketch using cv2 library
# The new image is being converted back into a PIL Image.
def dodge(x, y):
  return cv2.divide(x,  255 - y, scale=256)

def sketch(i):
  pil_image = i.convert('RGB')
  open_cv_image = np.array(pil_image)

  # Convert RGB to BGR
  open_cv_image = open_cv_image[:, :, ::-1].copy()
  img_gray = cv2.cvtColor(open_cv_image, cv2.COLOR_BGR2GRAY)
  img_invert = cv2.bitwise_not(img_gray)
  img_smoothing = cv2.GaussianBlur(img_invert, (21, 21), sigmaX=0, sigmaY=0)
  final_img = dodge(img_gray, img_smoothing)

  pil_image = Image.fromarray(final_img)
  return pil_image.save('images/sketch.jpg')

# BotStreamer class handles -- checking for a tweet with an image, fetching the link of image &
# applying tweet_image() function to tweet the reply with the new (sketch) image.
class BotStreamer(tweepy.StreamListener):

  # Called when a new status arrives which is passed down from the on_data method of the StreamListener
  def on_status(self, status):
    username = status.user.screen_name
    status_id = status.id

    # Checks if there is any media-entity
    for media in status.entities.get("media",[{}]):
        try:
            # Checks if the entity is of the type "photo"
            if media.get("type",None) == "photo":
                image_content=requests.get(media["media_url"], stream=True)

            tweet_image(image_content, username, status_id)
            sleep(43200) # sleeps for 12 hours
        except tweepy.TweepError as e:
            print(e.reason)
        except StopIteration:
            break

# Creating Stream object
myStreamListener = BotStreamer()
stream = tweepy.Stream(api.auth, myStreamListener)

# Filters real-time tweets which uses '#PicSketch' keyword
stream.filter(track=["PicSketch"])


from pyrogram import Client, filters
import asyncio
import json
import os
import sys

# Checks the packages
if "config.json" in os.listdir():

    with open("config.json", 'r') as json_file:
        data = json.loads(json_file.read())

else:
    with open("config.json", 'x') as json_file:
        json_file.write('{}')

    with open("config.json", 'r') as json_file:
        data = json.loads(json_file.read())

    data["api_hash"] = None
    data["api_id"] = None
    data["target_chat_id"] = None
    data["run_as_admin"] = False

    with open('config.json', 'w') as json_file:
        json_file.write(json.dumps(data, sort_keys=True, indent=4, ensure_ascii=False))

if "goyim_data.json" not in os.listdir():

    with open("goyim_data.json", 'x') as json_file:
        json_file.write('{}')

else:
    with open("goyim_data.json", 'w') as json_file:
        json_file.write('{}')

if "text.txt" not in os.listdir():

    with open('text.txt', 'x') as text_file:
        pass

else:
    rewrite_txt_input = input("ATTENTION! This will rewrite your previous text.txt!(-e to exit)")
    if rewrite_txt_input == '-e': sys.exit("Program stopped")

    with open('text.txt', 'w') as text_file:
        text_file.write('')

# Prints out the art, info about config and commands

print(f"""

                     .
                     M
                    dM
                    MMr
                   4MMMI                  .
                   MMMMM.                xf             [API_ID]: {data["api_id"]}
   .              "MMMMM               .MM-             [API_HASH]: {data["api_hash"]}
    Mh..          +MMMMMM            .MMMM              [TARGET_CHAT]: {data["target_chat_id"]}
    .MNM.         .MMMMML.          MMMMMh
     )MMMh.        MMWMMM         MMMMMMM               [COMMANDS]:
      3MMMMx.     'MMMMMMf      xnMMMMMM"
      '*MMMMM      MMMMMM.     nMMMAMMP"                -c        Change api id and hash (e.g. -c 12345354 hash)
        *MMMMMx    "MMMMM\    .MMMMMMM=                 {'-' * 3}
         *MMMMMh   "MMMMM"   JMMOMMMP                   -g        Set the chat id (e.g. -g -643222694)
           MMMMMM   3MMMM.  dMMMMMM            .        {'-' * 3}
            MMMMMM  "MMMM  .MMMMM(        .nnMP"        -i        Get the config info
=..          *MMMMx  MSM"  dMMMM"    .nnMMMMM*          {'-' * 3}
  "MMn...     'MMMMr 'MM   MMM"   .nMMMMMMM*"           -r        Save changes and run programm (-r a for admin)
   "4MMMMnn..   *MMM  MM  MMP"  .dMMMMMMM""             {'-' * 3}
     ^MMMMMMMMx.  *ML "M .M*  .MMMMMM**"                -e        Close programm
        *PMMMMMMhn. *x > M  .MMMM**""                   {'-' * 3}
           ""**MMMMhx/.h/ .=*"
                    .3P"%....
                  nP"     "*MMnx   By: seniornamedw@proton.me

""")

def handle_the_configurator():

    while True:

        initial_input = input("Enter command: ")

        if initial_input.startswith('-c'):

            try:

                data["api_id"] = initial_input.split(' ')[1]
                data["api_hash"] = initial_input.split(' ')[2]

                with open('config.json', 'w') as json_file:
                    json_file.write(json.dumps(data, sort_keys=True, indent=4, ensure_ascii=False))

                print(f"[api_id]: {initial_input.split(' ')[1]}\n[api_hash]: {initial_input.split(' ')[2]}")

            except Exception as e:

                print("Wrong data, cant split!")

        elif initial_input.startswith('-g'):

            try:

                data["target_chat_id"] = int(initial_input.split('-')[2]) * -1

                with open('config.json', 'w') as json_file:
                    json_file.write(json.dumps(data, sort_keys=True, indent=4, ensure_ascii=False))

                print("Target chat id:" + str(data["target_chat_id"]))
            except Exception as e:
                print("Wrong data, cant split!")

        elif initial_input.startswith('-i'):

            print(f'\n[api_id]: {data["api_id"]}\n[api_hash]: {data["api_hash"]}\n[target_chat]: {data["target_chat_id"]}\n')

        elif initial_input.startswith('-r'):
            with open("config.json", 'r') as json_file:
                data = json.loads(json_file.read())

            if data["api_id"] == None or data["api_hash"] == None or data["target_chat_id"] == None:

                print("Api id, api hash and chat_id are required!")
                continue

            print("Changes saved!")

            if initial_input == '-r a':
                data["run_as_admin"] = True
                print("Admin mode activated")
            else:
                data["run_as_admin"] = False

            with open('config.json', 'w') as json_file:
                json_file.write(json.dumps(data, sort_keys=True, indent=4, ensure_ascii=False))

            break

        elif initial_input.startswith('-e'):
            sys.exit("Exiting...")

        else: print("Unknown command!")

def parse_chat_if_member(chat_id):

    app = Client("my_account", data['api_id'], data['api_hash'])

    @app.on_message(filters.group)
    async def hello(client, message):

        with open('goyim_data.json', 'r', encoding='utf-8') as json_file:
            data = json.loads(json_file.read())

        if (message.chat.id == chat_id) and (message.from_user.username != None):

            if str(message.from_user.id) not in data:
                data[str(message.from_user.id)] = {
                    "goy_messages_count": 1,
                    "goy_nickname": f'@{message.from_user.username}'
                }

            else:
                data[str(message.from_user.id)]["goy_messages_count"] += 1

                if f'@{message.from_user.username}' != data[str(message.from_user.id)]["goy_nickname"]:
                    data[str(message.from_user.id)]["goy_nickname"] = f'@{message.from_user.username}'

            with open('goyim_data.json', 'w') as json_file:
                json_file.write(json.dumps(data, sort_keys=False, indent=4, ensure_ascii=False))

    try:
        app.run()
    except:
        app.stop()
        print(f'\nStopped!{Exception}')

async def parse_chat_if_admin(chat_id):

    NUMBER_OF_MESSAGES = 0
    MEMBERS_PARSED = 0

    async with Client("my_account", data['api_id'], data['api_hash']) as app:

        async for member in app.get_chat_members(chat_id):

            async for i in app.search_messages(chat_id, from_user=member.user.id):

                NUMBER_OF_MESSAGES += 1

            if NUMBER_OF_MESSAGES > 0 and member.user.username:
                MEMBERS_PARSED += 1

                with open('text.txt', 'a', encoding='utf-8') as text_file:
                    text_file.write(f'[NICKNAME]: @{member.user.username}\n[MESSAGES SENT]: {NUMBER_OF_MESSAGES}\n\n')

            NUMBER_OF_MESSAGES = 0

        print(f'Members parsed: {MEMBERS_PARSED}, data saved to text.txt')

def json_to_txt():

    MEMBERS_PARSED = 0

    with open('goyim_data.json', 'r') as json_file:
        data = json.loads(json_file.read())

    for i in data:

        MEMBERS_PARSED += 1

        with open('text.txt', 'a') as text_file:
            text_file.write(f'[MEMBER]: {data[i]["goy_nickname"]}\n[MESSAGE_SENT]: {data[i]["goy_messages_count"]}\n\n\n')

    print(f'{MEMBERS_PARSED} members parsed. Result in text.txt')

if __name__ == "__main__":
    handle_the_configurator()

    if data["run_as_admin"] == True:
        asyncio.run(parse_chat_if_admin(data["target_chat_id"]))
    elif data["run_as_admin"] == False:
        parse_chat_if_member(data["target_chat_id"])
        json_to_txt()


from bareos_libcloud_api.bucket_explorer import TASK_TYPE
from bareos_libcloud_api.process_base import ProcessBase
from bareos_libcloud_api.get_libcloud_driver import get_driver
import io
from libcloud.common.types import LibcloudError
from libcloud.storage.types import ObjectDoesNotExistError
from bareos_libcloud_api.utils import silentremove
from time import sleep
import uuid

FINISH = 0
CONTINUE = 1

class Worker(ProcessBase):
    def __init__(
        self,
        options,
        worker_id,
        tmp_dir_path,
        message_queue,
        discovered_objects_queue,
        downloaded_objects_queue,
    ):
        super(Worker, self).__init__(
            worker_id, message_queue,
        )
        self.options = options
        self.tmp_dir_path = tmp_dir_path
        self.input_queue = discovered_objects_queue
        self.output_queue = downloaded_objects_queue

    def run_process(self):
        self.driver = get_driver(self.options)
        if self.driver == None:
            self.error_message("Could not load driver")
            self.abort_message()
            return

        status = CONTINUE
        while status != FINISH:
            status = self.__iterate_input_queue()

    def __iterate_input_queue(self):
        while not self.input_queue.empty():
            if self.shutdown_event.is_set():
                return FINISH
            job = self.input_queue.get()
            if job == None:  # poison pill
                return FINISH
            if self.__run_job(job) == FINISH:
                return FINISH
        # try again
        return CONTINUE

    def __run_job(self, job):
        success = False
        try:
            obj = self.driver.get_object(job["bucket"], job["name"])
        except ObjectDoesNotExistError:
            self.error_message(
                "Could not get file object, skipping: %s/%s"
                % (job["bucket"], job["name"])
            )
            return CONTINUE

        if job["size"] < 1024 * 10:
            try:
                self.debug_message(
                    110,
                    "%3d: Put complete file %s into queue"
                    % (self.worker_id, job["bucket"] + job["name"]),
                )
                stream = obj.as_stream()
                content = b"".join(list(stream))

                size_of_fetched_object = len(content)
                if size_of_fetched_object != job["size"]:
                    self.error_message(
                        "prefetched file %s: got %s bytes, not the real size (%s bytes)"
                        % (job["name"], size_of_fetched_object, job["size"]),
                    )
                    return CONTINUE

                job["data"] = io.BytesIO(content)
                job["type"] = TASK_TYPE.DOWNLOADED
                success = True
            except LibcloudError:
                self.error_message("Libcloud error, could not download file")
                return CONTINUE
            except Exception:
                self.error_message("Could not download file")
                return CONTINUE
        elif job["size"] < self.options["prefetch_size"]:
            try:
                self.debug_message(
                    110,
                    "%3d: Prefetch file %s"
                    % (self.worker_id, job["bucket"] + job["name"]),
                )
                tmpfilename = self.tmp_dir_path + "/" + str(uuid.uuid4())
                obj.download(tmpfilename)
                job["data"] = None
                job["tmpfile"] = tmpfilename
                job["type"] = TASK_TYPE.TEMP_FILE
                success = True
            except OSError as e:
                self.error_message("Could not open temporary file %s" % e.filename)
                self.abort_message()
                return FINISH
            except ObjectDoesNotExistError as e:
                silentremove(tmpfilename)
                self.error_message(
                    "Could not open object, skipping: %s" % e.object_name
                )
                return CONTINUE
            except LibcloudError:
                silentremove(tmpfilename)
                self.error_message(
                    "Error downloading object, skipping: %s/%s"
                    % (job["bucket"], job["name"])
                )
                return CONTINUE
            except Exception:
                silentremove(tmpfilename)
                self.error_message(
                    "Error using temporary file for, skipping: %s/%s"
                    % (job["bucket"], job["name"])
                )
                return CONTINUE
        else:
            try:
                self.debug_message(
                    110,
                    "%3d: Prepare file as stream for download %s"
                    % (self.worker_id, job["bucket"] + job["name"]),
                )
                job["data"] = obj
                job["type"] = TASK_TYPE.STREAM
                success = True
            except LibcloudError:
                self.error_message(
                    "Libcloud error preparing stream object, skipping: %s/%s"
                    % (job["bucket"], job["name"])
                )
                return CONTINUE
            except Exception:
                self.error_message(
                    "Error preparing stream object, skipping: %s/%s"
                    % (job["bucket"], job["name"])
                )
                return CONTINUE

        if success == True:
            self.queue_try_put(self.output_queue, job)

        return CONTINUE


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

'''Discover and run the Python test files in this package.'''

# IMPORT STANDARD LIBRARIES
import unittest
import os

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

def discover_and_run():
    '''Look in the tests/test_*.py folder for unittests and run them all.'''
    loader = unittest.TestLoader()
    tests = loader.discover(CURRENT_DIR)
    runner = unittest.TextTestRunner()
    runner.run(tests)

if __name__ == '__main__':
    discover_and_run()