<commit_before>"""Shivali Chandra
Restructured code that takes coordinates of sides and axes of rotation, and rotates the sides
until they meet, forming a closed 3D shape.
"""

import numpy as np
import math
import collections
from scipy import ndimage

def find_intersection_distances(p1,y1,x1,y2,x2):
	if y2-y1 == 0:
		dist = math.fabs(p1[1]-y1)
	elif x2-x1 == 0:
		dist = math.fabs(p1[0]-x1)
	else:
		axis_line_slope = (y2-y1)/(x2-x1)
		perp_slope = -1/(axis_line_slope)
		c1 = axis_line_slope * x1 - y1
		c2 = perp_slope * p1[0] - p1[1]
		x_intersect = (c2 - c1)/(perp_slope - axis_line_slope)
		y_intersect = perp_slope * x_intersect + c2
		dist = math.sqrt((x_intersect-p1[0])**2+(y_intersect-p1[1])**2)
	hypotenuse = math.sqrt((x2-p1[0])**2+(y2-p1[1])**2)
	if hypotenuse == 0:
		angle = 0.0
	else:
		angle = math.asin(dist/hypotenuse)
	return dist,angle

def move_to_actual_coord(old_side,side_dict,side_num,theta):
	"""Change the xy coordinates of the sides to the correct values from the original image
		Input: side coordinates, sides dictionary
		Output: new side coordinates in the sides dictionary
	"""
	final_side = list()
	y1 = old_side[0][1]
	x1 = old_side[0][0]
	y2 = old_side[len(old_side)-1][1]
	x2 = old_side[len(old_side)-1][0]
	new_xaxis = side_dict[side_num][1][len(old_side)-1][0]
	new_xaxis1 = side_dict[side_num][1][0][0]
	new_yaxis = side_dict[side_num][1][len(old_side)-1][1]
	new_yaxis1 = side_dict[side_num][1][0][1]

	for i,j in enumerate(old_side):
		x = side_dict[side_num][1][i][0]
		y = side_dict[side_num][1][i][1]
		intersections = find_intersection_distances((j[0],j[1]),y1,x1,y2,x2)
		dist = intersections[0]
		coordinates = {1:(x,(dist+new_yaxis)),2:(x,(new_yaxis-dist)),3:((new_xaxis-dist),y),4:((new_xaxis+dist),y)}
		intersections = find_intersection_distances((j[0],j[1]),y1,x1,y2,x2)
		if (new_xaxis>new_xaxis1) and (new_yaxis-new_yaxis1==0):
			if math.degrees(theta) <= 90:
				[fin_x,fin_y] = coordinates[1]
			else:
				[fin_x,fin_y] = coordinates[2]
		elif (new_xaxis<new_xaxis1) and (new_yaxis-new_yaxis1==0):
			if math.degrees(theta) <= 90:
				[fin_x,fin_y] = coordinates[2]
			else:
				[fin_x,fin_y] = coordinates[1]
		elif (new_yaxis>new_yaxis1) and (new_xaxis-new_xaxis1==0):
			if math.degrees(theta) <= 90:
				[fin_x,fin_y] = coordinates[3]
			else:
				[fin_x,fin_y] = coordinates[4]
		else:
			if math.degrees(theta) <=90:
				[fin_x,fin_y] = coordinates[4]
			else:
				[fin_x,fin_y] = coordinates[3]

		#else:
			#hyp = intersections[0]/math.sin(intersections[1])
		#	print intersections

		z = j[2]

		final_coord = fin_x/1.0,fin_y/1.0,z
		final_coord = list(final_coord)
		final_side.append(final_coord)
	side_dict[side_num] = list(side_dict[side_num])
	side_dict[side_num].append(final_side)
	return side_dict

def transform_side(side_num,side_dict,theta):
	"""Transform the coordinates of the side onto the perpendicular plane using Euler-Rodrigues formula
		Input: side coordinates, plane
		Output: new coordinates
	"""
	side = side_dict[side_num][0]
	new_side = list()
	#calculating axis of rotation
	axis = side[len(side)-1][0]-side[0][0],0.0,0.0
	#converting theta to radians
	rad = math.radians(theta)
	for i in side:
		#calculating vector for each point in side
		side_vector = i[0],i[1],0.0
		#Euler-Rodrigues formula to rotate vectors
		axis = np.asarray(axis)
		theta = np.asarray(rad)
		axis = axis/math.sqrt(np.dot(axis, axis))
		a = math.cos(theta/2.0)
		b, c, d = -axis*math.sin(theta/2.0)
		aa, bb, cc, dd = a*a, b*b, c*c, d*d
		bc, ad, ac, ab, bd, cd = b*c, a*d, a*c, a*b, b*d, c*d
		multiplier = np.array([[aa+bb-cc-dd, 2.0*(bc+ad), 2.0*(bd-ac)],
					[2.0*(bc-ad), aa+cc-bb-dd, 2.0*(cd+ab)],
					[2.0*(bd+ac), 2.0*(cd-ab), aa+dd-bb-cc]])
		transform_vector = (np.dot(multiplier, side_vector))
		#round points to nearest whole number, add to list of transformed side coordinates
		folded_vector = round(transform_vector[0]),round(transform_vector[1]),round(transform_vector[2])
		new_side.append(folded_vector)

	moved_side = move_to_actual_coord(new_side,side_dict,side_num,theta)
	return moved_side

def output(theta,final_list):
	x = list()
	y = list()
	z = list()
	final_coordinates = []
	for i in final_list:
		final_coordinates.append(final_list[i][2])
	for i in final_coordinates:
		for j in i:
			x.append(j[0])
			y.append(j[1])
			z.append(j[2])
	return x,y,z

def check_sides(run,temp,theta,fin):
	vector_sides = temp
	data = []
	redo_sides = {}
	new_run = {}
	for i in run:
		position = run[i][2]
		for j in range(1,len(position)):
			if ((position[j][0]==position[j-1][0]) or (position[j][1]==position[j-1][1])) and (position[j][2]>position[j-1][2]):
				key = str(position[j])+str(position[j-1])
			elif ((position[j][0]>position[j-1][0]) or (position[j][1]>position[j-1][1])):
				key = str(position[j])+str(position[j-1])
			else:
				key = str(position[j-1])+str(position[j])
			if key in vector_sides:
				vector_sides[key].append(i)
			else:
				vector_sides[key] = [i]
	for k in vector_sides:
		if len(vector_sides[k])>1:
			data.append(vector_sides[k][0])
			data.append(vector_sides[k][1])
	new_side_list = list(set(run.keys())-set(data))
	if not new_side_list:
		return theta,run
	else:
		new_t = theta+1
		for i in run.keys():
			if i in new_side_list:
				redo_sides[i] = [run[i][0]]
				redo_sides[i].append(run[i][1])
			else:
				new_run[i] = run[i]
			redone = transform_side(i,redo_sides,new_t)
		final = redone.copy()
		final.update(new_run)
		return check_sides(redone,new_run,new_t,final)

def make_sides(sides,theta):
	"""call things"""
	length = len(sides)
	for i in sides:
		side = sides[i][0]
		transformed_side = transform_side(i,sides,theta)
	return transformed_side

def main(sides,xy_coord):
	#create dictionary of sides as keys, both sets of xy coordinates as values
	theta = 0
	sides_old_coordinates = {}
	for i in range(0,len(sides)):
		val1 = sides[i]
		val2 = xy_coord[i]
		if i not in sides_old_coordinates:
			sides_old_coordinates[i] = val1,val2
	run_fxn = make_sides(sides_old_coordinates,theta)
	final_sides = check_sides(run_fxn,{},theta,{})
	return output(final_sides[0],final_sides[1])

if __name__ == "__main__":

	"""CUBE WORKS
	side_coordinates = (([0,0],[0,6],[6,6],[6,0]),([0,0],[0,6],[6,6],[6,0]),([0,0],[0,6],[6,6],[6,0]),([0,0],[0,6],[6,6],[6,0]))
	actual_coordinates = (([6,6],[0,6],[0,12],[6,12]),([6,12],[6,18],[12,18],[12,12]),([12,12],[18,12],[18,6],[12,6]),([12,6],[12,0],[6,0],[6,6]))

	print main(side_coordinates,actual_coordinates)"""

	"""PYRAMID DOESN'T WORK
	side_coordinates = (([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]))
	actual_coordinates = (([6,0],[0,0],[3,6]),([3,6],[6,12],[9,6]),([9,6],[12,0],[6,0]))
	print main(side_coordinates,actual_coordinates)"""

	"""SQUARE PYRAMID WORKS"""
	side_coordinates = (([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]))
	actual_coordinates = (([6,6],[0,9],[6,12]),([6,12],[9,18],[12,12]),([12,12],[18,9],[12,6]),([12,6],[9,0],[6,6]))
	print main(side_coordinates,actual_coordinates)

	"""TRIANGULAR PRISM WIP
	side_coordinates = (([0,0],[0,6],[6,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[0,6],[6,6],[6,0]),([0,0],[3,6],[6,0]))
	actual_coordinates = (([6,6],[0,6],[0,12],[6,12]),([6,12],[9,18],[12,12]),([12,12],[18,12],[18,6],[12,6]),([12,6],[9,0],[6,6]))

	print main(side_coordinates,actual_coordinates)"""

<commit_msg>Removed unnecessary code<commit_after>"""Shivali Chandra
Restructured code that takes coordinates of sides and axes of rotation, and rotates the sides
until they meet, forming a closed 3D shape.
"""

import numpy as np
import math
import collections

def find_intersection_distances(p1,y1,x1,y2,x2):
	if y2-y1 == 0:
		dist = math.fabs(p1[1]-y1)
	elif x2-x1 == 0:
		dist = math.fabs(p1[0]-x1)
	else:
		axis_line_slope = (y2-y1)/(x2-x1)
		perp_slope = -1/(axis_line_slope)
		c1 = axis_line_slope * x1 - y1
		c2 = perp_slope * p1[0] - p1[1]
		x_intersect = (c2 - c1)/(perp_slope - axis_line_slope)
		y_intersect = perp_slope * x_intersect + c2
		dist = math.sqrt((x_intersect-p1[0])**2+(y_intersect-p1[1])**2)
	hypotenuse = math.sqrt((x2-p1[0])**2+(y2-p1[1])**2)
	if hypotenuse == 0:
		angle = 0.0
	else:
		angle = math.asin(dist/hypotenuse)
	return dist,angle

def move_to_actual_coord(old_side,side_dict,side_num,theta):
	"""Change the xy coordinates of the sides to the correct values from the original image
		Input: side coordinates, sides dictionary
		Output: new side coordinates in the sides dictionary
	"""
	final_side = list()
	y1 = old_side[0][1]
	x1 = old_side[0][0]
	y2 = old_side[len(old_side)-1][1]
	x2 = old_side[len(old_side)-1][0]
	new_xaxis = side_dict[side_num][1][len(old_side)-1][0]
	new_xaxis1 = side_dict[side_num][1][0][0]
	new_yaxis = side_dict[side_num][1][len(old_side)-1][1]
	new_yaxis1 = side_dict[side_num][1][0][1]

	for i,j in enumerate(old_side):
		x = side_dict[side_num][1][i][0]
		y = side_dict[side_num][1][i][1]
		intersections = find_intersection_distances((j[0],j[1]),y1,x1,y2,x2)
		dist = intersections[0]
		coordinates = {1:(x,(dist+new_yaxis)),2:(x,(new_yaxis-dist)),3:((new_xaxis-dist),y),4:((new_xaxis+dist),y)}
		intersections = find_intersection_distances((j[0],j[1]),y1,x1,y2,x2)
		if (new_xaxis>new_xaxis1) and (new_yaxis-new_yaxis1==0):
			if math.degrees(theta) <= 90:
				[fin_x,fin_y] = coordinates[1]
			else:
				[fin_x,fin_y] = coordinates[2]
		elif (new_xaxis<new_xaxis1) and (new_yaxis-new_yaxis1==0):
			if math.degrees(theta) <= 90:
				[fin_x,fin_y] = coordinates[2]
			else:
				[fin_x,fin_y] = coordinates[1]
		elif (new_yaxis>new_yaxis1) and (new_xaxis-new_xaxis1==0):
			if math.degrees(theta) <= 90:
				[fin_x,fin_y] = coordinates[3]
			else:
				[fin_x,fin_y] = coordinates[4]
		else:
			if math.degrees(theta) <=90:
				[fin_x,fin_y] = coordinates[4]
			else:
				[fin_x,fin_y] = coordinates[3]

		#else:
			#hyp = intersections[0]/math.sin(intersections[1])
		#	print intersections

		z = j[2]

		final_coord = fin_x/1.0,fin_y/1.0,z
		final_coord = list(final_coord)
		final_side.append(final_coord)
	side_dict[side_num] = list(side_dict[side_num])
	side_dict[side_num].append(final_side)
	return side_dict

def transform_side(side_num,side_dict,theta):
	"""Transform the coordinates of the side onto the perpendicular plane using Euler-Rodrigues formula
		Input: side coordinates, plane
		Output: new coordinates
	"""
	side = side_dict[side_num][0]
	new_side = list()
	#calculating axis of rotation
	axis = side[len(side)-1][0]-side[0][0],0.0,0.0
	#converting theta to radians
	rad = math.radians(theta)
	for i in side:
		#calculating vector for each point in side
		side_vector = i[0],i[1],0.0
		#Euler-Rodrigues formula to rotate vectors
		axis = np.asarray(axis)
		theta = np.asarray(rad)
		axis = axis/math.sqrt(np.dot(axis, axis))
		a = math.cos(theta/2.0)
		b, c, d = -axis*math.sin(theta/2.0)
		aa, bb, cc, dd = a*a, b*b, c*c, d*d
		bc, ad, ac, ab, bd, cd = b*c, a*d, a*c, a*b, b*d, c*d
		multiplier = np.array([[aa+bb-cc-dd, 2.0*(bc+ad), 2.0*(bd-ac)],
					[2.0*(bc-ad), aa+cc-bb-dd, 2.0*(cd+ab)],
					[2.0*(bd+ac), 2.0*(cd-ab), aa+dd-bb-cc]])
		transform_vector = (np.dot(multiplier, side_vector))
		#round points to nearest whole number, add to list of transformed side coordinates
		folded_vector = round(transform_vector[0]),round(transform_vector[1]),round(transform_vector[2])
		new_side.append(folded_vector)

	moved_side = move_to_actual_coord(new_side,side_dict,side_num,theta)
	return moved_side

def output(theta,final_list):
	x = list()
	y = list()
	z = list()
	final_coordinates = []
	for i in final_list:
		final_coordinates.append(final_list[i][2])
	for i in final_coordinates:
		for j in i:
			x.append(j[0])
			y.append(j[1])
			z.append(j[2])
	return x,y,z

def check_sides(run,temp,theta,fin):
	vector_sides = temp
	data = []
	redo_sides = {}
	new_run = {}
	for i in run:
		position = run[i][2]
		for j in range(1,len(position)):
			if ((position[j][0]==position[j-1][0]) or (position[j][1]==position[j-1][1])) and (position[j][2]>position[j-1][2]):
				key = str(position[j])+str(position[j-1])
			elif ((position[j][0]>position[j-1][0]) or (position[j][1]>position[j-1][1])):
				key = str(position[j])+str(position[j-1])
			else:
				key = str(position[j-1])+str(position[j])
			if key in vector_sides:
				vector_sides[key].append(i)
			else:
				vector_sides[key] = [i]
	for k in vector_sides:
		if len(vector_sides[k])>1:
			data.append(vector_sides[k][0])
			data.append(vector_sides[k][1])
	new_side_list = list(set(run.keys())-set(data))
	if not new_side_list:
		return theta,run
	else:
		new_t = theta+1
		for i in run.keys():
			if i in new_side_list:
				redo_sides[i] = [run[i][0]]
				redo_sides[i].append(run[i][1])
			else:
				new_run[i] = run[i]
			redone = transform_side(i,redo_sides,new_t)
		final = redone.copy()
		final.update(new_run)
		return check_sides(redone,new_run,new_t,final)

def make_sides(sides,theta):
	"""call things"""
	length = len(sides)
	for i in sides:
		side = sides[i][0]
		transformed_side = transform_side(i,sides,theta)
	return transformed_side

def main(sides,xy_coord):
	#create dictionary of sides as keys, both sets of xy coordinates as values
	theta = 0
	sides_old_coordinates = {}
	for i in range(0,len(sides)):
		val1 = sides[i]
		val2 = xy_coord[i]
		if i not in sides_old_coordinates:
			sides_old_coordinates[i] = val1,val2
	run_fxn = make_sides(sides_old_coordinates,theta)
	final_sides = check_sides(run_fxn,{},theta,{})
	return output(final_sides[0],final_sides[1])

if __name__ == "__main__":

	"""CUBE WORKS
	side_coordinates = (([0,0],[0,6],[6,6],[6,0]),([0,0],[0,6],[6,6],[6,0]),([0,0],[0,6],[6,6],[6,0]),([0,0],[0,6],[6,6],[6,0]))
	actual_coordinates = (([6,6],[0,6],[0,12],[6,12]),([6,12],[6,18],[12,18],[12,12]),([12,12],[18,12],[18,6],[12,6]),([12,6],[12,0],[6,0],[6,6]))

	print main(side_coordinates,actual_coordinates)"""

	"""PYRAMID DOESN'T WORK
	side_coordinates = (([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]))
	actual_coordinates = (([6,0],[0,0],[3,6]),([3,6],[6,12],[9,6]),([9,6],[12,0],[6,0]))
	print main(side_coordinates,actual_coordinates)"""

	"""SQUARE PYRAMID WORKS
	side_coordinates = (([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[3,6],[6,0]))
	actual_coordinates = (([6,6],[0,9],[6,12]),([6,12],[9,18],[12,12]),([12,12],[18,9],[12,6]),([12,6],[9,0],[6,6]))
	print main(side_coordinates,actual_coordinates)"""

	"""TRIANGULAR PRISM WIP
	side_coordinates = (([0,0],[0,6],[6,6],[6,0]),([0,0],[3,6],[6,0]),([0,0],[0,6],[6,6],[6,0]),([0,0],[3,6],[6,0]))
	actual_coordinates = (([6,6],[0,6],[0,12],[6,12]),([6,12],[9,18],[12,12]),([12,12],[18,12],[18,6],[12,6]),([12,6],[9,0],[6,6]))

	print main(side_coordinates,actual_coordinates)"""

<|endoftext|>


<commit_before># -*- coding:utf-8 -*-
# taken from libcloud.REST

import inspect
import re

#from libcloud.utils.misc import get_driver
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

from parinx.parser import parse_args, \
    parse_docstring, get_method_docstring
from parinx.parser import _ParinxHandler

from libcloudcli.errors import ProviderNotSupportedError,\
    MissingArguments, MissingHeadersError, MethodParsingException,\
    NoSuchOperationError

from libcloud_rest.api.entries import Entry
from parinx.utils import json

class DriverMethod(object):
    _type_name_pattern = r'.\{([_0-9a-zA-Z]+)\}'

    def __init__(self, driver_obj, method_name):
        if inspect.isclass(driver_obj):
            self.driver_cls = driver_obj
        else:
            self.driver_cls = driver_obj.__class__

        self.driver_obj = driver_obj
        self.method_name = method_name
        self.method = getattr(self.driver_obj, method_name, None)

        if not inspect.ismethod(self.method):
            raise NoSuchOperationError()
        method_doc = get_method_docstring(self.driver_cls, method_name)
        print self.method
        if not method_doc:
            raise MethodParsingException('Empty docstring')

        argspec_arg = parse_args(self.method)
        docstring_parse_result = parse_docstring(method_doc, self.driver_cls)
        self.description = docstring_parse_result['description']
        docstring_args = docstring_parse_result['arguments']
        #print docstring_parse_result
        #print docstring_args
        print argspec_arg

        #check vargs
        self.vargs_entries = []
        for name, arg_info in argspec_arg.iteritems():
            if name in docstring_args:
                docstring_arg = docstring_args[name]
                entry_kwargs = {
                    'name': name,
                    'description': docstring_arg['description'],
                    'type_name': docstring_arg['type_name'],
                    'required': (docstring_arg['required'] or
                                 arg_info['required']),
                }

                if not entry_kwargs['required'] and 'default' in arg_info:
                    entry_kwargs['default'] = arg_info['default']
                self.vargs_entries.append(Entry(**entry_kwargs))
            else:
                raise MethodParsingException(
                    '%s %s not described in docstring' % (method_name, name))

        #update kwargs
        kwargs = set(docstring_args).difference(argspec_arg)
        self.kwargs_entries = [Entry(arg_name, **docstring_args[arg_name])
                               for arg_name in kwargs]
        method_return = docstring_parse_result['return']
        self.result_entry = Entry('', method_return['type_name'],
                                  method_return['description'], True)

    @classmethod
    def _remove_type_name_brackets(cls, type_name):
        return re.sub(cls._type_name_pattern, r'\1', type_name)

    def get_description(self):
        result_arguments = []

        for entry in self.vargs_entries:
            result_arguments.extend(entry.get_arguments())

        for entry in self.kwargs_entries:
            result_arguments.extend(entry.get_arguments())

        result = {'name': self.method_name,
                  'description': self.description,
                  'arguments': result_arguments,
                  'return': {
                      'type': self._remove_type_name_brackets(
                          self.result_entry.type_name),
                      'description': self.result_entry.description}
                  }
        return result

    def invoke_result_to_json(self, value):
        return self.result_entry.to_json(value)

    def invoke(self, data):
        vargs = [e.from_json(data, self.driver_obj)
                 for e in self.vargs_entries]
        kwargs = {}
        for kw_entry in self.kwargs_entries:
            try:
                kwargs[kw_entry.name] = kw_entry.from_json(data,
                                                           self.driver_obj)
            except MissingArguments:
                if kw_entry.required:
                    raise
        if self.method_name == '__init__':
            return self.driver_cls(*vargs, **kwargs)
        return self.method(*vargs, **kwargs)

def get_providers_info(providers):
    """
    List of all supported providers.

    :param providers: object that contain supported providers.
    :type  providers: :class:`libcloud.types.Provider`

    :return `list of dict objects`
    """
    result = []
    for provider, Driver in get_providers_dict(providers.DRIVERS,
                                               providers.Provider).items():
        result.append({
            'id': provider,
            'friendly_name': getattr(Driver, 'name', ''),
            'website': getattr(Driver, 'website', ''),
        })
    return result

def get_providers_dict(drivers, providers):
    result = {}
    for provider_name in providers.__dict__.keys():
        if provider_name.startswith('_'):
            continue

        provider_name = provider_name.upper()
        try:
            Driver = get_driver_by_provider_name(drivers,
                                                 providers,
                                                 provider_name)
            result[provider_name] = Driver
        except ProviderNotSupportedError:
            continue
    return result

def get_driver_by_provider_name(drivers, providers, provider_name):
    """
    Get a driver by provider name
    If the provider is unknown, will raise an exception.

    :param drivers: Dictionary containing valid providers.

    :param providers: object that contain supported providers.
    :type providers: :class:`libcloud.types.Provider`

    :param    provider_name:   String with a provider name (required)
    :type     provider_name:   ``str``

    :return: :class:`NodeDriver`

    """
    provider_name = provider_name.upper()
    provider = getattr(providers, provider_name, None)
    try:
        Driver = get_driver(drivers, provider)
    except AttributeError:
        raise ProviderNotSupportedError(provider=provider_name)
    return Driver

def get_driver_instance(Driver, **kwargs):
    ph = _ParinxHandler()
    try:
        json_data = json.dumps(kwargs)
        driver_method = DriverMethod(Driver, '__init__')
        return driver_method.invoke(json_data)
    except MissingArguments, error:
        str_repr = ', '.join([ph.ARGS_TO_XHEADERS_DICT.get(arg, arg)
                              for arg in error.arguments])
        raise MissingHeadersError(headers=str_repr)

if __name__ == '__main__':
    cls = get_driver(Provider.EC2_US_WEST)
    #print dir(cls)
    DriverMethod(cls, 'create_node')
<commit_msg>update provider<commit_after># -*- coding:utf-8 -*-
# taken from libcloud.REST

import inspect
import re

#from libcloud.utils.misc import get_driver
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

from parinx.parser import parse_args, \
    parse_docstring, get_method_docstring
from parinx.parser import _ParinxHandler

from libcloudcli.errors import ProviderNotSupportedError,\
    MissingArguments, MissingHeadersError, MethodParsingException,\
    NoSuchOperationError

from entries import Entry
from parinx.utils import json

class DriverMethod(object):
    _type_name_pattern = r'.\{([_0-9a-zA-Z]+)\}'

    def __init__(self, driver_obj, method_name):
        if inspect.isclass(driver_obj):
            self.driver_cls = driver_obj
        else:
            self.driver_cls = driver_obj.__class__

        self.driver_obj = driver_obj
        self.method_name = method_name
        self.method = getattr(self.driver_obj, method_name, None)

        if not inspect.ismethod(self.method):
            raise NoSuchOperationError()
        method_doc = get_method_docstring(self.driver_cls, method_name)

        if not method_doc:
            raise MethodParsingException('Empty docstring')

        argspec_arg = parse_args(self.method)
        docstring_parse_result = parse_docstring(method_doc, self.driver_cls)
        self.description = docstring_parse_result['description']
        docstring_args = docstring_parse_result['arguments']

        #check vargs
        self.vargs_entries = []
        for name, arg_info in argspec_arg.iteritems():
            if name in docstring_args:
                docstring_arg = docstring_args[name]
                entry_kwargs = {
                    'name': name,
                    'description': docstring_arg['description'],
                    'type_name': docstring_arg['type_name'],
                    'required': (docstring_arg['required'] or
                                 arg_info['required']),
                }
                if not entry_kwargs['required'] and 'default' in arg_info:
                    entry_kwargs['default'] = arg_info['default']
                self.vargs_entries.append(Entry(**entry_kwargs))
            else:
                raise MethodParsingException(
                    '%s %s not described in docstring' % (method_name, name))

        #update kwargs
        kwargs = set(docstring_args).difference(argspec_arg)
        print kwargs
        '''
        self.kwargs_entries = [Entry(arg_name, **docstring_args[arg_name])
                               for arg_name in kwargs]
        method_return = docstring_parse_result['return']
        self.result_entry = Entry('', method_return['type_name'],
                                  method_return['description'], True)
        '''

    @classmethod
    def _remove_type_name_brackets(cls, type_name):
        return re.sub(cls._type_name_pattern, r'\1', type_name)

    def get_description(self):
        result_arguments = []

        for entry in self.vargs_entries:
            result_arguments.extend(entry.get_arguments())

        for entry in self.kwargs_entries:
            result_arguments.extend(entry.get_arguments())

        result = {'name': self.method_name,
                  'description': self.description,
                  'arguments': result_arguments,
                  'return': {
                      'type': self._remove_type_name_brackets(
                          self.result_entry.type_name),
                      'description': self.result_entry.description}
                  }
        return result

    def invoke_result_to_json(self, value):
        return self.result_entry.to_json(value)

    def invoke(self, data):
        vargs = [e.from_json(data, self.driver_obj)
                 for e in self.vargs_entries]
        kwargs = {}
        for kw_entry in self.kwargs_entries:
            try:
                kwargs[kw_entry.name] = kw_entry.from_json(data,
                                                           self.driver_obj)
            except MissingArguments:
                if kw_entry.required:
                    raise
        if self.method_name == '__init__':
            return self.driver_cls(*vargs, **kwargs)
        return self.method(*vargs, **kwargs)

def get_providers_info():
    """
    List of all supported providers.

    :param providers: object that contain supported providers.
    :type  providers: :class:`libcloud.compute.types.Provider`

    :return `list of dict objects`
    """
    result = []
    for provider, Driver in get_providers_dict().items():
        result.append({
            'id': provider,
            'friendly_name': getattr(Driver, 'name', ''),
            'website': getattr(Driver, 'website', ''),
        })
    return result

def get_providers_dict():
    result = {}
    for provider_name in Provider.__dict__.keys():
        if provider_name.startswith('_'):
            continue

        provider_name = provider_name.upper()
        try:
            Driver = get_driver_by_provider_name(provider_name)
            result[provider_name] = Driver
        except ProviderNotSupportedError:
            continue
    return result

def get_driver_by_provider_name(provider_name):
    """
    Get a driver by provider name
    If the provider is unknown, will raise an exception.

    :param drivers: Dictionary containing valid providers.

    :param provider: object that contain supported provider
    :type providers: :class:`libcloud.compute.types.Provider`

    :param    provider_name:   String with a provider name (required)
    :type     provider_name:   ``str``

    :return: :class:`NodeDriver`

    """
    provider_name = provider_name.upper()

    if ((provider_name == 'RACKSPACE_NOVA_DFW') or (provider_name == 'RACKSPACE_NOVA_BETA') or (provider_name == 'RACKSPACE_NOVA_ORD') or (provider_name == 'RACKSPACE_NOVA_LON')):
        provider_name = 'RACKSPACE'
    elif ((provider_name == 'RACKSPACE_UK')):
        provider_name = 'RACKSPACE_FIRST_GEN'
    else:
        "Name conflict"

    provider = getattr(Provider, provider_name, None)

    try:
        Driver = get_driver(provider)
    except AttributeError:
        raise ProviderNotSupportedError(provider=provider_name)
    return Driver

def get_driver_instance(Driver, **kwargs):
    ph = _ParinxHandler()
    try:
        json_data = json.dumps(kwargs)
        driver_method = DriverMethod(Driver, '__init__')
        return driver_method.invoke(json_data)
    except MissingArguments, error:
        str_repr = ', '.join([ph.ARGS_TO_XHEADERS_DICT.get(arg, arg)
                              for arg in error.arguments])
        raise MissingHeadersError(headers=str_repr)

if __name__ == '__main__':
    cls = get_driver(Provider.EC2_US_WEST)
    #print dir(cls)
    #DriverMethod(cls, 'create_node')
    #print get_driver_by_provider_name(Provider,  'EC2_US_EAST')
    #print get_providers_dict()
    #print get_providers_info()
    #print Provider.__dict__
<|endoftext|>


<commit_before>from django.core import meta
from django import templatetags
from django.conf import settings
from django.contrib.admin.views.decorators import staff_member_required
from django.models.core import sites
from django.core.extensions import DjangoContext, render_to_response
from django.core.exceptions import Http404, ViewDoesNotExist
from django.core import template, urlresolvers
from django.contrib.admin import utils
import inspect, os, re

# Exclude methods starting with these strings from documentation
MODEL_METHODS_EXCLUDE = ('_', 'add_', 'delete', 'save', 'set_')

def doc_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)
    return render_to_response('admin_doc/index', context_instance=DjangoContext(request))
doc_index = staff_member_required(doc_index)

def bookmarklets(request):
    # Hack! This couples this view to the URL it lives at.
    admin_root = request.path[:-len('doc/bookmarklets/')]
    return render_to_response('admin_doc/bookmarklets', {
        'admin_url': "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', request.META['HTTP_HOST'], admin_root),
    }, context_instance=DjangoContext(request))
bookmarklets = staff_member_required(bookmarklets)

def template_tag_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    load_all_installed_template_libraries()

    tags = []
    for module_name, library in template.libraries.items():
        for tag_name, tag_func in library.tags.items():
            title, body, metadata = utils.parse_docstring(tag_func.__doc__)
            if title:
                title = utils.parse_rst(title, 'tag', 'tag:' + tag_name)
            if body:
                body = utils.parse_rst(body, 'tag', 'tag:' + tag_name)
            for key in metadata:
                metadata[key] = utils.parse_rst(metadata[key], 'tag', 'tag:' + tag_name)
            if library in template.builtins:
                tag_library = None
            else:
                tag_library = module_name.split('.')[-1]
            tags.append({
                'name': tag_name,
                'title': title,
                'body': body,
                'meta': metadata,
                'library': tag_library,
            })

    return render_to_response('admin_doc/template_tag_index', {'tags': tags}, context_instance=DjangoContext(request))
template_tag_index = staff_member_required(template_tag_index)

def template_filter_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    load_all_installed_template_libraries()

    filters = []
    for module_name, library in template.libraries.items():
        for filter_name, filter_func in library.filters.items():
            title, body, metadata = utils.parse_docstring(filter_func.__doc__)
            if title:
                title = utils.parse_rst(title, 'filter', 'filter:' + filter_name)
            if body:
                body = utils.parse_rst(body, 'filter', 'filter:' + filter_name)
            for key in metadata:
                metadata[key] = utils.parse_rst(metadata[key], 'filter', 'filter:' + filter_name)
            if library in template.builtins:
                tag_library = None
            else:
                tag_library = module_name.split('.')[-1]
            filters.append({
                'name': filter_name,
                'title': title,
                'body': body,
                'meta': metadata,
                'library': tag_library,
            })
    return render_to_response('admin_doc/template_filter_index', {'filters': filters}, context_instance=DjangoContext(request))
template_filter_index = staff_member_required(template_filter_index)

def view_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    views = []
    for site_settings_module in settings.ADMIN_FOR:
        settings_mod = __import__(site_settings_module, '', '', [''])
        urlconf = __import__(settings_mod.ROOT_URLCONF, '', '', [''])
        view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
        for (func, regex) in view_functions:
            views.append({
                'name': func.__name__,
                'module': func.__module__,
                'site_id': settings_mod.SITE_ID,
                'site': sites.get_object(pk=settings_mod.SITE_ID),
                'url': simplify_regex(regex),
            })
    return render_to_response('admin_doc/view_index', {'views': views}, context_instance=DjangoContext(request))
view_index = staff_member_required(view_index)

def view_detail(request, view):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    mod, func = urlresolvers.get_mod_func(view)
    try:
        view_func = getattr(__import__(mod, '', '', ['']), func)
    except (ImportError, AttributeError):
        raise Http404
    title, body, metadata = utils.parse_docstring(view_func.__doc__)
    if title:
        title = utils.parse_rst(title, 'view', 'view:' + view)
    if body:
        body = utils.parse_rst(body, 'view', 'view:' + view)
    for key in metadata:
        metadata[key] = utils.parse_rst(metadata[key], 'model', 'view:' + view)
    return render_to_response('admin_doc/view_detail', {
        'name': view,
        'summary': title,
        'body': body,
        'meta': metadata,
    }, context_instance=DjangoContext(request))
view_detail = staff_member_required(view_detail)

def model_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    models = []
    for app in meta.get_installed_model_modules():
        for model in app._MODELS:
            opts = model._meta
            models.append({
                'name': '%s.%s' % (opts.app_label, opts.module_name),
                'module': opts.app_label,
                'class': opts.module_name,
            })
    return render_to_response('admin_doc/model_index', {'models': models}, context_instance=DjangoContext(request))
model_index = staff_member_required(model_index)

def model_detail(request, model):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    try:
        model = meta.get_app(model)
    except ImportError:
        raise Http404
    opts = model.Klass._meta

    # Gather fields/field descriptions
    fields = []
    for field in opts.fields:
        fields.append({
            'name': field.name,
            'data_type': get_readable_field_data_type(field),
            'verbose': field.verbose_name,
            'help': field.help_text,
        })
    for func_name, func in model.Klass.__dict__.items():
        if callable(func) and len(inspect.getargspec(func)[0]) == 0:
            try:
                for exclude in MODEL_METHODS_EXCLUDE:
                    if func_name.startswith(exclude):
                        raise StopIteration
            except StopIteration:
                continue
            verbose = func.__doc__
            if verbose:
                verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', 'model:' + opts.module_name)
            fields.append({
                'name': func_name,
                'data_type': get_return_data_type(func_name),
                'verbose': verbose,
            })
    return render_to_response('admin_doc/model_detail', {
        'name': '%s.%s' % (opts.app_label, opts.module_name),
        'summary': "Fields on %s objects" % opts.verbose_name,
        'description' : model.__doc__,
        'fields': fields,
    }, context_instance=DjangoContext(request))
model_detail = staff_member_required(model_detail)

def template_detail(request, template):
    templates = []
    for site_settings_module in settings.ADMIN_FOR:
        settings_mod = __import__(site_settings_module, '', '', [''])
        for dir in settings_mod.TEMPLATE_DIRS:
            template_file = os.path.join(dir, "%s.html" % template)
            templates.append({
                'file': template_file,
                'exists': os.path.exists(template_file),
                'contents': lambda: os.path.exists(template_file) and open(template_file).read() or '',
                'site_id': settings_mod.SITE_ID,
                'site': sites.get_object(pk=settings_mod.SITE_ID),
                'order': list(settings_mod.TEMPLATE_DIRS).index(dir),
            })
    return render_to_response('admin_doc/template_detail', {
        'name': template,
        'templates': templates,
    }, context_instance=DjangoContext(request))
template_detail = staff_member_required(template_detail)

####################
# Helper functions #
####################

def missing_docutils_page(request):
    """Display an error message for people without docutils"""
    return render_to_response('admin_doc/missing_docutils')

def load_all_installed_template_libraries():
    # Load/register all template tag libraries from installed apps.
    for e in templatetags.__path__:
        libraries = [os.path.splitext(p)[0] for p in os.listdir(e) if p.endswith('.py') and p[0].isalpha()]
        for library_name in libraries:
            try:
                lib = template.get_library("django.templatetags.%s" % library_name.split('.')[-1])
            except template.InvalidTemplateLibrary:
                pass

def get_return_data_type(func_name):
    """Return a somewhat-helpful data type given a function name"""
    if func_name.startswith('get_'):
        if func_name.endswith('_list'):
            return 'List'
        elif func_name.endswith('_count'):
            return 'Integer'
    return ''

# Maps Field objects to their human-readable data types, as strings.
# Column-type strings can contain format strings; they'll be interpolated
# against the values of Field.__dict__ before being output.
# If a column type is set to None, it won't be included in the output.
DATA_TYPE_MAPPING = {
    'AutoField'                 : _('Integer'),
    'BooleanField'              : _('Boolean (Either True or False)'),
    'CharField'                 : _('String (up to %(maxlength)s)'),
    'CommaSeparatedIntegerField': _('Comma-separated integers'),
    'DateField'                 : _('Date (without time)'),
    'DateTimeField'             : _('Date (with time)'),
    'EmailField'                : _('E-mail address'),
    'FileField'                 : _('File path'),
    'FloatField'                : _('Decimal number'),
    'ForeignKey'                : _('Integer'),
    'ImageField'                : _('File path'),
    'IntegerField'              : _('Integer'),
    'IPAddressField'            : _('IP address'),
    'ManyToManyField'           : '',
    'NullBooleanField'          : _('Boolean (Either True, False or None)'),
    'OneToOneField'             : _('Relation to parent model'),
    'PhoneNumberField'          : _('Phone number'),
    'PositiveIntegerField'      : _('Integer'),
    'PositiveSmallIntegerField' : _('Integer'),
    'SlugField'                 : _('String (up to %(maxlength)s)'),
    'SmallIntegerField'         : _('Integer'),
    'TextField'                 : _('Text'),
    'TimeField'                 : _('Time'),
    'URLField'                  : _('URL'),
    'USStateField'              : _('U.S. state (two uppercase letters)'),
    'XMLField'                  : _('XML text'),
}

def get_readable_field_data_type(field):
    # ForeignKey is a special case. Use the field type of the relation.
    if field.get_internal_type() == 'ForeignKey':
        field = field.rel.get_related_field()
    return DATA_TYPE_MAPPING[field.get_internal_type()] % field.__dict__

def extract_views_from_urlpatterns(urlpatterns, base=''):
    """
    Return a list of views from a list of urlpatterns.

    Each object in the returned list is a two-tuple: (view_func, regex)
    """
    views = []
    for p in urlpatterns:
        if hasattr(p, 'get_callback'):
            try:
                views.append((p.get_callback(), base + p.regex.pattern))
            except ViewDoesNotExist:
                continue
        elif hasattr(p, '_get_url_patterns'):
            views.extend(extract_views_from_urlpatterns(p.url_patterns, base + p.regex.pattern))
        else:
            raise TypeError, "%s does not appear to be a urlpattern object" % p
    return views

# Clean up urlpattern regexes into something somewhat readable by Mere Humans:
# turns something like "^(?P<sport_slug>\w+)/athletes/(?P<athlete_slug>\w+)/$"
# into "<sport_slug>/athletes/<athlete_slug>/"

named_group_matcher = re.compile(r'\(\?P(<\w+>).+?\)')

def simplify_regex(pattern):
    pattern = named_group_matcher.sub(lambda m: m.group(1), pattern)
    pattern = pattern.replace('^', '').replace('$', '').replace('?', '').replace('//', '/')
    if not pattern.startswith('/'):
        pattern = '/' + pattern
    return pattern
<commit_msg>Negligible formatting change to [2417] -- changed colon use to be consistent<commit_after>from django.core import meta
from django import templatetags
from django.conf import settings
from django.contrib.admin.views.decorators import staff_member_required
from django.models.core import sites
from django.core.extensions import DjangoContext, render_to_response
from django.core.exceptions import Http404, ViewDoesNotExist
from django.core import template, urlresolvers
from django.contrib.admin import utils
import inspect, os, re

# Exclude methods starting with these strings from documentation
MODEL_METHODS_EXCLUDE = ('_', 'add_', 'delete', 'save', 'set_')

def doc_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)
    return render_to_response('admin_doc/index', context_instance=DjangoContext(request))
doc_index = staff_member_required(doc_index)

def bookmarklets(request):
    # Hack! This couples this view to the URL it lives at.
    admin_root = request.path[:-len('doc/bookmarklets/')]
    return render_to_response('admin_doc/bookmarklets', {
        'admin_url': "%s://%s%s" % (os.environ.get('HTTPS') == 'on' and 'https' or 'http', request.META['HTTP_HOST'], admin_root),
    }, context_instance=DjangoContext(request))
bookmarklets = staff_member_required(bookmarklets)

def template_tag_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    load_all_installed_template_libraries()

    tags = []
    for module_name, library in template.libraries.items():
        for tag_name, tag_func in library.tags.items():
            title, body, metadata = utils.parse_docstring(tag_func.__doc__)
            if title:
                title = utils.parse_rst(title, 'tag', 'tag:' + tag_name)
            if body:
                body = utils.parse_rst(body, 'tag', 'tag:' + tag_name)
            for key in metadata:
                metadata[key] = utils.parse_rst(metadata[key], 'tag', 'tag:' + tag_name)
            if library in template.builtins:
                tag_library = None
            else:
                tag_library = module_name.split('.')[-1]
            tags.append({
                'name': tag_name,
                'title': title,
                'body': body,
                'meta': metadata,
                'library': tag_library,
            })

    return render_to_response('admin_doc/template_tag_index', {'tags': tags}, context_instance=DjangoContext(request))
template_tag_index = staff_member_required(template_tag_index)

def template_filter_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    load_all_installed_template_libraries()

    filters = []
    for module_name, library in template.libraries.items():
        for filter_name, filter_func in library.filters.items():
            title, body, metadata = utils.parse_docstring(filter_func.__doc__)
            if title:
                title = utils.parse_rst(title, 'filter', 'filter:' + filter_name)
            if body:
                body = utils.parse_rst(body, 'filter', 'filter:' + filter_name)
            for key in metadata:
                metadata[key] = utils.parse_rst(metadata[key], 'filter', 'filter:' + filter_name)
            if library in template.builtins:
                tag_library = None
            else:
                tag_library = module_name.split('.')[-1]
            filters.append({
                'name': filter_name,
                'title': title,
                'body': body,
                'meta': metadata,
                'library': tag_library,
            })
    return render_to_response('admin_doc/template_filter_index', {'filters': filters}, context_instance=DjangoContext(request))
template_filter_index = staff_member_required(template_filter_index)

def view_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    views = []
    for site_settings_module in settings.ADMIN_FOR:
        settings_mod = __import__(site_settings_module, '', '', [''])
        urlconf = __import__(settings_mod.ROOT_URLCONF, '', '', [''])
        view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
        for (func, regex) in view_functions:
            views.append({
                'name': func.__name__,
                'module': func.__module__,
                'site_id': settings_mod.SITE_ID,
                'site': sites.get_object(pk=settings_mod.SITE_ID),
                'url': simplify_regex(regex),
            })
    return render_to_response('admin_doc/view_index', {'views': views}, context_instance=DjangoContext(request))
view_index = staff_member_required(view_index)

def view_detail(request, view):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    mod, func = urlresolvers.get_mod_func(view)
    try:
        view_func = getattr(__import__(mod, '', '', ['']), func)
    except (ImportError, AttributeError):
        raise Http404
    title, body, metadata = utils.parse_docstring(view_func.__doc__)
    if title:
        title = utils.parse_rst(title, 'view', 'view:' + view)
    if body:
        body = utils.parse_rst(body, 'view', 'view:' + view)
    for key in metadata:
        metadata[key] = utils.parse_rst(metadata[key], 'model', 'view:' + view)
    return render_to_response('admin_doc/view_detail', {
        'name': view,
        'summary': title,
        'body': body,
        'meta': metadata,
    }, context_instance=DjangoContext(request))
view_detail = staff_member_required(view_detail)

def model_index(request):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    models = []
    for app in meta.get_installed_model_modules():
        for model in app._MODELS:
            opts = model._meta
            models.append({
                'name': '%s.%s' % (opts.app_label, opts.module_name),
                'module': opts.app_label,
                'class': opts.module_name,
            })
    return render_to_response('admin_doc/model_index', {'models': models}, context_instance=DjangoContext(request))
model_index = staff_member_required(model_index)

def model_detail(request, model):
    if not utils.docutils_is_available:
        return missing_docutils_page(request)

    try:
        model = meta.get_app(model)
    except ImportError:
        raise Http404
    opts = model.Klass._meta

    # Gather fields/field descriptions
    fields = []
    for field in opts.fields:
        fields.append({
            'name': field.name,
            'data_type': get_readable_field_data_type(field),
            'verbose': field.verbose_name,
            'help': field.help_text,
        })
    for func_name, func in model.Klass.__dict__.items():
        if callable(func) and len(inspect.getargspec(func)[0]) == 0:
            try:
                for exclude in MODEL_METHODS_EXCLUDE:
                    if func_name.startswith(exclude):
                        raise StopIteration
            except StopIteration:
                continue
            verbose = func.__doc__
            if verbose:
                verbose = utils.parse_rst(utils.trim_docstring(verbose), 'model', 'model:' + opts.module_name)
            fields.append({
                'name': func_name,
                'data_type': get_return_data_type(func_name),
                'verbose': verbose,
            })
    return render_to_response('admin_doc/model_detail', {
        'name': '%s.%s' % (opts.app_label, opts.module_name),
        'summary': "Fields on %s objects" % opts.verbose_name,
        'description': model.__doc__,
        'fields': fields,
    }, context_instance=DjangoContext(request))
model_detail = staff_member_required(model_detail)

def template_detail(request, template):
    templates = []
    for site_settings_module in settings.ADMIN_FOR:
        settings_mod = __import__(site_settings_module, '', '', [''])
        for dir in settings_mod.TEMPLATE_DIRS:
            template_file = os.path.join(dir, "%s.html" % template)
            templates.append({
                'file': template_file,
                'exists': os.path.exists(template_file),
                'contents': lambda: os.path.exists(template_file) and open(template_file).read() or '',
                'site_id': settings_mod.SITE_ID,
                'site': sites.get_object(pk=settings_mod.SITE_ID),
                'order': list(settings_mod.TEMPLATE_DIRS).index(dir),
            })
    return render_to_response('admin_doc/template_detail', {
        'name': template,
        'templates': templates,
    }, context_instance=DjangoContext(request))
template_detail = staff_member_required(template_detail)

####################
# Helper functions #
####################

def missing_docutils_page(request):
    """Display an error message for people without docutils"""
    return render_to_response('admin_doc/missing_docutils')

def load_all_installed_template_libraries():
    # Load/register all template tag libraries from installed apps.
    for e in templatetags.__path__:
        libraries = [os.path.splitext(p)[0] for p in os.listdir(e) if p.endswith('.py') and p[0].isalpha()]
        for library_name in libraries:
            try:
                lib = template.get_library("django.templatetags.%s" % library_name.split('.')[-1])
            except template.InvalidTemplateLibrary:
                pass

def get_return_data_type(func_name):
    """Return a somewhat-helpful data type given a function name"""
    if func_name.startswith('get_'):
        if func_name.endswith('_list'):
            return 'List'
        elif func_name.endswith('_count'):
            return 'Integer'
    return ''

# Maps Field objects to their human-readable data types, as strings.
# Column-type strings can contain format strings; they'll be interpolated
# against the values of Field.__dict__ before being output.
# If a column type is set to None, it won't be included in the output.
DATA_TYPE_MAPPING = {
    'AutoField'                 : _('Integer'),
    'BooleanField'              : _('Boolean (Either True or False)'),
    'CharField'                 : _('String (up to %(maxlength)s)'),
    'CommaSeparatedIntegerField': _('Comma-separated integers'),
    'DateField'                 : _('Date (without time)'),
    'DateTimeField'             : _('Date (with time)'),
    'EmailField'                : _('E-mail address'),
    'FileField'                 : _('File path'),
    'FloatField'                : _('Decimal number'),
    'ForeignKey'                : _('Integer'),
    'ImageField'                : _('File path'),
    'IntegerField'              : _('Integer'),
    'IPAddressField'            : _('IP address'),
    'ManyToManyField'           : '',
    'NullBooleanField'          : _('Boolean (Either True, False or None)'),
    'OneToOneField'             : _('Relation to parent model'),
    'PhoneNumberField'          : _('Phone number'),
    'PositiveIntegerField'      : _('Integer'),
    'PositiveSmallIntegerField' : _('Integer'),
    'SlugField'                 : _('String (up to %(maxlength)s)'),
    'SmallIntegerField'         : _('Integer'),
    'TextField'                 : _('Text'),
    'TimeField'                 : _('Time'),
    'URLField'                  : _('URL'),
    'USStateField'              : _('U.S. state (two uppercase letters)'),
    'XMLField'                  : _('XML text'),
}

def get_readable_field_data_type(field):
    # ForeignKey is a special case. Use the field type of the relation.
    if field.get_internal_type() == 'ForeignKey':
        field = field.rel.get_related_field()
    return DATA_TYPE_MAPPING[field.get_internal_type()] % field.__dict__

def extract_views_from_urlpatterns(urlpatterns, base=''):
    """
    Return a list of views from a list of urlpatterns.

    Each object in the returned list is a two-tuple: (view_func, regex)
    """
    views = []
    for p in urlpatterns:
        if hasattr(p, 'get_callback'):
            try:
                views.append((p.get_callback(), base + p.regex.pattern))
            except ViewDoesNotExist:
                continue
        elif hasattr(p, '_get_url_patterns'):
            views.extend(extract_views_from_urlpatterns(p.url_patterns, base + p.regex.pattern))
        else:
            raise TypeError, "%s does not appear to be a urlpattern object" % p
    return views

# Clean up urlpattern regexes into something somewhat readable by Mere Humans:
# turns something like "^(?P<sport_slug>\w+)/athletes/(?P<athlete_slug>\w+)/$"
# into "<sport_slug>/athletes/<athlete_slug>/"

named_group_matcher = re.compile(r'\(\?P(<\w+>).+?\)')

def simplify_regex(pattern):
    pattern = named_group_matcher.sub(lambda m: m.group(1), pattern)
    pattern = pattern.replace('^', '').replace('$', '').replace('?', '').replace('//', '/')
    if not pattern.startswith('/'):
        pattern = '/' + pattern
    return pattern
<|endoftext|>


<commit_before>from functools import partial

from django.contrib import auth
from django.contrib.auth import load_backend
from django.contrib.auth.backends import RemoteUserBackend
from django.core.exceptions import ImproperlyConfigured
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import SimpleLazyObject

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'session'), (
            "The Django authentication middleware requires session middleware "
            "to be installed. Edit your MIDDLEWARE setting to insert "
            "'django.contrib.sessions.middleware.SessionMiddleware' before "
            "'django.contrib.auth.middleware.AuthenticationMiddleware'."
        )
        request.user = SimpleLazyObject(partial(auth.get_user, request))

class RemoteUserMiddleware(MiddlewareMixin):
    """
    Middleware for utilizing Web-server-provided authentication.

    If request.user is not authenticated, then this middleware attempts to
    authenticate the username passed in the ``REMOTE_USER`` request header.
    If authentication is successful, the user is automatically logged in to
    persist the user in the session.

    The header used is configurable and defaults to ``REMOTE_USER``.  Subclass
    this class and change the ``header`` attribute if you need to use a
    different header.
    """

    # Name of request header to grab username from.  This will be the key as
    # used in the request.META dictionary, i.e. the normalization of headers to
    # all uppercase and the addition of "HTTP_" prefix apply.
    header = "REMOTE_USER"
    force_logout_if_no_header = True

    def process_request(self, request):
        # AuthenticationMiddleware is required so that request.user exists.
        if not hasattr(request, 'user'):
            raise ImproperlyConfigured(
                "The Django remote user auth middleware requires the"
                " authentication middleware to be installed.  Edit your"
                " MIDDLEWARE setting to insert"
                " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
                " before the RemoteUserMiddleware class.")
        try:
            username = request.META[self.header]
        except KeyError:
            # If specified header doesn't exist then remove any existing
            # authenticated remote-user, or return (leaving request.user set to
            # AnonymousUser by the AuthenticationMiddleware).
            if self.force_logout_if_no_header and request.user.is_authenticated:
                self._remove_invalid_user(request)
            return
        # If the user is already authenticated and that user is the user we are
        # getting passed in the headers, then the correct user is already
        # persisted in the session and we don't need to continue.
        if request.user.is_authenticated:
            if request.user.get_username() == self.clean_username(username, request):
                return
            else:
                # An authenticated user is associated with the request, but
                # it does not match the authorized user in the header.
                self._remove_invalid_user(request)

        # We are seeing this user for the first time in this session, attempt
        # to authenticate the user.
        user = auth.authenticate(request, remote_user=username)
        if user:
            # User is valid.  Set request.user and persist user in the session
            # by logging the user in.
            request.user = user
            auth.login(request, user)

    def clean_username(self, username, request):
        """
        Allow the backend to clean the username, if the backend defines a
        clean_username method.
        """
        backend_str = request.session[auth.BACKEND_SESSION_KEY]
        backend = auth.load_backend(backend_str)
        try:
            username = backend.clean_username(username)
        except AttributeError:  # Backend has no clean_username method.
            pass
        return username

    def _remove_invalid_user(self, request):
        """
        Remove the current authenticated user in the request which is invalid
        but only if the user is authenticated via the RemoteUserBackend.
        """
        try:
            stored_backend = load_backend(request.session.get(auth.BACKEND_SESSION_KEY, ''))
        except ImportError:
            # backend failed to load
            auth.logout(request)
        else:
            if isinstance(stored_backend, RemoteUserBackend):
                auth.logout(request)

class PersistentRemoteUserMiddleware(RemoteUserMiddleware):
    """
    Middleware for Web-server provided authentication on logon pages.

    Like RemoteUserMiddleware but keeps the user authenticated even if
    the header (``REMOTE_USER``) is not found in the request. Useful
    for setups when the external authentication via ``REMOTE_USER``
    is only expected to happen on some "logon" URL and the rest of
    the application wants to use Django's authentication mechanism.
    """
    force_logout_if_no_header = False
<commit_msg>Fixed #30941 -- Reverted "Simplified AuthenticationMiddleware a bit."<commit_after>from django.contrib import auth
from django.contrib.auth import load_backend
from django.contrib.auth.backends import RemoteUserBackend
from django.core.exceptions import ImproperlyConfigured
from django.utils.deprecation import MiddlewareMixin
from django.utils.functional import SimpleLazyObject

def get_user(request):
    if not hasattr(request, '_cached_user'):
        request._cached_user = auth.get_user(request)
    return request._cached_user

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        assert hasattr(request, 'session'), (
            "The Django authentication middleware requires session middleware "
            "to be installed. Edit your MIDDLEWARE setting to insert "
            "'django.contrib.sessions.middleware.SessionMiddleware' before "
            "'django.contrib.auth.middleware.AuthenticationMiddleware'."
        )
        request.user = SimpleLazyObject(lambda: get_user(request))

class RemoteUserMiddleware(MiddlewareMixin):
    """
    Middleware for utilizing Web-server-provided authentication.

    If request.user is not authenticated, then this middleware attempts to
    authenticate the username passed in the ``REMOTE_USER`` request header.
    If authentication is successful, the user is automatically logged in to
    persist the user in the session.

    The header used is configurable and defaults to ``REMOTE_USER``.  Subclass
    this class and change the ``header`` attribute if you need to use a
    different header.
    """

    # Name of request header to grab username from.  This will be the key as
    # used in the request.META dictionary, i.e. the normalization of headers to
    # all uppercase and the addition of "HTTP_" prefix apply.
    header = "REMOTE_USER"
    force_logout_if_no_header = True

    def process_request(self, request):
        # AuthenticationMiddleware is required so that request.user exists.
        if not hasattr(request, 'user'):
            raise ImproperlyConfigured(
                "The Django remote user auth middleware requires the"
                " authentication middleware to be installed.  Edit your"
                " MIDDLEWARE setting to insert"
                " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
                " before the RemoteUserMiddleware class.")
        try:
            username = request.META[self.header]
        except KeyError:
            # If specified header doesn't exist then remove any existing
            # authenticated remote-user, or return (leaving request.user set to
            # AnonymousUser by the AuthenticationMiddleware).
            if self.force_logout_if_no_header and request.user.is_authenticated:
                self._remove_invalid_user(request)
            return
        # If the user is already authenticated and that user is the user we are
        # getting passed in the headers, then the correct user is already
        # persisted in the session and we don't need to continue.
        if request.user.is_authenticated:
            if request.user.get_username() == self.clean_username(username, request):
                return
            else:
                # An authenticated user is associated with the request, but
                # it does not match the authorized user in the header.
                self._remove_invalid_user(request)

        # We are seeing this user for the first time in this session, attempt
        # to authenticate the user.
        user = auth.authenticate(request, remote_user=username)
        if user:
            # User is valid.  Set request.user and persist user in the session
            # by logging the user in.
            request.user = user
            auth.login(request, user)

    def clean_username(self, username, request):
        """
        Allow the backend to clean the username, if the backend defines a
        clean_username method.
        """
        backend_str = request.session[auth.BACKEND_SESSION_KEY]
        backend = auth.load_backend(backend_str)
        try:
            username = backend.clean_username(username)
        except AttributeError:  # Backend has no clean_username method.
            pass
        return username

    def _remove_invalid_user(self, request):
        """
        Remove the current authenticated user in the request which is invalid
        but only if the user is authenticated via the RemoteUserBackend.
        """
        try:
            stored_backend = load_backend(request.session.get(auth.BACKEND_SESSION_KEY, ''))
        except ImportError:
            # backend failed to load
            auth.logout(request)
        else:
            if isinstance(stored_backend, RemoteUserBackend):
                auth.logout(request)

class PersistentRemoteUserMiddleware(RemoteUserMiddleware):
    """
    Middleware for Web-server provided authentication on logon pages.

    Like RemoteUserMiddleware but keeps the user authenticated even if
    the header (``REMOTE_USER``) is not found in the request. Useful
    for setups when the external authentication via ``REMOTE_USER``
    is only expected to happen on some "logon" URL and the rest of
    the application wants to use Django's authentication mechanism.
    """
    force_logout_if_no_header = False
<|endoftext|>


<commit_before>"""
Cross Site Request Forgery Middleware.

This module provides a middleware that implements protection
against request forgeries from other sites.
"""

import re
import itertools
try:
    from functools import wraps
except ImportError:
    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.

from django.conf import settings
from django.http import HttpResponseForbidden
from django.utils.hashcompat import md5_constructor
from django.utils.safestring import mark_safe

_ERROR_MSG = mark_safe('
403 Forbidden

Cross Site Request Forgery detected. Request aborted.
')

_POST_FORM_RE = \
    re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)

_HTML_TYPES = ('text/html', 'application/xhtml+xml')

def _make_token(session_id):
    return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()

class CsrfViewMiddleware(object):
    """
    Middleware that requires a present and correct csrfmiddlewaretoken
    for POST requests that have an active session.
    """
    def process_view(self, request, callback, callback_args, callback_kwargs):
        if request.method == 'POST':
            if getattr(callback, 'csrf_exempt', False):
                return None

            if request.is_ajax():
                return None

            try:
                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
            except KeyError:
                # No session, no check required
                return None

            csrf_token = _make_token(session_id)
            # check incoming token
            try:
                request_csrf_token = request.POST['csrfmiddlewaretoken']
            except KeyError:
                return HttpResponseForbidden(_ERROR_MSG)

            if request_csrf_token != csrf_token:
                return HttpResponseForbidden(_ERROR_MSG)

        return None

class CsrfResponseMiddleware(object):
    """
    Middleware that post-processes a response to add a
    csrfmiddlewaretoken if the response/request have an active
    session.
    """
    def process_response(self, request, response):
        csrf_token = None
        try:
            cookie = response.cookies[settings.SESSION_COOKIE_NAME]
            csrf_token = _make_token(cookie.value)
        except KeyError:
            # No outgoing cookie to set session, but
            # a session might already exist.
            try:
                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
                csrf_token = _make_token(session_id)
            except KeyError:
                # no incoming or outgoing cookie
                pass

        if csrf_token is not None and \
                response['Content-Type'].split(';')[0] in _HTML_TYPES:

            # ensure we don't add the 'id' attribute twice (HTML validity)
            idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
                                            itertools.repeat(''))
            def add_csrf_field(match):
                """Returns the matched <form> tag plus the added <input> element"""
                return mark_safe(match.group() + "
" + \
                "<input type='hidden' " + idattributes.next() + \
                " name='csrfmiddlewaretoken' value='" + csrf_token + \
                "' />
")

            # Modify any POST forms
            response.content = _POST_FORM_RE.sub(add_csrf_field, response.content)
        return response

class CsrfMiddleware(CsrfViewMiddleware, CsrfResponseMiddleware):
    """Django middleware that adds protection against Cross Site
    Request Forgeries by adding hidden form fields to POST forms and
    checking requests for the correct value.

    In the list of middlewares, SessionMiddleware is required, and
    must come after this middleware.  CsrfMiddleWare must come after
    compression middleware.

    If a session ID cookie is present, it is hashed with the
    SECRET_KEY setting to create an authentication token.  This token
    is added to all outgoing POST forms and is expected on all
    incoming POST requests that have a session ID cookie.

    If you are setting cookies directly, instead of using Django's
    session framework, this middleware will not work.

    CsrfMiddleWare is composed of two middleware, CsrfViewMiddleware
    and CsrfResponseMiddleware which can be used independently.
    """
    pass

def csrf_exempt(view_func):
    """
    Marks a view function as being exempt from the CSRF checks
    """
    def wrapped_view(*args, **kwargs):
        return view_func(*args, **kwargs)
    # We could just do view.csrf_exempt = True, but decorators are
    # nicer if they don't have side-effects.
    wrapped_view.csrf_exempt = True
    return wraps(view_func)(wrapped_view)
<commit_msg>Added some explanatory comments in CsrfMiddleware<commit_after>"""
Cross Site Request Forgery Middleware.

This module provides a middleware that implements protection
against request forgeries from other sites.
"""

import re
import itertools
try:
    from functools import wraps
except ImportError:
    from django.utils.functional import wraps  # Python 2.3, 2.4 fallback.

from django.conf import settings
from django.http import HttpResponseForbidden
from django.utils.hashcompat import md5_constructor
from django.utils.safestring import mark_safe

_ERROR_MSG = mark_safe('
403 Forbidden

Cross Site Request Forgery detected. Request aborted.
')

_POST_FORM_RE = \
    re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)

_HTML_TYPES = ('text/html', 'application/xhtml+xml')

def _make_token(session_id):
    return md5_constructor(settings.SECRET_KEY + session_id).hexdigest()

class CsrfViewMiddleware(object):
    """
    Middleware that requires a present and correct csrfmiddlewaretoken
    for POST requests that have an active session.
    """
    def process_view(self, request, callback, callback_args, callback_kwargs):
        if request.method == 'POST':
            if getattr(callback, 'csrf_exempt', False):
                return None

            if request.is_ajax():
                return None

            try:
                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
            except KeyError:
                # No session, no check required
                return None

            csrf_token = _make_token(session_id)
            # check incoming token
            try:
                request_csrf_token = request.POST['csrfmiddlewaretoken']
            except KeyError:
                return HttpResponseForbidden(_ERROR_MSG)

            if request_csrf_token != csrf_token:
                return HttpResponseForbidden(_ERROR_MSG)

        return None

class CsrfResponseMiddleware(object):
    """
    Middleware that post-processes a response to add a
    csrfmiddlewaretoken if the response/request have an active
    session.
    """
    def process_response(self, request, response):
        csrf_token = None
        try:
            # This covers a corner case in which the outgoing request
            # both contains a form and sets a session cookie.  This
            # really should not be needed, since it is best if views
            # that create a new session (login pages) also do a
            # redirect, as is done by all such view functions in
            # Django.
            cookie = response.cookies[settings.SESSION_COOKIE_NAME]
            csrf_token = _make_token(cookie.value)
        except KeyError:
            # Normal case - look for existing session cookie
            try:
                session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
                csrf_token = _make_token(session_id)
            except KeyError:
                # no incoming or outgoing cookie
                pass

        if csrf_token is not None and \
                response['Content-Type'].split(';')[0] in _HTML_TYPES:

            # ensure we don't add the 'id' attribute twice (HTML validity)
            idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
                                            itertools.repeat(''))
            def add_csrf_field(match):
                """Returns the matched <form> tag plus the added <input> element"""
                return mark_safe(match.group() + "
" + \
                "<input type='hidden' " + idattributes.next() + \
                " name='csrfmiddlewaretoken' value='" + csrf_token + \
                "' />
")

            # Modify any POST forms
            response.content = _POST_FORM_RE.sub(add_csrf_field, response.content)
        return response

class CsrfMiddleware(CsrfViewMiddleware, CsrfResponseMiddleware):
    """Django middleware that adds protection against Cross Site
    Request Forgeries by adding hidden form fields to POST forms and
    checking requests for the correct value.

    In the list of middlewares, SessionMiddleware is required, and
    must come after this middleware.  CsrfMiddleWare must come after
    compression middleware.

    If a session ID cookie is present, it is hashed with the
    SECRET_KEY setting to create an authentication token.  This token
    is added to all outgoing POST forms and is expected on all
    incoming POST requests that have a session ID cookie.

    If you are setting cookies directly, instead of using Django's
    session framework, this middleware will not work.

    CsrfMiddleWare is composed of two middleware, CsrfViewMiddleware
    and CsrfResponseMiddleware which can be used independently.
    """
    pass

def csrf_exempt(view_func):
    """
    Marks a view function as being exempt from the CSRF checks
    """
    def wrapped_view(*args, **kwargs):
        return view_func(*args, **kwargs)
    # We could just do view.csrf_exempt = True, but decorators are
    # nicer if they don't have side-effects.
    wrapped_view.csrf_exempt = True
    return wraps(view_func)(wrapped_view)
<|endoftext|>