<commit_before>from scipy.interpolate import interp1d
import numpy as np
import math

from airfoil_module import CST, create_x
def taper_function(eta, shape = 'linear', points = {'eta':[0,1], 'chord':[1,.7]}):
    """Calculate chord along span of the wing.

    - If linear, taper function is a conjuction of lines connecting points
    - Possible shapes are the same as interp1d: ('linear', 'nearest',
        'zero', 'slinear', 'quadratic', 'cubic' where 'zero', 'slinear',
         'quadratic' and 'cubic' refer to a spline interpolation of zeroth,
          first, second or third order"""
    function = interp1d(points['eta'], points['chord'])
    return function(eta)

def twist_function(eta, shape = 'linear', points = {'eta':[0,1], 'delta_twist':[0,.1]}):
    """Calculate chord along span of the wing.

    - If linear, taper function is a conjuction of lines connecting points
    - Possible shapes are the same as interp1d: ('linear', 'nearest',
        'zero', 'slinear', 'quadratic', 'cubic' where 'zero', 'slinear',
         'quadratic' and 'cubic' refer to a spline interpolation of zeroth,
          first, second or third order"""
    function = interp1d(points['eta'], points['delta_twist'])
    return function(eta)

def CST_3D(Bu, Bl, span, N={'eta':[0,1], 'N1':[.5, .5], 'N2':[1., 1.], 'chord':[1., 0]},
           mesh = (100,100), chord = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial':1., 'final':0.1},
           sweep = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial':0, 'final':0},
           twist = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial':0, 'final':1}):
    """
    - Bu: upper shape coefficients
    - Bl: lower shape coefficients
    - mesh: list of number of points in x and y
    """
    def S(B, psi, eta):
        """ Cross section shape function. Validated for high dimensions.
           To debug just verify if it turns all ones when B=ones"""
        def S_i(r, n, psi):
            """Shape function"""
            value = K(r,n)*(psi**r)*(1.-psi)**(n-r)
            return value

        # Bersntein Polynomial
        def K(r,n):
            K=math.factorial(n)/(math.factorial(r)*math.factorial(n-r))
            return K

        Nx = len(B)-1
        Ny = len(B[0])-1

        output = 0
        for i in range(Nx+1):
            for j in range(Ny+1):
                output += B[i][j]*S_i(i, Nx, psi)*S_i(j, Ny, eta)
        return output

    def C(psi, eta):
        """Class function"""
        psi_max = N1(eta)/(N1(eta)+N2(eta))
        C_max = 2*((psi_max)**N1(eta))*((1.-psi_max)**N2(eta))
        output = ((psi)**N1(eta))*((1.-psi)**N2(eta))/C_max/2
        return output

    # Define non-dimensional domains
    psi = np.linspace(0,1,mesh[1])
    eta = np.linspace(0,1,mesh[1])
    zeta_u = np.zeros(mesh)
    zeta_l = np.zeros(mesh)

    # Interpolate class function coefficients
    N1 = interp1d(N['eta'], N['N1'])
    N2 = interp1d(N['eta'], N['N2'])

    print 'N1',N1(eta)

    for i in range(mesh[0]):
        for j in range(mesh[1]):
            zeta_u[j][i] = C(psi[i], eta[j])*S(Bu, psi[i], eta[j])
            zeta_l[j][i] = -C(psi[i], eta[j])*S(Bl, psi[i], eta[j])

    chord_distribution = CST(eta, chord['eta'][1], chord['initial'], Au=chord['A'], N1=chord['N1'], N2=chord['N2'], deltasLE=chord['final'])
    sweep_distribution = CST(eta, sweep['eta'][1], deltasz = sweep['final'], Au=sweep['A'], N1=sweep['N1'], N2=sweep['N2'])
    chord_distribution = chord_distribution[::-1]
    sweep_distribution = sweep_distribution
    twist_distribution = CST(eta, twist['eta'][1], twist['initial'], Au=twist['A'], N1=twist['N1'], N2=twist['N2'], deltasLE=twist['final'])
    # taper_function(eta, shape = 'linear', N)
    x = np.zeros(len(psi))
    for i in range(len(x)):
        x[i] = psi[i]*chord_distribution[i]
    print 'chord'
    print chord
    print chord_distribution
    print 'sweep'
    print sweep_distribution
    y = eta

    X = np.zeros(mesh)
    Y = np.zeros(mesh)
    Z_u = np.zeros(mesh)
    Z_l = np.zeros(mesh)
    for i in range(mesh[0]):
        for j in range(mesh[1]):
            X[j][i] = psi[i]*chord_distribution[j] - sweep_distribution[j] -.5*chord['initial']
            Y[j][i] = span*eta[j]
            Z_u[j][i] = zeta_u[j][i] *chord_distribution[j]
            Z_l[j][i] = zeta_l[j][i] *chord_distribution[j]
            if twist != None:
                X_u[j][i] = X[j][i]*math.cos(twist_distribution[j])-Z_u[j][i]*math.sin(twist_distribution[j])
                X_l[j][i] = X[j][i]*math.cos(twist_distribution[j])-Z_l[j][i]*math.sin(twist_distribution[j])
                Z_u[j][i] = X[j][i]*math.sin(twist_distribution[j])+Z_u[j][i]*math.cos(twist_distribution[j])
                Z_l[j][i] = X[j][i]*math.sin(twist_distribution[j])+Z_l[j][i]*math.cos(twist_distribution[j])
    if twist == None:
        return [X,Y,Z_u,Z_l]
    else:
        return [X_u,Z_l,Y,Z_u,Z_l]

if __name__ == '__main__':
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    from matplotlib import cm

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Inputs
    # One of the diameters
    initial_chord = 2.
    final_chord = 1.
    # Nosecone height
    span = 4.
    # Shape coefficient for cross section (if A=1, circular, otherwise it is an ellipse)
    A = .5
    # location of the nosecone tip
    initial_nosecone_x = 0
    final_nosecone_x = -2.
    # Class coefficient for chord distribution (Nb=.5, elliptical, Nb=1, Haack series)
    Nb = 0.0
    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    B = [[A], [A]]
    #B = [[A], [A]]
    Na = 0.0

    [X,Y,Z_u, Z_l] = CST_3D(B, B, mesh =(40,40), span=span,
                            N={'eta':[0,0.5,.8,1], 'N1':[.5, .5, 1., 1.], 'N2':[1., 1., 1., 1.]},
                            chord = {'eta':[0,1], 'A':[0.], 'N1':Na, 'N2':Nb,
                                     'initial':initial_chord,'final':final_chord},
                            sweep = {'eta':[0,1], 'A':[0.], 'N1':Nb, 'N2':Na,
                                     'initial':initial_nosecone_x, 'final':final_nosecone_x},
                            twist = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial':0, 'final':1})

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    surf_u = ax.plot_surface(X, Z_u, Y, cmap=plt.get_cmap('jet'),
                       linewidth=0, antialiased=False)
    surf_l = ax.plot_surface(X, Z_l, Y, cmap=plt.get_cmap('jet'),
                       linewidth=0, antialiased=False)
    # cset = ax.contour(X, Z_u, Y, zdir='z', offset=0, cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_l, Y, zdir='z', offset=0,  cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_u, Y, zdir='x', offset=-.1, cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_l, Y, zdir='x', offset=-.1, cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_u, Y, zdir='y', offset =0.5,  cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_l, Y, zdir='y', offset =0.5,  cmap=cm.coolwarm)

    # Customize the z axis.
    ax.set_zlim(0, 4)

    max_range = np.array([X.max()-X.min(),  Z_u.max()-Z_l.min(), Y.max()-Y.min()]).max() / 2.0

    mid_x = (X.max()+X.min()) * 0.5
    mid_y = (Y.max()+Y.min()) * 0.5
    mid_z = (Z_u.max()+Z_l.min()) * 0.5
    ax.set_xlim(mid_x - max_range, mid_x + max_range)
    ax.set_ylim(mid_z - max_range, mid_z + max_range)
    ax.set_zlim(mid_y - max_range, mid_y + max_range)
    plt.xlabel('x')
    plt.ylabel('z')
    plt.show()

    fig = plt.figure()
    ax = fig.gca(projection='3d')

    ax.plot_trisurf(X.flatten(),  Y.flatten(), Z_u.flatten(), linewidth=0.2, antialiased=True,)
    ax.plot_trisurf(X.flatten(),  Y.flatten(), Z_l.flatten(), linewidth=0.2, antialiased=True,)
    ax.set_xlim(mid_x - max_range, mid_x + max_range)
    ax.set_ylim(mid_y - max_range, mid_y + max_range)
    ax.set_zlim(mid_z - max_range, mid_z + max_range)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()<commit_msg>twisting working<commit_after>from scipy.interpolate import interp1d
import numpy as np
import math

from airfoil_module import CST, create_x
def taper_function(eta, shape = 'linear', points = {'eta':[0,1], 'chord':[1,.7]}):
    """Calculate chord along span of the wing.

    - If linear, taper function is a conjuction of lines connecting points
    - Possible shapes are the same as interp1d: ('linear', 'nearest',
        'zero', 'slinear', 'quadratic', 'cubic' where 'zero', 'slinear',
         'quadratic' and 'cubic' refer to a spline interpolation of zeroth,
          first, second or third order"""
    function = interp1d(points['eta'], points['chord'])
    return function(eta)

def twist_function(eta, shape = 'linear', points = {'eta':[0,1], 'delta_twist':[0,.1]}):
    """Calculate chord along span of the wing.

    - If linear, taper function is a conjuction of lines connecting points
    - Possible shapes are the same as interp1d: ('linear', 'nearest',
        'zero', 'slinear', 'quadratic', 'cubic' where 'zero', 'slinear',
         'quadratic' and 'cubic' refer to a spline interpolation of zeroth,
          first, second or third order"""
    function = interp1d(points['eta'], points['delta_twist'])
    return function(eta)

def CST_3D(Bu, Bl, span, N={'eta':[0,1], 'N1':[.5, .5], 'N2':[1., 1.], 'chord':[1., 0]},
           mesh = (100,100), chord = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial':1., 'final':0.1},
           sweep = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial':0, 'final':0},
           twist = {'eta':[0,1], 'A':[1.], 'N1':1, 'N2':1, 'initial':0, 'final':1}):
    """
    - Bu: upper shape coefficients
    - Bl: lower shape coefficients
    - mesh: list of number of points in x and y
    """
    def S(B, psi, eta):
        """ Cross section shape function. Validated for high dimensions.
           To debug just verify if it turns all ones when B=ones"""
        def S_i(r, n, psi):
            """Shape function"""
            value = K(r,n)*(psi**r)*(1.-psi)**(n-r)
            return value

        # Bersntein Polynomial
        def K(r,n):
            K=math.factorial(n)/(math.factorial(r)*math.factorial(n-r))
            return K

        Nx = len(B)-1
        Ny = len(B[0])-1

        output = 0
        for i in range(Nx+1):
            for j in range(Ny+1):
                output += B[i][j]*S_i(i, Nx, psi)*S_i(j, Ny, eta)
        return output

    def C(psi, eta):
        """Class function"""
        psi_max = N1(eta)/(N1(eta)+N2(eta))
        C_max = 2*((psi_max)**N1(eta))*((1.-psi_max)**N2(eta))
        output = ((psi)**N1(eta))*((1.-psi)**N2(eta))/C_max/2
        return output

    def Rotation(ux, uy, uz, theta):
        # Check if vector are normalized
        norm = math.sqrt(ux**2+uy**2+uz*2)
        if norm != 1:
            ux = ux/norm
            uy = uy/norm
            uz = uz/norm
        R11 = math.cos(theta) + ux**2*(1-math.cos(theta))
        R12 = ux*uy*(1-math.cos(theta)) - uz*math.sin(theta)
        R13 = ux*uz*(1-math.cos(theta)) + uy*math.sin(theta)
        R21 = ux*uy*(1-math.cos(theta)) + uz*math.sin(theta)
        R22 = math.cos(theta) + uy**2*(1-math.cos(theta))
        R23 = uy*uz*(1-math.cos(theta)) - ux*math.sin(theta)
        R31 = ux*uz*(1-math.cos(theta)) - uy*math.sin(theta)
        R32 = uy*uz*(1-math.cos(theta)) + ux*math.sin(theta)
        R33 = math.cos(theta) + uz**2*(1-math.cos(theta))
        R = np.array([[R11, R12, R13],
                      [R21, R22, R23],
                      [R31, R32, R33]])
        return R
    # Define non-dimensional domains

    psi = np.linspace(0,1,mesh[1])
    eta = np.linspace(0,1,mesh[1])
    zeta_u = np.zeros(mesh)
    zeta_l = np.zeros(mesh)

    # Interpolate class function coefficients

    N1 = interp1d(N['eta'], N['N1'])
    N2 = interp1d(N['eta'], N['N2'])

    for i in range(mesh[0]):
        for j in range(mesh[1]):
            zeta_u[j][i] = C(psi[i], eta[j])*S(Bu, psi[i], eta[j])
            zeta_l[j][i] = -C(psi[i], eta[j])*S(Bl, psi[i], eta[j])

    chord_distribution = CST(eta, chord['eta'][1], chord['initial'], Au=chord['A'], N1=chord['N1'], N2=chord['N2'], deltasLE=chord['final'])
    sweep_distribution = CST(eta, sweep['eta'][1], deltasz = sweep['final'], Au=sweep['A'], N1=sweep['N1'], N2=sweep['N2'])
    chord_distribution = chord_distribution[::-1]
    sweep_distribution = sweep_distribution
    twist_distribution = CST(eta, twist['eta'][1], twist['initial'], Au=twist['A'], N1=twist['N1'], N2=twist['N2'], deltasLE=twist['final'])

    # taper_function(eta, shape = 'linear', N)
    x = np.zeros(len(psi))
    for i in range(len(x)):
        x[i] = psi[i]*chord_distribution[i]
    print 'chord'
    print chord_distribution
    print 'sweep'
    print sweep_distribution
    print 'twist'
    print twist_distribution
    y = eta

    X = np.zeros(mesh)
    Y = np.zeros(mesh)
    X_u = np.zeros(mesh)
    X_l = np.zeros(mesh)
    Y_u = np.zeros(mesh)
    Y_l = np.zeros(mesh)
    Z_u = np.zeros(mesh)
    Z_l = np.zeros(mesh)
    for i in range(mesh[0]):
        for j in range(mesh[1]):
            X[j][i] = psi[i]*chord_distribution[j] + sweep_distribution[j]
            Y[j][i] = span*eta[j]
            Z_u[j][i] = zeta_u[j][i] *chord_distribution[j]
            Z_l[j][i] = zeta_l[j][i] *chord_distribution[j]
            if twist != None:
                xr = twist['psi_root']
                zr = twist['zeta_root']
                R = Rotation(twist['axis'][0], twist['axis'][1], twist['axis'][2],
                         twist_distribution[j])
                t_u = np.array([X[j][i]-xr,Y[j][i],Z_u[j][i]-zr])
                t_l = np.array([X[j][i]-xr,Y[j][i],Z_l[j][i]-zr])
                T_u = R.dot(t_u)
                T_l = R.dot(t_l)

                X_u[j][i] = xr + T_u[0]
                X_l[j][i] = xr + T_l[0]
                Y_u[j][i] = T_u[1]
                Y_l[j][i] = T_l[1]
                Z_u[j][i] = zr + T_u[2]
                Z_l[j][i] = zr + T_l[2]
    if twist == None:
        return [X,Y,Z_u,Z_l]
    else:
        return [X_u,X_l,Y_u,Y_l,Z_u,Z_l]

if __name__ == '__main__':
    from mpl_toolkits.mplot3d import Axes3D
    import matplotlib.pyplot as plt
    from matplotlib import cm

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Inputs
    # One of the diameters
    initial_chord = 2.
    final_chord = 1.
    # Nosecone height
    span = 4.
    # Shape coefficient for cross section (if A=1, circular, otherwise it is an ellipse)
    A = .5
    # location of the nosecone tip
    initial_nosecone_x = 0
    final_nosecone_x = 2.
    # Class coefficient for chord distribution (Nb=.5, elliptical, Nb=1, Haack series)
    Nb = 0.0

    axis = [final_nosecone_x - initial_nosecone_x, span,0]

    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    B = [[A], [A]]
    #B = [[A], [A]]
    Na = 0.0
    mesh =(20,20)
    N={'eta':[0,0.5,.8,1], 'N1':[.5, .5, 1., 1.], 'N2':[1., 1., 1., 1.]}
    chord = {'eta':[0,1], 'A':[0.], 'N1':Na, 'N2':Nb,
             'initial':initial_chord,'final':final_chord}
    sweep = {'eta':[0,1], 'A':[0.], 'N1':Nb, 'N2':Na,
             'initial':initial_nosecone_x, 'final':final_nosecone_x}
    twist = {'eta':[0,1], 'A':[0.], 'N1':1, 'N2':1,'initial':0.5, 'final':0, 'psi_root':0.2,'zeta_root':0, 'axis':axis}
    [X_u,X_l,Y_u,Y_l,Z_u, Z_l] = CST_3D(B, B,  span, N, mesh, chord, sweep, twist)

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    surf_u = ax.plot_surface(X_u, Z_u, Y_u, cmap=plt.get_cmap('jet'),
                       linewidth=0, antialiased=False)
    surf_l = ax.plot_surface(X_l, Z_l, Y_l, cmap=plt.get_cmap('jet'),
                       linewidth=0, antialiased=False)
    # cset = ax.contour(X, Z_u, Y, zdir='z', offset=0, cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_l, Y, zdir='z', offset=0,  cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_u, Y, zdir='x', offset=-.1, cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_l, Y, zdir='x', offset=-.1, cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_u, Y, zdir='y', offset =0.5,  cmap=cm.coolwarm)
    # cset = ax.contour(X, Z_l, Y, zdir='y', offset =0.5,  cmap=cm.coolwarm)

    # Customize the z axis.
    ax.set_zlim(0, 4)

    max_range = np.array([X_u.max()-X_u.min(), X_l.max()-X_l.min(), Z_u.max()-Z_l.min(),
                          Y_u.max()-Y_u.min(), Y_l.max()-Y_l.min()]).max() / 2.0

    mid_x = (X_u.max()+X_l.min()) * 0.5
    mid_y = (Y_u.max()+Y_l.min()) * 0.5
    mid_z = (Z_u.max()+Z_l.min()) * 0.5
    ax.set_xlim(mid_x - max_range, mid_x + max_range)
    ax.set_ylim(mid_z - max_range, mid_z + max_range)
    ax.set_zlim(mid_y - max_range, mid_y + max_range)
    plt.xlabel('x')
    plt.ylabel('z')
    plt.show()

    fig = plt.figure()
    ax = fig.gca(projection='3d')

    ax.plot_trisurf(X_u.flatten(),  Y_u.flatten(), Z_u.flatten(), linewidth=0.2, antialiased=True,)
    ax.plot_trisurf(X_l.flatten(),  Y_l.flatten(), Z_l.flatten(), linewidth=0.2, antialiased=True,)
    ax.plot([sweep['initial'] + twist['psi_root']*chord['initial'],sweep['initial'] + twist['psi_root']*chord['initial'] + axis[0]],[0,axis[1]])
    ax.set_xlim(mid_x - max_range, mid_x + max_range)
    ax.set_ylim(mid_y - max_range, mid_y + max_range)
    ax.set_zlim(mid_z - max_range, mid_z + max_range)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()<|endoftext|>


<commit_before>from warnings import warn

from skimage.util.dtype import dtype_range
from .base import Plugin
from ..utils import ClearColormap, update_axes_image
from skimage._shared import six

__all__ = ['OverlayPlugin']

def recent_mpl_version():
    import matplotlib
    version = matplotlib.__version__.split('.')
    return int(version[0]) == 1 and int(version[1]) >= 2

class OverlayPlugin(Plugin):
    """Plugin for ImageViewer that displays an overlay on top of main image.

    The base Plugin class displays the filtered image directly on the viewer.
    OverlayPlugin will instead overlay an image with a transparent colormap.

    See base Plugin class for additional details.

    Attributes
    ----------
    overlay : array
        Overlay displayed on top of image. This overlay defaults to a color map
        with alpha values varying linearly from 0 to 1.
    color : int
        Color of overlay.
    """
    colors = {'red': (1, 0, 0),
              'yellow': (1, 1, 0),
              'green': (0, 1, 0),
              'cyan': (0, 1, 1)}

    def __init__(self, **kwargs):
        if not recent_mpl_version():
            msg = "Matplotlib >= 1.2 required for OverlayPlugin."
            warn(RuntimeWarning(msg))
        super(OverlayPlugin, self).__init__(**kwargs)
        self._overlay_plot = None
        self._overlay = None
        self.cmap = None
        self.color_names = self.colors.keys()

    def attach(self, image_viewer):
        super(OverlayPlugin, self).attach(image_viewer)
        #TODO: `color` doesn't update GUI widget when set manually.
        self.color = 0

    @property
    def overlay(self):
        return self._overlay

    @overlay.setter
    def overlay(self, image):
        self._overlay = image
        ax = self.image_viewer.ax
        if image is None:
            ax.images.remove(self._overlay_plot)
            self._overlay_plot = None
        elif self._overlay_plot is None:
            vmin, vmax = dtype_range[image.dtype.type]
            self._overlay_plot = ax.imshow(image, cmap=self.cmap,
                                           vmin=vmin, vmax=vmax)
        else:
            update_axes_image(self._overlay_plot, image)

        self.image_viewer.redraw()

    @property
    def color(self):
        return self._color

    @color.setter
    def color(self, index):
        # Update colormap whenever color is changed.
        if isinstance(index, six.string_types) and \
           index not in self.color_names:
            raise ValueError("%s not defined in OverlayPlugin.colors" % index)
        else:
            name = self.color_names[index]
        self._color = name
        rgb = self.colors[name]
        self.cmap = ClearColormap(rgb)

        if self._overlay_plot is not None:
            self._overlay_plot.set_cmap(self.cmap)
        self.image_viewer.redraw()

    @property
    def filtered_image(self):
        """Return filtered image.

        This "filtered image" is used when saving from the plugin.
        """
        return self.overlay

    def display_filtered_image(self, image):
        """Display filtered image as an overlay on top of image in viewer."""
        self.overlay = image

    def closeEvent(self, event):
        # clear overlay from ImageViewer on close
        self.overlay = None
        super(OverlayPlugin, self).closeEvent(event)
<commit_msg>Allow OverlayPlugin to return the current overlay<commit_after>from warnings import warn

from skimage.util.dtype import dtype_range
from .base import Plugin
from ..utils import ClearColormap, update_axes_image
from skimage._shared import six

__all__ = ['OverlayPlugin']

def recent_mpl_version():
    import matplotlib
    version = matplotlib.__version__.split('.')
    return int(version[0]) == 1 and int(version[1]) >= 2

class OverlayPlugin(Plugin):
    """Plugin for ImageViewer that displays an overlay on top of main image.

    The base Plugin class displays the filtered image directly on the viewer.
    OverlayPlugin will instead overlay an image with a transparent colormap.

    See base Plugin class for additional details.

    Attributes
    ----------
    overlay : array
        Overlay displayed on top of image. This overlay defaults to a color map
        with alpha values varying linearly from 0 to 1.
    color : int
        Color of overlay.
    """
    colors = {'red': (1, 0, 0),
              'yellow': (1, 1, 0),
              'green': (0, 1, 0),
              'cyan': (0, 1, 1)}

    def __init__(self, **kwargs):
        if not recent_mpl_version():
            msg = "Matplotlib >= 1.2 required for OverlayPlugin."
            warn(RuntimeWarning(msg))
        super(OverlayPlugin, self).__init__(**kwargs)
        self._overlay_plot = None
        self._overlay = None
        self.cmap = None
        self.color_names = self.colors.keys()

    def attach(self, image_viewer):
        super(OverlayPlugin, self).attach(image_viewer)
        #TODO: `color` doesn't update GUI widget when set manually.
        self.color = 0

    @property
    def overlay(self):
        return self._overlay

    @overlay.setter
    def overlay(self, image):
        self._overlay = image
        ax = self.image_viewer.ax
        if image is None:
            ax.images.remove(self._overlay_plot)
            self._overlay_plot = None
        elif self._overlay_plot is None:
            vmin, vmax = dtype_range[image.dtype.type]
            self._overlay_plot = ax.imshow(image, cmap=self.cmap,
                                           vmin=vmin, vmax=vmax)
        else:
            update_axes_image(self._overlay_plot, image)

        self.image_viewer.redraw()

    @property
    def color(self):
        return self._color

    @color.setter
    def color(self, index):
        # Update colormap whenever color is changed.
        if isinstance(index, six.string_types) and \
           index not in self.color_names:
            raise ValueError("%s not defined in OverlayPlugin.colors" % index)
        else:
            name = self.color_names[index]
        self._color = name
        rgb = self.colors[name]
        self.cmap = ClearColormap(rgb)

        if self._overlay_plot is not None:
            self._overlay_plot.set_cmap(self.cmap)
        self.image_viewer.redraw()

    @property
    def filtered_image(self):
        """Return filtered image.

        This "filtered image" is used when saving from the plugin.
        """
        return self.overlay

    def display_filtered_image(self, image):
        """Display filtered image as an overlay on top of image in viewer."""
        self.overlay = image

    def closeEvent(self, event):
        # clear overlay from ImageViewer on close
        self.overlay = None
        super(OverlayPlugin, self).closeEvent(event)

    def output(self):
        """Return the overlaid image.

        Parameters
        ----------
        None

        Returns
        -------
        overlay : array, same shape as image
            The overlay currently displayed.
        data : None
        """
        return (self.overlay, None)

<|endoftext|>


<commit_before>#!/usr/bin/env python3
# Copyright (C) 2020 The Android Open Source Project
#
# 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 os

# This function lives in its own module to allow us to use a different
# mechanism of loading depending on the build system.
def read_descriptor():
  ws = os.path.dirname(__file__)
  with open(os.path.join(ws, 'trace_processor.descriptor'), 'rb') as x:
    return x.read()
<commit_msg>Add try block to read_descriptor for it to read the descriptor file correctly on Colab am: f81160f0c7 am: 8a3ff8c3f6 am: 34ff9bb285 am: 5cdb791ae0<commit_after>#!/usr/bin/env python3
# Copyright (C) 2020 The Android Open Source Project
#
# 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 os

# This function lives in its own module to allow us to use a different
# mechanism of loading depending on the build system.
def read_descriptor():
  try:
    from .descriptor_vendor import read_tp_descriptor
    return read_tp_descriptor()
  except ModuleNotFoundError:
    ws = os.path.dirname(__file__)
    with open(os.path.join(ws, 'trace_processor.descriptor'), 'rb') as x:
      return x.read()
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8 -*-

## Binary Analysis Tool
## Copyright 2014 Armijn Hemel for Tjaldur Software Governance Solutions
## Licensed under Apache 2.0, see LICENSE file for details

'''
Program to process a whole directory full of compressed source code archives
to create simple manifest files that list checksums of every individual file
in an archive. This is to speed up scanning of archives when rebuilding the
BAT database.

Needs a file LIST in the directory it is passed as a parameter, which has the
following format:

package version filename origin

separated by whitespace

Compression is determined using magic
'''

import sys, os, magic, string, re, subprocess, shutil, stat
import tempfile, bz2, tarfile, gzip, hashlib, zlib
from optparse import OptionParser
from multiprocessing import Pool

tarmagic = ['POSIX tar archive (GNU)'
           , 'tar archive'
           ]

ms = magic.open(magic.MAGIC_NONE)
ms.load()

## unpack the directories to be scanned.
def unpack(directory, filename, unpackdir):
	try:
		os.stat(os.path.join(directory, filename))
	except:
		print >>sys.stderr, "Can't find %s" % filename
		return None

        filemagic = ms.file(os.path.realpath(os.path.join(directory, filename)))

        ## Assume if the files are bz2 or gzip compressed they are compressed tar files
        if 'bzip2 compressed data' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
		## for some reason the tar.bz2 unpacking from python doesn't always work, like
		## aeneas-1.0.tar.bz2 from GNU, so use a subprocess instead of using the
		## Python tar functionality.
 		p = subprocess.Popen(['tar', 'jxf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		if p.returncode != 0:
			shutil.rmtree(tmpdir)
			return
		return tmpdir
	elif 'LZMA compressed data, streamed' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
		p = subprocess.Popen(['tar', 'ixf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		return tmpdir
        elif 'XZ compressed data' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
 		p = subprocess.Popen(['tar', 'Jxf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		return tmpdir
        elif 'gzip compressed data' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
 		p = subprocess.Popen(['tar', 'zxf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		return tmpdir
	elif 'Zip archive data' in filemagic:
		try:
			if unpackdir != None:
       				tmpdir = tempfile.mkdtemp(dir=unpackdir)
			else:
       				tmpdir = tempfile.mkdtemp()
			p = subprocess.Popen(['unzip', "-B", os.path.join(directory, filename), '-d', tmpdir], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
			(stanout, stanerr) = p.communicate()
			if p.returncode != 0 and p.returncode != 1:
				print >>sys.stderr, "unpacking ZIP failed for", filename, stanerr
				shutil.rmtree(tmpdir)
				pass
			else:
				return tmpdir
		except Exception, e:
			print >>sys.stderr, "unpacking ZIP failed", e

def grabhash(filedir, filename, filehash, pool, extrahashes, temporarydir):
	## unpack the archive. If it fails, cleanup and return.
	temporarydir = unpack(filedir, filename, temporarydir)
	if temporarydir == None:
		return None

	print "processing", filename
	sys.stdout.flush()

	## add 1 to deal with /
	lenunpackdir = len(temporarydir) + 1

	osgen = os.walk(temporarydir)

	try:
		scanfiles = []
		while True:
			i = osgen.next()
			## make sure all directories can be accessed
			for d in i[1]:
				if not os.path.islink(os.path.join(i[0], d)):
					os.chmod(os.path.join(i[0], d), stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
			for p in i[2]:
				scanfiles.append((i[0], p, extrahashes))
	except Exception, e:
		if str(e) != "":
			print >>sys.stderr, e

	## compute the hashes in parallel
	scanfile_result = filter(lambda x: x != None, pool.map(computehash, scanfiles, 1))
	cleanupdir(temporarydir)
	scanfile_result = map(lambda x: (x[0][lenunpackdir:],) +  x[1:], scanfile_result)
	return scanfile_result

def cleanupdir(temporarydir):
	osgen = os.walk(temporarydir)
	try:
		while True:
			i = osgen.next()
			## make sure all directories can be accessed
			for d in i[1]:
				if not os.path.islink(os.path.join(i[0], d)):
					os.chmod(os.path.join(i[0], d), stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
			for p in i[2]:
				try:
					if not os.path.islink(os.path.join(i[0], p)):
						os.chmod(os.path.join(i[0], p), stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
				except Exception, e:
					#print e
					pass
	except StopIteration:
		pass
	try:
		shutil.rmtree(temporarydir)
	except:
		## nothing that can be done right now, so just give up
		pass

def computehash((path, filename, extrahashes)):
	resolved_path = os.path.join(path, filename)
	if not os.path.isfile(resolved_path):
		## filter out fifo and pipe
		return None
	try:
		if not os.path.islink(resolved_path):
			os.chmod(resolved_path, stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
	except Exception, e:
		pass
	## skip links
	if os.path.islink(resolved_path):
        	return None
	filehashes = {}
	scanfile = open(resolved_path, 'r')
	h = hashlib.new('sha256')
	h.update(scanfile.read())
	scanfile.close()
	filehashes['sha256'] = h.hexdigest()
	for i in extrahashes:
		scanfile = open(resolved_path, 'r')
		if i == 'crc32':
			crcdata = scanfile.read()
			filehashes[i] = zlib.crc32(crcdata) & 0xffffffff
		else:
			h = hashlib.new(i)
			h.update(scanfile.read())
			filehashes[i] = h.hexdigest()
		scanfile.close()
	return (path, filename, filehashes)

def checkalreadyscanned((filedir, filename, checksum)):
	resolved_path = os.path.join(filedir, filename)
	try:
		os.stat(resolved_path)
	except:
		print >>sys.stderr, "Can't find %s" % filename
		return None
	if checksum != None:
		filehash = checksum
	else:
		scanfile = open(resolved_path, 'r')
		h = hashlib.new('sha256')
		h.update(scanfile.read())
		scanfile.close()
		filehash = h.hexdigest()
	return (filename, filehash)

def main(argv):
	parser = OptionParser()
	parser.add_option("-f", "--filedir", action="store", dest="filedir", help="path to directory containing files to unpack", metavar="DIR")
	parser.add_option("-u", "--update", action="store_true", dest="update", help="only create manifest files for new archives")
	parser.add_option("-t", "--temporarydir", action="store", dest="unpackdir", help="set unpacking directory (default: /tmp)", metavar="DIR")

	(options, args) = parser.parse_args()
	if options.filedir == None:
		parser.error("Specify dir with files")
	else:
		try:
			filelist = open(os.path.join(options.filedir,"LIST")).readlines()
		except:
			parser.error("'LIST' not found in file dir")

	if options.unpackdir != None:
		if not os.path.exists(options.unpackdir):
			parser.error("temporary unpacking directory '%s' does not exist" % options.unpackdir)

	options.unpackdir = '/ramdisk'

	pool = Pool()

	pkgmeta = []

	checksums = {}
	if os.path.exists(os.path.join(options.filedir, "SHA256SUM")):
		checksumlines = open(os.path.join(options.filedir, "SHA256SUM")).readlines()
		for c in checksumlines[1:]:
			checksumsplit = c.strip().split()
			if len(checksumsplit) < 2:
				continue
			archivefilename = checksumsplit[0]
			archivechecksum = checksumsplit[1]
			checksums[archivefilename] = archivechecksum

	extrahashes = ['md5', 'sha1', 'crc32']

	for unpackfile in filelist:
		try:
			unpacks = unpackfile.strip().split()
			if len(unpacks) == 4:
				(package, version, filename, origin) = unpacks
				batarchive = False
			else:
				(package, version, filename, origin, bat) = unpacks
				if bat == 'batarchive':
					batarchive = True
				else:
					batarchive = False
			pkgmeta.append((options.filedir, filename, checksums[filename]))
		except Exception, e:
			# oops, something went wrong
			print >>sys.stderr, e
	res = filter(lambda x: x != None, pool.map(checkalreadyscanned, pkgmeta, 1))

	processed_hashes = set()
	manifestdir = os.path.join(options.filedir, "MANIFESTS")
	if os.path.exists(manifestdir) and os.path.isdir(manifestdir):
		outputdir = manifestdir
	else:
		outputdir = "/tmp"

	print "outputting hashes to %s" % outputdir
	sys.stdout.flush()

	uniquehashes = set()
	for r in res:
		(filename, filehash) = r
		if filehash in uniquehashes:
			continue
		uniquehashes.add(filehash)
		if options.update and os.path.exists(os.path.join(outputdir, "%s.bz2" % filehash)):
			continue
		unpackres = grabhash(options.filedir, filename, filehash, pool, extrahashes, options.unpackdir)
		if unpackres == None:
			continue
		## first write the scanned/supported hashes, in the order in which they
		## appear for each file
		manifest = os.path.join(outputdir, "%s.bz2" % filehash)
		manifestfile = bz2.BZ2File(manifest, 'w')
		if extrahashes == []:
			manifestfile.write("sha256\n")
		else:
			hashesstring = "sha256"
			for h in extrahashes:
				hashesstring += "\t%s" % h
			manifestfile.write("%s\n" % hashesstring)
		for u in unpackres:
			if extrahashes == []:
				manifestfile.write("%s\t%s\n" % (os.path.join(u[0], u[1]), u[2]['sha256']))
			else:
				hashesstring = "\t%s" % u[2]['sha256']
				for h in extrahashes:
					hashesstring += "\t%s" % u[2][h]
				manifestfile.write("%s\t%s\n" % (os.path.join(u[0], u[1]), hashesstring))
		manifestfile.close()
	pool.terminate()
	print "%d hashes were written to %s" % (len(uniquehashes), outputdir)
	sys.stdout.flush()

if __name__ == "__main__":
    main(sys.argv)
<commit_msg>remove superfluous tab<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-

## Binary Analysis Tool
## Copyright 2014 Armijn Hemel for Tjaldur Software Governance Solutions
## Licensed under Apache 2.0, see LICENSE file for details

'''
Program to process a whole directory full of compressed source code archives
to create simple manifest files that list checksums of every individual file
in an archive. This is to speed up scanning of archives when rebuilding the
BAT database.

Needs a file LIST in the directory it is passed as a parameter, which has the
following format:

package version filename origin

separated by whitespace

Compression is determined using magic
'''

import sys, os, magic, string, re, subprocess, shutil, stat
import tempfile, bz2, tarfile, gzip, hashlib, zlib
from optparse import OptionParser
from multiprocessing import Pool

tarmagic = ['POSIX tar archive (GNU)'
           , 'tar archive'
           ]

ms = magic.open(magic.MAGIC_NONE)
ms.load()

## unpack the directories to be scanned.
def unpack(directory, filename, unpackdir):
	try:
		os.stat(os.path.join(directory, filename))
	except:
		print >>sys.stderr, "Can't find %s" % filename
		return None

        filemagic = ms.file(os.path.realpath(os.path.join(directory, filename)))

        ## Assume if the files are bz2 or gzip compressed they are compressed tar files
        if 'bzip2 compressed data' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
		## for some reason the tar.bz2 unpacking from python doesn't always work, like
		## aeneas-1.0.tar.bz2 from GNU, so use a subprocess instead of using the
		## Python tar functionality.
 		p = subprocess.Popen(['tar', 'jxf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		if p.returncode != 0:
			shutil.rmtree(tmpdir)
			return
		return tmpdir
	elif 'LZMA compressed data, streamed' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
		p = subprocess.Popen(['tar', 'ixf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		return tmpdir
        elif 'XZ compressed data' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
 		p = subprocess.Popen(['tar', 'Jxf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		return tmpdir
        elif 'gzip compressed data' in filemagic:
		if unpackdir != None:
       			tmpdir = tempfile.mkdtemp(dir=unpackdir)
		else:
       			tmpdir = tempfile.mkdtemp()
 		p = subprocess.Popen(['tar', 'zxf', os.path.join(directory, filename)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
		(stanout, stanerr) = p.communicate()
		return tmpdir
	elif 'Zip archive data' in filemagic:
		try:
			if unpackdir != None:
       				tmpdir = tempfile.mkdtemp(dir=unpackdir)
			else:
       				tmpdir = tempfile.mkdtemp()
			p = subprocess.Popen(['unzip', "-B", os.path.join(directory, filename), '-d', tmpdir], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
			(stanout, stanerr) = p.communicate()
			if p.returncode != 0 and p.returncode != 1:
				print >>sys.stderr, "unpacking ZIP failed for", filename, stanerr
				shutil.rmtree(tmpdir)
				pass
			else:
				return tmpdir
		except Exception, e:
			print >>sys.stderr, "unpacking ZIP failed", e

def grabhash(filedir, filename, filehash, pool, extrahashes, temporarydir):
	## unpack the archive. If it fails, cleanup and return.
	temporarydir = unpack(filedir, filename, temporarydir)
	if temporarydir == None:
		return None

	print "processing", filename
	sys.stdout.flush()

	## add 1 to deal with /
	lenunpackdir = len(temporarydir) + 1

	osgen = os.walk(temporarydir)

	try:
		scanfiles = []
		while True:
			i = osgen.next()
			## make sure all directories can be accessed
			for d in i[1]:
				if not os.path.islink(os.path.join(i[0], d)):
					os.chmod(os.path.join(i[0], d), stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
			for p in i[2]:
				scanfiles.append((i[0], p, extrahashes))
	except Exception, e:
		if str(e) != "":
			print >>sys.stderr, e

	## compute the hashes in parallel
	scanfile_result = filter(lambda x: x != None, pool.map(computehash, scanfiles, 1))
	cleanupdir(temporarydir)
	scanfile_result = map(lambda x: (x[0][lenunpackdir:],) +  x[1:], scanfile_result)
	return scanfile_result

def cleanupdir(temporarydir):
	osgen = os.walk(temporarydir)
	try:
		while True:
			i = osgen.next()
			## make sure all directories can be accessed
			for d in i[1]:
				if not os.path.islink(os.path.join(i[0], d)):
					os.chmod(os.path.join(i[0], d), stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
			for p in i[2]:
				try:
					if not os.path.islink(os.path.join(i[0], p)):
						os.chmod(os.path.join(i[0], p), stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
				except Exception, e:
					#print e
					pass
	except StopIteration:
		pass
	try:
		shutil.rmtree(temporarydir)
	except:
		## nothing that can be done right now, so just give up
		pass

def computehash((path, filename, extrahashes)):
	resolved_path = os.path.join(path, filename)
	if not os.path.isfile(resolved_path):
		## filter out fifo and pipe
		return None
	try:
		if not os.path.islink(resolved_path):
			os.chmod(resolved_path, stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR)
	except Exception, e:
		pass
	## skip links
	if os.path.islink(resolved_path):
        	return None
	filehashes = {}
	scanfile = open(resolved_path, 'r')
	h = hashlib.new('sha256')
	h.update(scanfile.read())
	scanfile.close()
	filehashes['sha256'] = h.hexdigest()
	for i in extrahashes:
		scanfile = open(resolved_path, 'r')
		if i == 'crc32':
			crcdata = scanfile.read()
			filehashes[i] = zlib.crc32(crcdata) & 0xffffffff
		else:
			h = hashlib.new(i)
			h.update(scanfile.read())
			filehashes[i] = h.hexdigest()
		scanfile.close()
	return (path, filename, filehashes)

def checkalreadyscanned((filedir, filename, checksum)):
	resolved_path = os.path.join(filedir, filename)
	try:
		os.stat(resolved_path)
	except:
		print >>sys.stderr, "Can't find %s" % filename
		return None
	if checksum != None:
		filehash = checksum
	else:
		scanfile = open(resolved_path, 'r')
		h = hashlib.new('sha256')
		h.update(scanfile.read())
		scanfile.close()
		filehash = h.hexdigest()
	return (filename, filehash)

def main(argv):
	parser = OptionParser()
	parser.add_option("-f", "--filedir", action="store", dest="filedir", help="path to directory containing files to unpack", metavar="DIR")
	parser.add_option("-u", "--update", action="store_true", dest="update", help="only create manifest files for new archives")
	parser.add_option("-t", "--temporarydir", action="store", dest="unpackdir", help="set unpacking directory (default: /tmp)", metavar="DIR")

	(options, args) = parser.parse_args()
	if options.filedir == None:
		parser.error("Specify dir with files")
	else:
		try:
			filelist = open(os.path.join(options.filedir,"LIST")).readlines()
		except:
			parser.error("'LIST' not found in file dir")

	if options.unpackdir != None:
		if not os.path.exists(options.unpackdir):
			parser.error("temporary unpacking directory '%s' does not exist" % options.unpackdir)

	options.unpackdir = '/ramdisk'

	pool = Pool()

	pkgmeta = []

	checksums = {}
	if os.path.exists(os.path.join(options.filedir, "SHA256SUM")):
		checksumlines = open(os.path.join(options.filedir, "SHA256SUM")).readlines()
		for c in checksumlines[1:]:
			checksumsplit = c.strip().split()
			if len(checksumsplit) < 2:
				continue
			archivefilename = checksumsplit[0]
			archivechecksum = checksumsplit[1]
			checksums[archivefilename] = archivechecksum

	extrahashes = ['md5', 'sha1', 'crc32']

	for unpackfile in filelist:
		try:
			unpacks = unpackfile.strip().split()
			if len(unpacks) == 4:
				(package, version, filename, origin) = unpacks
				batarchive = False
			else:
				(package, version, filename, origin, bat) = unpacks
				if bat == 'batarchive':
					batarchive = True
				else:
					batarchive = False
			pkgmeta.append((options.filedir, filename, checksums[filename]))
		except Exception, e:
			# oops, something went wrong
			print >>sys.stderr, e
	res = filter(lambda x: x != None, pool.map(checkalreadyscanned, pkgmeta, 1))

	processed_hashes = set()
	manifestdir = os.path.join(options.filedir, "MANIFESTS")
	if os.path.exists(manifestdir) and os.path.isdir(manifestdir):
		outputdir = manifestdir
	else:
		outputdir = "/tmp"

	print "outputting hashes to %s" % outputdir
	sys.stdout.flush()

	uniquehashes = set()
	for r in res:
		(filename, filehash) = r
		if filehash in uniquehashes:
			continue
		uniquehashes.add(filehash)
		if options.update and os.path.exists(os.path.join(outputdir, "%s.bz2" % filehash)):
			continue
		unpackres = grabhash(options.filedir, filename, filehash, pool, extrahashes, options.unpackdir)
		if unpackres == None:
			continue
		## first write the scanned/supported hashes, in the order in which they
		## appear for each file
		manifest = os.path.join(outputdir, "%s.bz2" % filehash)
		manifestfile = bz2.BZ2File(manifest, 'w')
		if extrahashes == []:
			manifestfile.write("sha256\n")
		else:
			hashesstring = "sha256"
			for h in extrahashes:
				hashesstring += "\t%s" % h
			manifestfile.write("%s\n" % hashesstring)
		for u in unpackres:
			if extrahashes == []:
				manifestfile.write("%s\t%s\n" % (os.path.join(u[0], u[1]), u[2]['sha256']))
			else:
				hashesstring = "%s" % u[2]['sha256']
				for h in extrahashes:
					hashesstring += "\t%s" % u[2][h]
				manifestfile.write("%s\t%s\n" % (os.path.join(u[0], u[1]), hashesstring))
		manifestfile.close()
	pool.terminate()
	print "%d hashes were written to %s" % (len(uniquehashes), outputdir)
	sys.stdout.flush()

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


<commit_before># import logging
# log = logging.getLogger(__name__)

from django.contrib import admin
from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse

from django_object_actions import (
    DjangoObjectActions,
    takes_instance_or_queryset,
)

from easy_select2 import select2_modelform

from .models import (
    Convention,
    Contest,
    District,
    Quartet,
    Chorus,
    Award,
    Performance,
    Singer,
    GroupMember,
    GroupAward,
    GroupFinish,
)

class GroupMemberInline(admin.TabularInline):
    form = select2_modelform(
        GroupMember,
        attrs={'width': '250px'},
    )
    model = GroupMember
    extra = 0
    show_change_link = True

class GroupAwardInline(admin.TabularInline):
    form = select2_modelform(
        GroupAward,
        attrs={'width': '250px'},
    )
    model = GroupAward
    extra = 0

class GroupFinishInline(admin.TabularInline):
    form = select2_modelform(
        GroupFinish,
        attrs={'width': '250px'},
    )
    model = GroupFinish
    extra = 0
    show_change_link = True

@admin.register(Convention)
class ConventionAdmin(admin.ModelAdmin):
    form = select2_modelform(
        Convention,
        attrs={'width': '250px'},
    )
    list_display = (
        '__unicode__',
        'location',
        'dates',
    )
    list_filter = (
        'district',
        'kind',
        'year',
    )

    save_on_top = True

@admin.register(Contest)
class ContestAdmin(DjangoObjectActions, admin.ModelAdmin):
    @takes_instance_or_queryset
    def import_scores(self, request, queryset):
        for obj in queryset:
            obj.import_scores()
    import_scores.label = 'Import Scores'
    form = select2_modelform(
        Contest,
        attrs={'width': '250px'},
    )
    save_on_top = True
    objectactions = [
        'import_scores',
    ]

    inlines = [
        GroupFinishInline,
    ]

    list_filter = (
        'kind',
        'year',
        'district',
    )

@admin.register(District)
class DistrictAdmin(admin.ModelAdmin):
    form = select2_modelform(
        District,
        attrs={'width': '250px'},
    )
    save_on_top = True

QuartetForm = select2_modelform(
    Quartet,
    attrs={'width': '250px'},
)

@admin.register(Quartet)
class QuartetAdmin(admin.ModelAdmin):
    form = QuartetForm
    inlines = (
        GroupMemberInline,
        GroupFinishInline,
        # GroupAwardInline,
    )
    save_on_top = True

@admin.register(Chorus)
class ChorusAdmin(admin.ModelAdmin):
    def is_picture(self, obj):
        return bool(obj.picture)

    form = select2_modelform(
        Chorus,
        attrs={'width': '250px'},
    )

    list_display = (
        'name',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'director',
        'chapter_name',
        'chapter_code',
        'is_picture',
    )

    readonly_fields = (
        'is_picture',
    )

    # inlines = (
    #     GroupMemberInline,
    #     GroupAwardInline,
    # )
    save_on_top = True

@admin.register(Award)
class AwardAdmin(admin.ModelAdmin):
    form = select2_modelform(
        Chorus,
        attrs={'width': '250px'},
    )

    save_on_top = True

@admin.register(Performance)
class PerformanceAdmin(admin.ModelAdmin):
    form = select2_modelform(
        Performance,
        attrs={'width': '250px'},
    )
    list_display = (
        'group',
        'contest',
        'round',
        'place',
        'song1',
        'mus1',
        'prs1',
        'sng1',
        'song2',
        'mus2',
        'prs2',
        'sng2',
        'men',
    )

    list_filter = (
        'contest',
    )

    ordering = (
        'place',
    )

    save_on_top = True

@admin.register(Singer)
class SingerAdmin(admin.ModelAdmin):
    fields = (
        'name',
    )

    form = select2_modelform(
        Singer,
        attrs={'width': '250px'},
    )
    save_on_top = True

@admin.register(GroupMember)
class GroupMemberAdmin(admin.ModelAdmin):
    save_on_top = True

@admin.register(GroupFinish)
class GroupFinishAdmin(admin.ModelAdmin):
    save_on_top = True
<commit_msg>List Display on Contest Admin<commit_after># import logging
# log = logging.getLogger(__name__)

from django.contrib import admin
from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse

from django_object_actions import (
    DjangoObjectActions,
    takes_instance_or_queryset,
)

from easy_select2 import select2_modelform

from .models import (
    Convention,
    Contest,
    District,
    Quartet,
    Chorus,
    Award,
    Performance,
    Singer,
    GroupMember,
    GroupAward,
    GroupFinish,
)

class GroupMemberInline(admin.TabularInline):
    form = select2_modelform(
        GroupMember,
        attrs={'width': '250px'},
    )
    model = GroupMember
    extra = 0
    show_change_link = True

class GroupAwardInline(admin.TabularInline):
    form = select2_modelform(
        GroupAward,
        attrs={'width': '250px'},
    )
    model = GroupAward
    extra = 0

class GroupFinishInline(admin.TabularInline):
    form = select2_modelform(
        GroupFinish,
        attrs={'width': '250px'},
    )
    model = GroupFinish
    extra = 0
    show_change_link = True

@admin.register(Convention)
class ConventionAdmin(admin.ModelAdmin):
    form = select2_modelform(
        Convention,
        attrs={'width': '250px'},
    )
    list_display = (
        '__unicode__',
        'location',
        'dates',
    )
    list_filter = (
        'district',
        'kind',
        'year',
    )

    save_on_top = True

@admin.register(Contest)
class ContestAdmin(DjangoObjectActions, admin.ModelAdmin):
    @takes_instance_or_queryset
    def import_scores(self, request, queryset):
        for obj in queryset:
            obj.import_scores()
    import_scores.label = 'Import Scores'
    form = select2_modelform(
        Contest,
        attrs={'width': '250px'},
    )
    save_on_top = True
    objectactions = [
        'import_scores',
    ]

    inlines = [
        GroupFinishInline,
    ]

    list_filter = (
        'kind',
        'year',
        'district',
    )

    list_display = (
        '__unicode__',
        'convention',
        'panel',
        'scoresheet_pdf',
    )

@admin.register(District)
class DistrictAdmin(admin.ModelAdmin):
    form = select2_modelform(
        District,
        attrs={'width': '250px'},
    )
    save_on_top = True

QuartetForm = select2_modelform(
    Quartet,
    attrs={'width': '250px'},
)

@admin.register(Quartet)
class QuartetAdmin(admin.ModelAdmin):
    form = QuartetForm
    inlines = (
        GroupMemberInline,
        GroupFinishInline,
        # GroupAwardInline,
    )
    save_on_top = True

@admin.register(Chorus)
class ChorusAdmin(admin.ModelAdmin):
    def is_picture(self, obj):
        return bool(obj.picture)

    form = select2_modelform(
        Chorus,
        attrs={'width': '250px'},
    )

    list_display = (
        'name',
        'location',
        'website',
        'facebook',
        'twitter',
        'email',
        'phone',
        'director',
        'chapter_name',
        'chapter_code',
        'is_picture',
    )

    readonly_fields = (
        'is_picture',
    )

    # inlines = (
    #     GroupMemberInline,
    #     GroupAwardInline,
    # )
    save_on_top = True

@admin.register(Award)
class AwardAdmin(admin.ModelAdmin):
    form = select2_modelform(
        Chorus,
        attrs={'width': '250px'},
    )

    save_on_top = True

@admin.register(Performance)
class PerformanceAdmin(admin.ModelAdmin):
    form = select2_modelform(
        Performance,
        attrs={'width': '250px'},
    )
    list_display = (
        'group',
        'contest',
        'round',
        'place',
        'song1',
        'mus1',
        'prs1',
        'sng1',
        'song2',
        'mus2',
        'prs2',
        'sng2',
        'men',
    )

    list_filter = (
        'contest',
    )

    ordering = (
        'place',
    )

    save_on_top = True

@admin.register(Singer)
class SingerAdmin(admin.ModelAdmin):
    fields = (
        'name',
    )

    form = select2_modelform(
        Singer,
        attrs={'width': '250px'},
    )
    save_on_top = True

@admin.register(GroupMember)
class GroupMemberAdmin(admin.ModelAdmin):
    save_on_top = True

@admin.register(GroupFinish)
class GroupFinishAdmin(admin.ModelAdmin):
    save_on_top = True
<|endoftext|>


<commit_before>#!/usr/bin/python

## Binary Analysis Tool
## Copyright 2011-2012 Armijn Hemel for Tjaldur Software Governance Solutions
## Licensed under Apache 2.0, see LICENSE file for details

'''
Helper script to generate the LIST files for the string extraction scripts. While this script is not foolproof, it will save lots of typing :-)

This variant is specifically for processing a directory full of SRPM files.

1. files are converted to CPIO archives using rpm2cpio
2. files are unpacked using cpio
3. archives (ZIP, tar.gz, tar.bz, tgz, etc.) are moved to a temporary directory. Any patches are put in a special patch
directory.
4. LIST file for temporary directory is created
'''

import sys, os, os.path, subprocess, tempfile
from optparse import OptionParser
from multiprocessing import Pool

## it's either in the form of:
##   package-version.extension
##   package_version.extension
## where extension is tar.gz, tar.bz2, tar.xz, tgz, zip, tbz2, etc.
def generatelist(filedir, origin):
	files = os.walk(filedir)
	try:
        	while True:
			i = files.next()
			for p in i[2]:
				if p == "LIST":
					continue
				## first determine things like the extension
				res = p.rsplit('.', 1)
				if len(res) == 1:
					print >>sys.stderr, "can't split %s -- add manually" % (p,)
					continue
				(packageversion, extension) = res
				if extension in ["tgz", "tbz2"]:
					pass
				elif extension in ["jar", "zip"]:
					pass
				else:
					try:
						(packageversion, extension, compression) = p.rsplit('.', 2)
					except:
						continue
					if not (extension in ["tar"] and compression in ["gz", "bz2", "xz"]):
						continue
				## exceptions go here
				if "wireless_tools" in packageversion:
					res = packageversion.rsplit(".", 1)
				## first try package-version
				else:
					res = packageversion.rsplit("-", 1)
					if len(res) == 1:
						## then try package_version
						res = packageversion.rsplit("_", 1)
						if len(res) == 1:
							print >>sys.stderr, "can't split %s -- add manually" % (p,)
							continue
				(package, version) = res
				print "%s\t%s\t%s\t%s" % (package, version, p, origin)

	except Exception, e:
		pass

def unpacksrpm(filedir):
	extensions = [".tar.gz", ".tar.bz2", ".tar.xz", ".tgz", ".tbz2"]
	tmpdir = tempfile.mkdtemp()
	files = os.walk(filedir)
	try:
        	while True:
			i = files.next()
			for p in i[2]:
				## first filter out files that are likely no source rpm, just by
				## looking at the extension.
				res = p.rsplit('.', 2)
				if res[-1] != 'srpm' and (res[-1] != 'rpm' and res[-2] != 'src'):
					continue
				else:
					p2 = subprocess.Popen(['rpm', '-qpl', "%s/%s" % (i[0], p)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
					(stanout, stanerr) = p2.communicate()
					files = stanout.strip().rsplit("\n")
					for f in files:
						fsplit = f.lower().rsplit('.', 1)
						if len(fsplit) == 1:
							continue
						(packageversion, extension) = fsplit
						if extension in ["tgz", "tbz2"]:
							pass
						elif extension in ["jar", "zip"]:
							pass
						else:
							try:
								(packageversion, extension, compression) = f.lower().rsplit('.', 2)
							except:
								continue
							if not (extension in ["tar"] and compression in ["gz", "bz2", "xz"]):
								continue
							else:
								print f
					## make a temporary directory
					## unpack
					## copy tarball to tmpdir
	except Exception, e:
		pass
	return tmpdir

def main(argv):
	parser = OptionParser()
	parser.add_option("-f", "--filedir", action="store", dest="filedir", help="path to directory containing files to unpack", metavar="DIR")
	parser.add_option("-o", "--origin", action="store", dest="origin", help="origin of packages (default: unknown)", metavar="ORIGIN")
	(options, args) = parser.parse_args()
	if options.filedir == None:
		print >>sys.stderr, "Specify dir with files"
		sys.exit(1)
	if options.origin == None:
		origin = "unknown"
	else:
		origin = options.origin
	srpmdir = unpacksrpm(options.filedir)
	generatelist(srpmdir, origin)

if __name__ == "__main__":
	main(sys.argv)
<commit_msg>more stubs<commit_after>#!/usr/bin/python

## Binary Analysis Tool
## Copyright 2011-2012 Armijn Hemel for Tjaldur Software Governance Solutions
## Licensed under Apache 2.0, see LICENSE file for details

'''
Helper script to generate the LIST files for the string extraction scripts. While this script is not foolproof, it will save lots of typing :-)

This variant is specifically for processing a directory full of SRPM files.

1. files are converted to CPIO archives using rpm2cpio
2. files are unpacked using cpio
3. archives (ZIP, tar.gz, tar.bz, tgz, etc.) are moved to a temporary directory. Any patches are put in a special patch
directory.
4. LIST file for temporary directory is created
'''

import sys, os, os.path, subprocess, tempfile, shutil
from optparse import OptionParser
from multiprocessing import Pool

## it's either in the form of:
##   package-version.extension
##   package_version.extension
## where extension is tar.gz, tar.bz2, tar.xz, tgz, zip, tbz2, etc.
def generatelist(filedir, origin):
	files = os.walk(filedir)
	try:
        	while True:
			i = files.next()
			for p in i[2]:
				if p == "LIST":
					continue
				## first determine things like the extension
				res = p.rsplit('.', 1)
				if len(res) == 1:
					print >>sys.stderr, "can't split %s -- add manually" % (p,)
					continue
				(packageversion, extension) = res
				if extension in ["tgz", "tbz2"]:
					pass
				elif extension in ["jar", "zip"]:
					pass
				else:
					try:
						(packageversion, extension, compression) = p.rsplit('.', 2)
					except:
						continue
					if not (extension in ["tar"] and compression in ["gz", "bz2", "xz"]):
						continue
				## exceptions go here
				if "wireless_tools" in packageversion:
					res = packageversion.rsplit(".", 1)
				## first try package-version
				else:
					res = packageversion.rsplit("-", 1)
					if len(res) == 1:
						## then try package_version
						res = packageversion.rsplit("_", 1)
						if len(res) == 1:
							print >>sys.stderr, "can't split %s -- add manually" % (p,)
							continue
				(package, version) = res
				print "%s\t%s\t%s\t%s" % (package, version, p, origin)

	except Exception, e:
		pass

def unpacksrpm(filedir):
	extensions = [".tar.gz", ".tar.bz2", ".tar.xz", ".tgz", ".tbz2"]
	tmpdir = tempfile.mkdtemp()
	files = os.walk(filedir)
	try:
        	while True:
			i = files.next()
			for p in i[2]:
				## first filter out files that are likely no source rpm, just by
				## looking at the extension.
				res = p.rsplit('.', 2)
				if res[-1] != 'srpm' and (res[-1] != 'rpm' and res[-2] != 'src'):
					continue
				else:
					p2 = subprocess.Popen(['rpm', '-qpl', "%s/%s" % (i[0], p)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
					(stanout, stanerr) = p2.communicate()
					files = stanout.strip().rsplit("\n")
					for f in files:
						fsplit = f.lower().rsplit('.', 1)
						if len(fsplit) == 1:
							continue
						(packageversion, extension) = fsplit
						if extension in ["tgz", "tbz2"]:
							#pass
							continue
						elif extension in ["jar", "zip"]:
							#pass
							continue
						else:
							try:
								(packageversion, extension, compression) = f.lower().rsplit('.', 2)
							except:
								continue
							if not (extension in ["tar"] and compression in ["gz", "bz2", "xz"]):
								continue
							else:
								print f
						## make a temporary directory
						cpiodir = tempfile.mkdtemp()
						## copy tarball to tmpdir
						oldcwd = os.getcwd()
						shutil.copy("%s/%s" % (i[0], p), cpiodir)
						os.chdir(cpiodir)
						#p1 = subprocess.Popen(['rpm2cpio'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
						#p2 = subprocess.Popen(['cpio', '-i'], stdin=bla], stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=tmpdir)
						#shutil.copy(f, tmpdir)
						os.chdir(oldcwd)
	except Exception, e:
		print >>sys.stderr, e
	return tmpdir

def main(argv):
	parser = OptionParser()
	parser.add_option("-f", "--filedir", action="store", dest="filedir", help="path to directory containing files to unpack", metavar="DIR")
	parser.add_option("-o", "--origin", action="store", dest="origin", help="origin of packages (default: unknown)", metavar="ORIGIN")
	(options, args) = parser.parse_args()
	if options.filedir == None:
		print >>sys.stderr, "Specify dir with files"
		sys.exit(1)
	if options.origin == None:
		origin = "unknown"
	else:
		origin = options.origin
	srpmdir = unpacksrpm(options.filedir)
	generatelist(srpmdir, origin)

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


<commit_before>from decimal import Decimal
import logging

from waldur_core.structure.permissions import _get_project
from waldur_mastermind.common.utils import quantize_price
from waldur_mastermind.invoices import models as invoices_models
from waldur_mastermind.invoices.registrators import BaseRegistrator
from waldur_mastermind.marketplace import models as marketplace_models
from waldur_mastermind.marketplace import utils as marketplace_utils
from waldur_vmware import models as vmware_models

logger = logging.getLogger(__name__)

def mb_to_gb(value):
    # In marketplace RAM and storage is stored in GB, but in plugin it is stored in MB.
    return quantize_price(Decimal(value / 1024.0))

class VirtualMachineRegistrator(BaseRegistrator):

    def get_customer(self, source):
        return source.service_project_link.project.customer

    def get_sources(self, customer):
        return vmware_models.VirtualMachine.objects.filter(
            service_project_link__project__customer=customer
        ).exclude(backend_id=None).exclude(backend_id='').distinct()

    def _create_item(self, source, invoice, start, end):
        try:
            resource = marketplace_models.Resource.objects.get(scope=source)
            plan = resource.plan
            if not plan:
                logger.warning('Skipping VMware item invoice creation because '
                               'billing plan is not defined for resource. '
                               'Resource ID: %s', resource.id)
                return
        except marketplace_models.Resource.DoesNotExist:
            logger.warning('Skipping VMware item invoice creation because '
                           'marketplace resource is not available for VMware resource. '
                           'Resource ID: %s', source.id)
            return

        components_map = {
            plan_component.component.type: plan_component.price
            for plan_component in plan.components.all()
        }

        missing_components = {'cpu', 'ram', 'disk'} - set(components_map.keys())
        if missing_components:
            logger.warning('Skipping VMware item invoice creation because plan components are missing. '
                           'Plan ID: %s. Missing components: %s', plan.id, ', '.join(missing_components))
            return

        cores_price = components_map['cpu'] * source.cores
        ram_price = components_map['ram'] * mb_to_gb(source.ram)
        disk_price = components_map['disk'] * mb_to_gb(source.total_disk)
        total_price = cores_price + ram_price + disk_price

        start = invoices_models.adjust_invoice_items(
            invoice, source, start, total_price, plan.unit)

        details = self.get_details(source)
        service_provider_info = marketplace_utils.get_service_provider_info(resource)
        details.update(service_provider_info)
        item = invoices_models.InvoiceItem.objects.create(
            scope=source,
            project=_get_project(source),
            unit_price=total_price,
            unit=plan.unit,
            product_code=plan.product_code,
            article_code=plan.article_code,
            invoice=invoice,
            start=start,
            end=end,
            details=details,
        )
        self.init_details(item)

    def get_name(self, source):
        return '{name} ({cores} CPU, {ram} GB RAM, {disk} GB disk)'.format(
            name=source.name,
            cores=source.cores,
            ram=mb_to_gb(source.ram),
            disk=mb_to_gb(source.total_disk),
        )

    def get_details(self, source):
        details = {
            'cpu': source.cores,
            'ram': source.ram,
            'disk': source.total_disk,
        }
        service_provider_info = marketplace_utils.get_service_provider_info(source)
        details.update(service_provider_info)
        return details
<commit_msg>Remove leftover.<commit_after>from decimal import Decimal
import logging

from waldur_core.structure.permissions import _get_project
from waldur_mastermind.common.utils import quantize_price
from waldur_mastermind.invoices import models as invoices_models
from waldur_mastermind.invoices.registrators import BaseRegistrator
from waldur_mastermind.marketplace import models as marketplace_models
from waldur_mastermind.marketplace import utils as marketplace_utils
from waldur_vmware import models as vmware_models

logger = logging.getLogger(__name__)

def mb_to_gb(value):
    # In marketplace RAM and storage is stored in GB, but in plugin it is stored in MB.
    return quantize_price(Decimal(value / 1024.0))

class VirtualMachineRegistrator(BaseRegistrator):

    def get_customer(self, source):
        return source.service_project_link.project.customer

    def get_sources(self, customer):
        return vmware_models.VirtualMachine.objects.filter(
            service_project_link__project__customer=customer
        ).exclude(backend_id=None).exclude(backend_id='').distinct()

    def _create_item(self, source, invoice, start, end):
        try:
            resource = marketplace_models.Resource.objects.get(scope=source)
            plan = resource.plan
            if not plan:
                logger.warning('Skipping VMware item invoice creation because '
                               'billing plan is not defined for resource. '
                               'Resource ID: %s', resource.id)
                return
        except marketplace_models.Resource.DoesNotExist:
            logger.warning('Skipping VMware item invoice creation because '
                           'marketplace resource is not available for VMware resource. '
                           'Resource ID: %s', source.id)
            return

        components_map = {
            plan_component.component.type: plan_component.price
            for plan_component in plan.components.all()
        }

        missing_components = {'cpu', 'ram', 'disk'} - set(components_map.keys())
        if missing_components:
            logger.warning('Skipping VMware item invoice creation because plan components are missing. '
                           'Plan ID: %s. Missing components: %s', plan.id, ', '.join(missing_components))
            return

        cores_price = components_map['cpu'] * source.cores
        ram_price = components_map['ram'] * mb_to_gb(source.ram)
        disk_price = components_map['disk'] * mb_to_gb(source.total_disk)
        total_price = cores_price + ram_price + disk_price

        start = invoices_models.adjust_invoice_items(
            invoice, source, start, total_price, plan.unit)

        details = self.get_details(source)
        item = invoices_models.InvoiceItem.objects.create(
            scope=source,
            project=_get_project(source),
            unit_price=total_price,
            unit=plan.unit,
            product_code=plan.product_code,
            article_code=plan.article_code,
            invoice=invoice,
            start=start,
            end=end,
            details=details,
        )
        self.init_details(item)

    def get_name(self, source):
        return '{name} ({cores} CPU, {ram} GB RAM, {disk} GB disk)'.format(
            name=source.name,
            cores=source.cores,
            ram=mb_to_gb(source.ram),
            disk=mb_to_gb(source.total_disk),
        )

    def get_details(self, source):
        details = {
            'cpu': source.cores,
            'ram': source.ram,
            'disk': source.total_disk,
        }
        service_provider_info = marketplace_utils.get_service_provider_info(source)
        details.update(service_provider_info)
        return details
<|endoftext|>