<commit_before># Copyright 2010 ITA Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import os
import sys
import re
import time

import coil
import rrdtool
from django.conf import settings
from django.http import HttpResponse
from django.template import Context, loader
from nagcat import nagios_objects

from railroad.errors import RailroadError

def is_graphable(host, service):
    rra_path = settings.RRA_PATH
    coilfile = rra_path + host + '/' + service + '.coil'
    rrd = rra_path + host + '/' + service + '.rrd'
    if os.path.exists(coilfile) and os.path.exists(rrd):
        coilstring = open(coilfile).read()
        coilstruct = coil.parse(coilstring)
        query = coilstruct.get('query')

        # rrdtool hates unicode strings, and Django gives us one,
        # so convert to ascii
        rrdslice = rrdtool.fetch(str(rrd),
                    '--start', '0',
                    '--end', '10',
                    '--resolution', '1',
                    'AVERAGE')

        try:
            rrdslice[1].index('_state')
            return True
        except ValueError:
            for key in query.keys():
                val = query.get(key)
                if type() == type(query) and val.has_key('trend'):
                    return True
            return False
    return False

def are_graphable(host, service_list):
    rra_path = settings.RRA_PATH
    for service in service_list:
        coilfile = rra_path + host + '/'    \
            + service['service_description'] + '.coil'
        rrd = rra_path + host + '/'         \
            + service['service_description'] + '.rrd'
        if os.path.exists(coilfile) and os.path.exists(rrd):
            coilstring = open(coilfile).read()
            coilstruct = coil.parse(coilstring)
            query = coilstruct.get('query')

            # rrdtool hates unicode strings, and Django gives us one,
            # so convert to ascii
            rrdslice = rrdtool.fetch(str(rrd),
                        '--start', '0',
                        '--end', '10',
                        '--resolution', '1',
                        'AVERAGE')

            try:
                rrdslice[1].index('_state')
                service['is_graphable'] = True
            except ValueError:
                for key in query.keys():
                    val = query.get(key)
                    if type() == type(query) and val.has_key('trend'):
                        service['is_graphable'] = True
                        break
                service['is_graphable'] = False

        else:
            service['is_graphable'] = False

def parse():
    data_path = settings.DATA_PATH
    stat_path = data_path + 'status.dat'
    obj_path = data_path + 'objects.cache'
    stat = nagios_objects.ObjectParser(stat_path, ('service', 'host'))
    obj = nagios_objects.ObjectParser(obj_path, ('hostgroup'))
    return stat, obj

def grouplist(obj):
    return obj['hostgroup']

def hostlist(stat):
    return stat['host']

def servicelist(stat):
    return stat['service']

def groupdetail(obj, group_name):
    group_list = grouplist(obj)
    for group in group_list:
        if group['alias'] == group_name:
            return group

def hostdetail(stat, host_name):
    host_list = hostlist(stat)
    for host in host_list:
        if host['host_name'] == host_name:
            return host

def servicelist_by_description(stat, service_description):
    all_services = servicelist(stat)
    return [service for service in all_services if service['service_description'] == service_description]

def servicedetail(stat, host, service_alias):
    all_services = servicelist(stat)
    for service in all_services:
        if service['host_name'] == host and service['service_description'] == service_alias:
            return service

def hostlist_by_group(stat, obj, group_name):
    group = groupdetail(obj, group_name)
    all_hosts = hostlist(stat)
    target = group['members'].split(',')
    return [host for host in all_hosts if host['host_name'] in target]

def hostnames_by_group(stat, obj, group_name):
    group = groupdetail(obj, group_name)
    return group['members'].split(',')

def hostlist_by_service(stat, service):
    all_services = servicelist(stat)
    return [hostdetail(stat, s['host_name']) for s in all_services if s['service_description'] == service]

def hostnames_by_service(stat, service):
    all_services = servicelist(stat)
    return [s['host_name'] for s in all_services if s['service_description'] == service]

def servicelist_by_host(stat, host):
    all_services = servicelist(stat)
    return [service for service in all_services if service['host_name'] == host]

def servicenames_by_host(stat, host):
    all_services = servicelist(stat)
    return [service['service_description'] for service in all_services if service['host_name'] == host]

def get_time_intervals():
    #            day  , week  , month  , year
    intervals = [86400, 604800, 2592000, 31104000]
    times = ['day', 'week', 'month', 'year']
    ending = int(time.time())
    return zip(times, [[ending-interval, ending] for interval in intervals])

# TODO: This should probably just be a class that wraps Context, as we
# will have to include this on each and every page
def add_hostlist(stat, obj, c):
    groups = grouplist(obj)
    groups.sort(lambda x, y: cmp(x['alias'], y['alias']))
    hosts = hostlist(stat)
    sidebar = []
    for group in groups:
        group_name = group['alias']
        addinghosts = group['members'].split(',')
        hosts_of_group = []
        for host in hosts:
            if host['host_name'] in addinghosts:
                hosts_of_group.append(host)
                host['has_group'] = True
        hosts_of_group.sort(lambda x, y: cmp(x['host_name'], y['host_name']))
        sidebar.append((group_name, hosts_of_group))
    no_group = filter(lambda x: not(x.has_key('has_group')), hosts)
    if len(no_group):
        sidebar.append(('(no group)', no_group))
    c['sidebar'] = sidebar
    return c

def index(request):
    t = loader.get_template('index.html')
    stat, obj = parse()
    context_data = {}
    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def host(request, host):
    t = loader.get_template('host.html')
    stat, obj = parse()
    services = servicelist_by_host(stat, host)
    services.sort(lambda x, y: cmp(x['service_description'], y['service_description']))
    are_graphable(host, services)
    host_detail = hostdetail(stat, host)
    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'host_name': host,
        'host': host_detail,
        'services': services,
        'true' : True,
        'time_interval': [starting, ending],
        'graphs': True,
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def service(request, host, service):
    t = loader.get_template('service.html')
    stat, obj = parse()
    service_detail = servicedetail(stat, host, service)

    str = service_detail.get('plugin_output', '')
    if str:
        str += '\n'
        str += service_detail.get('long_plugin_output', '')

    time_intervals = get_time_intervals()
    context_data = {
        'host_name': host,
        'service_name': service,
        'service_output': str,
        'graphable': is_graphable(host, service),
        'true': True,
        'time_intervals': time_intervals
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def group(request, group):
    t = loader.get_template('group.html')
    stat, obj = parse()
    service_dict = {}

    host_list = hostlist_by_group(stat, obj, group)
    host_names = map(lambda x: x['host_name'], host_list)
    service_list = servicelist(stat)

    # Handles removing unique digits, dashes, commas, and version numbers
    # Duplicated in groupservice
    janitor = re.compile("[-,]?\d+\.?\d*[-,]?")

    for service in service_list:
        service_alias = janitor.sub("", service['service_description'])
        service_test = service.get('_TEST', None)
        service_test = service_test if service_test else service['check_command']
        if service['host_name'] in host_names:
            if not(service_dict.get(service_test, None)):
                service_dict[service_test] = []
            if not (service_alias in service_dict[service_test]):
                service_dict[service_test].append(service_alias)

    services = []
    service_tests = service_dict.keys()
    for service_test in service_tests:
        #prefix = os.path.commonprefix(service_dict[service_test])
        #suffix = os.path.commonprefix(map(lambda x: x[:len(prefix):-1], service_dict[service_test]))[::-1]
        #d = locals()
        #service = ('%(prefix)s' % d) + ('%(suffix)s' % d)
        for service_alias in service_dict[service_test]:
            services.append({'service_test': service_test, 'service_alias' : service_alias})

    services.sort(lambda x, y: cmp(x['service_alias'], y['service_alias']))
    host_list.sort(lambda x, y: cmp(x['host_name'], y['host_name']))

    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'group_name': group,
        'hosts': host_list,
        'services': services,
        'time_interval': [starting, ending]
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def groupservice(request, group, test, alias):
    t = loader.get_template('groupservice.html')
    stat, obj = parse()
    host_list = hostlist_by_group(stat, obj, group)
    target = map(lambda x: x['host_name'], host_list)
    all_services = servicelist(stat)

    janitor = re.compile("[-,]?\d+\.?\d*[-,]?")
    for service in all_services:
        service_test = service.get('_TEST', None) if        \
                       service.get('_TEST', None) else      \
                       service.get('check_command', None)
        service_alias = janitor.sub("", service['service_description'])

        if service_test == test and service_alias == alias:
            host_name = service['host_name']
            try:
                host = host_list[target.index(host_name)]
                if not(host.has_key('services')): host['services'] = []
                service['is_graphable'] = is_graphable(host_name, service['service_description'])
                host['services'].append(service)
            except ValueError:
                continue

    host_list = filter(lambda x: x.has_key('services'), host_list)
    host_list.sort(lambda x, y: cmp(x['host_name'], y['host_name']))
    map(lambda z: z['services'].sort(lambda x, y: cmp(x['service_description'], y['service_description'])), host_list)

    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'group_name': group,
        'service_alias': alias,
        'host_list': host_list,
        'time_interval': [starting, ending],
        'true': True,
        'graphs': True,
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def form(request):
    t = loader.get_template('form.html')
    stat, obj = parse()
    group_list = grouplist(obj)
    group_list.sort(lambda x,y: cmp(x['alias'], y['alias']))
    host_list = hostlist(stat)
    host_list.sort(lambda x,y: cmp(x['host_name'], y['host_name']))
    service_list = list(set(map(lambda x: x['service_description'], servicelist(stat))))
    service_list.sort()

    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'group_list': group_list,
        'host_list': host_list,
        'service_list': service_list,
        'time_interval': [starting, ending]
    }
    c = Context(context_data)
    return HttpResponse(t.render(c))

def customgraph(request):
    querydict = request.GET
    host = querydict['host']
    service = querydict['service']

    t = loader.get_template('graph.html')
    stat, obj = parse()
    service_detail = servicedetail(stat, host, service)
    service_detail['is_graphable'] = is_graphable(host, service)
    ending = int(time.time())
    starting = ending - 86400

    context_data = {
        'host_name': host,
        'service': service_detail,
        'time_interval': [starting, ending],
    }
    c = Context(context_data)
    return HttpResponse(t.render(c))

def custom(request):
    t = loader.get_template('custom.html')
    stat, obj = parse()
    group_list = grouplist(obj)
    group_list.sort(lambda x,y: cmp(x['alias'], y['alias']))
    host_list = hostlist(stat)
    host_list.sort(lambda x,y: cmp(x['host_name'], y['host_name']))
    service_list = list(set(map(lambda x: x['service_description'], servicelist(stat))))
    service_list.sort()
    context_data = {
        'group_list': group_list,
        'host_list': host_list,
        'service_list': service_list,
    }
    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def selectgroup(request, group):
    stat, obj = parse()
    host_list = hostnames_by_group(stat, obj, group)
    service_list = []
    for host in host_list:
        service_list.extend(servicenames_by_host(stat, host))
    json.dumps({'host_list': host_list, 'service_list': service_list, })

def selecthost(request, host):
    stat, obj = parse()
    json.dumps({'service_list': servicenames_by_host(stat, host), })

def selectservice(request, service):
    stat, obj = parse()
    json.dumps({'host_list': hostnames_by_service(stat, service), })
<commit_msg>Fixed HttpResponse<commit_after># Copyright 2010 ITA Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import os
import sys
import re
import time

import coil
import rrdtool
from django.conf import settings
from django.http import HttpResponse
from django.template import Context, loader
from nagcat import nagios_objects

from railroad.errors import RailroadError

def is_graphable(host, service):
    rra_path = settings.RRA_PATH
    coilfile = rra_path + host + '/' + service + '.coil'
    rrd = rra_path + host + '/' + service + '.rrd'
    if os.path.exists(coilfile) and os.path.exists(rrd):
        coilstring = open(coilfile).read()
        coilstruct = coil.parse(coilstring)
        query = coilstruct.get('query')

        # rrdtool hates unicode strings, and Django gives us one,
        # so convert to ascii
        rrdslice = rrdtool.fetch(str(rrd),
                    '--start', '0',
                    '--end', '10',
                    '--resolution', '1',
                    'AVERAGE')

        try:
            rrdslice[1].index('_state')
            return True
        except ValueError:
            for key in query.keys():
                val = query.get(key)
                if type() == type(query) and val.has_key('trend'):
                    return True
            return False
    return False

def are_graphable(host, service_list):
    rra_path = settings.RRA_PATH
    for service in service_list:
        coilfile = rra_path + host + '/'    \
            + service['service_description'] + '.coil'
        rrd = rra_path + host + '/'         \
            + service['service_description'] + '.rrd'
        if os.path.exists(coilfile) and os.path.exists(rrd):
            coilstring = open(coilfile).read()
            coilstruct = coil.parse(coilstring)
            query = coilstruct.get('query')

            # rrdtool hates unicode strings, and Django gives us one,
            # so convert to ascii
            rrdslice = rrdtool.fetch(str(rrd),
                        '--start', '0',
                        '--end', '10',
                        '--resolution', '1',
                        'AVERAGE')

            try:
                rrdslice[1].index('_state')
                service['is_graphable'] = True
            except ValueError:
                for key in query.keys():
                    val = query.get(key)
                    if type() == type(query) and val.has_key('trend'):
                        service['is_graphable'] = True
                        break
                service['is_graphable'] = False

        else:
            service['is_graphable'] = False

def parse():
    data_path = settings.DATA_PATH
    stat_path = data_path + 'status.dat'
    obj_path = data_path + 'objects.cache'
    stat = nagios_objects.ObjectParser(stat_path, ('service', 'host'))
    obj = nagios_objects.ObjectParser(obj_path, ('hostgroup'))
    return stat, obj

def grouplist(obj):
    return obj['hostgroup']

def hostlist(stat):
    return stat['host']

def servicelist(stat):
    return stat['service']

def groupdetail(obj, group_name):
    group_list = grouplist(obj)
    for group in group_list:
        if group['alias'] == group_name:
            return group

def hostdetail(stat, host_name):
    host_list = hostlist(stat)
    for host in host_list:
        if host['host_name'] == host_name:
            return host

def servicelist_by_description(stat, service_description):
    all_services = servicelist(stat)
    return [service for service in all_services if service['service_description'] == service_description]

def servicedetail(stat, host, service_alias):
    all_services = servicelist(stat)
    for service in all_services:
        if service['host_name'] == host and service['service_description'] == service_alias:
            return service

def hostlist_by_group(stat, obj, group_name):
    group = groupdetail(obj, group_name)
    all_hosts = hostlist(stat)
    target = group['members'].split(',')
    return [host for host in all_hosts if host['host_name'] in target]

def hostnames_by_group(stat, obj, group_name):
    group = groupdetail(obj, group_name)
    return group['members'].split(',')

def hostlist_by_service(stat, service):
    all_services = servicelist(stat)
    return [hostdetail(stat, s['host_name']) for s in all_services if s['service_description'] == service]

def hostnames_by_service(stat, service):
    all_services = servicelist(stat)
    return [s['host_name'] for s in all_services if s['service_description'] == service]

def servicelist_by_host(stat, host):
    all_services = servicelist(stat)
    return [service for service in all_services if service['host_name'] == host]

def servicenames_by_host(stat, host):
    all_services = servicelist(stat)
    return [service['service_description'] for service in all_services if service['host_name'] == host]

def get_time_intervals():
    #            day  , week  , month  , year
    intervals = [86400, 604800, 2592000, 31104000]
    times = ['day', 'week', 'month', 'year']
    ending = int(time.time())
    return zip(times, [[ending-interval, ending] for interval in intervals])

# TODO: This should probably just be a class that wraps Context, as we
# will have to include this on each and every page
def add_hostlist(stat, obj, c):
    groups = grouplist(obj)
    groups.sort(lambda x, y: cmp(x['alias'], y['alias']))
    hosts = hostlist(stat)
    sidebar = []
    for group in groups:
        group_name = group['alias']
        addinghosts = group['members'].split(',')
        hosts_of_group = []
        for host in hosts:
            if host['host_name'] in addinghosts:
                hosts_of_group.append(host)
                host['has_group'] = True
        hosts_of_group.sort(lambda x, y: cmp(x['host_name'], y['host_name']))
        sidebar.append((group_name, hosts_of_group))
    no_group = filter(lambda x: not(x.has_key('has_group')), hosts)
    if len(no_group):
        sidebar.append(('(no group)', no_group))
    c['sidebar'] = sidebar
    return c

def index(request):
    t = loader.get_template('index.html')
    stat, obj = parse()
    context_data = {}
    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def host(request, host):
    t = loader.get_template('host.html')
    stat, obj = parse()
    services = servicelist_by_host(stat, host)
    services.sort(lambda x, y: cmp(x['service_description'], y['service_description']))
    are_graphable(host, services)
    host_detail = hostdetail(stat, host)
    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'host_name': host,
        'host': host_detail,
        'services': services,
        'true' : True,
        'time_interval': [starting, ending],
        'graphs': True,
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def service(request, host, service):
    t = loader.get_template('service.html')
    stat, obj = parse()
    service_detail = servicedetail(stat, host, service)

    str = service_detail.get('plugin_output', '')
    if str:
        str += '\n'
        str += service_detail.get('long_plugin_output', '')

    time_intervals = get_time_intervals()
    context_data = {
        'host_name': host,
        'service_name': service,
        'service_output': str,
        'graphable': is_graphable(host, service),
        'true': True,
        'time_intervals': time_intervals
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def group(request, group):
    t = loader.get_template('group.html')
    stat, obj = parse()
    service_dict = {}

    host_list = hostlist_by_group(stat, obj, group)
    host_names = map(lambda x: x['host_name'], host_list)
    service_list = servicelist(stat)

    # Handles removing unique digits, dashes, commas, and version numbers
    # Duplicated in groupservice
    janitor = re.compile("[-,]?\d+\.?\d*[-,]?")

    for service in service_list:
        service_alias = janitor.sub("", service['service_description'])
        service_test = service.get('_TEST', None)
        service_test = service_test if service_test else service['check_command']
        if service['host_name'] in host_names:
            if not(service_dict.get(service_test, None)):
                service_dict[service_test] = []
            if not (service_alias in service_dict[service_test]):
                service_dict[service_test].append(service_alias)

    services = []
    service_tests = service_dict.keys()
    for service_test in service_tests:
        #prefix = os.path.commonprefix(service_dict[service_test])
        #suffix = os.path.commonprefix(map(lambda x: x[:len(prefix):-1], service_dict[service_test]))[::-1]
        #d = locals()
        #service = ('%(prefix)s' % d) + ('%(suffix)s' % d)
        for service_alias in service_dict[service_test]:
            services.append({'service_test': service_test, 'service_alias' : service_alias})

    services.sort(lambda x, y: cmp(x['service_alias'], y['service_alias']))
    host_list.sort(lambda x, y: cmp(x['host_name'], y['host_name']))

    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'group_name': group,
        'hosts': host_list,
        'services': services,
        'time_interval': [starting, ending]
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def groupservice(request, group, test, alias):
    t = loader.get_template('groupservice.html')
    stat, obj = parse()
    host_list = hostlist_by_group(stat, obj, group)
    target = map(lambda x: x['host_name'], host_list)
    all_services = servicelist(stat)

    janitor = re.compile("[-,]?\d+\.?\d*[-,]?")
    for service in all_services:
        service_test = service.get('_TEST', None) if        \
                       service.get('_TEST', None) else      \
                       service.get('check_command', None)
        service_alias = janitor.sub("", service['service_description'])

        if service_test == test and service_alias == alias:
            host_name = service['host_name']
            try:
                host = host_list[target.index(host_name)]
                if not(host.has_key('services')): host['services'] = []
                service['is_graphable'] = is_graphable(host_name, service['service_description'])
                host['services'].append(service)
            except ValueError:
                continue

    host_list = filter(lambda x: x.has_key('services'), host_list)
    host_list.sort(lambda x, y: cmp(x['host_name'], y['host_name']))
    map(lambda z: z['services'].sort(lambda x, y: cmp(x['service_description'], y['service_description'])), host_list)

    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'group_name': group,
        'service_alias': alias,
        'host_list': host_list,
        'time_interval': [starting, ending],
        'true': True,
        'graphs': True,
    }

    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def form(request):
    t = loader.get_template('form.html')
    stat, obj = parse()
    group_list = grouplist(obj)
    group_list.sort(lambda x,y: cmp(x['alias'], y['alias']))
    host_list = hostlist(stat)
    host_list.sort(lambda x,y: cmp(x['host_name'], y['host_name']))
    service_list = list(set(map(lambda x: x['service_description'], servicelist(stat))))
    service_list.sort()

    ending = int(time.time())
    starting = ending - 86400
    context_data = {
        'group_list': group_list,
        'host_list': host_list,
        'service_list': service_list,
        'time_interval': [starting, ending]
    }
    c = Context(context_data)
    return HttpResponse(t.render(c))

def customgraph(request):
    querydict = request.GET
    host = querydict['host']
    service = querydict['service']

    t = loader.get_template('graph.html')
    stat, obj = parse()
    service_detail = servicedetail(stat, host, service)
    service_detail['is_graphable'] = is_graphable(host, service)
    ending = int(time.time())
    starting = ending - 86400

    context_data = {
        'host_name': host,
        'service': service_detail,
        'time_interval': [starting, ending],
    }
    c = Context(context_data)
    return HttpResponse(t.render(c))

def custom(request):
    t = loader.get_template('custom.html')
    stat, obj = parse()
    group_list = grouplist(obj)
    group_list.sort(lambda x,y: cmp(x['alias'], y['alias']))
    host_list = hostlist(stat)
    host_list.sort(lambda x,y: cmp(x['host_name'], y['host_name']))
    service_list = list(set(map(lambda x: x['service_description'], servicelist(stat))))
    service_list.sort()
    context_data = {
        'group_list': group_list,
        'host_list': host_list,
        'service_list': service_list,
    }
    context_data = add_hostlist(stat, obj, context_data)
    c = Context(context_data)
    return HttpResponse(t.render(c))

def selectgroup(request, group):
    stat, obj = parse()
    host_list = hostnames_by_group(stat, obj, group)
    service_list = []
    for host in host_list:
        service_list.extend(servicenames_by_host(stat, host))
    return HttpResponse(json.dumps({'host_list': host_list, 'service_list': service_list, }))

def selecthost(request, host):
    stat, obj = parse()
    return HttpResponse(json.dumps({'service_list': servicenames_by_host(stat, host), }))

def selectservice(request, service):
    stat, obj = parse()
    return HttpResponse(json.dumps({'host_list': hostnames_by_service(stat, service), }))
<|endoftext|>


<commit_before># Copyright 2016 Raytheon BBN Technologies
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0

__all__ = ['WriteToFile', 'DataBuffer']

import os
import sys

if sys.platform == 'win32' or 'NOFORKING' in os.environ:
    import threading as mp
    from threading import Thread as Process
    from queue import Queue
else:
    import multiprocessing as mp
    from multiprocessing import Process
    from multiprocessing import Queue

from auspex.data_format import AuspexDataContainer

import itertools
import contextlib
import queue
import numpy as np
import os.path
import os, psutil
import time
import datetime
import pandas as pd
from shutil import copyfile
import cProfile

from .filter import Filter
from auspex.parameter import Parameter, FilenameParameter, BoolParameter
from auspex.stream import InputConnector, OutputConnector
from auspex.log import logger
import auspex.config as config

from tqdm import tqdm, tqdm_notebook

class WriteToFile(Filter):
    """Writes data to file using the Auspex container type, which is a simple directory structure
    with subdirectories, binary datafiles, and json meta files that store the axis descriptors
    and other information."""

    sink        = InputConnector()
    filename    = FilenameParameter()
    groupname   = Parameter(default='main')

    def __init__(self, filename=None, groupname=None, datasetname='data', **kwargs):
        super(WriteToFile, self).__init__(**kwargs)
        if filename:
            self.filename.value = filename
        if groupname:
            self.groupname.value = groupname
        if datasetname:
            self.datasetname = datasetname

        self.ret_queue = None # MP queue For returning data

    def final_init(self):
        assert self.filename.value, "Filename never supplied to writer."
        assert self.groupname.value, "Groupname never supplied to writer."
        assert self.datasetname, "Dataset name never supplied to writer."

        self.descriptor = self.sink.input_streams[0].descriptor
        self.container  = AuspexDataContainer(self.filename.value)
        self.group      = self.container.new_group(self.groupname.value)
        self.mmap       = self.container.new_dataset(self.groupname.value, self.datasetname, self.descriptor)

        self.w_idx = 0
        self.points_taken = 0

    def get_data_while_running(self, return_queue):
        """Return data to the main thread or user as requested. Use a MP queue to transmit."""
        assert not self.done.is_set(), Exception("Experiment is over and filter done. Please use load_data")
        self.return_queue.put(np.array(self.mmap))

    def load_data(self):
        assert self.done.is_set(), Exception("Experiment is still running. Please use get_data_while_running")
        container = AuspexDataContainer(self.filename.value)
        return container.open_dataset(self.groupname.value, self.datasetname)

    def process_data(self, data):
        # Write the data
        self.mmap[self.w_idx:self.w_idx+data.size] = data
        self.w_idx += data.size
        self.points_taken = self.w_idx

class DataBuffer(Filter):
    """Writes data to IO."""

    sink = InputConnector()

    def __init__(self, **kwargs):
        super(DataBuffer, self).__init__(**kwargs)
        self._final_buffer = Queue()
        self.final_buffer  = None

    def final_init(self):
        self.w_idx        = 0
        self.points_taken = 0
        self.descriptor   = self.sink.input_streams[0].descriptor
        self.buff         = np.empty(self.descriptor.expected_num_points(), dtype=self.descriptor.dtype)

    def process_data(self, data):
        # Write the data
        self.buff[self.w_idx:self.w_idx+data.size] = data
        self.w_idx += data.size
        self.points_taken = self.w_idx

    def main(self):
        super(DataBuffer, self).main()
        self._final_buffer.put(self.buff)

    def get_data(self):
        if self.final_buffer is None:
            self.final_buffer = self._final_buffer.get()
        return np.reshape(self.final_buffer, self.descriptor.dims()), self.descriptor
<commit_msg>Now use get_data for both buffers and writers<commit_after># Copyright 2016 Raytheon BBN Technologies
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0

__all__ = ['WriteToFile', 'DataBuffer']

import os
import sys

if sys.platform == 'win32' or 'NOFORKING' in os.environ:
    import threading as mp
    from threading import Thread as Process
    from queue import Queue
else:
    import multiprocessing as mp
    from multiprocessing import Process
    from multiprocessing import Queue

from auspex.data_format import AuspexDataContainer

import itertools
import contextlib
import queue
import numpy as np
import os.path
import os, psutil
import time
import datetime
import pandas as pd
from shutil import copyfile
import cProfile

from .filter import Filter
from auspex.parameter import Parameter, FilenameParameter, BoolParameter
from auspex.stream import InputConnector, OutputConnector
from auspex.log import logger
import auspex.config as config

from tqdm import tqdm, tqdm_notebook

class WriteToFile(Filter):
    """Writes data to file using the Auspex container type, which is a simple directory structure
    with subdirectories, binary datafiles, and json meta files that store the axis descriptors
    and other information."""

    sink        = InputConnector()
    filename    = FilenameParameter()
    groupname   = Parameter(default='main')

    def __init__(self, filename=None, groupname=None, datasetname='data', **kwargs):
        super(WriteToFile, self).__init__(**kwargs)
        if filename:
            self.filename.value = filename
        if groupname:
            self.groupname.value = groupname
        if datasetname:
            self.datasetname = datasetname

        self.ret_queue = None # MP queue For returning data

    def final_init(self):
        assert self.filename.value, "Filename never supplied to writer."
        assert self.groupname.value, "Groupname never supplied to writer."
        assert self.datasetname, "Dataset name never supplied to writer."

        self.descriptor = self.sink.input_streams[0].descriptor
        self.container  = AuspexDataContainer(self.filename.value)
        self.group      = self.container.new_group(self.groupname.value)
        self.mmap       = self.container.new_dataset(self.groupname.value, self.datasetname, self.descriptor)

        self.w_idx = 0
        self.points_taken = 0

    def get_data_while_running(self, return_queue):
        """Return data to the main thread or user as requested. Use a MP queue to transmit."""
        assert not self.done.is_set(), Exception("Experiment is over and filter done. Please use get_data")
        self.return_queue.put(np.array(self.mmap))

    def get_data(self):
        assert self.done.is_set(), Exception("Experiment is still running. Please use get_data_while_running")
        container = AuspexDataContainer(self.filename.value)
        return container.open_dataset(self.groupname.value, self.datasetname)

    def process_data(self, data):
        # Write the data
        self.mmap[self.w_idx:self.w_idx+data.size] = data
        self.w_idx += data.size
        self.points_taken = self.w_idx

class DataBuffer(Filter):
    """Writes data to IO."""

    sink = InputConnector()

    def __init__(self, **kwargs):
        super(DataBuffer, self).__init__(**kwargs)
        self._final_buffer = Queue()
        self.final_buffer  = None

    def final_init(self):
        self.w_idx        = 0
        self.points_taken = 0
        self.descriptor   = self.sink.input_streams[0].descriptor
        self.buff         = np.empty(self.descriptor.expected_num_points(), dtype=self.descriptor.dtype)

    def process_data(self, data):
        # Write the data
        self.buff[self.w_idx:self.w_idx+data.size] = data
        self.w_idx += data.size
        self.points_taken = self.w_idx

    def main(self):
        super(DataBuffer, self).main()
        self._final_buffer.put(self.buff)

    def get_data(self):
        if self.final_buffer is None:
            self.final_buffer = self._final_buffer.get()
        return np.reshape(self.final_buffer, self.descriptor.dims()), self.descriptor
<|endoftext|>


<commit_before>"""
Coadd spectra
"""

from __future__ import absolute_import, division, print_function

import os
import numpy as np
from astropy.table import Table

from desiutil.log import get_logger
from desispec.io import read_frame,write_frame
from desispec.coaddition import coadd,coadd_cameras,resample_spectra_lin_or_log

def parse(options=None):
    import argparse

    parser = argparse.ArgumentParser("Coadd frames")
    parser.add_argument("-i","--infile", type=str, nargs='+', help="input frame files")
    parser.add_argument("-o","--outfile", type=str,  help="output frame file")

    if options is None:
        args = parser.parse_args()
    else:
        args = parser.parse_args(options)

    return args

def main(args=None):

    log = get_logger()

    if args is None:
        args = parse()

    log.info("reading frames ...")

    frames = []
    for filename in args.infile :
        frame = read_frame(filename)
        if len(frames)==0 :
            frames.append(frame)
            continue

        if "CAMERA" in frames[0].meta and (frame.meta["CAMERA"] != frames[0].meta["CAMERA"]) :
            log.error("ignore {} because not same camera".format(filename))
            continue
        if frame.wave.size != frames[0].wave.size or np.max(np.abs(frame.wave-frames[0].wave))>0.01 :
            log.error("ignore {} because not same wave".format(filename))
            continue
        if frames[0].fibermap is not None :
            if not np.all(frame.fibermap["TARGETID"] == frames[0].fibermap["TARGETID"]) :
                log.error("ignore {} because not same targets".format(filename))
                continue
        frames.append(frame)

    ivar = frames[0].ivar * (frames[0].mask == 0)
    ivarflux = frames[0].ivar * (frames[0].mask == 0) * frames[0].flux
    mask = frames[0].mask
    for frame in frames[1:] :
        ivar += frame.ivar * (frame.mask == 0)
        ivarflux += frame.ivar * (frame.mask == 0) * frame.flux
        mask &= frame.mask # and mask

    coadd = frames[0]
    coadd.ivar = ivar
    coadd.flux = ivarflux/(ivar+(ivar==0))
    coadd.mask = mask

    log.info("writing {} ...".format(args.outfile))
    write_frame(args.outfile,coadd)

    log.info("done")
<commit_msg>average resolution, add scores optionally<commit_after>"""
Coadd spectra
"""

from __future__ import absolute_import, division, print_function

import os
import numpy as np
from astropy.table import Table

from desiutil.log import get_logger
from desispec.io import read_frame,write_frame
from desispec.coaddition import coadd,coadd_cameras,resample_spectra_lin_or_log
from desispec.specscore import  compute_and_append_frame_scores

def parse(options=None):
    import argparse

    parser = argparse.ArgumentParser("Coadd frames")
    parser.add_argument("-i","--infile", type=str, nargs='+', help="input frame files")
    parser.add_argument("-o","--outfile", type=str,  help="output frame file")
    parser.add_argument("--scores",action="store_true", help="add scores")

    if options is None:
        args = parser.parse_args()
    else:
        args = parser.parse_args(options)

    return args

def main(args=None):

    log = get_logger()

    if args is None:
        args = parse()

    log.info("reading frames ...")

    frames = []
    for filename in args.infile :
        frame = read_frame(filename)
        if len(frames)==0 :
            frames.append(frame)
            continue

        if "CAMERA" in frames[0].meta and (frame.meta["CAMERA"] != frames[0].meta["CAMERA"]) :
            log.error("ignore {} because not same camera".format(filename))
            continue
        if frame.wave.size != frames[0].wave.size or np.max(np.abs(frame.wave-frames[0].wave))>0.01 :
            log.error("ignore {} because not same wave".format(filename))
            continue
        if frames[0].fibermap is not None :
            if not np.all(frame.fibermap["TARGETID"] == frames[0].fibermap["TARGETID"]) :
                log.error("ignore {} because not same targets".format(filename))
                continue
        frames.append(frame)

    ivar = frames[0].ivar * (frames[0].mask == 0)
    ivarflux = ivar * frames[0].flux
    ivarres = np.zeros(frames[0].resolution_data.shape)
    ndiag=ivarres.shape[1]
    for diag in range(ndiag) :
        ivarres[:,diag,:] = ivar * frames[0].resolution_data[:,diag,:]

    mask = frames[0].mask

    for frame in frames[1:] :
        tmp_ivar = frame.ivar * (frame.mask == 0)
        ivar += tmp_ivar
        ivarflux += tmp_ivar * frame.flux
        for diag in range(ndiag) :
            ivarres[:,diag,:] += tmp_ivar * frame.resolution_data[:,diag,:]
        mask &= frame.mask # and mask

    coadd = frames[0]
    coadd.ivar = ivar
    coadd.flux = ivarflux/(ivar+(ivar==0))
    coadd.mask = mask
    for diag in range(ndiag) :
        coadd.resolution_data[:,diag,:] = ivarres[:,diag,:]/(ivar+(ivar==0))

    if args.scores :
        compute_and_append_frame_scores(coadd)
    else :
        coadd.scores = None
        coadd.scores_comments = None

    # remove info on chi2pix
    coadd.chi2pix = None

    log.info("writing {} ...".format(args.outfile))
    write_frame(args.outfile,coadd)

    log.info("done")
<|endoftext|>


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

import gtk
import os
import pygtk
pygtk.require('2.0')
import sys
import urllib2

try:
    from json import loads as json_loads
except ImportError:
    from simplejson import loads as json_loads

from rbtools.api.serverinterface import ServerInterface
from rbtools.api.settings import Settings
from rbtools.api.resource import Resource, ResourceList, RootResource
from rbtools.api.resource import RESOURCE, RESOURCE_LIST

COOKIE_FILE = None
SERVER_URL = None

class ResourceWidget(gtk.ScrolledWindow):
    def __init__(self, hadjustment=None, vadjustment=None, server_url=SERVER_URL, is_root=True):
        super(ResourceWidget, self).__init__()
        self.set_border_width(10)
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
        self.main_box = gtk.VBox(False, 10)
        self.main_box.show()
        self.add_with_viewport(self.main_box)

        self.server_url = server_url
        self.init_root_resource(is_root)

        self.header_table = gtk.Table(1, 3)
        self.header_table.show()
        self.tree_box = gtk.VBox(False, 0)
        self.tree_box.show()
        tree_label = gtk.Label("Resource Tree:")
        tree_label.show()
        self.tree_box.pack_start(tree_label)
        self.header_table.attach(self.tree_box, 0, 1, 0, 1)
        self.current_tree_size = 0
        self.update_tree()
        self.main_box.pack_start(self.header_table)

        self.actions_box = gtk.VBox(False, 0)
        self.actions_box.show()
        actions_label = gtk.Label("Actions:")
        actions_label.show()
        self.actions_box.pack_start(actions_label)
        self.header_table.attach(self.actions_box, 2, 3, 0, 1)

        self.table = None
        self.get_id = None
        self.changes = {}
        self.build_table(self.root.data)

    def init_root_resource(self, is_root=True):
        self.server = ServerInterface(self.server_url, COOKIE_FILE)

        if is_root:
            self.root = RootResource(self.server, self.server_url)
        else:
            self.root = Resource(self.server, self.server_url)
            self.root._load()

        self.current = self.root
        self.stack = []
        self.stack.append([self.root, self.make_parent_button(self.root.resource_name)])

        self.actions = []

    def parent_clicked(self, widget, data):
        curr = self.stack[len(self.stack) - 1]

        while not curr[0].resource_name == data:
            curr = self.stack.pop()
            curr[1].hide()
            self.tree_box.remove(curr[1])
            self.current_tree_size = self.current_tree_size - 1
            curr = self.stack[len(self.stack) - 1]

        self.current = curr[0]
        self.link_clicked(None, 'self')
        #self.build_table(self.current.data)

    def link_clicked(self, widget, data):
        if data:
            if data == 'update':
                try:
                    for n in self.changes.keys():
                        self.current.update_field(n, self.changes[n])

                    self.current.save()
                except urllib2.HTTPError, e:
                    #print e.read()
                    pass
            elif data == 'create':
                error = True
                self.current = self.current.create()

                while error:
                    try:
                        self.current.save()
                        error = False
                    except urllib2.HTTPError, e:
                        text = e.read()
                        text_json = json_loads(text)
                        if 'fields' in text_json:
                            for n in text_json['fields']:
                                print 'Missing Field Required!'
                                print 'Please enter a value for %s' % n
                                value = raw_input('%s: ' % n)
                                self.current.update_field(n, value)
                        else:
                            self.current.clear_updates()

                self.stack.append([self.current, self.make_parent_button(self.current.resource_name)])
                self.update_tree()
            else:
                if data == 'get_button':
                    data = self.get_id.get_text()

                current_resource_name = self.current.resource_name

                if self.current.resource_type == RESOURCE:
                    self.current = self.current.get_or_create(data)
                else:
                    self.current = self.current.get(data)

                if not current_resource_name == self.current.resource_name:
                    self.stack.append([self.current, self.make_parent_button(self.current.resource_name)])
                    self.update_tree()

            self.changes = {}
            self.build_table(self.current.data)

    def entry_changed(self, widget, n):
        self.changes[n] = widget.get_text()
        #print "%s changed to %s" % (n, self.changes[n])

    def update_tree(self):
        i = len(self.stack)

        if i > self.current_tree_size:
            i = self.current_tree_size

            while i < len(self.stack):
                self.tree_box.pack_start(self.stack[i][1])
                self.stack[i][1].show()
                i = i + 1

            self.current_tree_size = len(self.stack)

    def make_parent_button(self, name):
        parent_button = gtk.Button(name)
        parent_button.set_size_request(1, 50)
        parent_button.connect('clicked', self.parent_clicked, name)
        return parent_button

    def get_dimensions(self, data, _c=0):
        rows = len(data)

        if _c == 0:
            columns = 1
        else:
            columns = _c

        max_c = columns
        itr = data.itervalues()

        for i in itr:
            if isinstance(i, dict):
                r, c = self.get_dimensions(i, columns + 1)
                rows = rows + r

                if c > max_c:
                    max_c = c

        columns = max_c
        return rows, columns

    def build_table(self, data):
        self.clear_actions()
        if self.current.resource_type == RESOURCE_LIST:
            get_box = gtk.HBox(False, 0)
            get_box.show()
            self.actions.append(get_box)
            self.actions_box.pack_start(get_box)
            self.get_id = gtk.Entry()
            self.get_id.set_editable(True)
            self.get_id.show()
            get_box.pack_end(self.get_id)
            get_button = gtk.Button('Get: ')
            get_button.connect("clicked", self.link_clicked, 'get_button')
            get_button.show()
            get_box.pack_start(get_button)

        rows, cols = self.get_dimensions(data)
        cols = cols + 1

        if self.table:
            self.main_box.remove(self.table)

        #print "rows %d, cols %d" % (rows, cols)
        self.table = gtk.Table(rows, cols)
        self.table.show()
        self.main_box.pack_start(self.table)
        self.populate_table(data, columns=cols)

    def populate_table(self, data, k=0, l=0, links=False, columns=1):
        i = k
        j = l
        for n in data:
            if not links:
                if isinstance(data[n], dict):
                    if n == 'links':
                        lnks = True
                    else:
                        lnks = False
                        next = gtk.Label("%s: " % n)
                        next.set_justify(gtk.JUSTIFY_LEFT)
                        next.show()
                        #print "%s at %d, %d, %d, %d" % (n, j, j+1, i, i+1)
                        self.table.attach(next, j, j + 1, i, i + 1)

                    i = i + 1
                    j = j + 1
                    i = self.populate_table(data[n], i, j, lnks, columns) - 1
                    j = j - 1
                else:
                    next_label = gtk.Label("%s: " % n)
                    next_label.set_justify(gtk.JUSTIFY_LEFT)
                    next_label.show()
                    #print "%s at %d, %d, %d, %d" % (n, j, j+1, i, i+1)
                    self.table.attach(next_label, j, j + 1, i, i + 1)
                    j = j + 1

                    if isinstance(data[n], list):
                        if len(data[n]) > 0:
                            scroll_window = gtk.ScrolledWindow()
                            scroll_window.show()
                            scroll_window.set_border_width(5)
                            scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
                            #print "attaching scroll window at %d, %d, %d, %d" % (j, columns + 1, i, i+1)
                            self.table.attach(scroll_window, j, columns + 1, i, i + 1)
                            vbox = gtk.VBox(False, 0)
                            vbox.show()
                            scroll_window.add_with_viewport(vbox)

                            # if it is a list where item's in the list have 'links',
                            # then its a list of resources
                            if not isinstance(data[n][0], int):
                                if 'links' in data[n][0]:
                                    for x in data[n]:
                                        if 'users' == n:
                                            id_name = 'username'
                                        elif 'diffs' == n:
                                            id_name = 'revision'
                                        else:
                                            id_name = 'id'

                                        button_text = '%s: ' % x[id_name]

                                        if 'review_requests' == n:
                                            button_text = button_text + '\n%s' % x['summary']
                                        elif 'repositories' == n:
                                            button_text = button_text + '\n%s' % x['name']

                                        id_button = gtk.Button(button_text)
                                        id_button.connect('clicked', self.link_clicked, x[id_name])
                                        id_button.show()
                                        vbox.pack_start(id_button)

                            # else its a plain ol' list
                            else:
                                for x in data[n]:
                                    next_box = gtk.Entry()
                                    next_box.set_editable(False)
                                    next_box.set_text(str(x))
                                    vbox.pack_start(next_box)
                        else:
                            next_box = gtk.Entry()
                            next_box.set_editable(False)
                            next_box.set_text(str(data[n]))
                            next_box.show()
                            #print "%s at %d, %d, %d, %d" % (str(data[n]), j, j+1, i, i+1)
                            self.table.attach(next_box, j, j + 1, i, i + 1)

                        j = j - 1
                    else:
                        next_box = gtk.Entry()
                        next_box.set_editable(True)
                        next_box.set_text(str(data[n]))
                        next_box.connect('changed', self.entry_changed, n)
                        next_box.show()
                        #print "%s at %d, %d, %d, %d" % (str(data[n]), j, j+1, i, i+1)
                        self.table.attach(next_box, j, j + 1, i, i + 1)
                        j = j - 1
            #else:
            #    next_button = gtk.Button("%s" % n)

            else:
                next_button = gtk.Button("%s" % n)
                next_button.connect("clicked", self.link_clicked, n)
                next_button.show()
                self.actions.append(next_button)
                self.add_action_button(next_button)
                #self.table.attach(next_button, j, j + 1, i, i + 1)

            i = i + 1

        return i

    def add_action_button(self, button):
        self.actions_box.pack_start(button)

    def clear_actions(self):
        for n in self.actions:
            self.actions_box.remove(n)

        self.actions = []

"""
    def msg_entry_change(self, widget):
        self.prompt_text = widget.get_text()

    def msg_entry_submit(self, widget):

        self.prompt_msg_box.destroy()

    def prompt_for_text(self, field):
        msg_box = gtk.Dialog()
        msg_box.show()
        msg_box.set_size_request(500, 500)
        msg_box.set_title('Missing required field')
        msg_text = gtk.Label('The field "%s" is required.  Please enter the field''s value.' % field)
        msg_text.show()
        msg_box.vbox.pack_start(msg_text)
        msg_entry = gtk.Entry()
        msg_entry.set_editable(True)
        msg_entry.connect('changed', self.msg_entry_changed)
        msg_box.vbox.pack_start(msg_entry)
        msg_submit = gtk.Button('Submit')
        msg_submit.show()
        msg_submit.connect('clicked', self.msg_entry_submit)
        msg_box.vbox.pack_start(msg_submit)
"""

class ResourceBrowser(object):
    def __init__(self, server_url=SERVER_URL):
        super(ResourceBrowser, self).__init__()
        self.window = gtk.Dialog()
        self.window.show()
        self.window.set_size_request(800, 600)
        self.window.set_border_width(0)
        self.server_url = server_url
        self.window.set_title("Resource Browser @ %s" % self.server_url)
        self.resource_page = ResourceWidget(None, None, self.server_url + 'api/')
        self.resource_page.show()
        self.window.vbox.pack_start(self.resource_page)
        self.window.connect('destroy', self.close_application)

    # another callback
    def close_application(self, widget):
        gtk.main_quit()

def main():
    settings = Settings(config_file='rb_scripts.dat')
    COOKIE_FILE = settings.get_cookie_file()
    SERVER_URL = settings.get_server_url()
    browser = ResourceBrowser(SERVER_URL)

    gtk.main()

if __name__ == "__main__":
    main()
<commit_msg>Fix line endings in resource-browser.py.<commit_after>#!/usr/bin/env python

import gtk
import os
import pygtk
pygtk.require('2.0')
import sys
import urllib2

try:
    from json import loads as json_loads
except ImportError:
    from simplejson import loads as json_loads

from rbtools.api.serverinterface import ServerInterface
from rbtools.api.settings import Settings
from rbtools.api.resource import Resource, ResourceList, RootResource
from rbtools.api.resource import RESOURCE, RESOURCE_LIST

COOKIE_FILE = None
SERVER_URL = None

class ResourceWidget(gtk.ScrolledWindow):
    def __init__(self, hadjustment=None, vadjustment=None, server_url=SERVER_URL, is_root=True):
        super(ResourceWidget, self).__init__()
        self.set_border_width(10)
        self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
        self.main_box = gtk.VBox(False, 10)
        self.main_box.show()
        self.add_with_viewport(self.main_box)

        self.server_url = server_url
        self.init_root_resource(is_root)

        self.header_table = gtk.Table(1, 3)
        self.header_table.show()
        self.tree_box = gtk.VBox(False, 0)
        self.tree_box.show()
        tree_label = gtk.Label("Resource Tree:")
        tree_label.show()
        self.tree_box.pack_start(tree_label)
        self.header_table.attach(self.tree_box, 0, 1, 0, 1)
        self.current_tree_size = 0
        self.update_tree()
        self.main_box.pack_start(self.header_table)

        self.actions_box = gtk.VBox(False, 0)
        self.actions_box.show()
        actions_label = gtk.Label("Actions:")
        actions_label.show()
        self.actions_box.pack_start(actions_label)
        self.header_table.attach(self.actions_box, 2, 3, 0, 1)

        self.table = None
        self.get_id = None
        self.changes = {}
        self.build_table(self.root.data)

    def init_root_resource(self, is_root=True):
        self.server = ServerInterface(self.server_url, COOKIE_FILE)

        if is_root:
            self.root = RootResource(self.server, self.server_url)
        else:
            self.root = Resource(self.server, self.server_url)
            self.root._load()

        self.current = self.root
        self.stack = []
        self.stack.append([self.root, self.make_parent_button(self.root.resource_name)])

        self.actions = []

    def parent_clicked(self, widget, data):
        curr = self.stack[len(self.stack) - 1]

        while not curr[0].resource_name == data:
            curr = self.stack.pop()
            curr[1].hide()
            self.tree_box.remove(curr[1])
            self.current_tree_size = self.current_tree_size - 1
            curr = self.stack[len(self.stack) - 1]

        self.current = curr[0]
        self.link_clicked(None, 'self')
        #self.build_table(self.current.data)

    def link_clicked(self, widget, data):
        if data:
            if data == 'update':
                try:
                    for n in self.changes.keys():
                        self.current.update_field(n, self.changes[n])

                    self.current.save()
                except urllib2.HTTPError, e:
                    #print e.read()
                    pass
            elif data == 'create':
                error = True
                self.current = self.current.create()

                while error:
                    try:
                        self.current.save()
                        error = False
                    except urllib2.HTTPError, e:
                        text = e.read()
                        text_json = json_loads(text)
                        if 'fields' in text_json:
                            for n in text_json['fields']:
                                print 'Missing Field Required!'
                                print 'Please enter a value for %s' % n
                                value = raw_input('%s: ' % n)
                                self.current.update_field(n, value)
                        else:
                            self.current.clear_updates()

                self.stack.append([self.current, self.make_parent_button(self.current.resource_name)])
                self.update_tree()
            else:
                if data == 'get_button':
                    data = self.get_id.get_text()

                current_resource_name = self.current.resource_name

                if self.current.resource_type == RESOURCE:
                    self.current = self.current.get_or_create(data)
                else:
                    self.current = self.current.get(data)

                if not current_resource_name == self.current.resource_name:
                    self.stack.append([self.current, self.make_parent_button(self.current.resource_name)])
                    self.update_tree()

            self.changes = {}
            self.build_table(self.current.data)

    def entry_changed(self, widget, n):
        self.changes[n] = widget.get_text()
        #print "%s changed to %s" % (n, self.changes[n])

    def update_tree(self):
        i = len(self.stack)

        if i > self.current_tree_size:
            i = self.current_tree_size

            while i < len(self.stack):
                self.tree_box.pack_start(self.stack[i][1])
                self.stack[i][1].show()
                i = i + 1

            self.current_tree_size = len(self.stack)

    def make_parent_button(self, name):
        parent_button = gtk.Button(name)
        parent_button.set_size_request(1, 50)
        parent_button.connect('clicked', self.parent_clicked, name)
        return parent_button

    def get_dimensions(self, data, _c=0):
        rows = len(data)

        if _c == 0:
            columns = 1
        else:
            columns = _c

        max_c = columns
        itr = data.itervalues()

        for i in itr:
            if isinstance(i, dict):
                r, c = self.get_dimensions(i, columns + 1)
                rows = rows + r

                if c > max_c:
                    max_c = c

        columns = max_c
        return rows, columns

    def build_table(self, data):
        self.clear_actions()
        if self.current.resource_type == RESOURCE_LIST:
            get_box = gtk.HBox(False, 0)
            get_box.show()
            self.actions.append(get_box)
            self.actions_box.pack_start(get_box)
            self.get_id = gtk.Entry()
            self.get_id.set_editable(True)
            self.get_id.show()
            get_box.pack_end(self.get_id)
            get_button = gtk.Button('Get: ')
            get_button.connect("clicked", self.link_clicked, 'get_button')
            get_button.show()
            get_box.pack_start(get_button)

        rows, cols = self.get_dimensions(data)
        cols = cols + 1

        if self.table:
            self.main_box.remove(self.table)

        #print "rows %d, cols %d" % (rows, cols)
        self.table = gtk.Table(rows, cols)
        self.table.show()
        self.main_box.pack_start(self.table)
        self.populate_table(data, columns=cols)

    def populate_table(self, data, k=0, l=0, links=False, columns=1):
        i = k
        j = l
        for n in data:
            if not links:
                if isinstance(data[n], dict):
                    if n == 'links':
                        lnks = True
                    else:
                        lnks = False
                        next = gtk.Label("%s: " % n)
                        next.set_justify(gtk.JUSTIFY_LEFT)
                        next.show()
                        #print "%s at %d, %d, %d, %d" % (n, j, j+1, i, i+1)
                        self.table.attach(next, j, j + 1, i, i + 1)

                    i = i + 1
                    j = j + 1
                    i = self.populate_table(data[n], i, j, lnks, columns) - 1
                    j = j - 1
                else:
                    next_label = gtk.Label("%s: " % n)
                    next_label.set_justify(gtk.JUSTIFY_LEFT)
                    next_label.show()
                    #print "%s at %d, %d, %d, %d" % (n, j, j+1, i, i+1)
                    self.table.attach(next_label, j, j + 1, i, i + 1)
                    j = j + 1

                    if isinstance(data[n], list):
                        if len(data[n]) > 0:
                            scroll_window = gtk.ScrolledWindow()
                            scroll_window.show()
                            scroll_window.set_border_width(5)
                            scroll_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
                            #print "attaching scroll window at %d, %d, %d, %d" % (j, columns + 1, i, i+1)
                            self.table.attach(scroll_window, j, columns + 1, i, i + 1)
                            vbox = gtk.VBox(False, 0)
                            vbox.show()
                            scroll_window.add_with_viewport(vbox)

                            # if it is a list where item's in the list have 'links',
                            # then its a list of resources
                            if not isinstance(data[n][0], int):
                                if 'links' in data[n][0]:
                                    for x in data[n]:
                                        if 'users' == n:
                                            id_name = 'username'
                                        elif 'diffs' == n:
                                            id_name = 'revision'
                                        else:
                                            id_name = 'id'

                                        button_text = '%s: ' % x[id_name]

                                        if 'review_requests' == n:
                                            button_text = button_text + '\n%s' % x['summary']
                                        elif 'repositories' == n:
                                            button_text = button_text + '\n%s' % x['name']

                                        id_button = gtk.Button(button_text)
                                        id_button.connect('clicked', self.link_clicked, x[id_name])
                                        id_button.show()
                                        vbox.pack_start(id_button)

                            # else its a plain ol' list
                            else:
                                for x in data[n]:
                                    next_box = gtk.Entry()
                                    next_box.set_editable(False)
                                    next_box.set_text(str(x))
                                    vbox.pack_start(next_box)
                        else:
                            next_box = gtk.Entry()
                            next_box.set_editable(False)
                            next_box.set_text(str(data[n]))
                            next_box.show()
                            #print "%s at %d, %d, %d, %d" % (str(data[n]), j, j+1, i, i+1)
                            self.table.attach(next_box, j, j + 1, i, i + 1)

                        j = j - 1
                    else:
                        next_box = gtk.Entry()
                        next_box.set_editable(True)
                        next_box.set_text(str(data[n]))
                        next_box.connect('changed', self.entry_changed, n)
                        next_box.show()
                        #print "%s at %d, %d, %d, %d" % (str(data[n]), j, j+1, i, i+1)
                        self.table.attach(next_box, j, j + 1, i, i + 1)
                        j = j - 1
            #else:
            #    next_button = gtk.Button("%s" % n)

            else:
                next_button = gtk.Button("%s" % n)
                next_button.connect("clicked", self.link_clicked, n)
                next_button.show()
                self.actions.append(next_button)
                self.add_action_button(next_button)
                #self.table.attach(next_button, j, j + 1, i, i + 1)

            i = i + 1

        return i

    def add_action_button(self, button):
        self.actions_box.pack_start(button)

    def clear_actions(self):
        for n in self.actions:
            self.actions_box.remove(n)

        self.actions = []

"""
    def msg_entry_change(self, widget):
        self.prompt_text = widget.get_text()

    def msg_entry_submit(self, widget):

        self.prompt_msg_box.destroy()

    def prompt_for_text(self, field):
        msg_box = gtk.Dialog()
        msg_box.show()
        msg_box.set_size_request(500, 500)
        msg_box.set_title('Missing required field')
        msg_text = gtk.Label('The field "%s" is required.  Please enter the field''s value.' % field)
        msg_text.show()
        msg_box.vbox.pack_start(msg_text)
        msg_entry = gtk.Entry()
        msg_entry.set_editable(True)
        msg_entry.connect('changed', self.msg_entry_changed)
        msg_box.vbox.pack_start(msg_entry)
        msg_submit = gtk.Button('Submit')
        msg_submit.show()
        msg_submit.connect('clicked', self.msg_entry_submit)
        msg_box.vbox.pack_start(msg_submit)
"""

class ResourceBrowser(object):
    def __init__(self, server_url=SERVER_URL):
        super(ResourceBrowser, self).__init__()
        self.window = gtk.Dialog()
        self.window.show()
        self.window.set_size_request(800, 600)
        self.window.set_border_width(0)
        self.server_url = server_url
        self.window.set_title("Resource Browser @ %s" % self.server_url)
        self.resource_page = ResourceWidget(None, None, self.server_url + 'api/')
        self.resource_page.show()
        self.window.vbox.pack_start(self.resource_page)
        self.window.connect('destroy', self.close_application)

    # another callback
    def close_application(self, widget):
        gtk.main_quit()

def main():
    settings = Settings(config_file='rb_scripts.dat')
    COOKIE_FILE = settings.get_cookie_file()
    SERVER_URL = settings.get_server_url()
    browser = ResourceBrowser(SERVER_URL)

    gtk.main()

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


<commit_before># -*- coding: utf-8 -*-
# Copyright (c) 2016, French National Center for Scientific Research (CNRS)
# Distributed under the (new) BSD License. See LICENSE for more info.

import pytest

from pyacq import create_manager
from pyacq.devices.webcam_av import WebCamAV, HAVE_AV
from pyacq.viewers.imageviewer import ImageViewer
from pyacq.rec.avirecorder import AviRecorder

import numpy as np

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg

import os
import shutil
import datetime

@pytest.mark.skipif(not HAVE_AV, reason='no have av')
def test_AviRecorder():
    app = pg.mkQApp()

    dev = WebCamAV(name='cam')
    dev.configure(camera_num=0)
    dev.output.configure(protocol='tcp', interface='127.0.0.1',transfermode='plaindata',)
    dev.initialize()

    dirname = './test_rec_avi'
    if os.path.exists(dirname):
        shutil.rmtree(dirname)

    rec = AviRecorder()
    #~ rec = ng1.create_node('RawRecorder')
    rec.configure(streams=[dev.output], autoconnect=True, dirname=dirname)
    rec.initialize()

    viewer = ImageViewer()
    viewer.configure()
    viewer.input.connect(dev.output)
    viewer.initialize()
    viewer.show()

    dev.start()
    rec.start()
    viewer.start()

    def terminate():
        viewer.stop()
        rec.stop()
        dev.stop()

        viewer.close()
        rec.close()
        dev.close()

        app.quit()

    # start for a while
    timer = QtCore.QTimer(singleShot=True, interval=10000)
    timer.timeout.connect(terminate)
    timer.start()
    app.exec_()

if __name__ == '__main__':
    test_AviRecorder()
<commit_msg>skip avirec in test<commit_after># -*- coding: utf-8 -*-
# Copyright (c) 2016, French National Center for Scientific Research (CNRS)
# Distributed under the (new) BSD License. See LICENSE for more info.

import pytest

from pyacq import create_manager
from pyacq.devices.webcam_av import WebCamAV, HAVE_AV
from pyacq.viewers.imageviewer import ImageViewer
from pyacq.rec.avirecorder import AviRecorder

import numpy as np

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg

import os
import shutil
import datetime

# TODO make this test able to run without device

@pytest.mark.skip(reason="need Device")
@pytest.mark.skipif(not HAVE_AV, reason='no have av')
def test_AviRecorder():
    app = pg.mkQApp()

    dev = WebCamAV(name='cam')
    dev.configure(camera_num=0)
    dev.output.configure(protocol='tcp', interface='127.0.0.1',transfermode='plaindata',)
    dev.initialize()

    dirname = './test_rec_avi'
    if os.path.exists(dirname):
        shutil.rmtree(dirname)

    rec = AviRecorder()
    #~ rec = ng1.create_node('RawRecorder')
    rec.configure(streams=[dev.output], autoconnect=True, dirname=dirname)
    rec.initialize()

    viewer = ImageViewer()
    viewer.configure()
    viewer.input.connect(dev.output)
    viewer.initialize()
    viewer.show()

    dev.start()
    rec.start()
    viewer.start()

    def terminate():
        viewer.stop()
        rec.stop()
        dev.stop()

        viewer.close()
        rec.close()
        dev.close()

        app.quit()

    # start for a while
    timer = QtCore.QTimer(singleShot=True, interval=10000)
    timer.timeout.connect(terminate)
    timer.start()
    app.exec_()

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


<commit_before>import compiler
import compiler                                          as one
import compiler.ast
import compiler.ast                                      as two
# import compiler.ast.Const
# import compiler.ast.Const                                as three
from   compiler import ast
from   compiler import ast                               as four
from   compiler.ast import Const
from   compiler.ast import Const                         as five

func = lambda x: x

class D:
    class B(compiler.ast.Const):
        inherited2 = 1
        def x(self):
            self.inherited1 = 1

class A(D.B):
    def __init__(self):
        self.x = 1                      # define x on A
        self.w.q = 1

    def f(s, self):                     # unusual self
        print self
        s.self = 1
        s = 7

    def x():                            # no self, redefine x on object
        pass

    def y(self):
        self.a, self.b = (1, 2)         # define a, b

    def _z(self):
        print self._z                   # method
        print self.x                    # assigned
        print self.a                    # unpacked
        print self.w                    # unknown
        print self.inherited1           # known from B
        print self.inherited2           # known from B
        print self.value                # from compiler.ast.Const, fails
        print self.goofy                # defined in class scope

    goofy = x

class E(one.ast.Const):
    def f(self):
        print self.value                # fails

class F(two.Const):
    def f(self):
        print self.value

class H(four.Const):
    def f(self):
        print self.value                # fails

class I(five):
    def f(self):
        print self.value

class J(ast.Const):
    def f(self):
        print self.value                # fails

class K(Const):
    def f(self):
        print self.value
<commit_msg>clean up test<commit_after>import compiler
import compiler                                          as one
import compiler.ast
import compiler.ast                                      as two
from   compiler import ast
from   compiler import ast                               as three
from   compiler.ast import Const
from   compiler.ast import Const                         as four

func = lambda x: x

class D:
    class B(compiler.ast.Const):
        inherited2 = 1
        def x(self):
            self.inherited1 = 1

class A(D.B):
    def __init__(self):
        self.x = 1                      # define x on A
        self.w.q = 1

    def f(s, self):                     # unusual self
        print self
        s.self = 1
        s = 7

    def x():                            # no self, redefine x on object
        pass

    def y(self):
        self.a, self.b = (1, 2)         # define a, b

    def _z(self):
        print self._z                   # method
        print self.x                    # assigned
        print self.a                    # unpacked
        print self.w                    # unknown
        print self.inherited1           # known from B
        print self.inherited2           # known from B
        print self.value                # from compiler.ast.Const, fails
        print self.goofy                # defined in class scope

    goofy = x

class E(one.ast.Const):
    def f(self):
        print self.value

class F(two.Const):
    def f(self):
        print self.value

class H(three.Const):
    def f(self):
        print self.value

class I(four):
    def f(self):
        print self.value

class J(ast.Const):
    def f(self):
        print self.value

class K(Const):
    def f(self):
        print self.value
<|endoftext|>


<commit_before>from __future__ import division

import OpenGL.GL as gl

from pycho.gl.drawing import draw_square

from pycho.core.blocking import into_sections

from pycho.world.navigation import DIRECTIONS

from pycho.hivemind import RecordingMind, Action

class WorldObject(object):

    def __init__(self,
        x,
        y,
        color,
        facing,
        health=3,
        scale=1,
        damagable=True,
        moveable=True,
        spawner=None,
        *args,
        **kwargs):

        self.health = health
        self.x = x
        self.y = y
        self.color = color
        self.scale = scale
        self.damagable = damagable
        self.moveable = moveable
        self.facing = facing
        self.mind = RecordingMind()
        self.spawned_by = spawner

        self._square_cache = {}
        self._section_cache = {}
        #TODO
        self._last_hit_by = None

        self._regsiter_actions()

    def _regsiter_actions(self):
        """ Very very very very hacky. Turn your eyes away here """
        from types import MethodType as instancemethod
        for func_name in dir(self):
            try:
                func = self.__getattribute__(func_name)
            except:
                pass
            if isinstance(func, instancemethod):
                try:
                    if 'action' in func.func_dict:
                        self.mind.register_action(func, func.func_dict['type'])
                except AttributeError:
                    pass

    def tick(self, world):
        pass

    @Action("Death", class_watch=['_last_hit_by'])
    def die(self):
        pass

    def _debug_draw(self):
        if (self.x, self.y, self.facing) not in self._section_cache:
            self._section_cache[(self.x, self.y, self.facing)] = into_sections(self.populated_squares)

        gl.glPushMatrix()

        for square in self.populated_squares:
            x, y, color = square
            r, g, b =color

            gl.glColor3f(r, g, b)
            draw_square(x, y)

        gl.glPopMatrix()

    def draw(self):
        """ draw method used to draw all the populated squares
            by this object - uses clever caching and sections to improve
            draw speed """

        if (self.x, self.y, self.facing, self.scale) not in self._section_cache:
            self._section_cache[(self.x, self.y, self.facing, self.scale)] = into_sections(self.populated_squares)

        gl.glPushMatrix()

        for section in self._section_cache[(self.x, self.y, self.facing, self.scale)]:
            (x, y, width, height, color) = section
            r, g, b = color
            gl.glColor3f(r, g, b)
            draw_square(x, y, width, height)

        gl.glPopMatrix()

    @Action("taking damage", class_watch=['_last_hit_by'])
    def take_damage(self, damage, other):
        self.health -= damage
        self._last_hit_by = other

    def deal_damage(self, other):
        pass

    @Action("Moving", watch={1 : 'facing', 2 : 'distance'})
    def move(self, world, facing, distance=1):
        if facing == DIRECTIONS['still']:
            return
        world.move_in_direction(self, facing, distance)

    def populated_at(self, x, y):
        """ returns a list of tuples containing the coordinates of populated
            squares, should the square be at this point
        """
        return [(x, y, self.color)]

    @property
    def populated_squares(self):
        """ returns the populated squares for the current object
            clever caching method """
        if (self.x, self.y, self.facing, self.scale) not in self._square_cache:
            self._square_cache[(self.x, self.y, self.facing, self.scale)] = self.populated_at(self.x, self.y)
        return self._square_cache[(self.x, self.y, self.facing, self.scale)]

    def closest_point(self, x, y):
        """ returns the coordinates which are part of this object and
            closest to x, y """
        x2nd = x ** 2
        y2nd = y ** 2
        euclid = lambda i, j: (x2nd - (i ** 2)) + (y2nd - (j ** 2))

        small_score = 9000001
        smallest = None

        for (x, y) in self.populated_squares:
            score = euclid(x, y)
            if score < small_score:
                smallest = (x, y)
                small_score = score
        return smallest

<commit_msg>improving docmentation of methods in preperation for #19<commit_after>from __future__ import division

import OpenGL.GL as gl

from pycho.gl.drawing import draw_square

from pycho.core.blocking import into_sections

from pycho.world.navigation import DIRECTIONS

from pycho.hivemind import RecordingMind, Action

class WorldObject(object):

    def __init__(self,
        x,
        y,
        color,
        facing,
        health=3,
        scale=1,
        damagable=True,
        moveable=True,
        spawner=None,
        *args,
        **kwargs):

        self.health = health
        self.x = x
        self.y = y
        self.color = color
        self.scale = scale
        self.damagable = damagable
        self.moveable = moveable
        self.facing = facing
        self.mind = RecordingMind()
        self.spawned_by = spawner

        self._square_cache = {}
        self._section_cache = {}
        #TODO
        self._last_hit_by = None

        self._regsiter_actions()

    def _regsiter_actions(self):
        """ Very very very very hacky. Turn your eyes away here """
        from types import MethodType as instancemethod
        for func_name in dir(self):
            try:
                func = self.__getattribute__(func_name)
            except:
                pass
            if isinstance(func, instancemethod):
                try:
                    if 'action' in func.func_dict:
                        self.mind.register_action(func, func.func_dict['type'])
                except AttributeError:
                    pass

    def tick(self, world):
        pass

    @Action("Death", class_watch=['_last_hit_by'])
    def die(self):
        pass

    def _debug_draw(self):
        """ Draw used for debugging. Allows you to draw pixel by pixel
            in the form of blocks without using sections """
        if (self.x, self.y, self.facing) not in self._section_cache:
            self._section_cache[(self.x, self.y, self.facing)] = into_sections(self.populated_squares)

        gl.glPushMatrix()

        for square in self.populated_squares:
            x, y, color = square
            r, g, b =color

            gl.glColor3f(r, g, b)
            draw_square(x, y)

        gl.glPopMatrix()

    def draw(self):
        """ draw method used to draw all the populated squares
            by this object - uses clever caching and sections to improve
            draw speed """

        if (self.x, self.y, self.facing, self.scale) not in self._section_cache:
            self._section_cache[(self.x, self.y, self.facing, self.scale)] = into_sections(self.populated_squares)

        gl.glPushMatrix()

        for section in self._section_cache[(self.x, self.y, self.facing, self.scale)]:
            (x, y, width, height, color) = section
            r, g, b = color
            gl.glColor3f(r, g, b)
            draw_square(x, y, width, height)

        gl.glPopMatrix()

    @Action("taking damage", class_watch=['_last_hit_by'])
    def take_damage(self, damage, other):
        """ Take a certain amount of damage dealt by other
            Stores oher in the _last_hit_by variable for
            later inspection"""
        self.health -= damage
        self._last_hit_by = other

    def deal_damage(self, other):
        """ Deal some damage to other """
        pass

    @Action("Moving", watch={1 : 'facing', 2 : 'distance'})
    def move(self, world, facing, distance=1):
        """ Move in the direction the object is facing """
        if facing == DIRECTIONS['still']:
            return
        world.move_in_direction(self, facing, distance)

    def populated_at(self, x, y):
        """ returns a list of tuples containing the coordinates of populated
            squares, should the square be at this point
        """
        return [(x, y, self.color)]

    @property
    def populated_squares(self):
        """ returns the populated squares for the current object
            clever caching method """
        if (self.x, self.y, self.facing, self.scale) not in self._square_cache:
            self._square_cache[(self.x, self.y, self.facing, self.scale)] = self.populated_at(self.x, self.y)
        return self._square_cache[(self.x, self.y, self.facing, self.scale)]

    def closest_point(self, x, y):
        """ returns the coordinates which are part of this object and
            closest to x, y """
        x2nd = x ** 2
        y2nd = y ** 2
        euclid = lambda i, j: (x2nd - (i ** 2)) + (y2nd - (j ** 2))

        small_score = 9000001
        smallest = None

        for (x, y) in self.populated_squares:
            score = euclid(x, y)
            if score < small_score:
                smallest = (x, y)
                small_score = score
        return smallest<|endoftext|>