<commit_before>from __future__ import with_statement

import sys
import os
from os import path

from pkg_resources import get_distribution
from optparse import OptionParser, make_option
from attest.collectors import Tests
from attest.reporters import get_all_reporters, get_reporter_by_name
from attest.utils import parse_options
from attest.hook import AssertImportHook

def make_parser(**kwargs):
    args = dict(
        prog='attest',
        usage='%prog [options] [tests...] [key=value...]',
        version=get_distribution('Attest').version,

        description=(
            'The positional "tests" are dotted '
            'names for modules or packages that are scanned '
            'recursively for Tests instances, or dotted names '
            'for any other object that iterates over tests. If '
            'not provided, packages in the working directory '
            'are scanned.\n'
            'The key/value pairs are passed to the '
            'reporter constructor, after some command-line '
            'friendly parsing.'
        ),

        option_list=[
            make_option('-d', '--debugger',
                action='store_true',
                help='enter pdb for failing tests',
            ),
            make_option('-r', '--reporter',
                metavar='NAME',
                help='select reporter by name'
            ),
            make_option('-l', '--list-reporters',
                action='store_true',
                help='list available reporters'
            ),
            make_option('-n', '--no-capture',
                action='store_true',
                help="don't capture stderr and stdout"
            ),
            make_option('--full-tracebacks',
                action='store_true',
                help="don't clean tracebacks"
            ),
            make_option('--fail-fast',
                action='store_true',
                help='stop at first failure'
            ),
            make_option('--native-assert',
                action='store_true',
                help="don't hook the assert statement"
            ),
            make_option('-p', '--profile',
                metavar='FILENAME',
                help='enable tests profiling and store results in filename'
            ),
            make_option('-k', '--keyboard-interrupt',
                action='store_true',
                help="Let KeyboardInterrupt exceptions (CTRL+C) propagate"
            ),
        ]
    )
    args.update(kwargs)
    return OptionParser(**args)

def main(tests=None, **kwargs):
    parser = make_parser(**kwargs)
    options, args = parser.parse_args()

    if options.list_reporters:
        for reporter in get_all_reporters():
            print reporter
        return

    opts = parse_options(args)
    reporter = get_reporter_by_name(options.reporter)(**opts)

    if not tests:
        sys.path.insert(0, os.getcwd())
        names = [arg for arg in args if '=' not in arg]
        if not names:
            names = [name for name in os.listdir('.')
                          if path.isfile('%s/__init__.py' % name)]

        if options.native_assert:
            tests = Tests(names)
        else:
            with AssertImportHook():
                tests = Tests(names)

    def run():
        tests.run(reporter, full_tracebacks=options.full_tracebacks,
                            fail_fast=options.fail_fast,
                            debugger=options.debugger,
                            no_capture=options.no_capture,
                            keyboard_interrupt=options.keyboard_interrupt)

    if options.profile:
        filename = options.profile
        import cProfile
        cProfile.runctx('run()', globals(), locals(), filename)
        print 'Wrote profiling results to %r.' % (filename,)
    else:
        run()

if __name__ == '__main__':
    main()
<commit_msg>When using 'attest' command, add cwd to sys.path[0] earlier<commit_after>from __future__ import with_statement

import sys
import os
from os import path

from pkg_resources import get_distribution
from optparse import OptionParser, make_option
from attest.collectors import Tests
from attest.reporters import get_all_reporters, get_reporter_by_name
from attest.utils import parse_options
from attest.hook import AssertImportHook

def make_parser(**kwargs):
    args = dict(
        prog='attest',
        usage='%prog [options] [tests...] [key=value...]',
        version=get_distribution('Attest').version,

        description=(
            'The positional "tests" are dotted '
            'names for modules or packages that are scanned '
            'recursively for Tests instances, or dotted names '
            'for any other object that iterates over tests. If '
            'not provided, packages in the working directory '
            'are scanned.\n'
            'The key/value pairs are passed to the '
            'reporter constructor, after some command-line '
            'friendly parsing.'
        ),

        option_list=[
            make_option('-d', '--debugger',
                action='store_true',
                help='enter pdb for failing tests',
            ),
            make_option('-r', '--reporter',
                metavar='NAME',
                help='select reporter by name'
            ),
            make_option('-l', '--list-reporters',
                action='store_true',
                help='list available reporters'
            ),
            make_option('-n', '--no-capture',
                action='store_true',
                help="don't capture stderr and stdout"
            ),
            make_option('--full-tracebacks',
                action='store_true',
                help="don't clean tracebacks"
            ),
            make_option('--fail-fast',
                action='store_true',
                help='stop at first failure'
            ),
            make_option('--native-assert',
                action='store_true',
                help="don't hook the assert statement"
            ),
            make_option('-p', '--profile',
                metavar='FILENAME',
                help='enable tests profiling and store results in filename'
            ),
            make_option('-k', '--keyboard-interrupt',
                action='store_true',
                help="Let KeyboardInterrupt exceptions (CTRL+C) propagate"
            ),
        ]
    )
    args.update(kwargs)
    return OptionParser(**args)

def main(tests=None, **kwargs):
    parser = make_parser(**kwargs)
    options, args = parser.parse_args()

    # When run as a console script (i.e. ``attest``), the CWD isn't
    # ``sys.path[0]``, but it should be. It's important to do this early in
    # case custom reporters are being used that make the assumption that CWD is
    # on ``sys.path``.
    cwd = os.getcwd()
    if sys.path[0] not in ('', cwd):
        sys.path.insert(0, cwd)

    if options.list_reporters:
        for reporter in get_all_reporters():
            print reporter
        return

    opts = parse_options(args)
    reporter = get_reporter_by_name(options.reporter)(**opts)

    if not tests:
        names = [arg for arg in args if '=' not in arg]
        if not names:
            names = [name for name in os.listdir('.')
                          if path.isfile('%s/__init__.py' % name)]

        if options.native_assert:
            tests = Tests(names)
        else:
            with AssertImportHook():
                tests = Tests(names)

    def run():
        tests.run(reporter, full_tracebacks=options.full_tracebacks,
                            fail_fast=options.fail_fast,
                            debugger=options.debugger,
                            no_capture=options.no_capture,
                            keyboard_interrupt=options.keyboard_interrupt)

    if options.profile:
        filename = options.profile
        import cProfile
        cProfile.runctx('run()', globals(), locals(), filename)
        print 'Wrote profiling results to %r.' % (filename,)
    else:
        run()

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Ecflow(CMakePackage):
    """ecFlow is a work flow package that enables users to run a large number
    of programs (with dependencies on each other and on time) in a controlled
    environment.

    It provides tolerance for hardware and software failures, combined with
    good restart capabilities.
    """

    homepage = 'https://confluence.ecmwf.int/display/ECFLOW/'
    url      = 'https://confluence.ecmwf.int/download/attachments/8650755/ecFlow-4.11.1-Source.tar.gz'

    version('4.12.0', sha256='566b797e8d78e3eb93946b923ef540ac61f50d4a17c9203d263c4fd5c39ab1d1')
    version('4.11.1', sha256='b3bcc1255939f87b9ba18d802940e08c0cf6379ca6aeec1fef7bd169b0085d6c')

    variant('static_boost', default=False,
            description='Use also static boost libraries when compiling')

    depends_on('boost+python')
    depends_on('boost+pic', when='+static_boost')
    depends_on('qt')
    depends_on('cmake@2.8.11:', type='build')

    def cmake_args(self):
        boost_lib = self.spec['boost'].prefix.lib
        args = ['-DBoost_PYTHON_LIBRARY_RELEASE=' + boost_lib]

        # https://jira.ecmwf.int/browse/SUP-2641#comment-208943
        use_static_boost = 'ON' if '+static_boost' in self.spec else 'OFF'
        args.append('-DENABLE_STATIC_BOOST_LIBS=' + use_static_boost)

        return args
<commit_msg>ecFlow added UI & GUI flag with new version (#16444)<commit_after># Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Ecflow(CMakePackage):
    """ecFlow is a work flow package that enables users to run a large number
    of programs (with dependencies on each other and on time) in a controlled
    environment.

    It provides tolerance for hardware and software failures, combined with
    good restart capabilities.
    """

    homepage = 'https://confluence.ecmwf.int/display/ECFLOW/'
    url      = 'https://confluence.ecmwf.int/download/attachments/8650755/ecFlow-4.11.1-Source.tar.gz'

    version('4.13.0', sha256='c743896e0ec1d705edd2abf2ee5a47f4b6f7b1818d8c159b521bdff50a403e39')
    version('4.12.0', sha256='566b797e8d78e3eb93946b923ef540ac61f50d4a17c9203d263c4fd5c39ab1d1')
    version('4.11.1', sha256='b3bcc1255939f87b9ba18d802940e08c0cf6379ca6aeec1fef7bd169b0085d6c')

    variant('static_boost', default=False,
            description='Use also static boost libraries when compiling')

    variant('ui', default=False, description='Enable ecflow_ui')

    # Boost-1.7X release not working well on serialization
    depends_on('boost@1.53:1.69+python')
    depends_on('boost@1.53:1.69+pic', when='+static_boost')
    depends_on('qt@5:', when='+ui')
    depends_on('cmake@2.12.11:', type='build')

    def cmake_args(self):
        boost_lib = self.spec['boost'].prefix.lib
        args = ['-DBoost_PYTHON_LIBRARY_RELEASE=' + boost_lib]

        ecflow_ui = 'ON' if '+ui' in self.spec else 'OFF'
        # https://jira.ecmwf.int/browse/SUP-2641#comment-208943
        use_static_boost = 'ON' if '+static_boost' in self.spec else 'OFF'
        args.append('-DENABLE_STATIC_BOOST_LIBS=' + use_static_boost)

        args.extend(['-DENABLE_UI=' + ecflow_ui, '-DENABLE_GUI=' + ecflow_ui])
        return args
<|endoftext|>


<commit_before>#!/usr/bin/env python

import re
import sys
import json
import time
import pickle
import struct
import socket
import thread
import urllib2
import argparse
from pprint import pprint
from datetime import datetime

NODES = {}
CLUSTER_NAME = ''
STATUS = {'red': 0, 'yellow': 1, 'green': 2}
SHARD_STATE = {'CREATED': 0, 'RECOVERING': 1, 'STARTED': 2, 'RELOCATED': 3, 'CLOSED': 4}
HOST_IDX = -1

def log(what, force=False):
    if args.verbose or force:
        pprint(what)

def get_es_host():
    global HOST_IDX
    HOST_IDX = (HOST_IDX + 1) % len(args.es) # round-robin
    return args.es[HOST_IDX]

def normalize(what):
    if not isinstance(what, (list, tuple)):
        return re.sub('\W+', '_',  what.strip().lower()).encode('utf-8')
    elif len(what) == 1:
        return normalize(what[0])
    else:
        return '%s.%s' % (normalize(what[0]), normalize(what[1:]))

def add_metric(metrics, prefix, stat, val, timestamp):
    if isinstance(val, bool):
        val = int(val)

    if prefix[-1] == 'translog' and stat == 'id':
        return
    elif isinstance(val, (int, long, float)) and stat != 'timestamp':
        metrics.append((normalize((prefix, stat)), (timestamp, val)))
    elif stat == 'status' and val in STATUS:
        metrics.append((normalize((prefix, stat)), (timestamp, STATUS[val])))
    elif stat == 'state' and val in SHARD_STATE:
        metrics.append((normalize((prefix, stat)), (timestamp, SHARD_STATE[val])))

def process_node_stats(prefix, stats):
    metrics = []
    global CLUSTER_NAME
    CLUSTER_NAME = stats['cluster_name']
    for node_id in stats['nodes']:
        node_stats = stats['nodes'][node_id]
        NODES[node_id] = node_stats['name']
        process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, NODES[node_id]), node_stats)
    return metrics

def process_cluster_health(prefix, health):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME), health)
    return metrics

def process_indices_status(prefix, status):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices'), status['indices'])
    return metrics

def process_indices_stats(prefix, stats):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices', '_all'), stats['_all'])
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices'), stats['indices'])
    return metrics

def process_segments_status(prefix, status):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices'), status['indices'])
    return metrics

def process_section(timestamp, metrics, prefix, section):
    for stat in section:
        stat_val = section[stat]
        if 'timestamp' in section:
            timestamp = int(section['timestamp'] / 1000) # es has epoch in ms, graphite needs seconds

        if isinstance(stat_val, dict):
            process_section(timestamp, metrics, (prefix, stat), stat_val)
        elif isinstance(stat_val, list):
            if prefix[-1] == 'fs' and stat == 'data':
                for disk in stat_val:
                    mount = disk['mount']
                    process_section(timestamp, metrics, (prefix, stat, mount), disk)
            elif prefix[-1] == 'os' and stat == 'load_average':
                add_metric(metrics, prefix, (stat, '1min_avg'), stat_val[0], timestamp)
                add_metric(metrics, prefix, (stat, '5min_avg'), stat_val[1], timestamp)
                add_metric(metrics, prefix, (stat, '15min_avg'), stat_val[2], timestamp)
            elif prefix[-1] == 'shards' and re.match('\d+', stat) is not None:
                for shard in stat_val:
                    shard_node = NODES[shard['routing']['node']]
                    process_section(timestamp, metrics, (prefix, stat, shard_node), shard)
            else:
                for stat_idx, sub_stat_val in enumerate(stat_val):
                    if isinstance(sub_stat_val, dict):
                        process_section(timestamp, metrics, (prefix, stat, str(stat_idx)), sub_stat_val)
                    else:
                        add_metric(metrics, prefix, (stat, str(stat_idx)), sub_stat_val, timestamp)
        else:
            add_metric(metrics, prefix, stat, stat_val, timestamp)

def send_to_graphite(metrics):
    if args.debug:
        for m, mval  in metrics:
            log('%s %s = %s' % (mval[0], m, mval[1]), True)
    else:
        payload = pickle.dumps(metrics)
        header = struct.pack('!L', len(payload))
        sock = socket.socket()
        sock.connect((args.graphite_host, args.graphite_port))
        sock.sendall('%s%s' % (header, payload))
        sock.close()

def get_metrics():
    dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    node_stats_url = 'http://%s/_nodes/stats?all=true' % get_es_host()
    log('%s: GET %s' % (dt, node_stats_url))
    node_stats_data = urllib2.urlopen(node_stats_url).read()
    node_stats = json.loads(node_stats_data)
    node_stats_metrics = process_node_stats(args.prefix, node_stats)
    send_to_graphite(node_stats_metrics)

    cluster_health_url = 'http://%s/_cluster/health?level=%s' % (get_es_host(), args.health_level)
    log('%s: GET %s' % (dt, cluster_health_url))
    cluster_health_data = urllib2.urlopen(cluster_health_url).read()
    cluster_health = json.loads(cluster_health_data)
    cluster_health_metrics = process_cluster_health(args.prefix, cluster_health)
    send_to_graphite(cluster_health_metrics)

    indices_status_url = 'http://%s/_status' % get_es_host()
    log('%s: GET %s' % (dt, indices_status_url))
    indices_status_data = urllib2.urlopen(indices_status_url).read()
    indices_status = json.loads(indices_status_data)
    indices_status_metrics = process_indices_status(args.prefix, indices_status)
    send_to_graphite(indices_status_metrics)

    indices_stats_url = 'http://%s/_stats?all=true' % get_es_host()
    if args.shard_stats:
        indices_stats_url = '%s&level=shards' % indices_stats_url
    log('%s: GET %s' % (dt, indices_stats_url))
    indices_stats_data = urllib2.urlopen(indices_stats_url).read()
    indices_stats = json.loads(indices_stats_data)
    indices_stats_metrics = process_indices_stats(args.prefix, indices_stats)
    send_to_graphite(indices_stats_metrics)

    if args.segments:
        segments_status_url = 'http://%s/_segments' % get_es_host()
        log('%s: GET %s' % (dt, segments_status_url))
        segments_status_data = urllib2.urlopen(segments_status_url).read()
        segments_status = json.loads(segments_status_data)
        segments_status_metrics = process_segments_status(args.prefix, segments_status)
        send_to_graphite(segments_status_metrics)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Send elasticsearch metrics to graphite')
    parser.add_argument('-p', '--prefix', default='es', help='graphite metric prefix. Default: %(default)s')
    parser.add_argument('-g', '--graphite-host', default='localhost', help='graphite hostname. Default: %(default)s')
    parser.add_argument('-o', '--graphite-port', default=2004, type=int, help='graphite pickle protocol port. Default: %(default)s')
    parser.add_argument('-i', '--interval', default=60, type=int, help='interval in seconds. Default: %(default)s')
    parser.add_argument('--health-level', choices=['cluster', 'indices', 'shards'], default='indices', help='The level of health metrics. Default: %(default)s')
    parser.add_argument('--shard-stats', action='store_true', help='Collect shard level stats metrics.')
    parser.add_argument('--segments', action='store_true', help='Collect low-level segment metrics.')
    parser.add_argument('-d', '--debug', action='store_true', help='Print metrics, don\'t send to graphite')
    parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
    parser.add_argument('es', nargs='+', help='elasticsearch host:port', metavar='ES_HOST')
    args = parser.parse_args()
    while True:
        thread.start_new_thread(get_metrics, ())
        time.sleep(args.interval)
<commit_msg>Bye bye whitespace<commit_after>#!/usr/bin/env python

import re
import sys
import json
import time
import pickle
import struct
import socket
import thread
import urllib2
import argparse
from pprint import pprint
from datetime import datetime

NODES = {}
CLUSTER_NAME = ''
STATUS = {'red': 0, 'yellow': 1, 'green': 2}
SHARD_STATE = {'CREATED': 0, 'RECOVERING': 1, 'STARTED': 2, 'RELOCATED': 3, 'CLOSED': 4}
HOST_IDX = -1

def log(what, force=False):
    if args.verbose or force:
        pprint(what)

def get_es_host():
    global HOST_IDX
    HOST_IDX = (HOST_IDX + 1) % len(args.es) # round-robin
    return args.es[HOST_IDX]

def normalize(what):
    if not isinstance(what, (list, tuple)):
        return re.sub('\W+', '_',  what.strip().lower()).encode('utf-8')
    elif len(what) == 1:
        return normalize(what[0])
    else:
        return '%s.%s' % (normalize(what[0]), normalize(what[1:]))

def add_metric(metrics, prefix, stat, val, timestamp):
    if isinstance(val, bool):
        val = int(val)

    if prefix[-1] == 'translog' and stat == 'id':
        return
    elif isinstance(val, (int, long, float)) and stat != 'timestamp':
        metrics.append((normalize((prefix, stat)), (timestamp, val)))
    elif stat == 'status' and val in STATUS:
        metrics.append((normalize((prefix, stat)), (timestamp, STATUS[val])))
    elif stat == 'state' and val in SHARD_STATE:
        metrics.append((normalize((prefix, stat)), (timestamp, SHARD_STATE[val])))

def process_node_stats(prefix, stats):
    metrics = []
    global CLUSTER_NAME
    CLUSTER_NAME = stats['cluster_name']
    for node_id in stats['nodes']:
        node_stats = stats['nodes'][node_id]
        NODES[node_id] = node_stats['name']
        process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, NODES[node_id]), node_stats)
    return metrics

def process_cluster_health(prefix, health):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME), health)
    return metrics

def process_indices_status(prefix, status):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices'), status['indices'])
    return metrics

def process_indices_stats(prefix, stats):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices', '_all'), stats['_all'])
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices'), stats['indices'])
    return metrics

def process_segments_status(prefix, status):
    metrics = []
    process_section(int(time.time()), metrics, (prefix, CLUSTER_NAME, 'indices'), status['indices'])
    return metrics

def process_section(timestamp, metrics, prefix, section):
    for stat in section:
        stat_val = section[stat]
        if 'timestamp' in section:
            timestamp = int(section['timestamp'] / 1000) # es has epoch in ms, graphite needs seconds

        if isinstance(stat_val, dict):
            process_section(timestamp, metrics, (prefix, stat), stat_val)
        elif isinstance(stat_val, list):
            if prefix[-1] == 'fs' and stat == 'data':
                for disk in stat_val:
                    mount = disk['mount']
                    process_section(timestamp, metrics, (prefix, stat, mount), disk)
            elif prefix[-1] == 'os' and stat == 'load_average':
                add_metric(metrics, prefix, (stat, '1min_avg'), stat_val[0], timestamp)
                add_metric(metrics, prefix, (stat, '5min_avg'), stat_val[1], timestamp)
                add_metric(metrics, prefix, (stat, '15min_avg'), stat_val[2], timestamp)
            elif prefix[-1] == 'shards' and re.match('\d+', stat) is not None:
                for shard in stat_val:
                    shard_node = NODES[shard['routing']['node']]
                    process_section(timestamp, metrics, (prefix, stat, shard_node), shard)
            else:
                for stat_idx, sub_stat_val in enumerate(stat_val):
                    if isinstance(sub_stat_val, dict):
                        process_section(timestamp, metrics, (prefix, stat, str(stat_idx)), sub_stat_val)
                    else:
                        add_metric(metrics, prefix, (stat, str(stat_idx)), sub_stat_val, timestamp)
        else:
            add_metric(metrics, prefix, stat, stat_val, timestamp)

def send_to_graphite(metrics):
    if args.debug:
        for m, mval  in metrics:
            log('%s %s = %s' % (mval[0], m, mval[1]), True)
    else:
        payload = pickle.dumps(metrics)
        header = struct.pack('!L', len(payload))
        sock = socket.socket()
        sock.connect((args.graphite_host, args.graphite_port))
        sock.sendall('%s%s' % (header, payload))
        sock.close()

def get_metrics():
    dt = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    node_stats_url = 'http://%s/_nodes/stats?all=true' % get_es_host()
    log('%s: GET %s' % (dt, node_stats_url))
    node_stats_data = urllib2.urlopen(node_stats_url).read()
    node_stats = json.loads(node_stats_data)
    node_stats_metrics = process_node_stats(args.prefix, node_stats)
    send_to_graphite(node_stats_metrics)

    cluster_health_url = 'http://%s/_cluster/health?level=%s' % (get_es_host(), args.health_level)
    log('%s: GET %s' % (dt, cluster_health_url))
    cluster_health_data = urllib2.urlopen(cluster_health_url).read()
    cluster_health = json.loads(cluster_health_data)
    cluster_health_metrics = process_cluster_health(args.prefix, cluster_health)
    send_to_graphite(cluster_health_metrics)

    indices_status_url = 'http://%s/_status' % get_es_host()
    log('%s: GET %s' % (dt, indices_status_url))
    indices_status_data = urllib2.urlopen(indices_status_url).read()
    indices_status = json.loads(indices_status_data)
    indices_status_metrics = process_indices_status(args.prefix, indices_status)
    send_to_graphite(indices_status_metrics)

    indices_stats_url = 'http://%s/_stats?all=true' % get_es_host()
    if args.shard_stats:
        indices_stats_url = '%s&level=shards' % indices_stats_url
    log('%s: GET %s' % (dt, indices_stats_url))
    indices_stats_data = urllib2.urlopen(indices_stats_url).read()
    indices_stats = json.loads(indices_stats_data)
    indices_stats_metrics = process_indices_stats(args.prefix, indices_stats)
    send_to_graphite(indices_stats_metrics)

    if args.segments:
        segments_status_url = 'http://%s/_segments' % get_es_host()
        log('%s: GET %s' % (dt, segments_status_url))
        segments_status_data = urllib2.urlopen(segments_status_url).read()
        segments_status = json.loads(segments_status_data)
        segments_status_metrics = process_segments_status(args.prefix, segments_status)
        send_to_graphite(segments_status_metrics)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Send elasticsearch metrics to graphite')
    parser.add_argument('-p', '--prefix', default='es', help='graphite metric prefix. Default: %(default)s')
    parser.add_argument('-g', '--graphite-host', default='localhost', help='graphite hostname. Default: %(default)s')
    parser.add_argument('-o', '--graphite-port', default=2004, type=int, help='graphite pickle protocol port. Default: %(default)s')
    parser.add_argument('-i', '--interval', default=60, type=int, help='interval in seconds. Default: %(default)s')
    parser.add_argument('--health-level', choices=['cluster', 'indices', 'shards'], default='indices', help='The level of health metrics. Default: %(default)s')
    parser.add_argument('--shard-stats', action='store_true', help='Collect shard level stats metrics.')
    parser.add_argument('--segments', action='store_true', help='Collect low-level segment metrics.')
    parser.add_argument('-d', '--debug', action='store_true', help='Print metrics, don\'t send to graphite')
    parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
    parser.add_argument('es', nargs='+', help='elasticsearch host:port', metavar='ES_HOST')
    args = parser.parse_args()
    while True:
        thread.start_new_thread(get_metrics, ())
        time.sleep(args.interval)
<|endoftext|>


<commit_before>import xmlrpclib
import traceback
import re
import time
from cStringIO import StringIO
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher

class RequestHandler(SimpleXMLRPCDispatcher):
    """A request dispatcher for the PyPI XML-RPC API."""

    def __init__(self):
        SimpleXMLRPCDispatcher.__init__(self, True, 'utf-8')
        self.register_function(list_packages)
        self.register_function(package_releases)
        self.register_function(release_urls)
        self.register_function(release_urls, name='package_urls') # Deprecated
        self.register_function(release_data)
        self.register_function(release_data, name='package_data') # Deprecated
        self.register_function(search)
        self.register_function(updated_releases)
        self.register_function(changelog)
        self.register_function(post_cheesecake_for_release)
        self.register_function(ratings)
        self.register_introspection_functions()
        self.register_multicall_functions()

    def __call__(self, webui_obj):
        webui_obj.handler.send_response(200, 'OK')
        webui_obj.handler.send_header('Content-type', 'text/xml')
        webui_obj.handler.send_header('charset', 'UTF-8' );
        webui_obj.handler.end_headers()
        data = webui_obj.handler.rfile.read()
        # This should be thread-safe, as the store is really a singleton
        self.store = webui_obj.store
        response = self._marshaled_dispatch(data)
        response = re.sub('([\x00-\x08]|[\x0b-\x0c]|[\x0e-\x1f])+', '', response)
        webui_obj.handler.wfile.write(response)

    def _dispatch(self, method, params):
        if not method.startswith('system.'):
            # Add store to all of our own methods
            params = (self.store,)+tuple(params)
        return SimpleXMLRPCDispatcher._dispatch(self, method, params)

    def system_multicall(self, call_list):
        if len(call_list) > 100:
            raise Fault, "multicall too large"
        return SimpleXMLRPCDispatcher.system_multicall(self, call_list)

def list_packages(store):
    result = store.get_packages()
    return [row['name'] for row in result]

def package_releases(store, package_name, show_hidden=False):
    if show_hidden:
        hidden = None
    else:
        hidden = False
    result = store.get_package_releases(package_name, hidden=hidden)
    return [row['version'] for row in result]

def release_urls(store, package_name, version):
    result = []
    for file in store.list_files(package_name, version):
        info = file.as_dict()
        info['url'] = store.gen_file_url(info['python_version'],
            package_name, info['filename'])
        result.append(info)
    # TODO do something with release_urls when there is something to do
    #info = store.get_package(package_name, version)
    #if info['download_url']:
    #    result.append({'url': info['download_url']})
    return result
package_urls = release_urls     # "deprecated"

def release_data(store, package_name, version):
    info = store.get_package(package_name, version).as_dict()
    del info['description_html']
    for col in ('requires', 'provides', 'obsoletes', 'requires_dist',
                'obsoletes_dist', 'project_url', 'provides_dist',
                'requires_external'):
        rows = store.get_release_relationships(package_name, version, col)
        info[col] = [row['specifier'] for row in rows]
    classifiers = [r[0] for r in store.get_release_classifiers(package_name,
        version)]
    info['classifiers' ] = classifiers
    return info
package_data = release_data     # "deprecated"

def search(store, spec, operator='and'):
    spec['_pypi_hidden'] = 'FALSE'
    return [row.as_dict() for row in store.query_packages(spec, operator)]

def updated_releases(store, since):
    result = store.updated_releases(since)
    return [(row['name'], row['version']) for row in result]

def changelog(store, since):
    result = store.changelog(since)
    return [(row['name'],row['version'],
             int(time.mktime(row['submitted_date'].timetuple())),
             row['action'])
             for row in result]

def post_cheesecake_for_release(store, name, version, score_data, password):
    if password != store.config.cheesecake_password:
        raise ValuError("Bad password.")

    store.save_cheesecake_score(name, version, score_data)
    store.commit()

def ratings(store, name, version, since):
    ratings, comments = store.all_ratings(name, version, since)
    for i, r in enumerate(ratings):
        r = list(r)
        r[3] = int(time.mktime(r[3].timetuple()))
        ratings[i] = tuple(r)
    for i, c in enumerate(comments):
        c = list(c)
        c[5] = int(time.mktime(c[5].timetuple()))
        comments[i] = c
    return ratings, comments

handle_request = RequestHandler()
<commit_msg>add some useful urls to the release data<commit_after>import xmlrpclib
import traceback
import re
import time
from cStringIO import StringIO
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher

class RequestHandler(SimpleXMLRPCDispatcher):
    """A request dispatcher for the PyPI XML-RPC API."""

    def __init__(self):
        SimpleXMLRPCDispatcher.__init__(self, True, 'utf-8')
        self.register_function(list_packages)
        self.register_function(package_releases)
        self.register_function(release_urls)
        self.register_function(release_urls, name='package_urls') # Deprecated
        self.register_function(release_data)
        self.register_function(release_data, name='package_data') # Deprecated
        self.register_function(search)
        self.register_function(updated_releases)
        self.register_function(changelog)
        self.register_function(post_cheesecake_for_release)
        self.register_function(ratings)
        self.register_introspection_functions()
        self.register_multicall_functions()

    def __call__(self, webui_obj):
        webui_obj.handler.send_response(200, 'OK')
        webui_obj.handler.send_header('Content-type', 'text/xml')
        webui_obj.handler.send_header('charset', 'UTF-8' );
        webui_obj.handler.end_headers()
        data = webui_obj.handler.rfile.read()
        # This should be thread-safe, as the store is really a singleton
        self.store = webui_obj.store
        response = self._marshaled_dispatch(data)
        response = re.sub('([\x00-\x08]|[\x0b-\x0c]|[\x0e-\x1f])+', '', response)
        webui_obj.handler.wfile.write(response)

    def _dispatch(self, method, params):
        if not method.startswith('system.'):
            # Add store to all of our own methods
            params = (self.store,)+tuple(params)
        return SimpleXMLRPCDispatcher._dispatch(self, method, params)

    def system_multicall(self, call_list):
        if len(call_list) > 100:
            raise Fault, "multicall too large"
        return SimpleXMLRPCDispatcher.system_multicall(self, call_list)

def list_packages(store):
    result = store.get_packages()
    return [row['name'] for row in result]

def package_releases(store, package_name, show_hidden=False):
    if show_hidden:
        hidden = None
    else:
        hidden = False
    result = store.get_package_releases(package_name, hidden=hidden)
    return [row['version'] for row in result]

def release_urls(store, package_name, version):
    result = []
    for file in store.list_files(package_name, version):
        info = file.as_dict()
        info['url'] = store.gen_file_url(info['python_version'],
            package_name, info['filename'])
        result.append(info)
    # TODO do something with release_urls when there is something to do
    #info = store.get_package(package_name, version)
    #if info['download_url']:
    #    result.append({'url': info['download_url']})
    return result
package_urls = release_urls     # "deprecated"

def release_data(store, package_name, version):
    info = store.get_package(package_name, version).as_dict()
    del info['description_html']
    for col in ('requires', 'provides', 'obsoletes', 'requires_dist',
                'obsoletes_dist', 'project_url', 'provides_dist',
                'requires_external'):
        rows = store.get_release_relationships(package_name, version, col)
        info[col] = [row['specifier'] for row in rows]
    classifiers = [r[0] for r in store.get_release_classifiers(package_name,
        version)]
    info['classifiers' ] = classifiers
    info['package_url'] = 'http://pypi.python.org/pypi/%s' % package_name
    info['release_url'] = 'http://pypi.python.org/pypi/%s/%s' % (package_name,
        version)
    return info
package_data = release_data     # "deprecated"

def search(store, spec, operator='and'):
    spec['_pypi_hidden'] = 'FALSE'
    return [row.as_dict() for row in store.query_packages(spec, operator)]

def updated_releases(store, since):
    result = store.updated_releases(since)
    return [(row['name'], row['version']) for row in result]

def changelog(store, since):
    result = store.changelog(since)
    return [(row['name'],row['version'],
             int(time.mktime(row['submitted_date'].timetuple())),
             row['action'])
             for row in result]

def post_cheesecake_for_release(store, name, version, score_data, password):
    if password != store.config.cheesecake_password:
        raise ValuError("Bad password.")

    store.save_cheesecake_score(name, version, score_data)
    store.commit()

def ratings(store, name, version, since):
    ratings, comments = store.all_ratings(name, version, since)
    for i, r in enumerate(ratings):
        r = list(r)
        r[3] = int(time.mktime(r[3].timetuple()))
        ratings[i] = tuple(r)
    for i, c in enumerate(comments):
        c = list(c)
        c[5] = int(time.mktime(c[5].timetuple()))
        comments[i] = c
    return ratings, comments

handle_request = RequestHandler()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from __future__ import absolute_import, division, print_function

import hashlib
import linecache

from ._compat import exec_

class _Nothing(object):
    """
    Sentinel class to indicate the lack of a value when ``None`` is ambiguous.

    All instances of `_Nothing` are equal.
    """
    def __copy__(self):
        return self

    def __deepcopy__(self, _):
        return self

    def __eq__(self, other):
        return self.__class__ == _Nothing

    def __ne__(self, other):
        return not self == other

    def __repr__(self):
        return "NOTHING"

NOTHING = _Nothing()
"""
Sentinel to indicate the lack of a value when ``None`` is ambiguous.
"""

def attr(default=NOTHING, validator=None):
    """
    Create a new attribute on a class.

    .. warning::

        Does nothing unless the class is also decorated with :func:`attr.s`!

    :param default: Value that is used if an ``attrs``-generated
        ``__init__`` is used and no value is passed while instantiating.
    :type default: Any value.

    :param validator: :func:`callable` that is called within
        ``attrs``-generated ``__init__`` methods with the :class:`Attribute` as
        the first parameter and the passed value as the second parameter.

        The return value is *not* inspected so the validator has to throw an
        exception itself.
    :type validator: callable
    """
    return _CountingAttr(
        default=default,
        validator=validator,
    )

def _transform_attrs(cl):
    """
    Transforms all `_CountingAttr`s on a class into `Attribute`s and saves the
    list in `__attrs_attrs__`.
    """
    cl.__attrs_attrs__ = []
    had_default = False
    for attr_name, ca in sorted(
            ((name, attr) for name, attr
             in cl.__dict__.items()
             if isinstance(attr, _CountingAttr)),
            key=lambda e: e[1].counter
    ):
        a = Attribute.from_counting_attr(name=attr_name, ca=ca)
        if had_default is True and a.default is NOTHING:
            raise ValueError(
                "No mandatory attributes allowed after an atribute with a "
                "default value or factory.  Attribute in question: {a!r}"
                .format(a=a)
            )
        elif had_default is False and a.default is not NOTHING:
            had_default = True
        cl.__attrs_attrs__.append(a)
        setattr(cl, attr_name, a)

def attributes(maybe_cl=None, add_repr=True, add_cmp=True, add_hash=True,
               add_init=True):
    """
    A class decorator that adds `dunder
    <https://wiki.python.org/moin/DunderAlias>`_\ -methods according to the
    specified attributes using :func:`attr.ib`.

    :param add_repr: Create a ``__repr__`` method with a human readable
        represantation of ``attrs`` attributes..
    :type add_repr: bool

    :param add_cmp: Create ``__eq__``, ``__ne__``, ``__lt__``, ``__le__``,
        ``__gt__``, and ``__ge__`` methods that compare the class as if it were
        a tuple of its ``attrs`` attributes.  But the attributes are *only*
        compared, if the type of both classes is *identical*!
    :type add_cmp: bool

    :param add_hash: Add a ``__hash__`` method that returns the :func:`hash` of
        a tuple of all ``attrs`` attribute values.
    :type add_hash: bool

    :param add_init: Add a ``__init__`` method that initialiazes the ``attrs``
        attributes.  Leading underscores are stripped for the argument name:.

        .. doctest::

            >>> import attr
            >>> @attr.s
            ... class C(object):
            ...     _private = attr.ib()
            >>> C(private=42)
            C(_private=42)
    :type add_init: bool
    """
    # attrs_or class type depends on the usage of the decorator.  It's a class
    # if it's used as `@attributes` but ``None`` (or a value passed) if used
    # as `@attributes()`.
    if isinstance(maybe_cl, type):
        _transform_attrs(maybe_cl)
        return _add_init(_add_hash(_add_cmp(_add_repr(maybe_cl))))
    else:
        def wrap(cl):
            _transform_attrs(cl)
            if add_repr is True:
                cl = _add_repr(cl)
            if add_cmp is True:
                cl = _add_cmp(cl)
            if add_hash is True:
                cl = _add_hash(cl)
            if add_init is True:
                cl = _add_init(cl)
            return cl

        return wrap

def _attrs_to_tuple(obj, attrs):
    """
    Create a tuple of all values of *obj*'s *attrs*.
    """
    return tuple(getattr(obj, a.name) for a in attrs)

def _add_hash(cl, attrs=None):
    if attrs is None:
        attrs = cl.__attrs_attrs__

    def hash_(self):
        """
        Automatically created by attrs.
        """
        return hash(_attrs_to_tuple(self, attrs))

    cl.__hash__ = hash_
    return cl

def _add_cmp(cl, attrs=None):
    if attrs is None:
        attrs = cl.__attrs_attrs__

    def attrs_to_tuple(obj):
        """
        Save us some typing.
        """
        return _attrs_to_tuple(obj, attrs)

    def eq(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) == attrs_to_tuple(other)
        else:
            return NotImplemented

    def ne(self, other):
        """
        Automatically created by attrs.
        """
        result = eq(self, other)
        if result is NotImplemented:
            return NotImplemented
        else:
            return not result

    def lt(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) < attrs_to_tuple(other)
        else:
            return NotImplemented

    def le(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) <= attrs_to_tuple(other)
        else:
            return NotImplemented

    def gt(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) > attrs_to_tuple(other)
        else:
            return NotImplemented

    def ge(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) >= attrs_to_tuple(other)
        else:
            return NotImplemented

    cl.__eq__ = eq
    cl.__ne__ = ne
    cl.__lt__ = lt
    cl.__le__ = le
    cl.__gt__ = gt
    cl.__ge__ = ge

    return cl

def _add_repr(cl, attrs=None):
    if attrs is None:
        attrs = cl.__attrs_attrs__

    def repr_(self):
        """
        Automatically created by attrs.
        """
        return "{0}({1})".format(
            self.__class__.__name__,
            ", ".join(a.name + "=" + repr(getattr(self, a.name))
                      for a in attrs)
        )
    cl.__repr__ = repr_
    return cl

def _add_init(cl):
    attrs = cl.__attrs_attrs__

    # We cache the generated init methods for the same kinds of attributes.
    sha1 = hashlib.sha1()
    sha1.update(repr(attrs).encode("utf-8"))
    unique_filename = "<attrs generated init {0}>".format(
        sha1.hexdigest()
    )

    script = _attrs_to_script(attrs)
    locs = {}
    bytecode = compile(script, unique_filename, "exec")
    attr_dict = dict((a.name, a) for a in attrs)
    exec_(bytecode, {"NOTHING": NOTHING, "attr_dict": attr_dict}, locs)
    init = locs["__init__"]

    # In order of debuggers like PDB being able to step through the code,
    # we add a fake linecache entry.
    linecache.cache[unique_filename] = (
        len(script),
        None,
        script.splitlines(True),
        unique_filename
    )
    cl.__init__ = init
    return cl

def _attrs_to_script(attrs):
    """
    Return a valid Python script of an initializer for *attrs*.
    """
    lines = []
    args = []
    for a in attrs:
        attr_name = a.name
        arg_name = a.name.lstrip("_")
        if a.validator is not None:
            lines.append("attr_dict['{attr_name}'].validator(attr_dict['"
                         "{attr_name}'], {attr_name})"
                         .format(attr_name=attr_name))
        if a.default is not NOTHING and not isinstance(a.default, Factory):
            args.append(
                "{arg_name}=attr_dict['{attr_name}'].default".format(
                    arg_name=arg_name,
                    attr_name=attr_name,
                )
            )
            lines.append("self.{attr_name} = {arg_name}".format(
                arg_name=arg_name,
                attr_name=attr_name,
            ))
        elif a.default is not NOTHING and isinstance(a.default, Factory):
            args.append("{arg_name}=NOTHING".format(arg_name=arg_name))
            lines.extend("""\
if {arg_name} is not NOTHING:
    self.{attr_name} = {arg_name}
else:
    self.{attr_name} = attr_dict["{attr_name}"].default.factory()"""
                         .format(attr_name=attr_name,
                                 arg_name=arg_name)
                         .split("\n"))
        else:
            args.append(arg_name)
            lines.append("self.{attr_name} = {arg_name}".format(
                attr_name=attr_name,
                arg_name=arg_name,
            ))

    return """\
def __init__(self, {args}):
    '''
    Attribute initializer automatically created by attrs.
    '''
    {setters}
""".format(
        args=", ".join(args),
        setters="\n    ".join(lines),
    )

class Attribute(object):
    """
    *Read-only* representation of an attribute.

    :attribute name: The name of the attribute.
    :attribute default: see :func:`attr.ib`
    :attribute validator: see :func:`attr.ib`
    """
    _attributes = [
        "name", "default", "validator",
    ]  # we can't use ``attrs`` so we have to cheat a little.

    def __init__(self, **kw):
        try:
            for a in Attribute._attributes:
                setattr(self, a, kw[a])
        except KeyError:
            raise TypeError("Missing argument '{arg}'.".format(arg=a))

    @classmethod
    def from_counting_attr(cl, name, ca):
        return cl(name=name,
                  **dict((k, getattr(ca, k))
                         for k
                         in Attribute._attributes
                         if k != "name"))

_a = [Attribute(name=name, default=NOTHING, validator=None)
      for name in Attribute._attributes]
Attribute = _add_hash(
    _add_cmp(_add_repr(Attribute, attrs=_a), attrs=_a), attrs=_a
)

class _CountingAttr(object):
    __attrs_attrs__ = [
        Attribute(name=name, default=NOTHING, validator=None)
        for name
        in ("counter", "default",)
    ]
    counter = 0

    def __init__(self, default, validator):
        _CountingAttr.counter += 1
        self.counter = _CountingAttr.counter
        self.default = default
        self.validator = validator

_CountingAttr = _add_cmp(_add_repr(_CountingAttr))

@attributes
class Factory(object):
    """
    Stores a factory callable.

    If passed as the default value to :func:`attr.ib`, the factory is used to
    generate a new value.
    """
    factory = attr()

def make_class(name, attrs, **attributes_arguments):
    """
    A quick way to create a new class called *name* with *attrs*.

    :param name: The name for the new class.
    :type name: str

    :param attrs: A list of names or a dictionary of mappings of names to
        attributes.
    :type attrs: :class:`list` or :class:`dict`

    :param attributes_arguments: Passed unmodified to :func:`attr.s`.

    :return: A new class with *attrs*.
    :rtype: type
    """
    if isinstance(attrs, dict):
        cl_dict = attrs
    elif isinstance(attrs, (list, tuple)):
        cl_dict = dict((a, attr()) for a in attrs)
    else:
        raise TypeError("attrs argument must be a dict or a list.")

    return attributes(**attributes_arguments)(type(name, (object,), cl_dict))
<commit_msg>Simplify attributes decorator<commit_after># -*- coding: utf-8 -*-

from __future__ import absolute_import, division, print_function

import hashlib
import linecache

from ._compat import exec_

class _Nothing(object):
    """
    Sentinel class to indicate the lack of a value when ``None`` is ambiguous.

    All instances of `_Nothing` are equal.
    """
    def __copy__(self):
        return self

    def __deepcopy__(self, _):
        return self

    def __eq__(self, other):
        return self.__class__ == _Nothing

    def __ne__(self, other):
        return not self == other

    def __repr__(self):
        return "NOTHING"

NOTHING = _Nothing()
"""
Sentinel to indicate the lack of a value when ``None`` is ambiguous.
"""

def attr(default=NOTHING, validator=None):
    """
    Create a new attribute on a class.

    .. warning::

        Does nothing unless the class is also decorated with :func:`attr.s`!

    :param default: Value that is used if an ``attrs``-generated
        ``__init__`` is used and no value is passed while instantiating.
    :type default: Any value.

    :param validator: :func:`callable` that is called within
        ``attrs``-generated ``__init__`` methods with the :class:`Attribute` as
        the first parameter and the passed value as the second parameter.

        The return value is *not* inspected so the validator has to throw an
        exception itself.
    :type validator: callable
    """
    return _CountingAttr(
        default=default,
        validator=validator,
    )

def _transform_attrs(cl):
    """
    Transforms all `_CountingAttr`s on a class into `Attribute`s and saves the
    list in `__attrs_attrs__`.
    """
    cl.__attrs_attrs__ = []
    had_default = False
    for attr_name, ca in sorted(
            ((name, attr) for name, attr
             in cl.__dict__.items()
             if isinstance(attr, _CountingAttr)),
            key=lambda e: e[1].counter
    ):
        a = Attribute.from_counting_attr(name=attr_name, ca=ca)
        if had_default is True and a.default is NOTHING:
            raise ValueError(
                "No mandatory attributes allowed after an atribute with a "
                "default value or factory.  Attribute in question: {a!r}"
                .format(a=a)
            )
        elif had_default is False and a.default is not NOTHING:
            had_default = True
        cl.__attrs_attrs__.append(a)
        setattr(cl, attr_name, a)

def attributes(maybe_cl=None, add_repr=True, add_cmp=True, add_hash=True,
               add_init=True):
    """
    A class decorator that adds `dunder
    <https://wiki.python.org/moin/DunderAlias>`_\ -methods according to the
    specified attributes using :func:`attr.ib`.

    :param add_repr: Create a ``__repr__`` method with a human readable
        represantation of ``attrs`` attributes..
    :type add_repr: bool

    :param add_cmp: Create ``__eq__``, ``__ne__``, ``__lt__``, ``__le__``,
        ``__gt__``, and ``__ge__`` methods that compare the class as if it were
        a tuple of its ``attrs`` attributes.  But the attributes are *only*
        compared, if the type of both classes is *identical*!
    :type add_cmp: bool

    :param add_hash: Add a ``__hash__`` method that returns the :func:`hash` of
        a tuple of all ``attrs`` attribute values.
    :type add_hash: bool

    :param add_init: Add a ``__init__`` method that initialiazes the ``attrs``
        attributes.  Leading underscores are stripped for the argument name:.

        .. doctest::

            >>> import attr
            >>> @attr.s
            ... class C(object):
            ...     _private = attr.ib()
            >>> C(private=42)
            C(_private=42)
    :type add_init: bool
    """
    def wrap(cl):
        _transform_attrs(cl)
        if add_repr is True:
            cl = _add_repr(cl)
        if add_cmp is True:
            cl = _add_cmp(cl)
        if add_hash is True:
            cl = _add_hash(cl)
        if add_init is True:
            cl = _add_init(cl)
        return cl
    # attrs_or class type depends on the usage of the decorator.  It's a class
    # if it's used as `@attributes` but ``None`` (or a value passed) if used
    # as `@attributes()`.
    if isinstance(maybe_cl, type):
        return wrap(maybe_cl)
    else:
        return wrap

def _attrs_to_tuple(obj, attrs):
    """
    Create a tuple of all values of *obj*'s *attrs*.
    """
    return tuple(getattr(obj, a.name) for a in attrs)

def _add_hash(cl, attrs=None):
    if attrs is None:
        attrs = cl.__attrs_attrs__

    def hash_(self):
        """
        Automatically created by attrs.
        """
        return hash(_attrs_to_tuple(self, attrs))

    cl.__hash__ = hash_
    return cl

def _add_cmp(cl, attrs=None):
    if attrs is None:
        attrs = cl.__attrs_attrs__

    def attrs_to_tuple(obj):
        """
        Save us some typing.
        """
        return _attrs_to_tuple(obj, attrs)

    def eq(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) == attrs_to_tuple(other)
        else:
            return NotImplemented

    def ne(self, other):
        """
        Automatically created by attrs.
        """
        result = eq(self, other)
        if result is NotImplemented:
            return NotImplemented
        else:
            return not result

    def lt(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) < attrs_to_tuple(other)
        else:
            return NotImplemented

    def le(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) <= attrs_to_tuple(other)
        else:
            return NotImplemented

    def gt(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) > attrs_to_tuple(other)
        else:
            return NotImplemented

    def ge(self, other):
        """
        Automatically created by attrs.
        """
        if isinstance(other, self.__class__):
            return attrs_to_tuple(self) >= attrs_to_tuple(other)
        else:
            return NotImplemented

    cl.__eq__ = eq
    cl.__ne__ = ne
    cl.__lt__ = lt
    cl.__le__ = le
    cl.__gt__ = gt
    cl.__ge__ = ge

    return cl

def _add_repr(cl, attrs=None):
    if attrs is None:
        attrs = cl.__attrs_attrs__

    def repr_(self):
        """
        Automatically created by attrs.
        """
        return "{0}({1})".format(
            self.__class__.__name__,
            ", ".join(a.name + "=" + repr(getattr(self, a.name))
                      for a in attrs)
        )
    cl.__repr__ = repr_
    return cl

def _add_init(cl):
    attrs = cl.__attrs_attrs__

    # We cache the generated init methods for the same kinds of attributes.
    sha1 = hashlib.sha1()
    sha1.update(repr(attrs).encode("utf-8"))
    unique_filename = "<attrs generated init {0}>".format(
        sha1.hexdigest()
    )

    script = _attrs_to_script(attrs)
    locs = {}
    bytecode = compile(script, unique_filename, "exec")
    attr_dict = dict((a.name, a) for a in attrs)
    exec_(bytecode, {"NOTHING": NOTHING, "attr_dict": attr_dict}, locs)
    init = locs["__init__"]

    # In order of debuggers like PDB being able to step through the code,
    # we add a fake linecache entry.
    linecache.cache[unique_filename] = (
        len(script),
        None,
        script.splitlines(True),
        unique_filename
    )
    cl.__init__ = init
    return cl

def _attrs_to_script(attrs):
    """
    Return a valid Python script of an initializer for *attrs*.
    """
    lines = []
    args = []
    for a in attrs:
        attr_name = a.name
        arg_name = a.name.lstrip("_")
        if a.validator is not None:
            lines.append("attr_dict['{attr_name}'].validator(attr_dict['"
                         "{attr_name}'], {attr_name})"
                         .format(attr_name=attr_name))
        if a.default is not NOTHING and not isinstance(a.default, Factory):
            args.append(
                "{arg_name}=attr_dict['{attr_name}'].default".format(
                    arg_name=arg_name,
                    attr_name=attr_name,
                )
            )
            lines.append("self.{attr_name} = {arg_name}".format(
                arg_name=arg_name,
                attr_name=attr_name,
            ))
        elif a.default is not NOTHING and isinstance(a.default, Factory):
            args.append("{arg_name}=NOTHING".format(arg_name=arg_name))
            lines.extend("""\
if {arg_name} is not NOTHING:
    self.{attr_name} = {arg_name}
else:
    self.{attr_name} = attr_dict["{attr_name}"].default.factory()"""
                         .format(attr_name=attr_name,
                                 arg_name=arg_name)
                         .split("\n"))
        else:
            args.append(arg_name)
            lines.append("self.{attr_name} = {arg_name}".format(
                attr_name=attr_name,
                arg_name=arg_name,
            ))

    return """\
def __init__(self, {args}):
    '''
    Attribute initializer automatically created by attrs.
    '''
    {setters}
""".format(
        args=", ".join(args),
        setters="\n    ".join(lines),
    )

class Attribute(object):
    """
    *Read-only* representation of an attribute.

    :attribute name: The name of the attribute.
    :attribute default: see :func:`attr.ib`
    :attribute validator: see :func:`attr.ib`
    """
    _attributes = [
        "name", "default", "validator",
    ]  # we can't use ``attrs`` so we have to cheat a little.

    def __init__(self, **kw):
        try:
            for a in Attribute._attributes:
                setattr(self, a, kw[a])
        except KeyError:
            raise TypeError("Missing argument '{arg}'.".format(arg=a))

    @classmethod
    def from_counting_attr(cl, name, ca):
        return cl(name=name,
                  **dict((k, getattr(ca, k))
                         for k
                         in Attribute._attributes
                         if k != "name"))

_a = [Attribute(name=name, default=NOTHING, validator=None)
      for name in Attribute._attributes]
Attribute = _add_hash(
    _add_cmp(_add_repr(Attribute, attrs=_a), attrs=_a), attrs=_a
)

class _CountingAttr(object):
    __attrs_attrs__ = [
        Attribute(name=name, default=NOTHING, validator=None)
        for name
        in ("counter", "default",)
    ]
    counter = 0

    def __init__(self, default, validator):
        _CountingAttr.counter += 1
        self.counter = _CountingAttr.counter
        self.default = default
        self.validator = validator

_CountingAttr = _add_cmp(_add_repr(_CountingAttr))

@attributes
class Factory(object):
    """
    Stores a factory callable.

    If passed as the default value to :func:`attr.ib`, the factory is used to
    generate a new value.
    """
    factory = attr()

def make_class(name, attrs, **attributes_arguments):
    """
    A quick way to create a new class called *name* with *attrs*.

    :param name: The name for the new class.
    :type name: str

    :param attrs: A list of names or a dictionary of mappings of names to
        attributes.
    :type attrs: :class:`list` or :class:`dict`

    :param attributes_arguments: Passed unmodified to :func:`attr.s`.

    :return: A new class with *attrs*.
    :rtype: type
    """
    if isinstance(attrs, dict):
        cl_dict = attrs
    elif isinstance(attrs, (list, tuple)):
        cl_dict = dict((a, attr()) for a in attrs)
    else:
        raise TypeError("attrs argument must be a dict or a list.")

    return attributes(**attributes_arguments)(type(name, (object,), cl_dict))
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Batiments import *

#TODO mettre les bonnes valeurs pour les couts de construction et de recherche
from Units import *

class AI:
    def __init__(self,parent, civilisation):
        self.civilisation = civilisation
        self.base = Base(self, 10, 10)
        self.parent = parent
        self.manqueRessource = False
        self.ressourceManquante = None
        self.qteRessourceManquante = 0
        self.batiments = []
        self.recherchesCompletes = []
        self.bois = 0
        self.minerais = 0
        self.charbon = 0
        self.nbNourriture = 0
        self.units = []
        parent.createUnit(Unit.generateId(self.civilisation),self.base.posX+1, self.base.posY+1, self.civilisation)
        self.paix = True
        self.paysansOccupes = True
        self.morale = 100
        self.nombreSoldatsAllies = 0
        self.nombreSoldatsEnnemis = 0
        self.hpMoyen = 0
        self.epoque = 0
        #valeurs pour empêcher de rappeler des fonctions trop souvent
        self.derniereFerme = 0
        self.derniereScierie = 0
        self.derniereFonderie = 0
        self.derniereBarraque = 0
        self.derniereEglise = 0
        self.dernierHopital = 0
        self.dernierGarage = 0
        self.derniereFete = 0
        self.lastCheck = time.time()
        self.departEpoque = time.time()
        self.cooldownAutomatisation = 60
        self.cooldownEpoque = 300
        self.cooldownAttaque = 60
        self.derniereAttaque = 0
        self.cooldownRecherche = 120
        self.cooldownRessource = 30
        self.dernierSoldat = 0
        self.dernierPaysan = 0
        self.cooldownUnite = 40
        self.derniereRecherche = 0
        self.derniereRessourceBois = 0
        self.derniereRessourceMinerai = 0
        self.derniereRessourceCharbon = 0
        self.derniereBase = 0
        self.cooldownBatiment = 60

    def penser(self):

        #fais des test requis pour savoir quel mode prendre
        self.blackboard()

        #premier test pour savoir si on est en paix
        if self.paix:

            #si on manque de ressources, aller les miner
            if self.manqueRessource:
                    self.chercherRessource(self.ressourceManquante)
                    if self.ressourceManquante == "bois":
                        if self.qteRessourceManquante <= self.bois:
                            self.manqueRessource = False
                            pass
                    elif self.ressourceManquante == "minerais":
                        if self.qteRessourceManquante <= self.minerais:
                            self.manqueRessource = False
                            pass
                    elif self.ressourceManquante == "nourriture":
                        if self.qteRessourceManquante <= self.nbNourriture:
                            self.manqueRessource = False
                            pass
                    elif self.ressourceManquante == "charbon":
                        if self.qteRessourceManquante <= self.charbon:
                            self.manqueRessource = False
                            pass
                    else:
                        return

            #si l'on peut changer d'époque, le faire
            if time.time() - self.departEpoque >= self.cooldownEpoque and self.epoque > 3:
                self.changerEpoque()
                self.departEpoque = time.time()
                return

            #si tous les paysans sont occupés et que l'on en a moins de 10, créer un nouveau paysan
            if self.paysansOccupes and time.time() - self.dernierPaysan >= self.cooldownUnite:
                self.creerPaysan()
                self.dernierPaysan = time.time()
                return

            #si le moral est trop bas, faire une fête
            if self.morale < 50 and time.time() - self.derniereFete >= self.cooldownRecherche:
                self.augmenterMoral()
                self.derniereFete = time.time()
                return

            #si un ennemi a plus de soldats que nous, creer des soldats
            if self.nombreSoldatsAllies < self.nombreSoldatsEnnemis and time.time() - self.dernierSoldat >= self.cooldownUnite:
                self.creerSoldat()
                self.dernierSoldat = time.time()
                return

            #si un ennemi a moins de soldats que nous, attaquer
            if self.nombreSoldatsAllies > self.nombreSoldatsEnnemis and time.time() - self.derniereAttaque >= self.cooldownAttaque:
                self.attaquer()
                self.derniereAttaque = time.time()
                return

            #si rien d'autre, faire des recgerches
            if time.time() - self.derniereRecherche >= self.cooldownRecherche:
                self.rechercher()
                self.derniereRecherche = time.time()

        #sinon on est en guerre
        else:
            if self.hpMoyen < 50 :
                self.retraite()

    def chercherRessource(self, ressource):
        print(ressource)
        if ressource == "bois":
            self.chercherBois()
        elif ressource == "minerais":
            self.chercherminerais()
        elif ressource == "charbon":
            self.cherchercharbon()
        elif ressource == "nourriture":
            self.chercherNourriture()

    def chercherBois(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                    if self.epoque >= 2:
                        if time.time() - self.derniereScierie >= self.cooldownAutomatisation:
                            #TODO creer une scierie et y mettre le paysan
                            return

                    if time.time() - self.derniereRessourceBois >= self.cooldownRessource:
                        position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.FORET)
                        unit.changerCible(position["x"], position["y"])
                        self.derniereRessourceBois = time.time()
                        return

        self.creerPaysan()

    def chercherminerais(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                    if self.epoque >= 3:
                        if time.time() - self.derniereFonderie >= self.cooldownAutomatisation:
                            #TODO creer une fonderie et y mettre le paysan
                            return
                    if time.time() - self.derniereRessourceMinerai >= self.cooldownRessource:
                        position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.MINERAI)
                        unit.changerCible(position["x"], position["y"])
                        self.derniereRessourceBois = time.time()
                        return
        self.creerPaysan()

    def cherchercharbon(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                    if time.time() - self.derniereRessourceCharbon >= self.cooldownRessource:
                        for x in range(unit.x, unit.x+20):
                            for y in range(unit.y, unit.y+20):
                                if time.time() - self.derniereRessourceBois >= self.cooldownRessource:
                                    position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.CHARBON)
                                    unit.changerCible(position["x"], position["y"])
                                    self.derniereRessourceBois = time.time()
                                    return
        self.creerPaysan()

    def chercherNourriture(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                        if time.time() - self.derniereFerme >= self.cooldownAutomatisation:
                            #TODO creer une ferme
                            return

        self.creerPaysan()

    def changerEpoque(self):
        print("changer Epoque")
        for batiment in self.batiments:
            if isinstance(batiment, Base):
                if self.epoque == 1:
                    if self.bois >= batiment.coutRecherche2[0]:
                        batiment.changerEpoque()
                    else:
                        self.manqueRessource = True
                        self.qteRessourceManquante = batiment.coutRecherche2[0]
                        self.ressourceManquante = "bois"
                    return

                elif self.epoque == 2:
                    if self.bois >= batiment.coutRecherche2[0]:
                        if self.minerais >= batiment.coutRecherche2[1]:
                            batiment.changerEpoque()
                        else:
                            self.manqueRessource = True
                            self.qteRessourceManquante = batiment.coutRecherche2[1]
                            self.ressourceManquante = "minerais"
                    else:
                        self.manqueRessource = True
                        self.qteRessourceManquante = batiment.coutRecherche2[0]
                        self.ressourceManquante = "bois"
                    return

        #TODO trouver un paysan et le faire créer une nouvelle base

    def creerPaysan(self):
        print("creer Paysan")
        if self.base != None:
                if self.bois >= self.base.coutCreer1[0]:
                    self.base.creer1()
                    return
                else:
                    self.manqueRessource = True
                    self.qteRessourceManquante = self.base.coutCreer1[0]
                    self.ressourceManquante = "bois"
                    return

        #TODO trouver paysan et créer une nouvelle base
        if time.time() - self.derniereBase >= self.cooldownBatiment:
            for unit in self.units:
                if isinstance(unit, Paysan):
                    if unit.typeRessource == 0:
                        position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.Gazon)
                        self.base = Base(self, position["x"], position["y"])

    def augmenterMoral(self):
        print("augmenter Moral")
        for batiment in self.batiments:
            if isinstance(batiment, Eglise):
                if self.bois >= batiment.coutRecherche1[0]:
                    batiment.recherche1()
                    return
                else:
                    self.manqueRessource = True
                    self.qteRessourceManquante = batiment.coutRecherche1[0]
                    self.ressourceManquante = "bois"
                    return
        #TODO trouver un paysan et creer une nouvelle Église

    def creerSoldat(self):
        print("creer Soldat")
        for batiment in self.batiments:
            if isinstance(batiment, Baraque):
                if not batiment.enCreation:
                    if self.bois >= batiment.coutCreer1[0]:
                        batiment.creer1()
                        return
                    else:
                        self.manqueRessource = True
                        self.qteRessourceManquante = batiment.coutCreer1[0]
                        self.ressourceManquante = "bois"
                        return
        #TODO trouver un paysan et creer une nouvelle baraque

    def attaquer(self):
        print("attaquer")
        for unit in self.units:
            if isinstance(unit, Soldat):
                #TODO faire Attaquer les Soldats
                pass

    def retraite(self):
        print("retraite")
        for unit in self.units:
            if isinstance(unit, Soldat):
                #TODO faire retraiter les Soldats
                pass

    def rechercher(self):
        print("rechercher")
        #TODO figurer comment rechercher
        pass

    def blackboard(self):
        #fais des test 1 fois au 30 sec pour éviter de trop répéter des taches
        if time.time() - self.lastCheck >= 30:
            #vérifie si tous les paysans sont occupés
            for unit in self.units:
                if isinstance(unit, Paysan):
                    if unit.typeRessource == 0:
                        self.paysansOccupes = False

            #compte les soldats à nous et trouve le hp moyen de ces soldats
            self.nombreSoldatsAllies = 0
            hpTotal = 0
            for unit in self.units:
                if isinstance(unit, Soldat):
                    self.nombreSoldatsAllies += 1
                    hpTotal += unit.hp

            self.hpMoyen = hpTotal/self.nombreSoldatsAllies

            #trouve le nombre de soldats de l'ennemi avec le plus de soldats
            ennemis = []
            for unit in self.parent.units:
                if unit.civilisation == "ROUGE":
                    ennemis[0] += 1
                elif unit.civilisation == "BLEU":
                    ennemis[1] += 1
                elif unit.civilisation == "VERT":
                    ennemis[2] += 1
                elif unit.civilisation == "ORANGE":
                    ennemis[3] += 1
                elif unit.civilisation == "MAUVE":
                    ennemis[4] += 1
                elif unit.civilisation == "BLANC":
                    ennemis[5] += 1
                elif unit.civilisation == "NOIR":
                    ennemis[6] += 1
                elif unit.civilisation == "ROSE":
                    ennemis[7] += 1
                elif unit.civilisation == "JAUNE":
                    ennemis[8] += 1

            self.nombreSoldatsEnnemis = 0
            for i in ennemis:
                if self.nombreSoldatsEnnemis < i:
                    self.nombreSoldatsEnnemis = i

    def trouverRessourcePlusPres(self, unit, typeRessource):
        ressource = {"x" : 0 , "y" : 0}

        minX = unit.x - 5
        minY = unit.y - 5
        maxX = unit.x + 5
        maxY = unit.y + 5
        found = False

        while not found:
            if minX < self.parent.parent.carte.size:
                minX = 0

            if minY < self.parent.parent.carte.size:
                minY = 0

            if maxX > self.parent.parent.carte.size:
                minX = self.parent.parent.carte.size

            if maxY > self.parent.parent.carte.size:
                maxY = self.parent.parent.carte.size

            for x in range (minX, maxX):
                for y in range (minY, maxY):
                    if self.parent.parent.carte.matrice[x][y].type == typeRessource:
                        found = True

            minX -= 5
            minY -= 5
            maxX += 5
            maxY += 5

        ressource["x"] = x
        ressource["y"] = y
        print(str(x) + " " + str(y))
        return ressource

<commit_msg>continue AI<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from Batiments import *

#TODO mode rechercher
#TODO mettre les bonnes valeurs pour les couts de construction et de recherche
from Units import Unit, Paysan

class AI(Joueur):
    def __init__(self, civilisation, parent):
        super().__init__(civilisation, parent)
        self.civilisation = civilisation
        self.base = Base(self, 10, 10)
        self.parent = parent
        self.manqueRessource = False
        self.ressourceManquante = None
        self.qteRessourceManquante = 0
        self.batiments = []
        self.recherchesCompletes = []
        self.ressources = {"bois" : 100, "minerai" : 0, "charbon" : 0}
        self.nbNourriture = 0
        self.units = []
        self.paix = True
        self.paysansOccupes = True
        self.morale = 100
        self.nombreSoldatsAllies = 0
        self.nombreSoldatsEnnemis = 0
        self.hpMoyen = 0
        self.epoque = 0
        #valeurs pour empêcher de rappeler des fonctions trop souvent
        self.derniereFerme = 0
        self.derniereScierie = 0
        self.derniereFonderie = 0
        self.derniereBarraque = 0
        self.derniereEglise = 0
        self.dernierHopital = 0
        self.dernierGarage = 0
        self.derniereFete = 0
        self.lastCheck = 0
        self.departEpoque = time.time()
        self.cooldownAutomatisation = 60
        self.cooldownEpoque = 300
        self.cooldownAttaque = 60
        self.derniereAttaque = 0
        self.cooldownRecherche = 120
        self.cooldownRessource = 30
        self.dernierSoldat = 0
        self.dernierPaysan = 0
        self.cooldownUnite = 40
        self.derniereRecherche = 0
        self.derniereRessourceBois = 0
        self.derniereRessourceMinerai = 0
        self.derniereRessourceCharbon = 0
        self.derniereBase = 0
        self.cooldownBatiment = 60

    def penser(self):

        #fais des test requis pour savoir quel mode prendre
        self.blackboard()

        #premier test pour savoir si on est en paix
        if self.paix:
            print("paix")
            #si on manque de ressources, aller les miner
            if self.manqueRessource:
                print("manque ressource")
                self.chercherRessource(self.ressourceManquante)
                if self.ressourceManquante == "bois":
                    if self.qteRessourceManquante <= self.ressources["bois"]:
                        self.manqueRessource = False
                        pass
                elif self.ressourceManquante == "minerais":
                    if self.qteRessourceManquante <= self.ressources["minerai"]:
                        self.manqueRessource = False
                        pass
                elif self.ressourceManquante == "nourriture":
                    if self.qteRessourceManquante <= self.nbNourriture:
                        self.manqueRessource = False
                        pass
                elif self.ressourceManquante == "charbon":
                    if self.qteRessourceManquante <= self.ressources["charbon"]:
                        self.manqueRessource = False
                        pass
                else:
                    return
            print("manque aucune ressource")
            #si l'on peut changer d'époque, le faire
            if time.time() - self.departEpoque >= self.cooldownEpoque and self.epoque > 3:
                print("changer époque")
                self.changerEpoque()
                self.departEpoque = time.time()
                return
            print("peux pas changer d'époque")
            #si tous les paysans sont occupés et que l'on en a moins de 10, créer un nouveau paysan
            if self.paysansOccupes and time.time() - self.dernierPaysan >= self.cooldownUnite:
                print("besoin Paysan")
                self.creerPaysan()
                self.dernierPaysan = time.time()
                return
            print("paysans libres")
            #si le moral est trop bas, faire une fête
            if self.morale < 50 and time.time() - self.derniereFete >= self.cooldownRecherche:
                print("moral bas")
                self.augmenterMoral()
                self.derniereFete = time.time()
                return
            print("moral assez haut")
            #si un ennemi a plus de soldats que nous, creer des soldats
            if self.nombreSoldatsAllies < self.nombreSoldatsEnnemis and time.time() - self.dernierSoldat >= self.cooldownUnite:
                print("besoin soldats")
                self.creerSoldat()
                self.dernierSoldat = time.time()
                return
            print("soldats suffisants")
            #si un ennemi a moins de soldats que nous, attaquer
            if self.nombreSoldatsAllies > self.nombreSoldatsEnnemis and time.time() - self.derniereAttaque >= self.cooldownAttaque:
                print("a l'attaque")
                self.attaquer()
                self.derniereAttaque = time.time()
                return
            print("peux pas attaquer")
            #si rien d'autre, faire des recgerches
            if time.time() - self.derniereRecherche >= self.cooldownRecherche:
                print("démarrer recherche")
                self.rechercher()
                return
            print("cooldown recherche")
        #sinon on est en guerre
        else:
            if self.hpMoyen < 50 :
                print("retreat")
                self.retraite()
            print("pas besoin retraite")

    def chercherRessource(self, ressource):
        print(ressource)
        if ressource == "bois":
            self.chercherBois()
        elif ressource == "minerais":
            self.chercherminerais()
        elif ressource == "charbon":
            self.cherchercharbon()
        elif ressource == "nourriture":
            self.chercherNourriture()

    def chercherBois(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                    if self.epoque >= 2:
                        if time.time() - self.derniereScierie >= self.cooldownAutomatisation:
                            #TODO creer une scierie et y mettre le paysan
                            return

                    if time.time() - self.derniereRessourceBois >= self.cooldownRessource:
                        print("not cd")
                        position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.FORET)
                        unit.changerCible(position["x"], position["y"])
                        self.derniereRessourceBois = time.time()
                        return
                    print("en cooldown bois")
        self.creerPaysan()

    def chercherminerais(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                    if self.epoque >= 3:
                        if time.time() - self.derniereFonderie >= self.cooldownAutomatisation:
                            #TODO creer une fonderie et y mettre le paysan
                            return
                    if time.time() - self.derniereRessourceMinerai >= self.cooldownRessource:
                        position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.MINERAI)
                        unit.changerCible(position["x"], position["y"])
                        self.derniereRessourceBois = time.time()
                        return
        self.creerPaysan()

    def cherchercharbon(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                    if time.time() - self.derniereRessourceCharbon >= self.cooldownRessource:
                        for x in range(unit.x, unit.x+20):
                            for y in range(unit.y, unit.y+20):
                                if time.time() - self.derniereRessourceBois >= self.cooldownRessource:
                                    position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.CHARBON)
                                    unit.changerCible(position["x"], position["y"])
                                    self.derniereRessourceBois = time.time()
                                    return
        self.creerPaysan()

    def chercherNourriture(self):
        for unit in self.units:
            if isinstance(unit, Paysan):
                if unit.typeRessource == 0:
                        if time.time() - self.derniereFerme >= self.cooldownAutomatisation:
                            #TODO creer une ferme
                            return

        self.creerPaysan()

    def changerEpoque(self):
        print("changer Epoque")
        for batiment in self.batiments:
            if isinstance(batiment, Base):
                if self.epoque == 1:
                    if self.ressources["bois"] >= batiment.coutRecherche2[0]:
                        batiment.recherche1()
                    else:
                        self.manqueRessource = True
                        self.qteRessourceManquante = batiment.coutRecherche2[0]
                        self.ressourceManquante = "bois"
                    return

                elif self.epoque == 2:
                    if self.ressources["bois"] >= batiment.coutRecherche2[0]:
                        if self.ressources["minerai"] >= batiment.coutRecherche2[1]:
                            batiment.recherche1()
                        else:
                            self.manqueRessource = True
                            self.qteRessourceManquante = batiment.coutRecherche2[1]
                            self.ressourceManquante = "minerais"
                    else:
                        self.manqueRessource = True
                        self.qteRessourceManquante = batiment.coutRecherche2[0]
                        self.ressourceManquante = "bois"
                    return

        #TODO trouver un paysan et le faire créer une nouvelle base

    def creerPaysan(self):
        print("creer Paysan")
        if self.base != None:
                if self.ressources["bois"] >= self.base.coutCreer1["bois"]:
                    self.base.creer1()
                    return
                else:
                    self.manqueRessource = True
                    self.qteRessourceManquante = self.base.coutCreer1["bois"]
                    self.ressourceManquante = "bois"
                    return

        if time.time() - self.derniereBase >= self.cooldownBatiment:
            for unit in self.units:
                if isinstance(unit, Paysan):
                    if unit.typeRessource == 0:
                        position = self.trouverRessourcePlusPres(unit, self.parent.parent.carte.Gazon)
                        self.base = Base(self, position["x"], position["y"])

    def augmenterMoral(self):
        print("augmenter Moral")
        for batiment in self.batiments:
            if isinstance(batiment, Eglise):
                if self.ressources["bois"] >= batiment.coutRecherche1[0]:
                    batiment.recherche1()
                    return
                else:
                    self.manqueRessource = True
                    self.qteRessourceManquante = batiment.coutRecherche1[0]
                    self.ressourceManquante = "bois"
                    return
        #TODO trouver un paysan et creer une nouvelle Église

    def creerSoldat(self):
        print("creer Soldat")
        for batiment in self.batiments:
            if isinstance(batiment, Baraque):
                if not batiment.enCreation:
                    if  self.ressources["bois"] >= batiment.coutCreer1[0]:
                        batiment.creer1()
                        return
                    else:
                        self.manqueRessource = True
                        self.qteRessourceManquante = batiment.coutCreer1[0]
                        self.ressourceManquante = "bois"
                        return
        #TODO trouver un paysan et creer une nouvelle baraque

    def attaquer(self):
        print("attaquer")
        for unit in self.units:
            if isinstance(unit, Soldat):
                #TODO faire Attaquer les Soldats
                pass

    def retraite(self):
        print("retraite")
        for unit in self.units:
            if isinstance(unit, Soldat):
                #TODO faire retraiter les Soldats
                pass

    def rechercher(self):
        print("rechercher")
        #TODO figurer comment rechercher
        self.derniereRecherche = time.time()

    def blackboard(self):
        #fais des test 1 fois au 30 sec pour éviter de trop répéter des taches
        if time.time() - self.lastCheck >= 30:
            self.units = []
            for unit in self.parent.units:
                if unit.civilisation == self.civilisation:
                    self.units.append(unit)
                    print("new unit")
                    print(unit)

            #vérifie si tous les paysans sont occupés
            for unit in self.units:
                if isinstance(unit, Paysan):
                    if unit.typeRessource == 0:
                        self.paysansOccupes = False
                        print("false")

            #compte les soldats à nous et trouve le hp moyen de ces soldats
            #self.nombreSoldatsAllies = 0
            #hpTotal = 0
            #for unit in self.units:
                #if isinstance(unit, Soldat):
                    #self.nombreSoldatsAllies += 1
                    #hpTotal += unit.hp

            #self.hpMoyen = hpTotal/self.nombreSoldatsAllies

            #trouve le nombre de soldats de l'ennemi avec le plus de soldats
            ennemis = []
            for unit in self.parent.units:
                if unit.civilisation == "ROUGE":
                    ennemis[0] += 1
                elif unit.civilisation == "BLEU":
                    ennemis[1] += 1
                elif unit.civilisation == "VERT":
                    ennemis[2] += 1
                elif unit.civilisation == "ORANGE":
                    ennemis[3] += 1
                elif unit.civilisation == "MAUVE":
                    ennemis[4] += 1
                elif unit.civilisation == "BLANC":
                    ennemis[5] += 1
                elif unit.civilisation == "NOIR":
                    ennemis[6] += 1
                elif unit.civilisation == "ROSE":
                    ennemis[7] += 1
                elif unit.civilisation == "JAUNE":
                    ennemis[8] += 1

            #check nombre ennemis
            #self.nombreSoldatsEnnemis = 0
            #for i in ennemis:
                #if self.nombreSoldatsEnnemis < i:
                    #self.nombreSoldatsEnnemis = i

            self.lastCheck = time.time()

    def trouverRessourcePlusPres(self, unit, typeRessource):
        ressource = {"x" : 0 , "y" : 0}

        minX = unit.x - 5
        minY = unit.y - 5
        maxX = unit.x + 5
        maxY = unit.y + 5
        found = False

        while not found:
            if minX < self.parent.parent.carte.size:
                minX = 0

            if minY < self.parent.parent.carte.size:
                minY = 0

            if maxX > self.parent.parent.carte.size:
                minX = self.parent.parent.carte.size

            if maxY > self.parent.parent.carte.size:
                maxY = self.parent.parent.carte.size

            for x in range (minX, maxX):
                for y in range (minY, maxY):
                    if self.parent.parent.carte.matrice[x][y].type == typeRessource:
                        found = True

            minX -= 5
            minY -= 5
            maxX += 5
            maxY += 5

        ressource["x"] = x
        ressource["y"] = y
        print(str(x) + " " + str(y))
        return ressource

<|endoftext|>


<commit_before>##############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/spack/spack
# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *

class JsonC(AutotoolsPackage):
    """A JSON implementation in C."""
    homepage = "https://github.com/json-c/json-c/wiki"
    url      = "https://s3.amazonaws.com/json-c_releases/releases/json-c-0.12.1.tar.gz"

    version('0.12.1', '55f7853f7d8cf664554ce3fa71bf1c7d')
    version('0.11',   'aa02367d2f7a830bf1e3376f77881e98')

    parallel = False
<commit_msg>Added missing build dependency to json-c (#6211)<commit_after>##############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/spack/spack
# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License (as
# published by the Free Software Foundation) version 2.1, February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
from spack import *

class JsonC(AutotoolsPackage):
    """A JSON implementation in C."""
    homepage = "https://github.com/json-c/json-c/wiki"
    url      = "https://s3.amazonaws.com/json-c_releases/releases/json-c-0.12.1.tar.gz"

    version('0.12.1', '55f7853f7d8cf664554ce3fa71bf1c7d')
    version('0.11',   'aa02367d2f7a830bf1e3376f77881e98')

    depends_on('autoconf', type='build')

    parallel = False
<|endoftext|>