<commit_before>import numpy as np
from pymatgen.io.vasp.outputs import Vasprun
from pymatgen.io.vasp.inputs import Kpoints, Poscar
from pymatgen.io.vasp.sets import MPNonSCFSet
from pymatgen.electronic_structure.bandstructure import Spin
from os.path import join

class Mass_eff():
    '''Calculating effective mass via finite difference method.
    '''
    def __init__(self, h):
        ''' h: step size
        '''
        self.h = h

    def stencil(self):
        '''hardcoded 5-point stencil in cartesian coordinates
        [x, y, z];
        h: step size in 1/Angstrom
        '''
        stcl = np.array([[0.0, 0.0, 0.0], [-2.0, 0.0, 0.0], [-1.0, 0.0, 0.0],
                         [1.0, 0.0, 0.0], [ 2.0, 0.0, 0.0], [ 0.0,-2.0, 0.0], [ 0.0,-1.0, 0.0],
                         [0.0, 1.0, 0.0], [ 0.0, 2.0, 0.0], [ 0.0, 0.0,-2.0], [ 0.0, 0.0,-1.0],
                         [0.0, 0.0, 1.0], [ 0.0, 0.0, 2.0], [-2.0,-2.0, 0.0], [-1.0,-2.0, 0.0],
                         [1.0,-2.0, 0.0], [ 2.0,-2.0, 0.0], [-2.0,-1.0, 0.0], [-1.0,-1.0, 0.0],
                         [1.0,-1.0, 0.0], [ 2.0,-1.0, 0.0], [-2.0, 1.0, 0.0], [-1.0, 1.0, 0.0],
                         [1.0, 1.0, 0.0], [ 2.0, 1.0, 0.0], [-2.0, 2.0, 0.0], [-1.0, 2.0, 0.0],
                         [1.0, 2.0, 0.0], [ 2.0, 2.0, 0.0], [-2.0, 0.0,-2.0], [-1.0, 0.0,-2.0],
                         [1.0, 0.0,-2.0], [ 2.0, 0.0,-2.0], [-2.0, 0.0,-1.0], [-1.0, 0.0,-1.0],
                         [1.0, 0.0,-1.0], [ 2.0, 0.0,-1.0], [-2.0, 0.0, 1.0], [-1.0, 0.0, 1.0],
                         [1.0, 0.0, 1.0], [ 2.0, 0.0, 1.0], [-2.0, 0.0, 2.0], [-1.0, 0.0, 2.0],
                         [1.0, 0.0, 2.0], [ 2.0, 0.0, 2.0], [ 0.0,-2.0,-2.0], [ 0.0,-1.0,-2.0],
                         [0.0, 1.0,-2.0], [ 0.0, 2.0,-2.0], [ 0.0,-2.0,-1.0], [ 0.0,-1.0,-1.0],
                         [0.0, 1.0,-1.0], [ 0.0, 2.0,-1.0], [ 0.0,-2.0, 1.0], [ 0.0,-1.0, 1.0],
                         [0.0, 1.0, 1.0], [ 0.0, 2.0, 1.0], [ 0.0,-2.0, 2.0], [ 0.0,-1.0, 2.0],
                         [0.0, 1.0, 2.0], [ 0.0, 2.0, 2.0]])

        return self.h*stcl

    def kpoints(self, recp_vec, k0_recp):
        '''List of kpoints for the nscf calculation
        in reciprocal lattice vectors;
        a: scaling factor found in POSCAR
        '''
        recp_vec_inv = np.linalg.inv(recp_vec)
        k0_cart = np.dot(k0_recp, recp_vec)
        kl_cart = k0_cart + self.stencil()
        kl_recp = np.dot(kl_cart, recp_vec_inv)
        return kl_recp

    def write_vasp(self, k0_recp, scfdir, destdir):
        '''Generate VASP nscf input files
        '''
        r = Vasprun(join(scfdir, 'vasprun.xml'))
        recp_vec = r.lattice_rec.matrix

        is_k_spin = True
        try:
            len(k0_recp[0])
        except:
            is_k_spin = False
            k0_up = k0_recp
            k0_dn = None

        if is_k_spin:
            k0_up, k0_dn = k0_recp[0], k0_recp[1]

        list_k = self.kpoints(recp_vec, k0_up)
        if is_k_spin:
           list_k = np.concatenate((list_k, self.kpoints(recp_vec, k0_dn)))
        nscf = MPNonSCFSet.from_prev_calc(scfdir, user_incar_settings=
                                          {"NCORE": 4, "EDIFF":"1E-7"})
        nscf.write_input(destdir)
        mode = Kpoints.supported_modes.Reciprocal
        kpt = Kpoints(style=mode, kpts=list_k, num_kpts=len(list_k),
                      kpts_weights=[1.0]*len(list_k),
                      comment="5-point stencil h:{}".format(self.h))
        kpt.write_file(join(destdir, 'KPOINTS'))

    def calc_mass(self, type='hole', destdir='./'):
        '''Calculate the effective mass (in m_0);
        e is a length-61 array (in eV).
        '''
        h = self.h
        eig = self.read_eigenvalues(type, destdir)

        is_k_spin = eig[Spin.up.name].size == 122

        mass = {}
        if not is_k_spin:
            for spin in eig.keys():
                mass[spin] = self.mass_tensor(eig[spin], self.h)
        else:
            mass[Spin.up.name] = self.mass_tensor(eig[Spin.up.name][:61], self.h)
            mass[Spin.down.name] = self.mass_tensor(eig[Spin.down.name][61:], self.h)

        return mass

    @staticmethod
    def mass_tensor(e,h):
        m_t = np.zeros((3,3)) # 3x3 tensor
        m_t[0,0] = (-(e[1]+e[4])  + 16*(e[2]+e[3])   - 30*e[0])/(12*h**2)
        m_t[1,1] = (-(e[5]+e[8])  + 16*(e[6]+e[7])   - 30*e[0])/(12*h**2)
        m_t[2,2] = (-(e[9]+e[12]) + 16*(e[10]+e[11]) - 30*e[0])/(12*h**2)
        m_t[0,1] = (-63*(e[15]+e[20]+e[21]+e[26]) + 63*(e[14]+e[17]+e[27]+e[24]) +
                     44*(e[16]+e[25]-e[13]-e[28]) + 74*(e[18]+e[23]-e[19]-e[22]))/(600*h**2)
        m_t[0,2] = (-63*(e[31]+e[36]+e[37]+e[42]) + 63*(e[30]+e[33]+e[43]+e[40]) +
                     44*(e[32]+e[41]-e[29]-e[44]) + 74*(e[34]+e[39]-e[35]-e[38]))/(600*h**2)
        m_t[1,2] = (-63*(e[47]+e[52]+e[53]+e[58]) + 63*(e[46]+e[49]+e[59]+e[56]) +
                     44*(e[48]+e[57]-e[45]-e[60]) + 74*(e[50]+e[55]-e[51]-e[54]))/(600*h**2)
        m_t[1,0] = m_t[0,1]
        m_t[2,0] = m_t[0,2]
        m_t[2,1] = m_t[1,2]

        w, v = np.linalg.eig(m_t)
        w /= 27.2114/1.8897**2 # -> atomic units
        m = 1.0/w

        return m

    def read_eigenvalues(self, type, destdir):
        r = Vasprun(join(destdir, 'vasprun.xml'))
        eig = {}
        if r.is_spin:
            spins = [Spin.up, Spin.down]
        else:
            spins = [Spin.up]

        for spin in spins:
            vbi, cbi = self.extremum_band_index(r, spin)
            if type == 'hole':
                eig[spin.name] = r.eigenvalues[spin][:,vbi,0]
            else:
                eig[spin.name] = r.eigenvalues[spin][:,cbi,0]

        return eig

    @staticmethod
    def extremum_band_index(r, spin):
        bs = r.eigenvalues[spin]
        ind = max(np.argwhere(bs[0][:,1] > 0))

        return ind, ind+1

if __name__ == '__main__':
    # example
    scfdir = "../"
    destdir = "./"
    h = 0.01            # stepsize in 1/angstrom
    k0_recp = [[0,0,0],[0,0,0]] # band extremum for the two spins
    em = Mass_eff(h)    # instantiate
    em.write_vasp(k0_recp, scfdir, destdir)  # generate the k-point list for nscf calculation
    #
    # do a vasp nscf calculation
    #
    m = em.calc_mass('hole')  # determine the hole effective mass
    print(h, m)
<commit_msg>Minor fixes<commit_after>import numpy as np
from pymatgen.io.vasp.outputs import Vasprun
from pymatgen.io.vasp.inputs import Kpoints, Poscar
from pymatgen.io.vasp.sets import MPNonSCFSet
from pymatgen.electronic_structure.bandstructure import Spin
from os.path import join

class Mass_eff():
    '''Calculating effective mass via finite difference method.
    '''
    def __init__(self, h):
        ''' h: step size
        '''
        self.h = h

    def stencil(self):
        '''hardcoded 5-point stencil in cartesian coordinates
        [x, y, z];
        h: step size in 1/Angstrom
        '''
        stcl = np.array([[0.0, 0.0, 0.0], [-2.0, 0.0, 0.0], [-1.0, 0.0, 0.0],
                         [1.0, 0.0, 0.0], [ 2.0, 0.0, 0.0], [ 0.0,-2.0, 0.0], [ 0.0,-1.0, 0.0],
                         [0.0, 1.0, 0.0], [ 0.0, 2.0, 0.0], [ 0.0, 0.0,-2.0], [ 0.0, 0.0,-1.0],
                         [0.0, 0.0, 1.0], [ 0.0, 0.0, 2.0], [-2.0,-2.0, 0.0], [-1.0,-2.0, 0.0],
                         [1.0,-2.0, 0.0], [ 2.0,-2.0, 0.0], [-2.0,-1.0, 0.0], [-1.0,-1.0, 0.0],
                         [1.0,-1.0, 0.0], [ 2.0,-1.0, 0.0], [-2.0, 1.0, 0.0], [-1.0, 1.0, 0.0],
                         [1.0, 1.0, 0.0], [ 2.0, 1.0, 0.0], [-2.0, 2.0, 0.0], [-1.0, 2.0, 0.0],
                         [1.0, 2.0, 0.0], [ 2.0, 2.0, 0.0], [-2.0, 0.0,-2.0], [-1.0, 0.0,-2.0],
                         [1.0, 0.0,-2.0], [ 2.0, 0.0,-2.0], [-2.0, 0.0,-1.0], [-1.0, 0.0,-1.0],
                         [1.0, 0.0,-1.0], [ 2.0, 0.0,-1.0], [-2.0, 0.0, 1.0], [-1.0, 0.0, 1.0],
                         [1.0, 0.0, 1.0], [ 2.0, 0.0, 1.0], [-2.0, 0.0, 2.0], [-1.0, 0.0, 2.0],
                         [1.0, 0.0, 2.0], [ 2.0, 0.0, 2.0], [ 0.0,-2.0,-2.0], [ 0.0,-1.0,-2.0],
                         [0.0, 1.0,-2.0], [ 0.0, 2.0,-2.0], [ 0.0,-2.0,-1.0], [ 0.0,-1.0,-1.0],
                         [0.0, 1.0,-1.0], [ 0.0, 2.0,-1.0], [ 0.0,-2.0, 1.0], [ 0.0,-1.0, 1.0],
                         [0.0, 1.0, 1.0], [ 0.0, 2.0, 1.0], [ 0.0,-2.0, 2.0], [ 0.0,-1.0, 2.0],
                         [0.0, 1.0, 2.0], [ 0.0, 2.0, 2.0]])

        return self.h*stcl

    def kpoints(self, recp_vec, k0_recp):
        '''List of kpoints for the nscf calculation
        in reciprocal lattice vectors;
        a: scaling factor found in POSCAR
        '''
        recp_vec_inv = np.linalg.inv(recp_vec)
        k0_cart = np.dot(k0_recp, recp_vec)
        kl_cart = k0_cart + self.stencil()
        kl_recp = np.dot(kl_cart, recp_vec_inv)
        return kl_recp

    def write_vasp(self, k0_recp, scfdir, destdir):
        '''Generate VASP nscf input files
        '''
        r = Vasprun(join(scfdir, 'vasprun.xml'))
        recp_vec = r.lattice_rec.matrix

        is_k_spin = True
        try:
            len(k0_recp[0])
        except:
            is_k_spin = False
            k0_up = k0_recp
            k0_dn = None

        if is_k_spin:
            k0_up, k0_dn = k0_recp[0], k0_recp[1]

        list_k = self.kpoints(recp_vec, k0_up)
        if is_k_spin:
           list_k = np.concatenate((list_k, self.kpoints(recp_vec, k0_dn)))
        nscf = MPNonSCFSet.from_prev_calc(scfdir, user_incar_settings=
                                          {"NCORE": 4, "EDIFF":"1E-7"})
        nscf.write_input(destdir)
        mode = Kpoints.supported_modes.Reciprocal
        kpt = Kpoints(style=mode, kpts=list_k, num_kpts=len(list_k),
                      kpts_weights=[1.0]*len(list_k),
                      comment="5-point stencil h:{}".format(self.h))
        kpt.write_file(join(destdir, 'KPOINTS'))

    def calc_mass(self, type='hole', destdir='./'):
        '''Calculate the effective mass (in m_0);
        e is a length-61 array (in eV).
        '''
        h = self.h
        eig = self.read_eigenvalues(type, destdir)

        is_k_spin = eig[Spin.up.name].size == 122

        mass = {}
        if not is_k_spin:
            for spin in eig.keys():
                mass[spin] = self.mass_tensor(eig[spin], self.h)
        else:
            mass[Spin.up.name] = self.mass_tensor(eig[Spin.up.name][:61], self.h)
            try:
                mass[Spin.down.name] = self.mass_tensor(eig[Spin.down.name][61:], self.h)
            except:
                pass

        return mass

    @staticmethod
    def mass_tensor(e,h):
        m_t = np.zeros((3,3)) # 3x3 tensor
        m_t[0,0] = (-(e[1]+e[4])  + 16*(e[2]+e[3])   - 30*e[0])/(12*h**2)
        m_t[1,1] = (-(e[5]+e[8])  + 16*(e[6]+e[7])   - 30*e[0])/(12*h**2)
        m_t[2,2] = (-(e[9]+e[12]) + 16*(e[10]+e[11]) - 30*e[0])/(12*h**2)
        m_t[0,1] = (-63*(e[15]+e[20]+e[21]+e[26]) + 63*(e[14]+e[17]+e[27]+e[24]) +
                     44*(e[16]+e[25]-e[13]-e[28]) + 74*(e[18]+e[23]-e[19]-e[22]))/(600*h**2)
        m_t[0,2] = (-63*(e[31]+e[36]+e[37]+e[42]) + 63*(e[30]+e[33]+e[43]+e[40]) +
                     44*(e[32]+e[41]-e[29]-e[44]) + 74*(e[34]+e[39]-e[35]-e[38]))/(600*h**2)
        m_t[1,2] = (-63*(e[47]+e[52]+e[53]+e[58]) + 63*(e[46]+e[49]+e[59]+e[56]) +
                     44*(e[48]+e[57]-e[45]-e[60]) + 74*(e[50]+e[55]-e[51]-e[54]))/(600*h**2)
        m_t[1,0] = m_t[0,1]
        m_t[2,0] = m_t[0,2]
        m_t[2,1] = m_t[1,2]

        w, v = np.linalg.eig(m_t)
        w /= 27.2114/1.8897**2 # -> atomic units
        m = 1.0/w

        return m

    def read_eigenvalues(self, type, destdir):
        r = Vasprun(join(destdir, 'vasprun.xml'))
        eig = {}
        if r.is_spin:
            spins = [Spin.up, Spin.down]
        else:
            spins = [Spin.up]

        for spin in spins:
            vbi, cbi = self.extremum_band_index(r, spin)
            if type == 'hole':
                eig[spin.name] = r.eigenvalues[spin][:,vbi,0]
            else:
                eig[spin.name] = r.eigenvalues[spin][:,cbi,0]

        return eig

    @staticmethod
    def extremum_band_index(r, spin):
        bs = r.eigenvalues[spin]
        ind = max(np.argwhere(bs[0][:,1] > 0))

        return ind, ind+1
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on Wed Mar 22 12:51:10 2017

@author: scram
"""

def all_keys(dic):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    if isinstance(dic,dict):
        return list(dic.keys())+[key for subdic in dic.values()
                                   if isinstance(subdic,dict)
                                       for key in all_keys(subdic)]
    else:
        return []

def to_edge_list(dic):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
#    print "\n",dic
    if isinstance(dic,dict):
        return [(k,i) for k,v in dic.items() for i in v]+[
               tup for subdic in dic.values() for tup in to_edge_list(subdic)]
    else:
        return dic

def subset_by_key(dic, keys2keep):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    return {k:subset_by_key(v, keys2keep)
            if isinstance(v,dict) else v
                for k,v in dic.items()
                    if k in keys2keep}

def vecs_to_recs(vector_list,field_names):
    return list(dict(zip(field_names,vector)) for vector in vector_list)

def map_keys(func,dic):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    return {func(k):map_keys(func,v)
            if isinstance(v,dict) else v
                for k,v in dic.items()}

def subset_of_keys(dic, keys2keep):
    """
    TODO:
        negative_sets iie. all keys but
        Test against all types
        handle python recursion limit
    """
    if isinstance(dic,dict):
        return dic.keys()+[key for subdic in dic.values()
                                   if isinstance(subdic,dict)
                                       for key in subset_of_keys(subdic,keys2keep) if key in keys2keep]
    else:
        return dic

def key_at_depth(dic, dpt):
    """ From koffein
        http://stackoverflow.com/questions/20425886/python-how-do-i-get-a-list-of-all-keys-in-a-dictionary-of-dictionaries-at-a-gi
    """
    if dpt > 0:
        return [key for subdic in dic.values() if isinstance(subdic,dict)
                         for key in key_at_depth(subdic, dpt-1) ]
    else:
        if isinstance(dic,dict):
            return dic.keys()
        else:
            return []

def value_all_depth(dic):
    """ STILL WORKING ON
    lit comprehension from Martijn Pieters
        http://stackoverflow.com/questions/28015458/list-comprehension-to-flatten-a-dictionary-of-dictionaries"""
    if isinstance(dic,dict):
        return [v for nested in dic.values() for v in nested.values()]
    else:
        return

<commit_msg>FINAL COMMIT added some slight changes for PY3 compatability and bug fixes<commit_after># -*- coding: utf-8 -*-
"""
Created on Wed Mar 22 12:51:10 2017

@author: Colin Drayton
"""

def all_keys(dic):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    if isinstance(dic,dict):
        return list(dic.keys())+[key for subdic in dic.values()
                                   if isinstance(subdic,dict)
                                       for key in all_keys(subdic)]
    else:
        return []

def to_edge_list(dic):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
#    print "\n",dic
    if isinstance(dic,dict):
        return [(k,i) for k,v in dic.items() for i in v]+[
               tup for subdic in dic.values() for tup in to_edge_list(subdic)]
    else:
        return dic

def subset_by_key(dic, keys2keep):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    return {k:subset_by_key(v, keys2keep)
            if isinstance(v,dict) else v
                for k,v in dic.items()
                    if k in keys2keep}

def vecs_to_recs(vector_list,field_names):
    return list(dict(zip(field_names,vector)) for vector in vector_list)

def map_list(func,container):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    return [map_list(func,v)
            if isinstance(v,(list,tuple)) else v
                for v in container]

def list_convert(func,container):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    return func([list_convert(func,v)
            if isinstance(v,(list,tuple)) else v
                for v in container])

def map_keys(func,dic):
    """
    TODO:
        Test against all types
        handle python recursion limit
    """
    return {func(k):map_keys(func,v)
            if isinstance(v,dict) else v
                for k,v in dic.items()}

def subset_of_keys(dic, keys2keep):
    """
    TODO:
        negative_sets iie. all keys but
        Test against all types
        handle python recursion limit
    """
    if isinstance(dic,dict):
        return dic.keys()+[key for subdic in dic.values()
                                   if isinstance(subdic,dict)
                                       for key in subset_of_keys(subdic,keys2keep) if key in keys2keep]
    else:
        return dic

def key_at_depth(dic, dpt):
    """ From koffein
        http://stackoverflow.com/questions/20425886/python-how-do-i-get-a-list-of-all-keys-in-a-dictionary-of-dictionaries-at-a-gi
    """
    if dpt > 0:
        return [key for subdic in dic.values() if isinstance(subdic,dict)
                         for key in key_at_depth(subdic, dpt-1) ]
    else:
        if isinstance(dic,dict):
            return dic.keys()
        else:
            return []

def value_all_depth(dic):
    """ STILL WORKING ON
    lit comprehension from Martijn Pieters
        http://stackoverflow.com/questions/28015458/list-comprehension-to-flatten-a-dictionary-of-dictionaries"""
    if isinstance(dic,dict):
        return [v for nested in dic.values() for v in nested.values()]
    else:
        return

<|endoftext|>


<commit_before>import sys, sublime, sublime_plugin
import subprocess, time
import os, signal

from subprocess import Popen, PIPE
from datetime import datetime

import threading
import traceback
import shlex
import re

def HaxeComplete_inst():
    from .HaxeComplete import HaxeComplete
    return HaxeComplete.inst

spaceChars = re.compile("\s")
wordChars = re.compile("[a-z0-9._]", re.I)
importLine = re.compile("^([ \t]*)import\s+([a-z0-9._]+);", re.I | re.M)
packageLine = re.compile("package\s*([a-z0-9.]*);", re.I)

compilerOutput = re.compile("^(.+):(\\d+): (lines|characters?) (\\d+)(?:-(\\d+))? : (.*)$", re.M)
compactFunc = re.compile("\(.*\)")
compactProp = re.compile(":.*\.([a-z_0-9]+)", re.I)
libLine = re.compile("([^:]*):[^\[]*\[(dev\:)?(.*)\]")
classpathLine = re.compile("Classpath : (.*)")
typeDecl = re.compile("(class|typedef|enum|typedef|abstract)\s+([A-Z][a-zA-Z0-9_]*)\s*(<[a-zA-Z0-9_,]+>)?" , re.M )
libFlag = re.compile("-lib\s+(.*?)")
skippable = re.compile("^[a-zA-Z0-9_\s]*$")
inAnonymous = re.compile("[{,]\s*([a-zA-Z0-9_\"\']+)\s*:\s*$" , re.M | re.U )
extractTag = re.compile("<([a-z0-9_-]+).*\s(name|main|path)=\"([a-z0-9_./-]+)\"", re.I)
extractTagName = re.compile("<([a-z0-9_-]+).*\s", re.I)
variables = re.compile("var\s+([^:;(\s]*)", re.I)
functions = re.compile("function\s+([^;\.\(\)\s]*)", re.I)
functionParams = re.compile("function\s+[a-zA-Z0-9_]+\s*\(([^\)]*)", re.M)
paramDefault = re.compile("(=\s*\"*[^\"]*\")", re.M)
isType = re.compile("^[A-Z][a-zA-Z0-9_]*$")
comments = re.compile("(//[^\n\r]*?[\n\r]|/\*(.*?)\*/)", re.MULTILINE | re.DOTALL )

haxeVersion = re.compile("(Haxe|haXe) Compiler ([0-9]\.[0-9])",re.M)
#haxeFileRegex = "^([^:]*):([0-9]+): characters? ([0-9]+)-?[0-9]* :(.*)$"
haxeFileRegex = "^([^:\n\r]*\.hx):([0-9]+):.*$"
controlStruct = re.compile( "\s*(if|switch|for|while)\s*\($" );

try:
  STARTUP_INFO = subprocess.STARTUPINFO()
  STARTUP_INFO.dwFlags |= subprocess.STARTF_USESHOWWINDOW
  STARTUP_INFO.wShowWindow = subprocess.SW_HIDE
except (AttributeError):
    STARTUP_INFO = None

try :
    stexec = __import__("exec")
    ExecCommand = stexec.ExecCommand
    AsyncProcess = stexec.AsyncProcess
except ImportError as e :
    import Default
    stexec = getattr( Default , "exec" )
    ExecCommand = stexec.ExecCommand
    AsyncProcess = stexec.AsyncProcess
    unicode = str #dirty...

def runcmd( args, input=None ):
    try:
        if int(sublime.version()) >= 3000 :
            p = Popen(args, stdout=PIPE, stderr=PIPE, stdin=PIPE, startupinfo=STARTUP_INFO)
        else:
            p = Popen([a.encode(sys.getfilesystemencoding()) for a in args], stdout=PIPE, stderr=PIPE, stdin=PIPE, startupinfo=STARTUP_INFO)
        if isinstance(input, unicode) :
            input = input.encode('utf-8')
        out, err = p.communicate(input=input)
        return (out.decode('utf-8') if out else '', err.decode('utf-8') if err else '')
    except (OSError, ValueError) as e:
        err = u'Error while running %s: %s' % (args[0], e)
        if int(sublime.version()) >= 3000 :
            return ("",err)
        else:
            return ("", err.decode('utf-8'))

def show_quick_panel(_window, options, done, flags=0, sel_index=0):
    sublime.set_timeout(lambda: _window.show_quick_panel(options, done, flags, sel_index), 10)

class runcmd_async(object):
    """
    Enables to run subprocess commands in a different thread with TIMEOUT option.

    Based on jcollado's solution:
    http://stackoverflow.com/questions/1191374/subprocess-with-timeout/4825933#4825933
    """
    command = None
    process = None
    status = None
    output, error = '', ''

    def __init__(self, command):
        if isinstance(command, str):
            command = shlex.split(command)
        self.command = command

    def run(self, timeout=None, **kwargs):
        """ Run a command then return: (status, output, error). """
        def target(**kwargs):
            try:
                self.process = subprocess.Popen(self.command, **kwargs)
                self.output, self.error = self.process.communicate()
                self.status = self.process.returncode
            except:
                self.error = traceback.format_exc()
                self.status = -1
        # default stdout and stderr
        if 'stdout' not in kwargs:
            kwargs['stdout'] = subprocess.PIPE
        if 'stderr' not in kwargs:
            kwargs['stderr'] = subprocess.PIPE
        # thread
        thread = threading.Thread(target=target, kwargs=kwargs)
        thread.start()
        thread.join(timeout)
        if thread.is_alive():
            self.process.terminate()
            thread.join()
        return self.status, self.output, self.error

<commit_msg>also use correct file_regex for commands issues from the plugin<commit_after>import sys, sublime, sublime_plugin
import subprocess, time
import os, signal

from subprocess import Popen, PIPE
from datetime import datetime

import threading
import traceback
import shlex
import re

def HaxeComplete_inst():
    from .HaxeComplete import HaxeComplete
    return HaxeComplete.inst

spaceChars = re.compile("\s")
wordChars = re.compile("[a-z0-9._]", re.I)
importLine = re.compile("^([ \t]*)import\s+([a-z0-9._]+);", re.I | re.M)
packageLine = re.compile("package\s*([a-z0-9.]*);", re.I)

compilerOutput = re.compile("^(.+):(\\d+): (lines|characters?) (\\d+)(?:-(\\d+))? : (.*)$", re.M)
compactFunc = re.compile("\(.*\)")
compactProp = re.compile(":.*\.([a-z_0-9]+)", re.I)
libLine = re.compile("([^:]*):[^\[]*\[(dev\:)?(.*)\]")
classpathLine = re.compile("Classpath : (.*)")
typeDecl = re.compile("(class|typedef|enum|typedef|abstract)\s+([A-Z][a-zA-Z0-9_]*)\s*(<[a-zA-Z0-9_,]+>)?" , re.M )
libFlag = re.compile("-lib\s+(.*?)")
skippable = re.compile("^[a-zA-Z0-9_\s]*$")
inAnonymous = re.compile("[{,]\s*([a-zA-Z0-9_\"\']+)\s*:\s*$" , re.M | re.U )
extractTag = re.compile("<([a-z0-9_-]+).*\s(name|main|path)=\"([a-z0-9_./-]+)\"", re.I)
extractTagName = re.compile("<([a-z0-9_-]+).*\s", re.I)
variables = re.compile("var\s+([^:;(\s]*)", re.I)
functions = re.compile("function\s+([^;\.\(\)\s]*)", re.I)
functionParams = re.compile("function\s+[a-zA-Z0-9_]+\s*\(([^\)]*)", re.M)
paramDefault = re.compile("(=\s*\"*[^\"]*\")", re.M)
isType = re.compile("^[A-Z][a-zA-Z0-9_]*$")
comments = re.compile("(//[^\n\r]*?[\n\r]|/\*(.*?)\*/)", re.MULTILINE | re.DOTALL )

haxeVersion = re.compile("(Haxe|haXe) Compiler ([0-9]\.[0-9])",re.M)
haxeFileRegex = "^(.+):(\\d+): (?:lines \\d+-\\d+|character(?:s \\d+-| )(\\d+)) : (.*)$"
controlStruct = re.compile( "\s*(if|switch|for|while)\s*\($" );

try:
  STARTUP_INFO = subprocess.STARTUPINFO()
  STARTUP_INFO.dwFlags |= subprocess.STARTF_USESHOWWINDOW
  STARTUP_INFO.wShowWindow = subprocess.SW_HIDE
except (AttributeError):
    STARTUP_INFO = None

try :
    stexec = __import__("exec")
    ExecCommand = stexec.ExecCommand
    AsyncProcess = stexec.AsyncProcess
except ImportError as e :
    import Default
    stexec = getattr( Default , "exec" )
    ExecCommand = stexec.ExecCommand
    AsyncProcess = stexec.AsyncProcess
    unicode = str #dirty...

def runcmd( args, input=None ):
    try:
        if int(sublime.version()) >= 3000 :
            p = Popen(args, stdout=PIPE, stderr=PIPE, stdin=PIPE, startupinfo=STARTUP_INFO)
        else:
            p = Popen([a.encode(sys.getfilesystemencoding()) for a in args], stdout=PIPE, stderr=PIPE, stdin=PIPE, startupinfo=STARTUP_INFO)
        if isinstance(input, unicode) :
            input = input.encode('utf-8')
        out, err = p.communicate(input=input)
        return (out.decode('utf-8') if out else '', err.decode('utf-8') if err else '')
    except (OSError, ValueError) as e:
        err = u'Error while running %s: %s' % (args[0], e)
        if int(sublime.version()) >= 3000 :
            return ("",err)
        else:
            return ("", err.decode('utf-8'))

def show_quick_panel(_window, options, done, flags=0, sel_index=0):
    sublime.set_timeout(lambda: _window.show_quick_panel(options, done, flags, sel_index), 10)

class runcmd_async(object):
    """
    Enables to run subprocess commands in a different thread with TIMEOUT option.

    Based on jcollado's solution:
    http://stackoverflow.com/questions/1191374/subprocess-with-timeout/4825933#4825933
    """
    command = None
    process = None
    status = None
    output, error = '', ''

    def __init__(self, command):
        if isinstance(command, str):
            command = shlex.split(command)
        self.command = command

    def run(self, timeout=None, **kwargs):
        """ Run a command then return: (status, output, error). """
        def target(**kwargs):
            try:
                self.process = subprocess.Popen(self.command, **kwargs)
                self.output, self.error = self.process.communicate()
                self.status = self.process.returncode
            except:
                self.error = traceback.format_exc()
                self.status = -1
        # default stdout and stderr
        if 'stdout' not in kwargs:
            kwargs['stdout'] = subprocess.PIPE
        if 'stderr' not in kwargs:
            kwargs['stderr'] = subprocess.PIPE
        # thread
        thread = threading.Thread(target=target, kwargs=kwargs)
        thread.start()
        thread.join(timeout)
        if thread.is_alive():
            self.process.terminate()
            thread.join()
        return self.status, self.output, self.error

<|endoftext|>


<commit_before>#!/usr/bin/env python
# coding=utf-8
from __future__ import division, print_function, unicode_literals

import os
import pickle

import json

import sacred.optional as opt
from sacred.serializer import flatten, restore

__all__ = ('load_config_file', 'save_config_file')

class Handler(object):
    def __init__(self, load, dump, mode):
        self.load = load
        self.dump = dump
        self.mode = mode

HANDLER_BY_EXT = {
    '.json': Handler(lambda fp: restore(json.load(fp)),
                     lambda obj, fp: json.dump(flatten(obj), fp,
                                               sort_keys=True, indent=2), ''),
    '.pickle': Handler(pickle.load, pickle.dump, 'b'),
}

if opt.has_yaml:
    HANDLER_BY_EXT['.yaml'] = Handler(opt.yaml.load, opt.yaml.dump, '')
    HANDLER_BY_EXT['.yml'] = Handler(opt.yaml.load, opt.yaml.dump, '')

def get_handler(filename):
    _, extension = os.path.splitext(filename)
    try:
        return HANDLER_BY_EXT[extension]
    except KeyError:
        raise ValueError(
            'Configuration file "{}" has invalid or unsupported extension '
            '"{}".'.format(filename, extension)
        )

def load_config_file(filename):
    handler = get_handler(filename)
    with open(filename, 'r' + handler.mode) as f:
        return handler.load(f)

def save_config_file(config, filename):
    handler = get_handler(filename)
    with open(filename, 'w' + handler.mode) as f:
        handler.dump(config, f)
<commit_msg>Better error message for yaml missing. (#450)<commit_after>#!/usr/bin/env python
# coding=utf-8
from __future__ import division, print_function, unicode_literals

import os
import pickle

import json

import sacred.optional as opt
from sacred.serializer import flatten, restore

__all__ = ('load_config_file', 'save_config_file')

class Handler(object):
    def __init__(self, load, dump, mode):
        self.load = load
        self.dump = dump
        self.mode = mode

HANDLER_BY_EXT = {
    '.json': Handler(lambda fp: restore(json.load(fp)),
                     lambda obj, fp: json.dump(flatten(obj), fp,
                                               sort_keys=True, indent=2), ''),
    '.pickle': Handler(pickle.load, pickle.dump, 'b'),
}

yaml_extensions = ('.yaml', '.yml')
if opt.has_yaml:
    for extension in yaml_extensions:
        HANDLER_BY_EXT[extension] = Handler(opt.yaml.load, opt.yaml.dump, '')

def get_handler(filename):
    _, extension = os.path.splitext(filename)
    if extension in yaml_extensions and not opt.has_yaml:
        raise KeyError('Configuration file "{}" cannot be loaded as '
                       'you do not have PyYAML installed.'.format(filename))
    try:
        return HANDLER_BY_EXT[extension]
    except KeyError:
        raise ValueError(
            'Configuration file "{}" has invalid or unsupported extension '
            '"{}".'.format(filename, extension)
        )

def load_config_file(filename):
    handler = get_handler(filename)
    with open(filename, 'r' + handler.mode) as f:
        return handler.load(f)

def save_config_file(config, filename):
    handler = get_handler(filename)
    with open(filename, 'w' + handler.mode) as f:
        handler.dump(config, f)
<|endoftext|>


<commit_before>from __future__ import absolute_import, unicode_literals

from collections import OrderedDict

class Immutable(object):
    """
    Immutable object which adheres to the Mapping and the Sequence protocols.

    * Attributes are kept in `self._ordered_dict`. NEVER MUTATE THIS!
    * Instantiate with kwargs or args. Instantiating with args preserves order.
    * Mapping methods get(), items(), keys(), and values() are also included.
    * Sequence methods index() and count() are also included.

    """

    class ImmutableError(Exception):
        pass

    def __init__(self, *args, **kwargs):
        """
        Instantiate an Immutable instance.

        >>> # tuple instantiation --> Note that this method preserves order!
        >>> obj = Immutable((('val_0', 0), ('val_1', 1)))
        >>> # key=value pairs
        >>> obj = Immutable(val_0=0, val_1=1)
        >>> # same as above, but by upacking a dict
        >>> attribute_dict = {'val_0': 0, 'val_1': 1}
        >>> obj = Immutable(**attribute_dict)
        >>> # access via '.' or '[]'
        >>> obj.val_0
        >>> obj['val_0']

        :param args: (<attr>, <val>,) pairs to add *in order*
        :param kwargs: Allows you to unpack a dict to create this.

        """
        reserved_keys = ('get', 'keys', 'values', 'items', 'count', 'index',
                         '_ordered_dict', '_tuple')
        ordered_dict = OrderedDict()
        for key, val in args:
            if key in kwargs:
                raise self.ImmutableError('Key in args duplicated in kwargs.')
            ordered_dict[key] = val
        ordered_dict.update(kwargs)
        for key, val in ordered_dict.items():
            try:
                hash(key)
                hash(val)
            except TypeError:
                raise self.ImmutableError('Keys and vals must be hashable.')
            if isinstance(key, int):
                raise self.ImmutableError('Keys cannot be integers.')
            if key in reserved_keys:
                raise self.ImmutableError('Keys cannot be any of these: {}.'
                                          .format(reserved_keys))
        self.__dict__['_ordered_dict'] = ordered_dict
        self.__dict__['_tuple'] = tuple(ordered_dict.values())

    def __contains__(self, item):
        raise self.ImmutableError('Containment not implemented. Try with '
                                  'keys(), values(), or items().')

    def __reversed__(self):
        raise self.ImmutableError('Reversal not implemented. Try with '
                                  'keys(), values(), or items().')

    def __getitem__(self, key):
        if isinstance(key, int):
            return self.__dict__['_tuple'][key]
        else:
            return self.__dict__['_ordered_dict'][key]

    def __setitem__(self, key, value):
        raise self.ImmutableError('Cannot set items on Immutable.')

    def __getattr__(self, key):
        if key == 'items':
            return self.__dict__['_ordered_dict'].items
        elif key == 'keys':
            return self.__dict__['_ordered_dict'].keys
        elif key == 'values':
            return self.__dict__['_ordered_dict'].values
        elif key == 'index':
            return self.__dict__['_tuple'].index
        elif key == 'count':
            return self.__dict__['_tuple'].count
        else:
            return self.__getitem__(key)

    def __setattr__(self, key, value):
        raise self.ImmutableError('Cannot set attributes on Immutable.')

    def __cmp__(self, other):
        raise self.ImmutableError('Only equality comparisons implemented.')

    def __eq__(self, other):
        if not isinstance(other, Immutable):
            return False
        return hash(self) == hash(other)

    def __ne__(self, other):
        if not isinstance(other, Immutable):
            return True
        return hash(self) != hash(other)

    def __len__(self):
        return len(self.__dict__['_tuple'])

    def __iter__(self):
        raise self.ImmutableError('Iteration not implemented. Try with '
                                  'keys(), values(), or items().')

    def __hash__(self):
        return hash(tuple(self._ordered_dict.items()))

    def __str__(self):
        return '{}'.format(self.__repr__())

    def __unicode__(self):
        return u'{}'.format(self.__repr__())

    def __repr__(self):
        keys_repr = u', '.join(u'{}={}'.format(key, repr(val))
                               for key, val in self.items())
        return u'Immutable({})'.format(keys_repr)

    def __dir__(self):
        return list(self.keys())
<commit_msg>Remove `u` literal for Python 3.<commit_after>from __future__ import absolute_import, unicode_literals

from collections import OrderedDict

class Immutable(object):
    """
    Immutable object which adheres to the Mapping and the Sequence protocols.

    * Attributes are kept in `self._ordered_dict`. NEVER MUTATE THIS!
    * Instantiate with kwargs or args. Instantiating with args preserves order.
    * Mapping methods get(), items(), keys(), and values() are also included.
    * Sequence methods index() and count() are also included.

    """

    class ImmutableError(Exception):
        pass

    def __init__(self, *args, **kwargs):
        """
        Instantiate an Immutable instance.

        >>> # tuple instantiation --> Note that this method preserves order!
        >>> obj = Immutable((('val_0', 0), ('val_1', 1)))
        >>> # key=value pairs
        >>> obj = Immutable(val_0=0, val_1=1)
        >>> # same as above, but by upacking a dict
        >>> attribute_dict = {'val_0': 0, 'val_1': 1}
        >>> obj = Immutable(**attribute_dict)
        >>> # access via '.' or '[]'
        >>> obj.val_0
        >>> obj['val_0']

        :param args: (<attr>, <val>,) pairs to add *in order*
        :param kwargs: Allows you to unpack a dict to create this.

        """
        reserved_keys = ('get', 'keys', 'values', 'items', 'count', 'index',
                         '_ordered_dict', '_tuple')
        ordered_dict = OrderedDict()
        for key, val in args:
            if key in kwargs:
                raise self.ImmutableError('Key in args duplicated in kwargs.')
            ordered_dict[key] = val
        ordered_dict.update(kwargs)
        for key, val in ordered_dict.items():
            try:
                hash(key)
                hash(val)
            except TypeError:
                raise self.ImmutableError('Keys and vals must be hashable.')
            if isinstance(key, int):
                raise self.ImmutableError('Keys cannot be integers.')
            if key in reserved_keys:
                raise self.ImmutableError('Keys cannot be any of these: {}.'
                                          .format(reserved_keys))
        self.__dict__['_ordered_dict'] = ordered_dict
        self.__dict__['_tuple'] = tuple(ordered_dict.values())

    def __contains__(self, item):
        raise self.ImmutableError('Containment not implemented. Try with '
                                  'keys(), values(), or items().')

    def __reversed__(self):
        raise self.ImmutableError('Reversal not implemented. Try with '
                                  'keys(), values(), or items().')

    def __getitem__(self, key):
        if isinstance(key, int):
            return self.__dict__['_tuple'][key]
        else:
            return self.__dict__['_ordered_dict'][key]

    def __setitem__(self, key, value):
        raise self.ImmutableError('Cannot set items on Immutable.')

    def __getattr__(self, key):
        if key == 'items':
            return self.__dict__['_ordered_dict'].items
        elif key == 'keys':
            return self.__dict__['_ordered_dict'].keys
        elif key == 'values':
            return self.__dict__['_ordered_dict'].values
        elif key == 'index':
            return self.__dict__['_tuple'].index
        elif key == 'count':
            return self.__dict__['_tuple'].count
        else:
            return self.__getitem__(key)

    def __setattr__(self, key, value):
        raise self.ImmutableError('Cannot set attributes on Immutable.')

    def __cmp__(self, other):
        raise self.ImmutableError('Only equality comparisons implemented.')

    def __eq__(self, other):
        if not isinstance(other, Immutable):
            return False
        return hash(self) == hash(other)

    def __ne__(self, other):
        if not isinstance(other, Immutable):
            return True
        return hash(self) != hash(other)

    def __len__(self):
        return len(self.__dict__['_tuple'])

    def __iter__(self):
        raise self.ImmutableError('Iteration not implemented. Try with '
                                  'keys(), values(), or items().')

    def __hash__(self):
        return hash(tuple(self._ordered_dict.items()))

    def __str__(self):
        return bytes('{}'.format(self.__repr__()))

    def __unicode__(self):
        return '{}'.format(self.__repr__())

    def __repr__(self):
        keys_repr = ', '.join('{}={}'.format(key, repr(val))
                              for key, val in self.items())
        return 'Immutable({})'.format(keys_repr)

    def __dir__(self):
        return list(self.keys())
<|endoftext|>


<commit_before>"""Provides interface for training the model."""

import os
from pathlib import Path

import torch
from tqdm import tqdm

from . import models
from .preprocessing import ImageDataPipeline

def main(train_dir,
         label_dict,
         steps,
         savepath,
         resuming=True):
    """
    Trains the model and saves the result.

    Parameters:
        - train_dir (str)
            - Path to the directory of classes.
            - e.g. 'data/train', where 'train' holds subdirs with images in them.
        - label_dict (dict, str -> np.ndarray)
            - Maps the name of the subdirectory (class) to a label.
                - e.g. {'cats': np.array([[1, 0]]), 'dogs': np.array([[0, 1]])}
                    - Each label must have the same shape!
                    - In this case, the two labels are of shape [1, 2].
        - steps (int)
            - Number of gradient updates (samples to train on).
        - savepath (str)
            - Path where the model will be saved/loaded from.
            - e.g. hello/world/save_model.pth
        - resuming (bool)
            - Whether to resume training from a saved model or to start from scratch.
    """
    # Initialize device, model, and optimizer.
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    model = models.BabyResNet().to(device)
    if resuming:
        model.load_state_dict(torch.load(savepath))
    optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)
    # Initialize preprocessor and begin training the model.
    preprocessor = ImageDataPipeline()
    for step, img_path, img_tensor, img_label in tqdm(preprocessor.preprocess_classes(steps,
                                                                                train_dir,
                                                                                label_dict),
                                                      desc='Progress', total=steps, ncols=99,
                                                      unit='img'):
        img_tensor, img_label = (torch.tensor(img_tensor, dtype=torch.float32).to(device),
                                 torch.tensor(img_label, dtype=torch.float32).to(device))
        optimizer.zero_grad()
        output = model(img_tensor)
        objective = torch.sqrt(torch.nn.functional.mse_loss(output, img_label))
        objective.backward()
        optimizer.step()
        # print('Step: {}/{} | Image: {} | Objective: {}'.format(step, steps, img_path, objective))
    # Create savedir if nonexistent, and save the model.
    savedir = Path(Path(savepath).parent)
    if not os.path.exists(savedir):
        os.makedirs(savedir)
    torch.save(model.state_dict(), savepath)
    # Play a noise to signify end of training.
    print('\a')
<commit_msg>Refactoring for readability.<commit_after>"""Provides interface for training the model."""

import os
from pathlib import Path

import torch
from tqdm import tqdm

from . import models
from .preprocessing import ImageDataPipeline

def main(train_dir,
         label_dict,
         steps,
         savepath,
         resuming=True):
    """
    Trains the model and saves the result.

    Parameters:
        - train_dir (str)
            - Path to the directory of classes.
            - e.g. 'data/train', where 'train' holds subdirs with images in them.
        - label_dict (dict, str -> np.ndarray)
            - Maps the name of the subdirectory (class) to a label.
                - e.g. {'cats': np.array([[1, 0]]), 'dogs': np.array([[0, 1]])}
                    - Each label must have the same shape!
                    - In this case, the two labels are of shape [1, 2].
        - steps (int)
            - Number of gradient updates (samples to train on).
        - savepath (str)
            - Path where the model will be saved/loaded from.
            - e.g. hello/world/save_model.pth
        - resuming (bool)
            - Whether to resume training from a saved model or to start from scratch.
    """
    # Initialize device, model, and optimizer.
    device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
    model = models.BabyResNet().to(device)
    if resuming:
        model.load_state_dict(torch.load(savepath))
    optimizer = torch.optim.Adam(model.parameters(), lr=0.0001)
    # Initialize preprocessor and begin training the model.
    preproc = ImageDataPipeline()
    for step, path, image, label in tqdm(preproc.preprocess_classes(steps, train_dir, label_dict),
                                         desc='Progress', total=steps, ncols=99, unit='image'):
        image, label = (torch.tensor(image, dtype=torch.float32).to(device),
                        torch.tensor(label, dtype=torch.float32).to(device))
        optimizer.zero_grad()
        output = model(image)
        objective = torch.sqrt(torch.nn.functional.mse_loss(output, label))
        objective.backward()
        optimizer.step()
        # print('Step: {}/{} | Image: {} | Objective: {}'.format(step, steps, img_path, objective))
    # Create savedir if nonexistent, and save the model.
    savedir = Path(Path(savepath).parent)
    if not os.path.exists(savedir):
        os.makedirs(savedir)
    torch.save(model.state_dict(), savepath)
    # Play a noise to signify end of training.
    print('\a')
<|endoftext|>


<commit_before>#
# Copyright (c) 2015 ThoughtWorks, Inc.
#
# Pixelated is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pixelated is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
from test.support.integration import SoledadTestBase, load_mail_from_file
from twisted.internet import defer

class LeapMailStoreTest(SoledadTestBase):

    @defer.inlineCallbacks
    def setUp(self):
        yield super(LeapMailStoreTest, self).setUp()

    @defer.inlineCallbacks
    def test_get_mail_with_body(self):
        mail = load_mail_from_file('mbox00000000')
        mail_id = yield self._create_mail_in_soledad(mail)
        expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'tags': set([])}

        result = yield self.mail_store.get_mail(mail_id, include_body=True)
        self.assertIsNotNone(result)
        self.assertEqual(expected_mail_dict, result.as_dict())

    @defer.inlineCallbacks
    def test_round_trip_through_soledad_does_not_modify_content(self):
        mail = load_mail_from_file('mbox00000000')
        mail_id = yield self._create_mail_in_soledad(mail)
        expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'tags': set([])}

        mail = yield self.mail_store.add_mail('INBOX', mail.as_string())
        fetched_mail = yield self.mail_store.get_mail(mail_id, include_body=True)
        self.assertEqual(expected_mail_dict['header'], mail.as_dict()['header'])
        self.assertEqual(expected_mail_dict['header'], fetched_mail.as_dict()['header'])

    @defer.inlineCallbacks
    def test_all_mails(self):
        mail = load_mail_from_file('mbox00000000')
        yield self._create_mail_in_soledad(mail)

        mails = yield self.mail_store.all_mails()

        self.assertEqual(1, len(mails))
        self.assertEqual('Itaque consequatur repellendus provident sunt quia.', mails[0].subject)

    @defer.inlineCallbacks
    def test_add_and_remove_mail(self):
        yield self.adaptor.initialize_store(self.soledad)
        mail = load_mail_from_file('mbox00000000')
        yield self.mail_store.add_mailbox('INBOX')

        msg = yield self.mail_store.add_mail('INBOX', mail.as_string())

        yield self.mail_store.delete_mail(msg.mail_id)

        deleted_msg = yield self.mail_store.get_mail(msg.mail_id)

        self.assertIsNone(deleted_msg)

    @defer.inlineCallbacks
    def test_get_mailbox_mail_ids(self):
        mail = load_mail_from_file('mbox00000000')
        yield self.mail_store.add_mailbox('INBOX')
        mail = yield self.mail_store.add_mail('INBOX', mail.as_string())

        mails = yield self.mail_store.get_mailbox_mail_ids('INBOX')

        self.assertEqual(1, len(mails))
        self.assertEqual(mail.mail_id, mails[0])
<commit_msg>Fixed test_leap_mailstore integration test.<commit_after>#
# Copyright (c) 2015 ThoughtWorks, Inc.
#
# Pixelated is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pixelated is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
from test.support.integration import SoledadTestBase, load_mail_from_file
from twisted.internet import defer

class LeapMailStoreTest(SoledadTestBase):

    @defer.inlineCallbacks
    def setUp(self):
        yield super(LeapMailStoreTest, self).setUp()

    @defer.inlineCallbacks
    def test_get_mail_with_body(self):
        self.maxDiff = None
        mail = load_mail_from_file('mbox00000000')
        mail_id = yield self._create_mail_in_soledad(mail)
        expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'status': [], 'tags': set([])}

        result = yield self.mail_store.get_mail(mail_id, include_body=True)
        self.assertIsNotNone(result)
        self.assertEqual(expected_mail_dict, result.as_dict())

    @defer.inlineCallbacks
    def test_round_trip_through_soledad_does_not_modify_content(self):
        mail = load_mail_from_file('mbox00000000')
        mail_id = yield self._create_mail_in_soledad(mail)
        expected_mail_dict = {'body': u'Dignissimos ducimus veritatis. Est tenetur consequatur quia occaecati. Vel sit sit voluptas.\n\nEarum distinctio eos. Accusantium qui sint ut quia assumenda. Facere dignissimos inventore autem sit amet. Pariatur voluptatem sint est.\n\nUt recusandae praesentium aspernatur. Exercitationem amet placeat deserunt quae consequatur eum. Unde doloremque suscipit quia.\n\n', 'header': {u'date': u'Tue, 21 Apr 2015 08:43:27 +0000 (UTC)', u'to': [u'carmel@murazikortiz.name'], u'x-tw-pixelated-tags': u'nite, macro, trash', u'from': u'darby.senger@zemlak.biz', u'subject': u'Itaque consequatur repellendus provident sunt quia.'}, 'ident': mail_id, 'status': [], 'tags': set([])}

        mail = yield self.mail_store.add_mail('INBOX', mail.as_string())
        fetched_mail = yield self.mail_store.get_mail(mail_id, include_body=True)
        self.assertEqual(expected_mail_dict['header'], mail.as_dict()['header'])
        self.assertEqual(expected_mail_dict['header'], fetched_mail.as_dict()['header'])

    @defer.inlineCallbacks
    def test_all_mails(self):
        mail = load_mail_from_file('mbox00000000')
        yield self._create_mail_in_soledad(mail)

        mails = yield self.mail_store.all_mails()

        self.assertEqual(1, len(mails))
        self.assertEqual('Itaque consequatur repellendus provident sunt quia.', mails[0].subject)

    @defer.inlineCallbacks
    def test_add_and_remove_mail(self):
        yield self.adaptor.initialize_store(self.soledad)
        mail = load_mail_from_file('mbox00000000')
        yield self.mail_store.add_mailbox('INBOX')

        msg = yield self.mail_store.add_mail('INBOX', mail.as_string())

        yield self.mail_store.delete_mail(msg.mail_id)

        deleted_msg = yield self.mail_store.get_mail(msg.mail_id)

        self.assertIsNone(deleted_msg)

    @defer.inlineCallbacks
    def test_get_mailbox_mail_ids(self):
        mail = load_mail_from_file('mbox00000000')
        yield self.mail_store.add_mailbox('INBOX')
        mail = yield self.mail_store.add_mail('INBOX', mail.as_string())

        mails = yield self.mail_store.get_mailbox_mail_ids('INBOX')

        self.assertEqual(1, len(mails))
        self.assertEqual(mail.mail_id, mails[0])
<|endoftext|>


<commit_before>"""Clean an input BAM file to work with downstream pipelines.

GATK and Picard based pipelines have specific requirements for
chromosome order, run group information and other BAM formatting.
This provides a pipeline to prepare and resort an input.
"""
import os

from bcbio import bam, broad, utils
from bcbio.distributed.transaction import file_transaction

def picard_prep(in_bam, names, ref_file, dirs, config):
    """Prepare input BAM using Picard and GATK cleaning tools.

    - ReorderSam to reorder file to reference
    - AddOrReplaceReadGroups to add read group information and coordinate sort
    - PrintReads to filters to remove problem records:
    - filterMBQ to remove reads with mismatching bases and base qualities
    """
    runner = broad.runner_from_config(config)
    work_dir = utils.safe_makedir(os.path.join(dirs["work"], "bamclean", names["sample"]))
    reorder_bam = os.path.join(work_dir, "%s-reorder.bam" %
                               os.path.splitext(os.path.basename(in_bam))[0])
    reorder_bam = runner.run_fn("picard_reorder", in_bam, ref_file, reorder_bam)
    rg_bam = runner.run_fn("picard_fix_rgs", reorder_bam, names)
    return _filter_bad_reads(rg_bam, ref_file, runner, config)

def _filter_bad_reads(in_bam, ref_file, runner, config):
    """Use GATK filter to remove problem reads which choke GATK and Picard.
    """
    bam.index(in_bam, config)
    out_file = "%s-gatkfilter.bam" % os.path.splitext(in_bam)[0]
    if not utils.file_exists(out_file):
        with utils.curdir_tmpdir() as tmp_dir:
            with file_transaction(out_file) as tx_out_file:
                params = ["-T", "PrintReads",
                          "-R", ref_file,
                          "-I", in_bam,
                          "--out", tx_out_file,
                          "--filter_mismatching_base_and_quals"]
                runner.run_gatk(params, tmp_dir)
    return out_file
<commit_msg>Ensure sequence has hg19.dict reference prior to running. Fixes #336<commit_after>"""Clean an input BAM file to work with downstream pipelines.

GATK and Picard based pipelines have specific requirements for
chromosome order, run group information and other BAM formatting.
This provides a pipeline to prepare and resort an input.
"""
import os

from bcbio import bam, broad, utils
from bcbio.distributed.transaction import file_transaction

def picard_prep(in_bam, names, ref_file, dirs, config):
    """Prepare input BAM using Picard and GATK cleaning tools.

    - ReorderSam to reorder file to reference
    - AddOrReplaceReadGroups to add read group information and coordinate sort
    - PrintReads to filters to remove problem records:
    - filterMBQ to remove reads with mismatching bases and base qualities
    """
    runner = broad.runner_from_config(config)
    work_dir = utils.safe_makedir(os.path.join(dirs["work"], "bamclean", names["sample"]))
    runner.run_fn("picard_index_ref", ref_file)
    reorder_bam = os.path.join(work_dir, "%s-reorder.bam" %
                               os.path.splitext(os.path.basename(in_bam))[0])
    reorder_bam = runner.run_fn("picard_reorder", in_bam, ref_file, reorder_bam)
    rg_bam = runner.run_fn("picard_fix_rgs", reorder_bam, names)
    return _filter_bad_reads(rg_bam, ref_file, runner, config)

def _filter_bad_reads(in_bam, ref_file, runner, config):
    """Use GATK filter to remove problem reads which choke GATK and Picard.
    """
    bam.index(in_bam, config)
    out_file = "%s-gatkfilter.bam" % os.path.splitext(in_bam)[0]
    if not utils.file_exists(out_file):
        with utils.curdir_tmpdir() as tmp_dir:
            with file_transaction(out_file) as tx_out_file:
                params = ["-T", "PrintReads",
                          "-R", ref_file,
                          "-I", in_bam,
                          "--out", tx_out_file,
                          "--filter_mismatching_base_and_quals"]
                runner.run_gatk(params, tmp_dir)
    return out_file
<|endoftext|>


<commit_before>"""
Queries routing and caching.

Exports:

    get_topics_list()
    get_answer_dict()
"""
from __future__ import print_function

import re
import random
import cache
import adapter.cheat_sheets
import adapter.cmd
import adapter.internal
import adapter.latenz
import adapter.learnxiny
import adapter.question
import adapter.rosetta
from config import CONFIG

class Router(object):

    """
    Implementation of query routing. Routing is based on `routing_table`
    and the data exported by the adapters (functions `get_list()` and `is_found()`).

    `get_topics_list()` returns available topics (accessible at /:list).
    `get_answer_dict()` return answer for the query.
    """

    def __init__(self):

        self._cached_topics_list = []
        self._cached_topic_type = {}

        adapter_class = adapter.all_adapters(as_dict=True)

        active_adapters = set(CONFIG['adapters.active'] + CONFIG['adapters.mandatory'])

        self._adapter = {
            "internal": adapter.internal.InternalPages(
                get_topic_type=self.get_topic_type,
                get_topics_list=self.get_topics_list),
            "unknown": adapter.internal.UnknownPages(
                get_topic_type=self.get_topic_type,
                get_topics_list=self.get_topics_list),
        }

        for by_name in active_adapters:
            if by_name not in self._adapter:
                self._adapter[by_name] = adapter_class[by_name]()

        self._topic_list = {
            key: obj.get_list()
            for key, obj in self._adapter.items()
        }

        self.routing_table = CONFIG["routing.main"]
        self.routing_table = CONFIG["routing.pre"] + self.routing_table + CONFIG["routing.post"]

    def get_topics_list(self, skip_dirs=False, skip_internal=False):
        """
        List of topics returned on /:list
        """

        if self._cached_topics_list:
            return self._cached_topics_list

        skip = ['fosdem']
        if skip_dirs:
            skip.append("cheat.sheets dir")
        if skip_internal:
            skip.append("internal")
        sources_to_merge = [x for x in self._adapter if x not in skip]

        answer = {}
        for key in sources_to_merge:
            answer.update({name:key for name in self._topic_list[key]})
        answer = sorted(set(answer.keys()))

        self._cached_topics_list = answer
        return answer

    def get_topic_type(self, topic):
        """
        Return topic type for `topic` or "unknown" if topic can't be determined.
        """

        def __get_topic_type(topic):
            for regexp, route in self.routing_table:
                if re.search(regexp, topic):
                    if route in self._adapter:
                        if self._adapter[route].is_found(topic):
                            return route
                    else:
                        return route
            return CONFIG["routing.default"]

        if topic not in self._cached_topic_type:
            self._cached_topic_type[topic] = __get_topic_type(topic)
        return self._cached_topic_type[topic]

    def _get_page_dict(self, query, topic_type, request_options=None):
        """
        Return answer_dict for the `query`.
        """
        return self._adapter[topic_type]\
               .get_page_dict(query, request_options=request_options)

    def handle_if_random_request(self, topic):
        """
        Check if the `query` if a :random one, if yes we check its correctness and then randomly select a topic, based on the provided prefix.

        """

        def __select_random_topic(prefix, topic_list):
            #Here we remove the special cases
            if "rosetta/" in topic_list:
                topic_list.remove("rosetta/")

            cleaned_topic_list = [ x for x in topic_list if ':' not in x]

            #Here we still check that cleaned_topic_list in not empty
            if not cleaned_topic_list:
                return prefix

            random_topic = random.choice(cleaned_topic_list)
            return prefix + random_topic

        if topic.endswith('/:random') or topic.lstrip('/') == ':random':
            #We strip the :random part and see if the query is valid by running a get_topics_list()
            if topic.lstrip('/') == ':random' :
                 topic = topic.lstrip('/')
            prefix = topic[:-7]

            topic_list = [x[len(prefix):]
                         for x in self.get_topics_list()
                         if x.startswith(prefix)]

            if '' in topic_list:
                topic_list.remove('')

            if topic_list:
                # This is a correct formatted random query like /cpp/:random as the topic_list is not empty.
                random_topic = __select_random_topic(prefix, topic_list)
                return random_topic
            else:
                # This is a wrongly formatted random query like /xyxyxy/:random as the topic_list is empty
                # we just strip the /:random and let the already implemented logic handle it.
                wrongly_formatted_random = topic[:-8]
                return wrongly_formatted_random

        #Here if not a random requst, we just forward the topic
        return topic

    def get_answer_dict(self, topic, request_options=None):
        """
        Find cheat sheet for the topic.

        Args:
            `topic` (str):    the name of the topic of the cheat sheet

        Returns:
            answer_dict:      the answer dictionary
        """

        topic = self.handle_if_random_request(topic)
        topic_type = self.get_topic_type(topic)

        # 'question' queries are pretty expensive, that's why they should be handled
        # in a special way:
        # we do not drop the old style cache entries and try to reuse them if possible
        if topic_type == 'question':
            answer = cache.get('q:' + topic)
            if answer:
                if isinstance(answer, dict):
                    return answer
                return {
                    'topic': topic,
                    'topic_type': 'question',
                    'answer': answer,
                    'format': 'text+code',
                    }

            answer = self._get_page_dict(topic, topic_type, request_options=request_options)
            cache.put('q:' + topic, answer)
            return answer

        # Try to find cacheable queries in the cache.
        # If answer was not found in the cache, resolve it in a normal way and save in the cache
        cache_needed = self._adapter[topic_type].is_cache_needed()
        if cache_needed:
            answer = cache.get(topic)
            if not isinstance(answer, dict):
                answer = None
            if answer:
                return answer

        answer = self._get_page_dict(topic, topic_type, request_options=request_options)
        if isinstance(answer, dict):
            if "cache" in answer:
                cache_needed = answer["cache"]

        if cache_needed and answer:
            cache.put(topic, answer)
        return answer

# pylint: disable=invalid-name
_ROUTER = Router()
get_topics_list = _ROUTER.get_topics_list
get_answer_dict = _ROUTER.get_answer_dict
<commit_msg>Further removing of special cases<commit_after>"""
Queries routing and caching.

Exports:

    get_topics_list()
    get_answer_dict()
"""
from __future__ import print_function

import re
import random
import cache
import adapter.cheat_sheets
import adapter.cmd
import adapter.internal
import adapter.latenz
import adapter.learnxiny
import adapter.question
import adapter.rosetta
from config import CONFIG

class Router(object):

    """
    Implementation of query routing. Routing is based on `routing_table`
    and the data exported by the adapters (functions `get_list()` and `is_found()`).

    `get_topics_list()` returns available topics (accessible at /:list).
    `get_answer_dict()` return answer for the query.
    """

    def __init__(self):

        self._cached_topics_list = []
        self._cached_topic_type = {}

        adapter_class = adapter.all_adapters(as_dict=True)

        active_adapters = set(CONFIG['adapters.active'] + CONFIG['adapters.mandatory'])

        self._adapter = {
            "internal": adapter.internal.InternalPages(
                get_topic_type=self.get_topic_type,
                get_topics_list=self.get_topics_list),
            "unknown": adapter.internal.UnknownPages(
                get_topic_type=self.get_topic_type,
                get_topics_list=self.get_topics_list),
        }

        for by_name in active_adapters:
            if by_name not in self._adapter:
                self._adapter[by_name] = adapter_class[by_name]()

        self._topic_list = {
            key: obj.get_list()
            for key, obj in self._adapter.items()
        }

        self.routing_table = CONFIG["routing.main"]
        self.routing_table = CONFIG["routing.pre"] + self.routing_table + CONFIG["routing.post"]

    def get_topics_list(self, skip_dirs=False, skip_internal=False):
        """
        List of topics returned on /:list
        """

        if self._cached_topics_list:
            return self._cached_topics_list

        skip = ['fosdem']
        if skip_dirs:
            skip.append("cheat.sheets dir")
        if skip_internal:
            skip.append("internal")
        sources_to_merge = [x for x in self._adapter if x not in skip]

        answer = {}
        for key in sources_to_merge:
            answer.update({name:key for name in self._topic_list[key]})
        answer = sorted(set(answer.keys()))

        self._cached_topics_list = answer
        return answer

    def get_topic_type(self, topic):
        """
        Return topic type for `topic` or "unknown" if topic can't be determined.
        """

        def __get_topic_type(topic):
            for regexp, route in self.routing_table:
                if re.search(regexp, topic):
                    if route in self._adapter:
                        if self._adapter[route].is_found(topic):
                            return route
                    else:
                        return route
            return CONFIG["routing.default"]

        if topic not in self._cached_topic_type:
            self._cached_topic_type[topic] = __get_topic_type(topic)
        return self._cached_topic_type[topic]

    def _get_page_dict(self, query, topic_type, request_options=None):
        """
        Return answer_dict for the `query`.
        """
        return self._adapter[topic_type]\
               .get_page_dict(query, request_options=request_options)

    def handle_if_random_request(self, topic):
        """
        Check if the `query` if a :random one, if yes we check its correctness and then randomly select a topic, based on the provided prefix.

        """

        def __select_random_topic(prefix, topic_list):
            #Here we remove the special cases
            cleaned_topic_list = [ x for x in topic_list if '/' not in x and ':' not in x]

            #Here we still check that cleaned_topic_list in not empty
            if not cleaned_topic_list:
                return prefix

            random_topic = random.choice(cleaned_topic_list)
            return prefix + random_topic

        if topic.endswith('/:random') or topic.lstrip('/') == ':random':
            #We strip the :random part and see if the query is valid by running a get_topics_list()
            if topic.lstrip('/') == ':random' :
                 topic = topic.lstrip('/')
            prefix = topic[:-7]

            topic_list = [x[len(prefix):]
                         for x in self.get_topics_list()
                         if x.startswith(prefix)]

            if '' in topic_list:
                topic_list.remove('')

            if topic_list:
                # This is a correct formatted random query like /cpp/:random as the topic_list is not empty.
                random_topic = __select_random_topic(prefix, topic_list)
                return random_topic
            else:
                # This is a wrongly formatted random query like /xyxyxy/:random as the topic_list is empty
                # we just strip the /:random and let the already implemented logic handle it.
                wrongly_formatted_random = topic[:-8]
                return wrongly_formatted_random

        #Here if not a random requst, we just forward the topic
        return topic

    def get_answer_dict(self, topic, request_options=None):
        """
        Find cheat sheet for the topic.

        Args:
            `topic` (str):    the name of the topic of the cheat sheet

        Returns:
            answer_dict:      the answer dictionary
        """

        topic = self.handle_if_random_request(topic)
        topic_type = self.get_topic_type(topic)

        # 'question' queries are pretty expensive, that's why they should be handled
        # in a special way:
        # we do not drop the old style cache entries and try to reuse them if possible
        if topic_type == 'question':
            answer = cache.get('q:' + topic)
            if answer:
                if isinstance(answer, dict):
                    return answer
                return {
                    'topic': topic,
                    'topic_type': 'question',
                    'answer': answer,
                    'format': 'text+code',
                    }

            answer = self._get_page_dict(topic, topic_type, request_options=request_options)
            cache.put('q:' + topic, answer)
            return answer

        # Try to find cacheable queries in the cache.
        # If answer was not found in the cache, resolve it in a normal way and save in the cache
        cache_needed = self._adapter[topic_type].is_cache_needed()
        if cache_needed:
            answer = cache.get(topic)
            if not isinstance(answer, dict):
                answer = None
            if answer:
                return answer

        answer = self._get_page_dict(topic, topic_type, request_options=request_options)
        if isinstance(answer, dict):
            if "cache" in answer:
                cache_needed = answer["cache"]

        if cache_needed and answer:
            cache.put(topic, answer)
        return answer

# pylint: disable=invalid-name
_ROUTER = Router()
get_topics_list = _ROUTER.get_topics_list
get_answer_dict = _ROUTER.get_answer_dict
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
#
#    Copyright (C) 2013-15 Agile Business Group sagl
#    (<http://www.agilebg.com>)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published
#    by the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#

from openerp.osv import orm

class SaleOrderLine(orm.Model):
    _inherit = "sale.order.line"

    def product_id_change(
        self, cr, uid, ids, pricelist, product_id, qty=0,
        uom=False, qty_uos=0, uos=False, name='', partner_id=False,
        lang=False, update_tax=True, date_order=False, packaging=False,
        fiscal_position=False, flag=False, context=None
    ):
        res = super(SaleOrderLine, self).product_id_change(
            cr, uid, ids, pricelist, product_id, qty=qty, uom=uom,
            qty_uos=qty_uos, uos=uos, name='', partner_id=partner_id,
            lang=lang, update_tax=update_tax, date_order=date_order,
            packaging=packaging, fiscal_position=fiscal_position,
            flag=flag, context=context
        )
        if product_id:
            user = self.pool.get('res.users').browse(
                cr, uid, uid, context=context)
            user_groups = [g.id for g in user.groups_id]
            ref = self.pool.get('ir.model.data').get_object_reference(
                cr, uid, 'sale_line_description',
                'group_use_product_description_per_so_line'
            )
            if ref and len(ref) > 1 and ref[1] and not flag:
                group_id = ref[1]
                if group_id in user_groups:
                    product_obj = self.pool.get('product.product')
                    product = product_obj.browse(
                        cr, uid, product_id, context=context)
                    if (
                        product and
                        product.description and
                        'value' in res
                    ):
                        res['value']['name'] = product.description_sale
        return res
<commit_msg>Check description_sale instead of description<commit_after># -*- coding: utf-8 -*-
#
#
#    Copyright (C) 2013-15 Agile Business Group sagl
#    (<http://www.agilebg.com>)
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as published
#    by the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#

from openerp.osv import orm

class SaleOrderLine(orm.Model):
    _inherit = "sale.order.line"

    def product_id_change(
        self, cr, uid, ids, pricelist, product_id, qty=0,
        uom=False, qty_uos=0, uos=False, name='', partner_id=False,
        lang=False, update_tax=True, date_order=False, packaging=False,
        fiscal_position=False, flag=False, context=None
    ):
        res = super(SaleOrderLine, self).product_id_change(
            cr, uid, ids, pricelist, product_id, qty=qty, uom=uom,
            qty_uos=qty_uos, uos=uos, name='', partner_id=partner_id,
            lang=lang, update_tax=update_tax, date_order=date_order,
            packaging=packaging, fiscal_position=fiscal_position,
            flag=flag, context=context
        )
        if product_id:
            user = self.pool.get('res.users').browse(
                cr, uid, uid, context=context)
            user_groups = [g.id for g in user.groups_id]
            ref = self.pool.get('ir.model.data').get_object_reference(
                cr, uid, 'sale_line_description',
                'group_use_product_description_per_so_line'
            )
            if ref and len(ref) > 1 and ref[1] and not flag:
                group_id = ref[1]
                if group_id in user_groups:
                    product_obj = self.pool.get('product.product')
                    product = product_obj.browse(
                        cr, uid, product_id, context=context)
                    if (product.description_sale and 'value' in res):
                        res['value']['name'] = product.description_sale
        return res
<|endoftext|>