<commit_before>#!/usr/bin/env python2.5
#
# Copyright 2009 the Melange authors.
#
# 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.

"""This module contains the Student Proposal Model.
"""

__authors__ = [
  '"Daniel Hans <daniel.m.hans@gmail.com>',
  '"Lennard de Rijk" <ljvderijk@gmail.com>',
]

from google.appengine.ext import db

from django.utils.translation import ugettext

import soc.models.linkable
import soc.models.mentor
import soc.models.organization
import soc.models.program

# define the [min_score, max_score] and the name for the RankList
DEF_SCORE = [-1000, 1000]
DEF_RANKER_NAME = 'student_app_ranker'

class StudentProposal(soc.models.linkable.Linkable):
  """Model for a student proposal used in the GSoC workflow.
  """

  #: Required field indicating the "title" of the proposal
  title = db.StringProperty(required=True,
      verbose_name=ugettext('Title'))
  title.help_text = ugettext('Title of the proposal')

  #: required, text field used for different purposes,
  #: depending on the specific type of the proposal
  abstract = db.TextProperty(required=True)
  abstract.help_text = ugettext(
      'Short abstract, summary, or snippet;'
      ' 500 characters or less, plain text displayed publicly')

  #: Required field containing the content of the proposal.
  content = db.TextProperty(required=True)
  content.help_text = ugettext('This contains your actual proposal')

  #: an URL linking to more information about this students proposal
  additional_info = db.URLProperty(required=False)
  additional_info.help_text = ugettext(
      'Link to a resource containing more information about your proposal')

  #: A property containing which mentor has assigned himself to this proposal.
  #: Only a proposal with an assigned mentor can be turned into
  #: a accepted proposal. A proposal can only have one mentor.
  mentor = db.ReferenceProperty(reference_class=soc.models.mentor.Mentor,
                                required=False,
                                collection_name='student_proposals')

  #: A property containing a list of possible Mentors for this proposal
  possible_mentors = db.ListProperty(item_type=db.Key, default=[])

  #: the current score of this proposal, used to determine which proposals
  #: should be assigned a project slot.
  score = db.IntegerProperty(required=True, default=0)

  #: the status of this proposal
  #: new : the proposal has not been ranked/scored yet
  #: pending: the proposal is in the process of being ranked/scored
  #: accepted: the proposal has been assigned a project slot
  #: rejected: the proposal has not been assigned a slot
  #: invalid: the student or org admin marked this as an invalid proposal.
  status = db.StringProperty(required=True, default='new',
      choices=['new', 'pending', 'accepted', 'rejected', 'invalid'])

  #: organization to which this proposal is directed
  org = db.ReferenceProperty(
      reference_class=soc.models.organization.Organization,
      required=True, collection_name='student_proposals')

  #: program in which this proposal has been created
  program = db.ReferenceProperty(reference_class=soc.models.program.Program,
                                 required=True,
                                 collection_name='student_proposals')

  #: date when the proposal was created
  created_on = db.DateTimeProperty(required=True, auto_now_add=True)

  #: date when the proposal was last modified, should be set manually on edit
  last_modified_on = db.DateTimeProperty(required=True, auto_now_add=True)

  #: indicates whether the proposal's content may be publicly seen or not
  is_publicly_visible = db.BooleanProperty(required=False, default=False,
      verobose_name=ugettext('Make public'))
  is_publicly_visible.help_text = ugettext(
      'If you check here, the content of your proposal will be visible '
      'for others. Please not that they still will not be able to see '
      'any public comments and reviews of the proposal.')
<commit_msg>is_publicly_visible field moved between additional_info and mentor fields.<commit_after>#!/usr/bin/env python2.5
#
# Copyright 2009 the Melange authors.
#
# 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.

"""This module contains the Student Proposal Model.
"""

__authors__ = [
  '"Daniel Hans <daniel.m.hans@gmail.com>',
  '"Lennard de Rijk" <ljvderijk@gmail.com>',
]

from google.appengine.ext import db

from django.utils.translation import ugettext

import soc.models.linkable
import soc.models.mentor
import soc.models.organization
import soc.models.program

# define the [min_score, max_score] and the name for the RankList
DEF_SCORE = [-1000, 1000]
DEF_RANKER_NAME = 'student_app_ranker'

class StudentProposal(soc.models.linkable.Linkable):
  """Model for a student proposal used in the GSoC workflow.
  """

  #: Required field indicating the "title" of the proposal
  title = db.StringProperty(required=True,
      verbose_name=ugettext('Title'))
  title.help_text = ugettext('Title of the proposal')

  #: required, text field used for different purposes,
  #: depending on the specific type of the proposal
  abstract = db.TextProperty(required=True)
  abstract.help_text = ugettext(
      'Short abstract, summary, or snippet;'
      ' 500 characters or less, plain text displayed publicly')

  #: Required field containing the content of the proposal.
  content = db.TextProperty(required=True)
  content.help_text = ugettext('This contains your actual proposal')

  #: an URL linking to more information about this students proposal
  additional_info = db.URLProperty(required=False)
  additional_info.help_text = ugettext(
      'Link to a resource containing more information about your proposal')

  #: indicates whether the proposal's content may be publicly seen or not
  is_publicly_visible = db.BooleanProperty(required=False, default=False,
      verbose_name=ugettext('Make public'))
  is_publicly_visible.help_text = ugettext(
      'If you check here, the content of your proposal will be visible '
      'for others. Please not that they still will not be able to see '
      'any public comments and reviews of the proposal.')

  #: A property containing which mentor has assigned himself to this proposal.
  #: Only a proposal with an assigned mentor can be turned into
  #: a accepted proposal. A proposal can only have one mentor.
  mentor = db.ReferenceProperty(reference_class=soc.models.mentor.Mentor,
                                required=False,
                                collection_name='student_proposals')

  #: A property containing a list of possible Mentors for this proposal
  possible_mentors = db.ListProperty(item_type=db.Key, default=[])

  #: the current score of this proposal, used to determine which proposals
  #: should be assigned a project slot.
  score = db.IntegerProperty(required=True, default=0)

  #: the status of this proposal
  #: new : the proposal has not been ranked/scored yet
  #: pending: the proposal is in the process of being ranked/scored
  #: accepted: the proposal has been assigned a project slot
  #: rejected: the proposal has not been assigned a slot
  #: invalid: the student or org admin marked this as an invalid proposal.
  status = db.StringProperty(required=True, default='new',
      choices=['new', 'pending', 'accepted', 'rejected', 'invalid'])

  #: organization to which this proposal is directed
  org = db.ReferenceProperty(
      reference_class=soc.models.organization.Organization,
      required=True, collection_name='student_proposals')

  #: program in which this proposal has been created
  program = db.ReferenceProperty(reference_class=soc.models.program.Program,
                                 required=True,
                                 collection_name='student_proposals')

  #: date when the proposal was created
  created_on = db.DateTimeProperty(required=True, auto_now_add=True)

  #: date when the proposal was last modified, should be set manually on edit
  last_modified_on = db.DateTimeProperty(required=True, auto_now_add=True)
<|endoftext|>


<commit_before>import SimpleHTTPServer
import SocketServer
import json
import logging
import os
import traceback
import urlparse

import controller

DEPLOYED_PACKAGE = 'build'
DEVELOPMENT_PACKAGE = 'web'

class KCAAHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    GET_OBJECTS = '/get_objects'
    GET_NEW_OBJECTS = '/get_new_objects'
    GET_OBJECT = '/get_object'
    CLICK = '/click'
    RELOAD_KCSAPI = '/reload_kcsapi'
    RELOAD_MANIPULATORS = '/reload_manipulators'
    MANIPULATE = '/manipulate'
    CLIENT_PREFIX = '/client/'

    def do_HEAD(self):
        self.dispatch()

    def do_GET(self):
        self.dispatch()

    def log_message(self, format, *args):
        # Kill verbose HTTP logging.
        return

    def dispatch(self):
        o = urlparse.urlparse(self.path)
        if o.path == KCAAHTTPRequestHandler.GET_OBJECTS:
            self.handle_get_objects(o)
        elif o.path == KCAAHTTPRequestHandler.GET_NEW_OBJECTS:
            self.handle_get_new_objects(o)
        elif o.path == KCAAHTTPRequestHandler.GET_OBJECT:
            self.handle_get_object(o)
        elif o.path == KCAAHTTPRequestHandler.CLICK:
            self.handle_click(o)
        elif o.path == KCAAHTTPRequestHandler.RELOAD_KCSAPI:
            self.handle_reload_kcsapi(o)
        elif o.path == KCAAHTTPRequestHandler.RELOAD_MANIPULATORS:
            self.handle_reload_manipulators(o)
        elif o.path == KCAAHTTPRequestHandler.MANIPULATE:
            self.handle_manipulate(o)
        elif o.path.startswith(KCAAHTTPRequestHandler.CLIENT_PREFIX):
            self.handle_client(o)
        else:
            self.send_error(404, 'Unknown handler: {}'.format(self.path))

    def handle_get_objects(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        self.send_response(200)
        self.send_header('Content-Type', 'text/json; charset=UTF-8')
        self.end_headers()
        self.wfile.write(json.dumps(sorted(list(
            self.server.objects.iterkeys()))))

    def handle_get_new_objects(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        self.send_response(200)
        self.send_header('Content-Type', 'text/json; charset=UTF-8')
        self.end_headers()
        self.wfile.write(json.dumps(sorted(list(self.server.new_objects))))

    def handle_get_object(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        queries = urlparse.parse_qs(o.query)
        try:
            object_type = queries['type']
            if len(object_type) > 1:
                self.send_error(400, 'Parameter type should have only 1 value')
                return
            object_type = object_type[0]
        except KeyError:
            self.send_error(400, 'Missing parameter: type')
            return
        try:
            data = self.server.objects[object_type]
            self.server.new_objects.discard(object_type)
            self.send_response(200)
            self.send_header('Content-Type', 'text/json; charset=UTF-8')
            self.end_headers()
            self.wfile.write(data)
        except KeyError:
            self.send_error(404)

    def handle_click(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        queries = urlparse.parse_qs(o.query)
        try:
            x = int(queries['x'][0])
            y = int(queries['y'][0])
        except KeyError:
            self.send_error(400, 'Missing parameter: x or y')
            return
        self.server.controller_conn.send((controller.COMMAND_CLICK, (x, y)))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_reload_kcsapi(self, o):
        self.server.controller_conn.send(
            (controller.COMMAND_RELOAD_KCSAPI, None))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_reload_manipulators(self, o):
        self.server.controller_conn.send(
            (controller.COMMAND_RELOAD_MANIPULATORS, None))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_manipulate(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        queries = urlparse.parse_qs(o.query)
        try:
            command_type = queries['type'][0]
            del queries['type']
        except KeyError:
            self.send_error(400, 'Missing parameter: type')
            return
        command_args = {}
        for key, values in queries.iteritems():
            if len(values) == 1:
                command_args[key] = values[0]
            else:
                command_args[key] = values
        self.server.controller_conn.send((controller.COMMAND_MANIPULATE,
                                          (command_type, command_args)))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_client(self, o):
        self.path = '/' + o.path[len(KCAAHTTPRequestHandler.CLIENT_PREFIX):]
        # Note: HTTP request handlers are not new-style classes.
        # super() cannot be used.
        if self.command == 'HEAD':
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self)
        elif self.command == 'GET':
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
        else:
            self.send_error(501, 'Unknown method: {}'.format(self.command))

def move_to_client_dir():
    # Change directory to client directory so that SimpleHTTPServer can serve
    # client resources.
    client_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
                                              '..', 'client'))
    if not os.path.isdir(client_dir):
        raise IOError('No client directory found: {}'.format(client_dir))
    os.chdir(client_dir)
    # Use 'build' subdirectory when deployed, or 'web' when being developed.
    if os.path.isdir(DEPLOYED_PACKAGE):
        os.chdir(DEPLOYED_PACKAGE)
    elif os.path.isdir(DEVELOPMENT_PACKAGE):
        os.chdir(DEVELOPMENT_PACKAGE)
    else:
        raise IOError('No client package directories found under {}.'.format(
            client_dir))

def setup(args, logger):
    move_to_client_dir()
    httpd = SocketServer.TCPServer(('', args.server_port),
                                   KCAAHTTPRequestHandler)
    _, port = httpd.server_address
    # Don't use query (something like ?key=value). Kancolle widget detects it
    # from referer and rejects to respond.
    root_url = 'http://localhost:{}/client/'.format(port)
    logger.info('KCAA server ready at {}'.format(root_url))
    return httpd, root_url

def handle_server(args, to_exit, controller_conn):
    try:
        logger = logging.getLogger('kcaa.server')
        httpd, root_url = setup(args, logger)
        httpd.new_objects = set()
        httpd.objects = {}
        httpd.controller_conn = controller_conn
        controller_conn.send(root_url)
        httpd.timeout = 0.1
        while True:
            httpd.handle_request()
            if to_exit.wait(0.0):
                logger.info('Server got an exit signal. Shutting down.')
                break
            while controller_conn.poll():
                object_type, data = controller_conn.recv()
                httpd.new_objects.add(object_type)
                httpd.objects[object_type] = data
    except:
        traceback.print_exc()
    to_exit.set()
<commit_msg>Fix the deployed path so that it works with Dart 1.2.0.<commit_after>import SimpleHTTPServer
import SocketServer
import json
import logging
import os
import traceback
import urlparse

import controller

DEPLOYED_PACKAGE = 'build/web'
DEVELOPMENT_PACKAGE = 'web'

class KCAAHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    GET_OBJECTS = '/get_objects'
    GET_NEW_OBJECTS = '/get_new_objects'
    GET_OBJECT = '/get_object'
    CLICK = '/click'
    RELOAD_KCSAPI = '/reload_kcsapi'
    RELOAD_MANIPULATORS = '/reload_manipulators'
    MANIPULATE = '/manipulate'
    CLIENT_PREFIX = '/client/'

    def do_HEAD(self):
        self.dispatch()

    def do_GET(self):
        self.dispatch()

    def log_message(self, format, *args):
        # Kill verbose HTTP logging.
        return

    def dispatch(self):
        o = urlparse.urlparse(self.path)
        if o.path == KCAAHTTPRequestHandler.GET_OBJECTS:
            self.handle_get_objects(o)
        elif o.path == KCAAHTTPRequestHandler.GET_NEW_OBJECTS:
            self.handle_get_new_objects(o)
        elif o.path == KCAAHTTPRequestHandler.GET_OBJECT:
            self.handle_get_object(o)
        elif o.path == KCAAHTTPRequestHandler.CLICK:
            self.handle_click(o)
        elif o.path == KCAAHTTPRequestHandler.RELOAD_KCSAPI:
            self.handle_reload_kcsapi(o)
        elif o.path == KCAAHTTPRequestHandler.RELOAD_MANIPULATORS:
            self.handle_reload_manipulators(o)
        elif o.path == KCAAHTTPRequestHandler.MANIPULATE:
            self.handle_manipulate(o)
        elif o.path.startswith(KCAAHTTPRequestHandler.CLIENT_PREFIX):
            self.handle_client(o)
        else:
            self.send_error(404, 'Unknown handler: {}'.format(self.path))

    def handle_get_objects(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        self.send_response(200)
        self.send_header('Content-Type', 'text/json; charset=UTF-8')
        self.end_headers()
        self.wfile.write(json.dumps(sorted(list(
            self.server.objects.iterkeys()))))

    def handle_get_new_objects(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        self.send_response(200)
        self.send_header('Content-Type', 'text/json; charset=UTF-8')
        self.end_headers()
        self.wfile.write(json.dumps(sorted(list(self.server.new_objects))))

    def handle_get_object(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        queries = urlparse.parse_qs(o.query)
        try:
            object_type = queries['type']
            if len(object_type) > 1:
                self.send_error(400, 'Parameter type should have only 1 value')
                return
            object_type = object_type[0]
        except KeyError:
            self.send_error(400, 'Missing parameter: type')
            return
        try:
            data = self.server.objects[object_type]
            self.server.new_objects.discard(object_type)
            self.send_response(200)
            self.send_header('Content-Type', 'text/json; charset=UTF-8')
            self.end_headers()
            self.wfile.write(data)
        except KeyError:
            self.send_error(404)

    def handle_click(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        queries = urlparse.parse_qs(o.query)
        try:
            x = int(queries['x'][0])
            y = int(queries['y'][0])
        except KeyError:
            self.send_error(400, 'Missing parameter: x or y')
            return
        self.server.controller_conn.send((controller.COMMAND_CLICK, (x, y)))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_reload_kcsapi(self, o):
        self.server.controller_conn.send(
            (controller.COMMAND_RELOAD_KCSAPI, None))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_reload_manipulators(self, o):
        self.server.controller_conn.send(
            (controller.COMMAND_RELOAD_MANIPULATORS, None))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_manipulate(self, o):
        if self.command != 'GET':
            self.send_error(501, 'Unknown method: {}'.format(self.command))
            return
        queries = urlparse.parse_qs(o.query)
        try:
            command_type = queries['type'][0]
            del queries['type']
        except KeyError:
            self.send_error(400, 'Missing parameter: type')
            return
        command_args = {}
        for key, values in queries.iteritems():
            if len(values) == 1:
                command_args[key] = values[0]
            else:
                command_args[key] = values
        self.server.controller_conn.send((controller.COMMAND_MANIPULATE,
                                          (command_type, command_args)))
        self.send_response(200)
        self.send_header('Content-Type', 'text/plain')
        self.end_headers()
        self.wfile.write('success')

    def handle_client(self, o):
        self.path = '/' + o.path[len(KCAAHTTPRequestHandler.CLIENT_PREFIX):]
        # Note: HTTP request handlers are not new-style classes.
        # super() cannot be used.
        if self.command == 'HEAD':
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_HEAD(self)
        elif self.command == 'GET':
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
        else:
            self.send_error(501, 'Unknown method: {}'.format(self.command))

def move_to_client_dir():
    # Change directory to client directory so that SimpleHTTPServer can serve
    # client resources.
    client_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
                                              '..', 'client'))
    if not os.path.isdir(client_dir):
        raise IOError('No client directory found: {}'.format(client_dir))
    os.chdir(client_dir)
    # Use 'build' subdirectory when deployed, or 'web' when being developed.
    if os.path.isdir(DEPLOYED_PACKAGE):
        os.chdir(DEPLOYED_PACKAGE)
    elif os.path.isdir(DEVELOPMENT_PACKAGE):
        os.chdir(DEVELOPMENT_PACKAGE)
    else:
        raise IOError('No client package directories found under {}.'.format(
            client_dir))

def setup(args, logger):
    move_to_client_dir()
    httpd = SocketServer.TCPServer(('', args.server_port),
                                   KCAAHTTPRequestHandler)
    _, port = httpd.server_address
    # Don't use query (something like ?key=value). Kancolle widget detects it
    # from referer and rejects to respond.
    root_url = 'http://localhost:{}/client/'.format(port)
    logger.info('KCAA server ready at {}'.format(root_url))
    return httpd, root_url

def handle_server(args, to_exit, controller_conn):
    try:
        logger = logging.getLogger('kcaa.server')
        httpd, root_url = setup(args, logger)
        httpd.new_objects = set()
        httpd.objects = {}
        httpd.controller_conn = controller_conn
        controller_conn.send(root_url)
        httpd.timeout = 0.1
        while True:
            httpd.handle_request()
            if to_exit.wait(0.0):
                logger.info('Server got an exit signal. Shutting down.')
                break
            while controller_conn.poll():
                object_type, data = controller_conn.recv()
                httpd.new_objects.add(object_type)
                httpd.objects[object_type] = data
    except:
        traceback.print_exc()
    to_exit.set()
<|endoftext|>


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

""" Tools for checking and generating prime numbers. """

import math

def is_prime(num):
    """ Test if a number is prime. """
    if num < 2:
        return False

    # take advantage of the speedup gained by only checking the sqrt
    sqrt = int(math.sqrt(num))

    # use xrange to generate the list as we iterate
    # use sqrt + 1 to handle smaller composites where the sqrt is 2.
    # we need an initial case to test fail out as False.
    for i in xrange(2, sqrt + 1):
        if num % i == 0:
            return False

    return True

def generate_list_of_primes(min, max):
    """ Given a min and max generate all the primes in that range. """
    assert max > min, "min %s is > than max %s" % (min, max)

    primes = []

    for x in xrange(min, max):
        if is_prime(x):
            primes.append(x)

    return primes

if __name__ == "__main__":
    # check for some simple prime and not prime numbers
    assert not is_prime(1), "1 should not be prime"
    assert is_prime(5), "5 should be prime"
    assert not is_prime(6), "6 should not be prime"
    assert not is_prime(100), "100 should be be prime"
    assert not is_prime(1000), "1000 should not be prime"

    # check the primes from the problem 49 example
    assert is_prime(1487), "1487 should be prime"
    assert is_prime(4817), "4817 should be prime"
    assert is_prime(8147), "8147 should be prime"

    for num in generate_list_of_primes(1, 100):
        assert is_prime(num), "%s should be prime" % num

    for num in generate_list_of_primes(1000, 9999):
        assert is_prime(num), "%s should be prime" % num

    print "all assertions passed"
<commit_msg>Add a function to check for circular primes.<commit_after>#!/usr/bin/env python

""" Tools for checking and generating prime numbers. """

import math

def is_prime(num):
    """ Test if a number is prime. """
    if num < 2:
        return False

    # take advantage of the speedup gained by only checking the sqrt
    sqrt = int(math.sqrt(num))

    # use xrange to generate the list as we iterate
    # use sqrt + 1 to handle smaller composites where the sqrt is 2.
    # we need an initial case to test fail out as False.
    for i in xrange(2, sqrt + 1):
        if num % i == 0:
            return False

    return True

def is_circular_prime(num):
    """ Check if a number is a circular prime. """

    # check the single digit circular primes
    if num in [2, 3, 5, 7]:
        return True

    num_str = str(num)

    # bail early if it is divisible by 2 or 5
    if num % 2 == 0 or num % 5 == 5:
        return False

    # check tif the rotations are prime
    for digit in num_str:
        front = num_str[0]
        num_str = num_str[1:] + front
        if not is_prime(int(num_str)):
            return False

    return True

def generate_list_of_primes(min, max):
    """ Given a min and max generate all the primes in that range. """
    assert max > min, "min %s is > than max %s" % (min, max)

    primes = []

    for x in xrange(min, max):
        if is_prime(x):
            primes.append(x)

    return primes

if __name__ == "__main__":
    # check for some simple prime and not prime numbers
    assert not is_prime(1), "1 should not be prime"
    assert is_prime(5), "5 should be prime"
    assert not is_prime(6), "6 should not be prime"
    assert not is_prime(100), "100 should be be prime"
    assert not is_prime(1000), "1000 should not be prime"

    # check the primes from the problem 49 example
    assert is_prime(1487), "1487 should be prime"
    assert is_prime(4817), "4817 should be prime"
    assert is_prime(8147), "8147 should be prime"

    # check some circular primes
    assert is_circular_prime(197), "197 should be circular"
    assert is_circular_prime(2), "2 should be circular"
    assert is_circular_prime(3), "3 should be circular"
    assert is_circular_prime(5), "5 should be circular"
    assert is_circular_prime(7), "7 should be circular"
    assert is_circular_prime(11), "11 should be circular"
    assert is_circular_prime(13), "13 should be circular"
    assert is_circular_prime(17), "17 should be circular"
    assert is_circular_prime(31), "31 should be circular"
    assert is_circular_prime(37), "37 should be circular"
    assert is_circular_prime(71), "71 should be circular"
    assert is_circular_prime(73), "73 should be circular"
    assert is_circular_prime(79), "79 should be circular"
    assert is_circular_prime(97), "97 should be circular"

    for num in generate_list_of_primes(1, 100):
        assert is_prime(num), "%s should be prime" % num

    for num in generate_list_of_primes(1000, 9999):
        assert is_prime(num), "%s should be prime" % num

    print "all assertions passed"
<|endoftext|>


<commit_before>###### PRIORS ########
#
# Definitions for various prior functions
#
#
#
#
#
#
import scipy.stats
import numpy

def flatprior(x, xmin=None, xmax = None):

    if xmin == None and xmax == None:
        return gaussprior(x, 0.0, 1000.0)
    elif xmin == None and not xmax == None:
        xswitch = (x <= xmax)
        if xswitch:
            return gaussprior(x, 0.0, 1000.0)/2.0
        else:
            return 0.0
    elif xmax == None and not xmin == None:
        xswitch (x >= xmin)
        if xswitch:
            return(gaussprior(x, 0.0, 1000.0)/2.0
        else:
            return 0.0
    else:
        xswitch = (xmin <= x and x <= xmax)
        if xswitch:
            return 1.0/(xmax - xmin)
        else:
            return 0.0

def gaussprior(x, mean, sigma):
    px = scipy.stats.norm.pdf(x, mea sigma)
    return px

<commit_msg>Old version of priors.py<commit_after>###### PRIORS ########
#
# Definitions for various prior functions
#
#
#
#
#
#
import scipy.stats
import numpy

def flatprior(x, xmin=None, xmax = None):

    if xmin == None and xmax == None:
        return gaussprior(x, 0.0, 1000.0)
    elif xmin == None and not xmax == None:
        xswitch = (x <= xmax)
        if xswitch:
            return gaussprior(x, 0.0, 1000.0)/2.0
        else:
            return 0.0

    elif xmax == None and not xmin == None:
        xswitch = (x >= xmin)
        if xswitch:
            return gaussprior(x, 0.0, 1000.0)/2.0
        else:
            return 0.0

#    elif xmax == None and not xmin == None:
#        xswitch = (x >= xmin)
#        if xswitch:
#            return gaussprior(x, 0.0, 1000.0)/2.0
#        else:
#            return 0.0
    else:
        xswitch = (xmin <= x and x <= xmax)
        if xswitch:
            return 1.0/(xmax - xmin)
        else:
            return 0.0

def gaussprior(x, mean, sigma):
    px = scipy.stats.norm.pdf(x, mean, sigma)
    return px

<|endoftext|>


<commit_before>import threading
import sys
from select import select
sys.path.insert(0, '../mars')
import run as Mars #note as long as __main__ is defined this will write a usage violation to the console

MARS_EXIT_COMMAND = 'exit'

class MarsThread(threading.Thread):
    '''
    The idea here is that the client will connect
    And we want to keep mars chugging when the client losses connection.
    We want to easily reconnnect, so we stick with queues here, mars won't stop
    until mars is explicitly stopped or watchdog stop is triggered
    '''
    def __init__(self, configuration, marsCommandQueue, marsConnectionQueue, marsOnlineQueue, debugEnabled = False):
        super(MarsThread, self).__init__()
        self._stop = threading.Event()

        self.config = configuration
        self.marsCommandQueue = marsCommandQueue
        self.marsConnectionQueue = marsConnectionQueue
        self.marsOnlineQueue = marsOnlineQueue
        self.debugEnabled = debugEnabled

    def run(self):
        Mars.run(self.config, self.marsCommandQueue, self.marsConnectionQueue, self.marsOnlineQueue, self.debugEnabled)

    def stop(self):
        self.marsCommandQueue.put(MARS_EXIT_COMMAND)
<commit_msg>Fix the marsHandler so it wont make infinite loghandlers<commit_after>import threading
import sys
import logging
from select import select
sys.path.insert(0, '../mars')
import run as Mars #note as long as __main__ is defined this will write a usage violation to the console

MARS_EXIT_COMMAND = 'exit'

class MarsThread(threading.Thread):
    '''
    The idea here is that the client will connect
    And we want to keep mars chugging when the client losses connection.
    We want to easily reconnnect, so we stick with queues here, mars won't stop
    until mars is explicitly stopped or watchdog stop is triggered
    '''
    def __init__(self, configuration, marsCommandQueue, marsConnectionQueue, marsOnlineQueue, debugEnabled = False):
        super(MarsThread, self).__init__()
        self._stop = threading.Event()

        self.config = configuration
        self.marsCommandQueue = marsCommandQueue
        self.marsConnectionQueue = marsConnectionQueue
        self.marsOnlineQueue = marsOnlineQueue
        self.debugEnabled = debugEnabled

    def run(self):
        Mars.run(self.config, self.marsCommandQueue, self.marsConnectionQueue, self.marsOnlineQueue, self.debugEnabled)
        '''
        Here we are on death. Usually Because mars quit, we would expect all logging to stop,
        but it persists because we still have the server up.
        To prevent logging handlers from just getting indefinitely larger, we remove them all on quit of mars
        '''
        debugLog = logging.getLogger('mars_logging')
        telemetryLog = logging.getLogger('telemetry_logging')
        debugLog.handlers = []
        telemetryLog.handlers = []
    def stop(self):
        self.marsCommandQueue.put(MARS_EXIT_COMMAND)
<|endoftext|>


<commit_before>import sys
import os
import socket
import ssl
import httplib
import urlparse
import threading
import gzip
import zlib
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
from cStringIO import StringIO
from subprocess import Popen, PIPE

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
    address_family = socket.AF_INET6

    def handle_error(self, request, client_address):
        # surpress SSL related errors
        pass

class ProxyRequestHandler(BaseHTTPRequestHandler):
    cakey = 'ca.key'
    cacert = 'ca.crt'
    certkey = 'cert.key'
    certdir = 'certs/'
    timeout = 5
    lock = threading.Lock()

    def __init__(self, *args, **kwargs):
        self.tls = threading.local()
        self.tls.conns = {}

        BaseHTTPRequestHandler.__init__(self, *args, **kwargs)

    def log_error(self, format, *args):
        # surpress "Request timed out: timeout('timed out',)"
        if isinstance(args[0], socket.timeout):
            return

        self.log_message(format, *args)

    def do_CONNECT(self):
        path = "https://%s/" % self.path.replace(':443', '')
        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, 200, 'Connection Established'))
        self.end_headers()

        if not os.path.isdir(self.certdir):
            os.makedirs(self.certdir)
        u = urlparse.urlsplit(path)
        certpath = "%s/%s.crt" % (self.certdir.rstrip('/'), u.hostname)

        with self.lock:
            if not os.path.isfile(certpath):
                p1 = Popen(["openssl", "req", "-new", "-key", self.certkey, "-subj", "/CN=%s" % u.hostname], stdout=PIPE)
                p2 = Popen(["openssl", "x509", "-req", "-days", "3650", "-CA", self.cacert, "-CAkey", self.cakey, "-CAcreateserial", "-out", certpath], stdin=p1.stdout, stderr=PIPE)
                p2.communicate()

        self.connection = ssl.wrap_socket(self.connection, keyfile=self.certkey, certfile=certpath, server_side=True)
        self.rfile = self.connection.makefile("rb", self.rbufsize)
        self.wfile = self.connection.makefile("wb", self.wbufsize)

        self.https_origin = path.rstrip('/')

    def do_GET(self):
        if self.command == 'GET' and self.path == 'http://proxy2.test/':
            self.send_cacert()
            return

        req = self
        content_length = int(req.headers.get('Content-Length', 0))
        req_body = self.rfile.read(content_length) if content_length else None

        if hasattr(self, 'https_origin'):
            req.path = self.https_origin + req.path

        req_body_modified = self.request_handler(req, req_body)
        if req_body_modified is not None:
            req_body = req_body_modified
            req.headers['Content-length'] = str(len(req_body))

        u = urlparse.urlsplit(self.path)
        scheme, host, path = u.scheme, u.netloc, (u.path + '?' + u.query if u.query else u.path)
        assert scheme in ('http', 'https')
        if host:
            req.headers['Host'] = host
        req_headers = self.filter_headers(req.headers)

        try:
            if not host in self.tls.conns:
                if scheme == 'https':
                    self.tls.conns[host] = httplib.HTTPSConnection(host, timeout=self.timeout)
                else:
                    self.tls.conns[host] = httplib.HTTPConnection(host, timeout=self.timeout)
            conn = self.tls.conns[host]
            conn.request(self.command, path, req_body, dict(req_headers))
            res = conn.getresponse()
            setattr(res, 'headers', res.msg)
            res_body = res.read()
        except Exception as e:
            self.send_response(502, 'Bad Gateway')
            self.send_header('Content-Type', 'text/html')
            self.send_header('Connection', 'close')
            self.end_headers()
            print >>self.wfile, "<!DOCTYPE html><title>502 Bad Gateway</title>
%s: %s
" % (type(e).__name__, e)
            if host in self.tls.conns:
                del self.tls.conns[host]
            return

        content_encoding = res.headers.get('Content-Encoding', 'identity')
        res_body_plain = self.decode_content_body(res_body, content_encoding)

        res_body_modified = self.response_handler(req, req_body, res, res_body_plain)
        if res_body_modified is not None:
            res_body_plain = res_body_modified
            res_body = self.encode_content_body(res_body_plain, content_encoding)
            res.headers['Content-Length'] = str(len(res_body))

        res_headers = self.filter_headers(res.headers)

        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, res.status, res.reason))
        for line in res_headers.headers:
            self.wfile.write(line)
        self.end_headers()
        self.wfile.write(res_body)
        self.wfile.flush()

        with self.lock:
            self.save_handler(req, req_body, res, res_body_plain)

    do_HEAD = do_GET
    do_POST = do_GET

    def filter_headers(self, headers):
        # http://tools.ietf.org/html/rfc2616#section-13.5.1
        hop_by_hop = ('connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 'upgrade')
        for k in hop_by_hop:
            del headers[k]
        return headers

    def encode_content_body(self, text, encoding):
        if encoding in ('gzip', 'x-gzip'):
            io = StringIO()
            with gzip.GzipFile(fileobj=io, mode='wb') as f:
                f.write(text)
            data = io.getvalue()
        elif encoding == 'deflate':
            data = zlib.compress(text)
        elif encoding == 'identity':
            data = text
        else:
            raise Exception("Unknown Content-Encoding: %s" % encoding)
        return data

    def decode_content_body(self, data, encoding):
        if encoding in ('gzip', 'x-gzip'):
            io = StringIO(data)
            with gzip.GzipFile(fileobj=io) as f:
                text = f.read()
        elif encoding == 'deflate':
            text = zlib.decompress(data)
        elif encoding == 'identity':
            text = data
        else:
            raise Exception("Unknown Content-Encoding: %s" % encoding)
        return text

    def send_cacert(self):
        with open(self.cacert, 'rb') as f:
            data = f.read()

        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, 200, 'OK'))
        self.send_header('Content-Type', 'application/x-x509-ca-cert')
        self.send_header('Content-Length', len(data))
        self.send_header('Connection', 'close')
        self.end_headers()
        self.wfile.write(data)

    def request_handler(self, req, req_body):
        pass

    def response_handler(self, req, req_body, res, res_body):
        pass

    def save_handler(self, req, req_body, res, res_body):
        version_table = {10: 'HTTP/1.0', 11: 'HTTP/1.1'}

        print "%s%s %s %s\n%s%s" % ('\x1b[33m', req.command, req.path, req.request_version, req.headers, '\x1b[0m')
        if req_body is not None:
            print "%s%r%s\n" % ('\x1b[32m', req_body[:1024], '\x1b[0m')
        print "%s%s %d %s\n%s%s" % ('\x1b[36m', version_table[res.version], res.status, res.reason, res.headers, '\x1b[0m')

def test(HandlerClass = ProxyRequestHandler, ServerClass = ThreadingHTTPServer, protocol="HTTP/1.1"):
    if sys.argv[1:]:
        port = int(sys.argv[1])
    else:
        port = 8080
    server_address = ('', port)

    HandlerClass.protocol_version = protocol
    httpd = ServerClass(server_address, HandlerClass)

    sa = httpd.socket.getsockname()
    print "Serving HTTP Proxy on", sa[0], "port", sa[1], "..."
    httpd.serve_forever()

if __name__ == '__main__':
    test()
<commit_msg>use epoch time as the serial number of generated certificate<commit_after>import sys
import os
import socket
import ssl
import httplib
import urlparse
import threading
import gzip
import zlib
import time
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
from cStringIO import StringIO
from subprocess import Popen, PIPE

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
    address_family = socket.AF_INET6

    def handle_error(self, request, client_address):
        # surpress SSL related errors
        pass

class ProxyRequestHandler(BaseHTTPRequestHandler):
    cakey = 'ca.key'
    cacert = 'ca.crt'
    certkey = 'cert.key'
    certdir = 'certs/'
    timeout = 5
    lock = threading.Lock()

    def __init__(self, *args, **kwargs):
        self.tls = threading.local()
        self.tls.conns = {}

        BaseHTTPRequestHandler.__init__(self, *args, **kwargs)

    def log_error(self, format, *args):
        # surpress "Request timed out: timeout('timed out',)"
        if isinstance(args[0], socket.timeout):
            return

        self.log_message(format, *args)

    def do_CONNECT(self):
        path = "https://%s/" % self.path.replace(':443', '')
        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, 200, 'Connection Established'))
        self.end_headers()

        if not os.path.isdir(self.certdir):
            os.makedirs(self.certdir)
        u = urlparse.urlsplit(path)
        certpath = "%s/%s.crt" % (self.certdir.rstrip('/'), u.hostname)

        with self.lock:
            if not os.path.isfile(certpath):
                epoch = "%d" % (time.time() * 1000)
                p1 = Popen(["openssl", "req", "-new", "-key", self.certkey, "-subj", "/CN=%s" % u.hostname], stdout=PIPE)
                p2 = Popen(["openssl", "x509", "-req", "-days", "3650", "-CA", self.cacert, "-CAkey", self.cakey, "-set_serial", epoch, "-out", certpath], stdin=p1.stdout, stderr=PIPE)
                p2.communicate()

        self.connection = ssl.wrap_socket(self.connection, keyfile=self.certkey, certfile=certpath, server_side=True)
        self.rfile = self.connection.makefile("rb", self.rbufsize)
        self.wfile = self.connection.makefile("wb", self.wbufsize)

        self.https_origin = path.rstrip('/')

    def do_GET(self):
        if self.command == 'GET' and self.path == 'http://proxy2.test/':
            self.send_cacert()
            return

        req = self
        content_length = int(req.headers.get('Content-Length', 0))
        req_body = self.rfile.read(content_length) if content_length else None

        if hasattr(self, 'https_origin'):
            req.path = self.https_origin + req.path

        req_body_modified = self.request_handler(req, req_body)
        if req_body_modified is not None:
            req_body = req_body_modified
            req.headers['Content-length'] = str(len(req_body))

        u = urlparse.urlsplit(self.path)
        scheme, host, path = u.scheme, u.netloc, (u.path + '?' + u.query if u.query else u.path)
        assert scheme in ('http', 'https')
        if host:
            req.headers['Host'] = host
        req_headers = self.filter_headers(req.headers)

        try:
            if not host in self.tls.conns:
                if scheme == 'https':
                    self.tls.conns[host] = httplib.HTTPSConnection(host, timeout=self.timeout)
                else:
                    self.tls.conns[host] = httplib.HTTPConnection(host, timeout=self.timeout)
            conn = self.tls.conns[host]
            conn.request(self.command, path, req_body, dict(req_headers))
            res = conn.getresponse()
            setattr(res, 'headers', res.msg)
            res_body = res.read()
        except Exception as e:
            self.send_response(502, 'Bad Gateway')
            self.send_header('Content-Type', 'text/html')
            self.send_header('Connection', 'close')
            self.end_headers()
            print >>self.wfile, "<!DOCTYPE html><title>502 Bad Gateway</title>
%s: %s
" % (type(e).__name__, e)
            if host in self.tls.conns:
                del self.tls.conns[host]
            return

        content_encoding = res.headers.get('Content-Encoding', 'identity')
        res_body_plain = self.decode_content_body(res_body, content_encoding)

        res_body_modified = self.response_handler(req, req_body, res, res_body_plain)
        if res_body_modified is not None:
            res_body_plain = res_body_modified
            res_body = self.encode_content_body(res_body_plain, content_encoding)
            res.headers['Content-Length'] = str(len(res_body))

        res_headers = self.filter_headers(res.headers)

        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, res.status, res.reason))
        for line in res_headers.headers:
            self.wfile.write(line)
        self.end_headers()
        self.wfile.write(res_body)
        self.wfile.flush()

        with self.lock:
            self.save_handler(req, req_body, res, res_body_plain)

    do_HEAD = do_GET
    do_POST = do_GET

    def filter_headers(self, headers):
        # http://tools.ietf.org/html/rfc2616#section-13.5.1
        hop_by_hop = ('connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 'upgrade')
        for k in hop_by_hop:
            del headers[k]
        return headers

    def encode_content_body(self, text, encoding):
        if encoding in ('gzip', 'x-gzip'):
            io = StringIO()
            with gzip.GzipFile(fileobj=io, mode='wb') as f:
                f.write(text)
            data = io.getvalue()
        elif encoding == 'deflate':
            data = zlib.compress(text)
        elif encoding == 'identity':
            data = text
        else:
            raise Exception("Unknown Content-Encoding: %s" % encoding)
        return data

    def decode_content_body(self, data, encoding):
        if encoding in ('gzip', 'x-gzip'):
            io = StringIO(data)
            with gzip.GzipFile(fileobj=io) as f:
                text = f.read()
        elif encoding == 'deflate':
            text = zlib.decompress(data)
        elif encoding == 'identity':
            text = data
        else:
            raise Exception("Unknown Content-Encoding: %s" % encoding)
        return text

    def send_cacert(self):
        with open(self.cacert, 'rb') as f:
            data = f.read()

        self.wfile.write("%s %d %s\r\n" % (self.protocol_version, 200, 'OK'))
        self.send_header('Content-Type', 'application/x-x509-ca-cert')
        self.send_header('Content-Length', len(data))
        self.send_header('Connection', 'close')
        self.end_headers()
        self.wfile.write(data)

    def request_handler(self, req, req_body):
        pass

    def response_handler(self, req, req_body, res, res_body):
        pass

    def save_handler(self, req, req_body, res, res_body):
        version_table = {10: 'HTTP/1.0', 11: 'HTTP/1.1'}

        print "%s%s %s %s\n%s%s" % ('\x1b[33m', req.command, req.path, req.request_version, req.headers, '\x1b[0m')
        if req_body is not None:
            print "%s%r%s\n" % ('\x1b[32m', req_body[:1024], '\x1b[0m')
        print "%s%s %d %s\n%s%s" % ('\x1b[36m', version_table[res.version], res.status, res.reason, res.headers, '\x1b[0m')

def test(HandlerClass = ProxyRequestHandler, ServerClass = ThreadingHTTPServer, protocol="HTTP/1.1"):
    if sys.argv[1:]:
        port = int(sys.argv[1])
    else:
        port = 8080
    server_address = ('', port)

    HandlerClass.protocol_version = protocol
    httpd = ServerClass(server_address, HandlerClass)

    sa = httpd.socket.getsockname()
    print "Serving HTTP Proxy on", sa[0], "port", sa[1], "..."
    httpd.serve_forever()

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


<commit_before>def gmtColormap(palette):
      from matplotlib.colors import LinearSegmentedColormap,Normalize
      import colorsys
      import numpy as N
      try:
          f = open('/home/nicolasf/pythonlibs/GMTcolormaps/' + palette + '.cpt')
      except:
          print "file " + palette + ".cpt not found"
          return None

      lines = f.readlines()
      f.close()

      x = []
      r = []
      g = []
      b = []
      colorModel = "RGB"
      for l in lines:
          ls = l.split()
          if l[0] == "#":
             if ls[-1] == "HSV":
                 colorModel = "HSV"
                 continue
             else:
                 continue
          if ls[0] == "B" or ls[0] == "F" or ls[0] == "N":
             pass
          else:
              x.append(float(ls[0]))
              r.append(float(ls[1]))
              g.append(float(ls[2]))
              b.append(float(ls[3]))
              xtemp = float(ls[4])
              rtemp = float(ls[5])
              gtemp = float(ls[6])
              btemp = float(ls[7])

      x.append(xtemp)
      r.append(rtemp)
      g.append(gtemp)
      b.append(btemp)

      nTable = len(r)
      x = N.array( x , N.float32)
      r = N.array( r , N.float32)
      g = N.array( g , N.float32)
      b = N.array( b , N.float32)
      if colorModel == "HSV":
         for i in range(r.shape[0]):
             rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i])
             r[i] = rr ; g[i] = gg ; b[i] = bb
      if colorModel == "HSV":
         for i in range(r.shape[0]):
             rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i])
             r[i] = rr ; g[i] = gg ; b[i] = bb
      if colorModel == "RGB":
          r = r/255.
          g = g/255.
          b = b/255.
      xNorm = (x - x[0])/(x[-1] - x[0])

      red = []
      blue = []
      green = []
      for i in range(len(x)):
          red.append([xNorm[i],r[i],r[i]])
          green.append([xNorm[i],g[i],g[i]])
          blue.append([xNorm[i],b[i],b[i]])
      colorDict = {"red":red, "green":green, "blue":blue}
      matcmap = LinearSegmentedColormap('my_colormap',colorDict)
      return matcmap

def cmap_map(function,cmap):
    from numpy import array
    import matplotlib
    """ Applies function (which should operate on vectors of shape 3:
    [r, g, b], on colormap cmap. This routine will break any discontinuous     points in a colormap.
    """
    cdict = cmap._segmentdata
    step_dict = {}
    # Firt get the list of points where the segments start or end
    for key in ('red','green','blue'):         step_dict[key] = map(lambda x: x[0], cdict[key])
    step_list = sum(step_dict.values(), [])
    step_list = array(list(set(step_list)))
    # Then compute the LUT, and apply the function to the LUT
    reduced_cmap = lambda step : array(cmap(step)[0:3])
    old_LUT = array(map( reduced_cmap, step_list))
    new_LUT = array(map( function, old_LUT))
    # Now try to make a minimal segment definition of the new LUT
    cdict = {}
    for i,key in enumerate(('red','green','blue')):
        this_cdict = {}
        for j,step in enumerate(step_list):
            if step in step_dict[key]:
                this_cdict[step] = new_LUT[j,i]
            elif new_LUT[j,i]!=old_LUT[j,i]:
                this_cdict[step] = new_LUT[j,i]
        colorvector=  map(lambda x: x + (x[1], ), this_cdict.items())
        colorvector.sort()
        cdict[key] = colorvector

    return matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024)

def reverse(cmap):
    from colormaps_functions import cmap_map
    cmap_r = cmap_map(lambda x: x[::-1], cmap)
    return(cmap_r)

def cmap_discretize(cmap, N):
	"""
	Return a discrete colormap from the continuous colormap cmap.

	cmap: colormap instance, eg. cm.jet.
	N: Number of colors.

	Example
	x = resize(arange(100), (5,100))
	djet = cmap_discretize(cm.jet, 5)
	imshow(x, cmap=djet)
	"""
	import numpy as np
	from pylab import interp
	import pylab as pl
	import pylab as plt

	cdict = cmap._segmentdata.copy()
	# N colors
	colors_i = np.linspace(0,1.,N)
	# N+1 indices
	indices = np.linspace(0,1.,N+1)
	for key in ('red','green','blue'):
		# Find the N colors
		D = np.array(cdict[key])
		#I = interpolate.interp1d(D[:,0], D[:,1])
		#I = interpolate.interp1d(D[:,0],D[:,1])
		colors = interp(colors_i,D[:,0],D[:,1])
		# Place these colors at the correct indices.
		A = np.zeros((N+1,3), float)
		A[:,0] = indices
		A[1:,1] = colors
		A[:-1,2] = colors
		# Create a tuple for the dictionary.
		L = []
		for l in A:
			L.append(tuple(l))
		cdict[key] = tuple(L)
	# Return colormap object.
	return plt.matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024)

def clisttomapdict(clist,name='myColorMap', number=256):
      from matplotlib import colors
      nColors = len(clist)
      red = []
      blue = []
      green = []
      delta = 1.0/(nColors-1)
      for n in range(nColors):
          red.append([n*delta, clist[n][0],clist[n][0]])
          green.append([n*delta, clist[n][1],clist[n][1]])
          blue.append([n*delta, clist[n][2],clist[n][2]])
      cmDict = {'red':red,'green':green,'blue':blue}
      return (colors.LinearSegmentedColormap(name,cmDict,number))

def textfiletoarray(file_name,numberOfHeaderLines=0):
     import numpy
     import string
     try:
        f = open(file_name,'r')
     except:
        print ' file not opened ',file_name
        return(None)
     lines = f.readlines()
     i = len(lines)
     j = len(string.split(lines[numberOfHeaderLines]))
     array = numpy.zeros((i-numberOfHeaderLines,j), float)
     xx = 0
     e = None
     for x in range(numberOfHeaderLines,i):
         for y in range(0,j):
                try:
                   array[xx:xx+1, y:y+1] = string.atof(string.split(lines[x])[y])
                except ValueError:
                   new = array[:xx,:]
                   f.close()
                   return new
         xx = xx + 1
     f.close()
     return(array)

def readnclcolormaps(fileName, Path='/home/nicolasf/pythonlibs/NCLcolormaps',returnAs='colorMap',alpha=1.):
      from os.path import exists
      from glob import glob
      from colormaps_functions import clisttomapdict, textfiletoarray
      filePath = Path + '/' + fileName+'.rgb'
      if not exists(filePath):
          print 'file not found ',filePath
          print 'Possible  ones are '
          flist = glob(Path+'/*.rgb')
          for l in flist:
              print l
          return None
      a = textfiletoarray(filePath,numberOfHeaderLines=2)
      clist = []
      for i in range(a.shape[0]):
          c = (a[i,0]/255,a[i,1]/255,a[i,2]/255,alpha)
          clist.append(c)
      if returnAs == 'listOfTuples':
          return clist
      elif returnAs == 'colorMap':
          cmap = clisttomapdict(clist,fileName)
          return cmap
      else:
          print 'return type not recognized'
          return None

def loadCCPLOTcolormap(filename):
    import os
    import numpy as np
    import matplotlib as mpl
    """"Returns a tuple of matplotlib colormap, matplotlib norm,
    and a list of ticks loaded from the file filename in format:

    BOUNDS
    from1 to1 step1
    from2 to2 step2
    ...

    TICKS
    from1 to1 step1
    from2 to2 step2

    COLORS
    r1 g1 b1
    r2 g2 b2
    ...

    UNDER_OVER_BAD_COLORS
    ro go bo
    ru gu bu
    rb gb bb

    Where fromn, ton, stepn are floating point numbers as would be supplied
    to numpy.arange, and rn, gn, bn are the color components the n-th color
    stripe. Components are expected to be in base10 format (0-255).
    UNDER_OVER_BAD_COLORS section specifies colors to be used for
    over, under and bad (masked) values in that order.

    Arguments:
        filename    -- name of the colormap file
        name        -- name for the matplotlib colormap object

    Returns:
        A tuple of: instance of ListedColormap, instance of BoundaryNorm, ticks.
    """
    path = '/home/nicolasf/pythonlibs/CCPLOTcolormaps/'

    bounds = []
    ticks = []
    rgbarray = []
    specials = []
    mode = "COLORS"

    fp = None
    try:
        fp = open(os.path.join(path, filename), "r")
    except IOError:
        print "File not found"
    lines = fp.readlines()
    for n, s in enumerate(lines):
        s = s.strip()
        if len(s) == 0: continue
        if s in ("BOUNDS", "TICKS", "COLORS", "UNDER_OVER_BAD_COLORS"):
            mode = s
            continue

        a = s.split()
        if len(a) not in (3, 4):
            raise ValueError("Invalid number of fields")

        if mode == "BOUNDS":
            bounds += list(np.arange(float(a[0]), float(a[1]), float(a[2])))
        elif mode == "TICKS":
            ticks += list(np.arange(float(a[0]), float(a[1]), float(a[2])))
        elif mode == "COLORS":
            rgba = [int(c)/256.0 for c in a]
            if len(rgba) == 3: rgba.append(1)
            rgbarray.append(rgba)
        elif mode == "UNDER_OVER_BAD_COLORS":
            rgba = [int(c)/256.0 for c in a]
            if len(rgba) == 3: rgba.append(1)
            specials.append(rgba)
    if (len(rgbarray) > 0):
        colormap = mpl.colors.ListedColormap(rgbarray)
        try:
            colormap.set_under(specials[0][:3], specials[0][3])
            colormap.set_over(specials[1][:3], specials[1][3])
            colormap.set_bad(specials[2][:3], specials[2][3])
        except IndexError: pass
    else:
        colormap = None

    if len(bounds) == 0:
        norm = None
    else:
        norm = mpl.colors.BoundaryNorm(bounds, colormap.N)
    if len(ticks) == 0: ticks = None
    return (colormap, norm, ticks)
<commit_msg>added colormaps_functions.py<commit_after>import os

def gmtColormap(palette):
      from matplotlib.colors import LinearSegmentedColormap,Normalize
      import colorsys
      import numpy as N
      try:
          f = open(os.path.join(os.environ['HOME']), 'pythonlibs/GMTcolormaps/', palette,'.cpt' )
      except:
          print "file " + palette + ".cpt not found"
          return None

      lines = f.readlines()
      f.close()

      x = []
      r = []
      g = []
      b = []
      colorModel = "RGB"
      for l in lines:
          ls = l.split()
          if l[0] == "#":
             if ls[-1] == "HSV":
                 colorModel = "HSV"
                 continue
             else:
                 continue
          if ls[0] == "B" or ls[0] == "F" or ls[0] == "N":
             pass
          else:
              x.append(float(ls[0]))
              r.append(float(ls[1]))
              g.append(float(ls[2]))
              b.append(float(ls[3]))
              xtemp = float(ls[4])
              rtemp = float(ls[5])
              gtemp = float(ls[6])
              btemp = float(ls[7])

      x.append(xtemp)
      r.append(rtemp)
      g.append(gtemp)
      b.append(btemp)

      nTable = len(r)
      x = N.array( x , N.float32)
      r = N.array( r , N.float32)
      g = N.array( g , N.float32)
      b = N.array( b , N.float32)
      if colorModel == "HSV":
         for i in range(r.shape[0]):
             rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i])
             r[i] = rr ; g[i] = gg ; b[i] = bb
      if colorModel == "HSV":
         for i in range(r.shape[0]):
             rr,gg,bb = colorsys.hsv_to_rgb(r[i]/360.,g[i],b[i])
             r[i] = rr ; g[i] = gg ; b[i] = bb
      if colorModel == "RGB":
          r = r/255.
          g = g/255.
          b = b/255.
      xNorm = (x - x[0])/(x[-1] - x[0])

      red = []
      blue = []
      green = []
      for i in range(len(x)):
          red.append([xNorm[i],r[i],r[i]])
          green.append([xNorm[i],g[i],g[i]])
          blue.append([xNorm[i],b[i],b[i]])
      colorDict = {"red":red, "green":green, "blue":blue}
      matcmap = LinearSegmentedColormap('my_colormap',colorDict)
      return matcmap

def cmap_map(function,cmap):
    from numpy import array
    import matplotlib
    """ Applies function (which should operate on vectors of shape 3:
    [r, g, b], on colormap cmap. This routine will break any discontinuous     points in a colormap.
    """
    cdict = cmap._segmentdata
    step_dict = {}
    # Firt get the list of points where the segments start or end
    for key in ('red','green','blue'):         step_dict[key] = map(lambda x: x[0], cdict[key])
    step_list = sum(step_dict.values(), [])
    step_list = array(list(set(step_list)))
    # Then compute the LUT, and apply the function to the LUT
    reduced_cmap = lambda step : array(cmap(step)[0:3])
    old_LUT = array(map( reduced_cmap, step_list))
    new_LUT = array(map( function, old_LUT))
    # Now try to make a minimal segment definition of the new LUT
    cdict = {}
    for i,key in enumerate(('red','green','blue')):
        this_cdict = {}
        for j,step in enumerate(step_list):
            if step in step_dict[key]:
                this_cdict[step] = new_LUT[j,i]
            elif new_LUT[j,i]!=old_LUT[j,i]:
                this_cdict[step] = new_LUT[j,i]
        colorvector=  map(lambda x: x + (x[1], ), this_cdict.items())
        colorvector.sort()
        cdict[key] = colorvector

    return matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024)

def reverse(cmap):
    from colormaps_functions import cmap_map
    cmap_r = cmap_map(lambda x: x[::-1], cmap)
    return(cmap_r)

def cmap_discretize(cmap, N):
	"""
	Return a discrete colormap from the continuous colormap cmap.

	cmap: colormap instance, eg. cm.jet.
	N: Number of colors.

	Example
	x = resize(arange(100), (5,100))
	djet = cmap_discretize(cm.jet, 5)
	imshow(x, cmap=djet)
	"""
	import numpy as np
	from pylab import interp
	import pylab as pl
	import pylab as plt

	cdict = cmap._segmentdata.copy()
	# N colors
	colors_i = np.linspace(0,1.,N)
	# N+1 indices
	indices = np.linspace(0,1.,N+1)
	for key in ('red','green','blue'):
		# Find the N colors
		D = np.array(cdict[key])
		#I = interpolate.interp1d(D[:,0], D[:,1])
		#I = interpolate.interp1d(D[:,0],D[:,1])
		colors = interp(colors_i,D[:,0],D[:,1])
		# Place these colors at the correct indices.
		A = np.zeros((N+1,3), float)
		A[:,0] = indices
		A[1:,1] = colors
		A[:-1,2] = colors
		# Create a tuple for the dictionary.
		L = []
		for l in A:
			L.append(tuple(l))
		cdict[key] = tuple(L)
	# Return colormap object.
	return plt.matplotlib.colors.LinearSegmentedColormap('colormap',cdict,1024)

def clisttomapdict(clist,name='myColorMap', number=256):
      from matplotlib import colors
      nColors = len(clist)
      red = []
      blue = []
      green = []
      delta = 1.0/(nColors-1)
      for n in range(nColors):
          red.append([n*delta, clist[n][0],clist[n][0]])
          green.append([n*delta, clist[n][1],clist[n][1]])
          blue.append([n*delta, clist[n][2],clist[n][2]])
      cmDict = {'red':red,'green':green,'blue':blue}
      return (colors.LinearSegmentedColormap(name,cmDict,number))

def textfiletoarray(file_name,numberOfHeaderLines=0):
     import numpy
     import string
     try:
        f = open(file_name,'r')
     except:
        print ' file not opened ',file_name
        return(None)
     lines = f.readlines()
     i = len(lines)
     j = len(string.split(lines[numberOfHeaderLines]))
     array = numpy.zeros((i-numberOfHeaderLines,j), float)
     xx = 0
     e = None
     for x in range(numberOfHeaderLines,i):
         for y in range(0,j):
                try:
                   array[xx:xx+1, y:y+1] = string.atof(string.split(lines[x])[y])
                except ValueError:
                   new = array[:xx,:]
                   f.close()
                   return new
         xx = xx + 1
     f.close()
     return(array)

def readnclcolormaps(fileName,returnAs='colorMap',alpha=1.):
      from os.path import exists
      from glob import glob
      from colormaps_functions import clisttomapdict, textfiletoarray
      filePath = os.path.join(os.environ['HOME'], 'pythonlibs/NCLcolormaps', fileName, '.rgb')
      if not exists(filePath):
          print 'file not found ',filePath
          print 'Possible  ones are '
          flist = glob(Path+'/*.rgb')
          for l in flist:
              print l
          return None
      a = textfiletoarray(filePath,numberOfHeaderLines=2)
      clist = []
      for i in range(a.shape[0]):
          c = (a[i,0]/255,a[i,1]/255,a[i,2]/255,alpha)
          clist.append(c)
      if returnAs == 'listOfTuples':
          return clist
      elif returnAs == 'colorMap':
          cmap = clisttomapdict(clist,fileName)
          return cmap
      else:
          print 'return type not recognized'
          return None

def loadCCPLOTcolormap(filename):
    import os
    import numpy as np
    import matplotlib as mpl
    """"Returns a tuple of matplotlib colormap, matplotlib norm,
    and a list of ticks loaded from the file filename in format:

    BOUNDS
    from1 to1 step1
    from2 to2 step2
    ...

    TICKS
    from1 to1 step1
    from2 to2 step2

    COLORS
    r1 g1 b1
    r2 g2 b2
    ...

    UNDER_OVER_BAD_COLORS
    ro go bo
    ru gu bu
    rb gb bb

    Where fromn, ton, stepn are floating point numbers as would be supplied
    to numpy.arange, and rn, gn, bn are the color components the n-th color
    stripe. Components are expected to be in base10 format (0-255).
    UNDER_OVER_BAD_COLORS section specifies colors to be used for
    over, under and bad (masked) values in that order.

    Arguments:
        filename    -- name of the colormap file
        name        -- name for the matplotlib colormap object

    Returns:
        A tuple of: instance of ListedColormap, instance of BoundaryNorm, ticks.
    """
    path = os.path.join(os.environ['HOME'], 'pythonlibs/CCPLOTcolormaps')

    bounds = []
    ticks = []
    rgbarray = []
    specials = []
    mode = "COLORS"

    fp = None
    try:
        fp = open(os.path.join(path, filename), "r")
    except IOError:
        print "File not found"
    lines = fp.readlines()
    for n, s in enumerate(lines):
        s = s.strip()
        if len(s) == 0: continue
        if s in ("BOUNDS", "TICKS", "COLORS", "UNDER_OVER_BAD_COLORS"):
            mode = s
            continue

        a = s.split()
        if len(a) not in (3, 4):
            raise ValueError("Invalid number of fields")

        if mode == "BOUNDS":
            bounds += list(np.arange(float(a[0]), float(a[1]), float(a[2])))
        elif mode == "TICKS":
            ticks += list(np.arange(float(a[0]), float(a[1]), float(a[2])))
        elif mode == "COLORS":
            rgba = [int(c)/256.0 for c in a]
            if len(rgba) == 3: rgba.append(1)
            rgbarray.append(rgba)
        elif mode == "UNDER_OVER_BAD_COLORS":
            rgba = [int(c)/256.0 for c in a]
            if len(rgba) == 3: rgba.append(1)
            specials.append(rgba)
    if (len(rgbarray) > 0):
        colormap = mpl.colors.ListedColormap(rgbarray)
        try:
            colormap.set_under(specials[0][:3], specials[0][3])
            colormap.set_over(specials[1][:3], specials[1][3])
            colormap.set_bad(specials[2][:3], specials[2][3])
        except IndexError: pass
    else:
        colormap = None

    if len(bounds) == 0:
        norm = None
    else:
        norm = mpl.colors.BoundaryNorm(bounds, colormap.N)
    if len(ticks) == 0: ticks = None
    return (colormap, norm, ticks)
<|endoftext|>


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

"""

py2neo - Python library for accessing Neo4j via REST interface

---

Copyright 2011 Three Steps Beyond LLP

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 httplib2
import json

class Direction:

	BOTH     = 'all'
	INCOMING = 'incoming'
	OUTGOING = 'outgoing'

class ReturnFilter:

	ALL                = 'all'
	ALL_BUT_START_NODE = 'all_but_start_node'

class Resource:
	"""
	Web service resource class, nothing here specific to Neo4j but designed to
	work with a well-behaved hypermedia web service; used here as a base class
	for objects represented within the neo4j web service
	"""

	_read_headers = {
		'Accept': "application/json"
	}
	_write_headers = {
		'Accept': "application/json",
		'Content-Type': "application/json"
	}

	def __init__(self, uri, http=None):
		"""
		Creates a new Resource instance

		Parameters:
			uri  - the root URI for this resource
			http - optional httplib2.Http() object to use for requests

		"""
		self.uri = uri
		self._http = http or httplib2.Http()
		self._index = None

	def lookup(self, key):
		"""
		Looks up a value in the resource index by key; will lazily load
		resource index if required
		"""
		if(self._index == None):
			self._index = self._get(self.uri)
		return self._index[key]

	def _get(self, uri):
		"""
		Issues an HTTP GET request

		Parameters:
			uri  - the URI of the resource to GET
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			200 - returns value created from returned json content
			204 - returns None
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		response, content = self._http.request(uri, 'GET', None, self._read_headers)
		if response.status == 200:
			return json.loads(content)
		elif response.status == 204:
			return None
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def _post(self, uri, data):
		"""
		Issues an HTTP POST request

		Parameters:
			uri  - the URI of the resource to POST to
			data - value to be converted to json and passed in request payload
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			200 - returns value created from returned json content
			201 - returns value from "Location" header
			400 - raises a ValueError against the specified data
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		data = {} if data == None else json.dumps(data)
		response, content = self._http.request(uri, 'POST', data, self._write_headers)
		if response.status == 200:
			return json.loads(content)
		elif response.status == 201:
			return response['location']
		elif response.status == 400:
			raise ValueError(data)
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def _put(self, uri, data):
		"""
		Issues an HTTP PUT request

		Parameters:
			uri  - the URI of the resource to PUT
			data - value to be converted to json and passed in request payload
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			204 - success (no return value)
			400 - raises a ValueError against the specified data
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		data = {} if data == None else json.dumps(data)
		response, content = self._http.request(uri, 'PUT', data, self._write_headers)
		if response.status == 204:
			pass
		elif response.status == 400:
			raise ValueError(data)
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def _delete(self, uri):
		"""
		Issues an HTTP DELETE request

		Parameters:
			uri  - the URI of the resource to DELETE
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			204 - success (no return value)
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		response, content = self._http.request(uri, 'DELETE', None, self._read_headers)
		if response.status == 204:
			pass
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def __repr__(self):
		return '%s(%s)' % (self.__class__.__name__, repr(self.uri))

class GraphDatabaseService(Resource):

	def __init__(self, uri, http=None):
		Resource.__init__(self, uri, http)

	def create_node(self, properties=None):
		return Node(self._post(self.lookup('node'), properties), self._http)

	def get_reference_node(self):
		return Node(self.lookup('reference_node'), self._http)

	def get_subreference_node(self, type):
		"""
		Returns subreference node for given relationship type as defined by:
		http://wiki.neo4j.org/content/Design_Guide#Subreferences
		"""
		ref_node = self.get_reference_node()
		subref_nodes = ref_node.get_related_nodes(Direction.OUTGOING, type)
		if len(subref_nodes) == 0:
			subref_node = gdb.create_node()
			ref_node.create_relationship_to(subref_node, type)
		else:
			subref_node = subref_nodes[0]
		return subref_node

	def get_relationship_types(self):
		return self._get(self.lookup('relationship_types'))

	def get_node_indexes(self):
		indexes = self._get(self.lookup('node_index'))
		# replace with map()
		for i in indexes:
			index = indexes[i]
			indexes[i] = NodeIndex(index['type'], index['template'], index['provider'], self._http)
		return indexes

	def get_relationship_indexes(self):
		indexes = self._get(self.lookup('relationship_index'))
		# replace with map()
		for i in indexes:
			index = indexes[i]
			indexes[i] = RelationshipIndex(index['type'], index['template'], index['provider'], self._http)
		return indexes

class PropertyContainer(Resource):

	def __init__(self, uri, http=None):
		Resource.__init__(self, uri, http)

	def set_properties(self, properties):
		self._put(self.lookup('properties'), properties)

	def get_properties(self):
		return self._get(self.lookup('properties'))

	def remove_properties(self):
		self._delete(self.lookup('properties'))

	def __setitem__(self, key, value):
		self._put(self.lookup('property').format(key=key), value)

	def __getitem__(self, key):
		return self._get(self.lookup('property').format(key=key))

	def __delitem__(self, key):
		self._delete(self.lookup('property').format(key=key))

class Node(PropertyContainer):

	def __init__(self, uri, http=None):
		PropertyContainer.__init__(self, uri, http)

	def delete(self):
		self._delete(self._index['self'])

	def create_relationship_to(self, other_node, type, data=None):
		return Relationship(self._post(self.lookup('create_relationship'), {
			'to': str(other_node),
			'type': type,
			'data': data
		}), self._http)

	def get_relationships(self, direction, *types):
		if len(types) == 0:
			uri = self.lookup(direction + '_relationships')
		else:
			uri = self.lookup(direction + '_typed_relationships').replace('{-list|&|types}', '&'.join(types))
		return [Relationship(rel['self'], self._http) for rel in self._get(uri)]

	def get_related_nodes(self, direction, *types):
		if len(types) == 0:
			uri = self.lookup(direction + '_relationships')
		else:
			uri = self.lookup(direction + '_typed_relationships').replace('{-list|&|types}', '&'.join(types))
		return [Node(rel['start'] if rel['end'] == self.uri else rel['end'], self._http) for rel in self._get(uri)]

	def get_node_traverser(self):
		return NodeTraverser(self.lookup('traverse').format(returnType='node'), self._http)

class Relationship(PropertyContainer):

	def __init__(self, uri, http=None):
		PropertyContainer.__init__(self, uri, http)
		self.type = self.lookup('type')
		self.data = self.lookup('data')

	def delete(self):
		self._delete(self.lookup('self'))

	def get_start_node(self):
		return Node(self.lookup('start'), self._http)

	def get_end_node(self):
		return Node(self.lookup('end'), self._http)

class Index(Resource):

	def __init__(self, type, template, provider, http=None):
		Resource.__init__(self, template, http)
		self._type = type
		self._provider = provider

	def _search(self, key, value):
		return self._get(self.uri.format(key=key, value=value))

	def add(self, entity, key, value):
		self._post(self.uri.format(key=key, value=value), entity.uri)

class NodeIndex(Index):

	def __init__(self, type, template, provider, http=None):
		Index.__init__(self, type, template, provider, http)

	def search(self, key, value):
		return [Node(item['self'], self._http) for item in self._search(key, value)]

class RelationshipIndex(Index):

	def __init__(self, type, template, provider, http=None):
		Index.__init__(self, type, template, provider, http)

	def search(self, key, value):
		return [Relationship(item['self'], self._http) for item in self._search(key, value)]

class Traverser(Resource):

	class Order:

		BREADTH_FIRST = 'breadth_first'
		DEPTH_FIRST   = 'depth_first'

	def __init__(self, uri, http=None):
		Resource.__init__(self, uri, http)
		self._criteria = {
			'order': Traverser.Order.DEPTH_FIRST,
			'uniqueness': 'node_path'
		}

	def set_max_depth(self, max_depth):
		if 'prune_evaluator' in self._criteria:
			del self._criteria['prune_evaluator']
		self._criteria['max_depth'] = max_depth

	def set_prune_evaluator(self, language, body):
		if 'max_depth' in self._criteria:
			del self._criteria['max_depth']
		self._criteria['prune_evaluator'] = {
			'language': language,
			'body': body
		}

	def set_return_filter(self, language, name):
		self._criteria['return_filter'] = {
			'language': language,
			'name': name
		}

	def add_relationship(self, type, direction=None):
		if 'relationships' not in self._criteria:
			self._criteria['relationships'] = []
		if direction:
			self._criteria['relationships'].append({
				'type': type,
				'direction': direction
			})
		else:
			self._criteria['relationships'].append({
				'type': type
			})

	def remove_relationship(self, type):
		if 'relationships' in self._criteria:
			self._criteria['relationships'] = [item for item in self._criteria['relationships'] if item['type'] != type]
			if self._criteria['relationships'] == []:
				del self._criteria['relationships']

class NodeTraverser(Traverser):

	def traverse_depth_first(self):
		self._criteria['order'] = Traverser.Order.DEPTH_FIRST
		return [Node(item['self'], self._http) for item in self._post(self.uri, self._criteria)]

	def traverse_breadth_first(self):
		self._criteria['order'] = Traverser.Order.BREADTH_FIRST
		return [Node(item['self'], self._http) for item in self._post(self.uri, self._criteria)]

<commit_msg>Added "to" and "fro" to Node class for quick manual traversal<commit_after>#!/usr/bin/env python

"""

py2neo - Python library for accessing Neo4j via REST interface

---

Copyright 2011 Three Steps Beyond LLP

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 httplib2
import json

class Direction:

	BOTH     = 'all'
	INCOMING = 'incoming'
	OUTGOING = 'outgoing'

class ReturnFilter:

	ALL                = 'all'
	ALL_BUT_START_NODE = 'all_but_start_node'

class Resource:
	"""
	Web service resource class, nothing here specific to Neo4j but designed to
	work with a well-behaved hypermedia web service; used here as a base class
	for objects represented within the neo4j web service
	"""

	_read_headers = {
		'Accept': "application/json"
	}
	_write_headers = {
		'Accept': "application/json",
		'Content-Type': "application/json"
	}

	def __init__(self, uri, http=None):
		"""
		Creates a new Resource instance

		Parameters:
			uri  - the root URI for this resource
			http - optional httplib2.Http() object to use for requests

		"""
		self.uri = uri
		self._http = http or httplib2.Http()
		self._index = None

	def lookup(self, key):
		"""
		Looks up a value in the resource index by key; will lazily load
		resource index if required
		"""
		if(self._index == None):
			self._index = self._get(self.uri)
		if key in self._index:
			return self._index[key]
		else:
			return None

	def _get(self, uri):
		"""
		Issues an HTTP GET request

		Parameters:
			uri  - the URI of the resource to GET
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			200 - returns value created from returned json content
			204 - returns None
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		response, content = self._http.request(uri, 'GET', None, self._read_headers)
		if response.status == 200:
			return json.loads(content)
		elif response.status == 204:
			return None
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def _post(self, uri, data):
		"""
		Issues an HTTP POST request

		Parameters:
			uri  - the URI of the resource to POST to
			data - value to be converted to json and passed in request payload
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			200 - returns value created from returned json content
			201 - returns value from "Location" header
			400 - raises a ValueError against the specified data
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		data = {} if data == None else json.dumps(data)
		response, content = self._http.request(uri, 'POST', data, self._write_headers)
		if response.status == 200:
			return json.loads(content)
		elif response.status == 201:
			return response['location']
		elif response.status == 400:
			raise ValueError(data)
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def _put(self, uri, data):
		"""
		Issues an HTTP PUT request

		Parameters:
			uri  - the URI of the resource to PUT
			data - value to be converted to json and passed in request payload
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			204 - success (no return value)
			400 - raises a ValueError against the specified data
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		data = {} if data == None else json.dumps(data)
		response, content = self._http.request(uri, 'PUT', data, self._write_headers)
		if response.status == 204:
			pass
		elif response.status == 400:
			raise ValueError(data)
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def _delete(self, uri):
		"""
		Issues an HTTP DELETE request

		Parameters:
			uri  - the URI of the resource to DELETE
			args - optional dictionary of URI template substitution values

		Result (dependent on HTTP status code):
			204 - success (no return value)
			404 - raises a KeyError against the specified URI
			??? - raises a SystemError with the HTTP response

		"""
		response, content = self._http.request(uri, 'DELETE', None, self._read_headers)
		if response.status == 204:
			pass
		elif response.status == 404:
			raise KeyError(uri)
		else:
			raise SystemError(response)

	def __repr__(self):
		return '%s(%s)' % (self.__class__.__name__, repr(self.uri))

class GraphDatabaseService(Resource):

	def __init__(self, uri, http=None):
		Resource.__init__(self, uri, http)

	def create_node(self, properties=None):
		return Node(self._post(self.lookup('node'), properties), self._http)

	def get_reference_node(self):
		return Node(self.lookup('reference_node'), self._http)

	def get_subreference_node(self, type):
		"""
		Returns subreference node for given relationship type as defined by:
		http://wiki.neo4j.org/content/Design_Guide#Subreferences
		"""
		ref_node = self.get_reference_node()
		subref_nodes = ref_node.get_related_nodes(Direction.OUTGOING, type)
		if len(subref_nodes) == 0:
			subref_node = gdb.create_node()
			ref_node.create_relationship_to(subref_node, type)
		else:
			subref_node = subref_nodes[0]
		return subref_node

	def get_relationship_types(self):
		return self._get(self.lookup('relationship_types'))

	def get_node_indexes(self):
		indexes = self._get(self.lookup('node_index'))
		# replace with map()
		for i in indexes:
			index = indexes[i]
			indexes[i] = NodeIndex(index['type'], index['template'], index['provider'], self._http)
		return indexes

	def get_relationship_indexes(self):
		indexes = self._get(self.lookup('relationship_index'))
		# replace with map()
		for i in indexes:
			index = indexes[i]
			indexes[i] = RelationshipIndex(index['type'], index['template'], index['provider'], self._http)
		return indexes

class PropertyContainer(Resource):

	def __init__(self, uri, http=None):
		Resource.__init__(self, uri, http)

	def set_properties(self, properties):
		self._put(self.lookup('properties'), properties)

	def get_properties(self):
		return self._get(self.lookup('properties'))

	def remove_properties(self):
		self._delete(self.lookup('properties'))

	def __setitem__(self, key, value):
		self._put(self.lookup('property').format(key=key), value)

	def __getitem__(self, key):
		return self._get(self.lookup('property').format(key=key))

	def __delitem__(self, key):
		self._delete(self.lookup('property').format(key=key))

class Node(PropertyContainer):

	def __init__(self, uri, http=None):
		PropertyContainer.__init__(self, uri, http)

	def delete(self):
		self._delete(self._index['self'])

	def create_relationship_to(self, other_node, type, data=None):
		return Relationship(self._post(self.lookup('create_relationship'), {
			'to': str(other_node),
			'type': type,
			'data': data
		}), self._http)

	def get_relationships(self, direction, *types):
		if len(types) == 0:
			uri = self.lookup(direction + '_relationships')
		else:
			uri = self.lookup(direction + '_typed_relationships').replace('{-list|&|types}', '&'.join(types))
		return [Relationship(rel['self'], self._http) for rel in self._get(uri)]

	def get_related_nodes(self, direction, *types):
		if len(types) == 0:
			uri = self.lookup(direction + '_relationships')
		else:
			uri = self.lookup(direction + '_typed_relationships').replace('{-list|&|types}', '&'.join(types))
		return [Node(rel['start'] if rel['end'] == self.uri else rel['end'], self._http) for rel in self._get(uri)]

	def to(self, *types):
		nodes = self.get_related_nodes(Direction.OUTGOING, *types)
		if len(nodes) == 0:
			return None
		elif len(nodes) == 1:
			return nodes[0]
		else:
			return nodes

	def fro(self, *types):
		nodes = self.get_related_nodes(Direction.INCOMING, *types)
		if len(nodes) == 0:
			return None
		elif len(nodes) == 1:
			return nodes[0]
		else:
			return nodes

	def get_node_traverser(self):
		return NodeTraverser(self.lookup('traverse').format(returnType='node'), self._http)

class Relationship(PropertyContainer):

	def __init__(self, uri, http=None):
		PropertyContainer.__init__(self, uri, http)
		self.type = self.lookup('type')
		self.data = self.lookup('data')

	def delete(self):
		self._delete(self.lookup('self'))

	def get_start_node(self):
		return Node(self.lookup('start'), self._http)

	def get_end_node(self):
		return Node(self.lookup('end'), self._http)

class Index(Resource):

	def __init__(self, type, template, provider, http=None):
		Resource.__init__(self, template, http)
		self._type = type
		self._provider = provider

	def _search(self, key, value):
		return self._get(self.uri.format(key=key, value=value))

	def add(self, entity, key, value):
		self._post(self.uri.format(key=key, value=value), entity.uri)

class NodeIndex(Index):

	def __init__(self, type, template, provider, http=None):
		Index.__init__(self, type, template, provider, http)

	def search(self, key, value):
		return [Node(item['self'], self._http) for item in self._search(key, value)]

class RelationshipIndex(Index):

	def __init__(self, type, template, provider, http=None):
		Index.__init__(self, type, template, provider, http)

	def search(self, key, value):
		return [Relationship(item['self'], self._http) for item in self._search(key, value)]

class Traverser(Resource):

	class Order:

		BREADTH_FIRST = 'breadth_first'
		DEPTH_FIRST   = 'depth_first'

	def __init__(self, uri, http=None):
		Resource.__init__(self, uri, http)
		self._criteria = {
			'order': Traverser.Order.DEPTH_FIRST,
			'uniqueness': 'node_path'
		}

	def set_max_depth(self, max_depth):
		if 'prune_evaluator' in self._criteria:
			del self._criteria['prune_evaluator']
		self._criteria['max_depth'] = max_depth

	def set_prune_evaluator(self, language, body):
		if 'max_depth' in self._criteria:
			del self._criteria['max_depth']
		self._criteria['prune_evaluator'] = {
			'language': language,
			'body': body
		}

	def set_return_filter(self, language, name):
		self._criteria['return_filter'] = {
			'language': language,
			'name': name
		}

	def add_relationship(self, type, direction=None):
		if 'relationships' not in self._criteria:
			self._criteria['relationships'] = []
		if direction:
			self._criteria['relationships'].append({
				'type': type,
				'direction': direction
			})
		else:
			self._criteria['relationships'].append({
				'type': type
			})

	def remove_relationship(self, type):
		if 'relationships' in self._criteria:
			self._criteria['relationships'] = [item for item in self._criteria['relationships'] if item['type'] != type]
			if self._criteria['relationships'] == []:
				del self._criteria['relationships']

class NodeTraverser(Traverser):

	def traverse_depth_first(self):
		self._criteria['order'] = Traverser.Order.DEPTH_FIRST
		return [Node(item['self'], self._http) for item in self._post(self.uri, self._criteria)]

	def traverse_breadth_first(self):
		self._criteria['order'] = Traverser.Order.BREADTH_FIRST
		return [Node(item['self'], self._http) for item in self._post(self.uri, self._criteria)]

<|endoftext|>