<commit_before>import os
import glob
import re
import sys
import socket
import couchdb
import logging
import argparse
import ConfigParser
import yaml
import json
import distance
import operator

CONFIG = {}

logger = logging.getLogger(__name__)

def list_applications():
    couch        = setupServer(CONFIG)
    projects_db  = couch['projects']
    applications = {}
    for project_id in projects_db:
        if "creation_time" not in projects_db[project_id]:
            continue
        application  = "unkonwn"
        if "application" in projects_db[project_id]:
            application = projects_db[project_id]["application"]
        if application in applications:
            applications[application] += 1
        else:
            applications[application] = 1
    for application in applications:
        print "{} {}".format(application, applications[application])

def setupServer(conf):
    db_conf = conf['statusdb']
    url="http://{0}:{1}@{2}:{3}".format(db_conf['username'], db_conf['password'], db_conf['url'], db_conf['port'])
    return couchdb.Server(url)

def load_yaml_config(config_file):
    """Load YAML config file

    :param str config_file: The path to the configuration file.

    :returns: A dict of the parsed config file.
    :rtype: dict
    :raises IOError: If the config file cannot be opened.
    """
    if type(config_file) is file:
        CONFIG.update(yaml.load(config_file) or {})
        return CONFIG
    else:
        try:
            with open(config_file, 'r') as f:
                content = yaml.load(f)
                CONFIG.update(content)
                return content
        except IOError as e:
            e.message = "Could not open configuration file \"{}\".".format(config_file)
            raise e

class Indexes:

    indexes_by_prep = {}
    indexes = {}

    def __init__(self, indexes_file):
        try:
            with open(indexes_file, 'r') as f:
                self.indexes_by_prep = yaml.load(f)
        except IOError as e:
                e.message = "Could not open configuration file \"{}\".".format(indexes_file)
                raise e
        #now create a more index centric object
        for library_type in self.indexes_by_prep: #for each lib prep type
            for index_type in self.indexes_by_prep[library_type]: # for each type of indexes
                for index_name, index_seq in self.indexes_by_prep[library_type][index_type]['Index'].iteritems():
                    if index_seq not in self.indexes:
                        self.indexes[index_seq] = []
                    self.indexes[index_seq].append({'name': index_name,
                        'index_type': index_type,
                        'library': library_type,
                        'supported_sequencers': self.indexes_by_prep[library_type][index_type]['Instrument']
                        })

    def return_libraries(self):
        libraries = []
        for library_type in self.indexes_by_prep:
            libraries.append(library_type)
        return libraries

    def check_left_shift_conflicts(self):
        #checks if indexes from the same library after a left shift are conflicting
        for library_type in self.indexes_by_prep: #for each lib prep type
            for index_type in self.indexes_by_prep[library_type]: # for each type of indexes
                for index_name, index_seq in self.indexes_by_prep[library_type][index_type]['Index'].iteritems():
                    fake_index = index_seq[1:] + "A"
                    for index_name_check, index_seq_check in self.indexes_by_prep[library_type][index_type]['Index'].iteritems():
                        hamming_dist = distance.hamming(index_seq_check, fake_index)
                        if hamming_dist <= 2:
                            print "{} {} {} {} {}".format(index_seq, index_seq_check, fake_index, hamming_dist, library_type)

def fetch_undermined_stats(configuration_file, INDEXES):
    load_yaml_config(configuration_file)
    couch=setupServer(CONFIG)
    flowcell_db = couch["x_flowcells"]

    MostOccurringUndetIndexes = {}
    FC_num = 0
    lanes_num = 0
    MostOccurringUndetIndexes["Total"] = {}

    FC_XTen_num = 0
    lanes_Xten_num = 0
    MostOccurringUndetIndexes["HiSeqX"] = {}

    FC_MiSeq_num = 0
    lanes_MiSeq_num = 0
    MostOccurringUndetIndexes["MiSeq"] = {}

    FC_HiSeq_num = 0
    lanes_HiSeq_num = 0
    MostOccurringUndetIndexes["HiSeq2500"] = {}

    #if "ST-" in flowcell_db[fc_doc]["RunInfo"]["Id"]: XTEN specific check
    for fc_doc in sorted(flowcell_db):
        # first check that I have all necessary info to extract information
        try:
            undetermined = flowcell_db[fc_doc]["Undetermined"]
        except KeyError:
            continue
        FCid = flowcell_db[fc_doc]["RunInfo"]["Id"]
        FC_type = ""
        if "ST-" in FCid:
            FC_XTen_num += 1
            FC_type = "HiSeqX"
        elif "000000000-" in FCid:
            FC_MiSeq_num += 1
            FC_type = "MiSeq"
        else:
            FC_HiSeq_num += 1
            FC_type = "HiSeq2500"
        FC_num += 1
        #we can use the illumina Demultiplex_Stats Barcode_lane_statistics to fetch info about indexes
        #to do: most commonly occurring undet index

        for lane in undetermined:
        #for each lane
            if len(undetermined[lane]) > 1: # if there are elements (there is the NoIndex case)
                if 'TOTAL' in undetermined[lane]:
                    del undetermined[lane]['TOTAL']
                most_occuring_undet = sorted(undetermined[lane].items(), key=operator.itemgetter(1), reverse=True)[0]
                lanes_num += 1
                if FC_type is "HiSeqX":
                    lanes_Xten_num += 1
                elif FC_type is "HiSeq2500":
                    lanes_HiSeq_num += 1
                elif FC_type is "MiSeq":
                    lanes_MiSeq_num += 1

                if most_occuring_undet[0] not in MostOccurringUndetIndexes[FC_type]:
                    MostOccurringUndetIndexes[FC_type][most_occuring_undet[0]] = 0
                MostOccurringUndetIndexes[FC_type][most_occuring_undet[0]] += 1
                if most_occuring_undet[0] not in MostOccurringUndetIndexes["Total"]:
                    MostOccurringUndetIndexes["Total"][most_occuring_undet[0]] = 0
                MostOccurringUndetIndexes["Total"][most_occuring_undet[0]] += 1

    # how often I see the left index shift

    #
    print "Flowcells: {}".format(FC_num)
    print "HiSeqX: {}".format(FC_XTen_num)
    print "HiSeq2500: {}".format(FC_HiSeq_num)
    print "MiSeq: {}".format(FC_MiSeq_num)

    print "Most occuring undetermined (seen in #lanes)"
    print "All Flowcells:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["Total"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_num))
    print "All HiSeqX:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["HiSeqX"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_Xten_num))
    print "All HiSeq2500:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["HiSeq2500"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_HiSeq_num))
    print "All MiSeq:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["MiSeq"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_MiSeq_num))

def main(args):
    configuration_file = args.config
    indexes_file = args.indexes
    INDEXES = Indexes(indexes_file)
    #INDEXES.check_left_shift_conflicts()

    load_yaml_config(configuration_file)
    couch=setupServer(CONFIG)
    flowcell_db = couch["x_flowcells"]
    fetch_undermined_stats(configuration_file, INDEXES)

if __name__ == '__main__':
    parser = argparse.ArgumentParser("""This scripts queries statusdb x_flowcell_db  and fetch informaiton about runs""")
    parser.add_argument('--config', help="configuration file", type=str,  required=True)
    parser.add_argument('--indexes', help="yamls file containing indexes we want to analyse", type=str, required=True)
    args = parser.parse_args()
    main(args)

<commit_msg>incredible.. i found 50 minutes in a raw to wrtie some code<commit_after>import os
import glob
import re
import sys
import socket
import couchdb
import logging
import argparse
import ConfigParser
import yaml
import json
import distance
import operator

CONFIG = {}

logger = logging.getLogger(__name__)

def list_applications():
    couch        = setupServer(CONFIG)
    projects_db  = couch['projects']
    applications = {}
    for project_id in projects_db:
        if "creation_time" not in projects_db[project_id]:
            continue
        application  = "unkonwn"
        if "application" in projects_db[project_id]:
            application = projects_db[project_id]["application"]
        if application in applications:
            applications[application] += 1
        else:
            applications[application] = 1
    for application in applications:
        print "{} {}".format(application, applications[application])

def setupServer(conf):
    db_conf = conf['statusdb']
    url="http://{0}:{1}@{2}:{3}".format(db_conf['username'], db_conf['password'], db_conf['url'], db_conf['port'])
    return couchdb.Server(url)

def load_yaml_config(config_file):
    """Load YAML config file

    :param str config_file: The path to the configuration file.

    :returns: A dict of the parsed config file.
    :rtype: dict
    :raises IOError: If the config file cannot be opened.
    """
    if type(config_file) is file:
        CONFIG.update(yaml.load(config_file) or {})
        return CONFIG
    else:
        try:
            with open(config_file, 'r') as f:
                content = yaml.load(f)
                CONFIG.update(content)
                return content
        except IOError as e:
            e.message = "Could not open configuration file \"{}\".".format(config_file)
            raise e

class Indexes:

    #indexes_by_kit looks like:
    #Kit_name:
    #   i7_index1:
    #       index_name: index_seq
    #       ...
    #   i5_index2:
    indexes_by_kit = {}
    #indexes looks like:
    #index_seq: ((index_name, index_type, kit_name), ....)
    indexes = {}

    def __init__(self, indexes_file):
        try:
            with open(indexes_file, 'r') as f:
                self.indexes_by_kit = yaml.load(f)
        except IOError as e:
                e.message = "Could not open configuration file \"{}\".".format(indexes_file)
                raise e
        #now create a more index centric object
        for kit_type in self.indexes_by_kit: #for each kit type
            if kit_type not in self.indexes_by_kit:
                print "file {} badly fomatted".format(indexes_file)
                return
            for index_type in self.indexes_by_kit[kit_type]: # for each type of indexes
                for index_name, index_seq in self.indexes_by_kit[kit_type][index_type].iteritems():
                    if not self.is_index(index_seq):
                        self.indexes[index_seq] = []
                    self.indexes[index_seq].append({'name': index_name,
                                                'index_type': index_type,
                                                'kit_type': kit_type,
                                               })

    def reverse_complement(self, index):
        for base in index:
            if base not in 'ATCGatcg':
                print "Error: NOT a DNA sequence"
                return None
        seq1 = 'ATCGTAGCatcgtagc'
        seq_dict = { seq1[i]:seq1[i+4] for i in range(16) if i < 4 or 8<=i<12 }
        return "".join([seq_dict[base] for base in reversed(index)])

    def is_index(self, index):
        if index not in self.indexes or self.reverse_complement(index) not in self.indexes:
            return False
        else:
            return True

    def return_kits(self):
        kits = []
        for kit_type in self.indexes_by_kit:
            kits.append(kit_type)
        return kits

    def check_left_shift_conflicts(self):
        #checks if indexes from the same library after a left shift are conflicting
        for kit_type in self.indexes_by_kit: #for each lib kit type
            for index_type in self.indexes_by_kit[kit_type]: # for each type of indexes
                for index_name, index_seq in self.indexes_by_kit[kit_type][index_type].iteritems():
                    fake_index = index_seq[1:] + "A"
                    for index_name_check, index_seq_check in self.indexes_by_kit[kit_type][index_type].iteritems():
                        hamming_dist = distance.hamming(index_seq_check, fake_index)
                        if hamming_dist <= 2:
                            print "{} {} {} {} {}".format(index_seq, index_seq_check, fake_index, hamming_dist, kit_type)

def fetch_undermined_stats(configuration_file, INDEXES):
    load_yaml_config(configuration_file)
    couch=setupServer(CONFIG)
    flowcell_db = couch["x_flowcells"]

    MostOccurringUndetIndexes = {}
    FC_num = 0
    lanes_num = 0
    MostOccurringUndetIndexes["Total"] = {}

    FC_XTen_num = 0
    lanes_Xten_num = 0
    MostOccurringUndetIndexes["HiSeqX"] = {}

    FC_MiSeq_num = 0
    lanes_MiSeq_num = 0
    MostOccurringUndetIndexes["MiSeq"] = {}

    FC_HiSeq_num = 0
    lanes_HiSeq_num = 0
    MostOccurringUndetIndexes["HiSeq2500"] = {}

    #if "ST-" in flowcell_db[fc_doc]["RunInfo"]["Id"]: XTEN specific check
    for fc_doc in sorted(flowcell_db):
        # first check that I have all necessary info to extract information
        try:
            undetermined = flowcell_db[fc_doc]["Undetermined"]
        except KeyError:
            continue
        FCid = flowcell_db[fc_doc]["RunInfo"]["Id"]
        FC_type = ""
        if "ST-" in FCid:
            FC_XTen_num += 1
            FC_type = "HiSeqX"
        elif "000000000-" in FCid:
            FC_MiSeq_num += 1
            FC_type = "MiSeq"
        else:
            FC_HiSeq_num += 1
            FC_type = "HiSeq2500"
        FC_num += 1
        #we can use the illumina Demultiplex_Stats Barcode_lane_statistics to fetch info about indexes
        #to do: most commonly occurring undet index

        for lane in undetermined:
        #for each lane
            if len(undetermined[lane]) > 1: # if there are elements (there is the NoIndex case)
                if 'TOTAL' in undetermined[lane]:
                    del undetermined[lane]['TOTAL']
                most_occuring_undet = sorted(undetermined[lane].items(), key=operator.itemgetter(1), reverse=True)[0]
                lanes_num += 1
                if FC_type is "HiSeqX":
                    lanes_Xten_num += 1
                elif FC_type is "HiSeq2500":
                    lanes_HiSeq_num += 1
                elif FC_type is "MiSeq":
                    lanes_MiSeq_num += 1

                if most_occuring_undet[0] not in MostOccurringUndetIndexes[FC_type]:
                    MostOccurringUndetIndexes[FC_type][most_occuring_undet[0]] = 0
                MostOccurringUndetIndexes[FC_type][most_occuring_undet[0]] += 1
                if most_occuring_undet[0] not in MostOccurringUndetIndexes["Total"]:
                    MostOccurringUndetIndexes["Total"][most_occuring_undet[0]] = 0
                MostOccurringUndetIndexes["Total"][most_occuring_undet[0]] += 1

    # how often I see the left index shift

    #
    print "Flowcells: {}".format(FC_num)
    print "HiSeqX: {}".format(FC_XTen_num)
    print "HiSeq2500: {}".format(FC_HiSeq_num)
    print "MiSeq: {}".format(FC_MiSeq_num)

    print "Most occuring undetermined (seen in #lanes)"
    print "All Flowcells:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["Total"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_num))
    print "All HiSeqX:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["HiSeqX"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_Xten_num))
    print "All HiSeq2500:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["HiSeq2500"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_HiSeq_num))
    print "All MiSeq:"
    for twenty_most_occuring_undet in sorted(MostOccurringUndetIndexes["MiSeq"].items(), key=operator.itemgetter(1), reverse=True)[0:10]:
        print "{}\t{}\t{}".format(twenty_most_occuring_undet[0], twenty_most_occuring_undet[1], twenty_most_occuring_undet[1]/float(lanes_MiSeq_num))

def main(args):
    configuration_file = args.config
    indexes_file = args.indexes
    INDEXES = Indexes(indexes_file)
    #INDEXES.check_left_shift_conflicts()

    load_yaml_config(configuration_file)
    couch=setupServer(CONFIG)
    flowcell_db = couch["x_flowcells"]
    import pdb
    pdb.set_trace()
    fetch_undermined_stats(configuration_file, INDEXES)

if __name__ == '__main__':
    parser = argparse.ArgumentParser("""This scripts queries statusdb x_flowcell_db  and fetch informaiton about runs""")
    parser.add_argument('--config', help="configuration file", type=str,  required=True)
    parser.add_argument('--indexes', help="yamls file containing indexes we want to analyse", type=str, required=True)
    args = parser.parse_args()
    main(args)

<|endoftext|>


<commit_before>def identity(x):
	return x

# Read a file straight into a list of strings
def read_straight(fname):
	f = open(fname, 'rt')
	ret = [x.strip() for x in f.readlines()[1:]]
	f.close()
	return ret

# Quick read if the data is one-per-line integers
def read_simple(fname, fMap=int):
	f = open(fname, 'rt')
	ret = [map(fMap, x.strip().split()) for x in f.readlines()[1:]]
	f.close()
	return ret

# One-per-twoline with first line removable
def read_simple_2(fname, fMap=int):
	f = open(fname, 'rt')
	ret = [map(fMap, x.strip().split()) for x in f.readlines()[2::2]]
	f.close()
	return ret

# Quick read T groups of N lines each (N given a line before as first element)
def read_N(fname, Nelt = 0, fMap=str, fOfN = lambda x: x):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	output = []
	ln = 1
	for i in xrange(T):
		N = fOfN(int(L[ln][Nelt]))
		output.append([map(fMap, x) for x in L[ln+1:ln+N+1]])
		ln += (N+1)
	return output

# Quick read T groups of lines given by some function of the first line among them
# Exact same default behaviour as read_N; but more flexible
def read_f(fname, fMapFn=lambda x: [str]*x[0], fOfN = lambda x: x[0]):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	output = []
	ln = 1
	for i in xrange(T):
		N = fOfN(map(int,L[ln]))
		fMap = fMapFn(map(int,L[ln]))
		output.append([map(fMap[k], L[ln+1+k]) for k in xrange(N)])
		ln += (N+1)
	return output
# e.g. L = read_f('C-test.in', lambda x: [str]*x[0] + [int]*x[1], lambda x: x[0]+x[1])

# READ_F with multi-line headers (also saves the headers if storeHead=True)
# This is the most general read function and can mimic (almost) the behaviour of all the others
def read_f_multi(fname, nlines_head=1,fMapFn=lambda x: [str]*x[0][0], fOfN = lambda x: x[0][0], storeHead=True):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	output = []
	ln = 1
	for i in xrange(T):
		head = [map(int, x) for x in L[ln:ln+nlines_head]]
		N = fOfN(head)
		fMap = fMapFn(head)
		if storeHead:
			output.append([head,[map(fMap[k], L[ln+nlines_head+k]) for k in xrange(N)]])
		else:
			output.append([map(fMap[k], L[ln+nlines_head+k]) for k in xrange(N)])
		ln += (N+nlines_head)
	return output

def read_fixed(fname, N, fMaps):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	ln = 1
	output = []
	for i in xrange(T):
		output.append([map(fMaps[k], L[ln+k]) for k in xrange(N)])
		ln+=N
	return output

# Quick one-item-per-line outputs
def write_simple(fname, lst):
	f = open(fname, 'wt')
	f.writelines(['Case #' + str(i+1) + ': ' + str(lst[i]) + '\n' for i in xrange(len(lst))])
	f.close()
	return

# Write a list of lists of strings
def write_slst(fname, strlst):
	lwrt = []
	for i, L in enumerate(strlst):
		lwrt.append('Case #' + str(i+1) + ':\n')
		lwrt.extend([' '.join(map(str, s)) + '\n' for s in L])

	f = open(fname, 'wt')
	f.writelines(lwrt)
	f.close()
	return
<commit_msg>Added space_as_string<commit_after>def identity(x):
	return x

def list_as_string(L):
	return ' '.join(map(str, L))

# Read a file straight into a list of strings
def read_straight(fname):
	f = open(fname, 'rt')
	ret = [x.strip() for x in f.readlines()[1:]]
	f.close()
	return ret

# Quick read if the data is one-per-line integers
def read_simple(fname, fMap=int):
	f = open(fname, 'rt')
	ret = [map(fMap, x.strip().split()) for x in f.readlines()[1:]]
	f.close()
	return ret

# One-per-twoline with first line removable
def read_simple_2(fname, fMap=int):
	f = open(fname, 'rt')
	ret = [map(fMap, x.strip().split()) for x in f.readlines()[2::2]]
	f.close()
	return ret

# Quick read T groups of N lines each (N given a line before as first element)
def read_N(fname, Nelt = 0, fMap=str, fOfN = lambda x: x):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	output = []
	ln = 1
	for i in xrange(T):
		N = fOfN(int(L[ln][Nelt]))
		output.append([map(fMap, x) for x in L[ln+1:ln+N+1]])
		ln += (N+1)
	return output

# Quick read T groups of lines given by some function of the first line among them
# Exact same default behaviour as read_N; but more flexible
def read_f(fname, fMapFn=lambda x: [str]*x[0], fOfN = lambda x: x[0]):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	output = []
	ln = 1
	for i in xrange(T):
		N = fOfN(map(int,L[ln]))
		fMap = fMapFn(map(int,L[ln]))
		output.append([map(fMap[k], L[ln+1+k]) for k in xrange(N)])
		ln += (N+1)
	return output
# e.g. L = read_f('C-test.in', lambda x: [str]*x[0] + [int]*x[1], lambda x: x[0]+x[1])

# READ_F with multi-line headers (also saves the headers if storeHead=True)
# This is the most general read function and can mimic (almost) the behaviour of all the others
def read_f_multi(fname, nlines_head=1,fMapFn=lambda x: [str]*x[0][0], fOfN = lambda x: x[0][0], storeHead=True):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	output = []
	ln = 1
	for i in xrange(T):
		head = [map(int, x) for x in L[ln:ln+nlines_head]]
		N = fOfN(head)
		fMap = fMapFn(head)
		if storeHead:
			output.append([head,[map(fMap[k], L[ln+nlines_head+k]) for k in xrange(N)]])
		else:
			output.append([map(fMap[k], L[ln+nlines_head+k]) for k in xrange(N)])
		ln += (N+nlines_head)
	return output

def read_fixed(fname, N, fMaps):
	f = open(fname, 'rt')
	L = [x.strip().split() for x in f.readlines()]
	f.close()
	T = int(L[0][0])
	ln = 1
	output = []
	for i in xrange(T):
		output.append([map(fMaps[k], L[ln+k]) for k in xrange(N)])
		ln+=N
	return output

# Quick one-item-per-line outputs
def write_simple(fname, lst):
	f = open(fname, 'wt')
	f.writelines(['Case #' + str(i+1) + ': ' + str(lst[i]) + '\n' for i in xrange(len(lst))])
	f.close()
	return

# Write a list of lists of strings
def write_slst(fname, strlst):
	lwrt = []
	for i, L in enumerate(strlst):
		lwrt.append('Case #' + str(i+1) + ':\n')
		lwrt.extend([' '.join(map(str, s)) + '\n' for s in L])

	f = open(fname, 'wt')
	f.writelines(lwrt)
	f.close()
	return
<|endoftext|>


<commit_before>#README to build botan 2.8.0 use conan create (botan/2.8.0@user/channel) path to this file
import shutil

from conans import ConanFile,tools,CMake

class IncludeOSConan(ConanFile):
    settings= "os","arch","build_type","compiler"
    name = "includeos"
    license = 'Apache-2.0'
    description = 'Run your application with zero overhead'
    generators = 'cmake'
    url = "http://www.includeos.org/"

    options = {
        "apple":['',True],
        "solo5":['ON','OFF'],
        "basic":['ON','OFF']
    }
    #actually we cant build without solo5 ?
    default_options= {
        "apple": '',
        "solo5": 'OFF',
        "basic": 'OFF'
    }
    #no_copy_source=True
    #keep_imports=True
    def requirements(self):
        self.requires("libcxx/[>=5.0]@includeos/test")## do we need this or just headers
        self.requires("GSL/2.0.0@includeos/test")

        if self.options.basic == 'OFF':
            self.requires("rapidjson/1.1.0@includeos/test")
            self.requires("http-parser/2.8.1@includeos/test") #this one is almost free anyways
            self.requires("uzlib/v2.1.1@includeos/test")
            self.requires("protobuf/3.5.1.1@includeos/test")
            self.requires("botan/2.8.0@includeos/test")
            self.requires("openssl/1.1.1@includeos/test")
            self.requires("s2n/1.1.1@includeos/test")

        if (self.options.apple):
            self.requires("libgcc/1.0@includeos/stable")
        if (self.options.solo5):
            self.requires("solo5/0.4.1@includeos/test")

    def imports(self):
        self.copy("*")

    def source(self):
        repo = tools.Git(folder="includeos")
        repo.clone("https://github.com/hioa-cs/IncludeOS.git",branch="conan")

    def _configure_cmake(self):
        cmake = CMake(self)
        cmake.configure(source_folder=self.source_folder+"/IncludeOS")
        return cmake;
    def build(self):
        cmake=self._configure_cmake()
        cmake.build()

    def package(self):
        cmake=self._configure_cmake()
        cmake.install()

    def deploy(self):
        self.copy("*",dst=".",src=".")
<commit_msg>conan: includeos recipe that acts on options<commit_after>#README to build botan 2.8.0 use conan create (botan/2.8.0@user/channel) path to this file
import shutil

from conans import ConanFile,tools,CMake

class IncludeOSConan(ConanFile):
    settings= "os","arch","build_type","compiler"
    name = "includeos"
    license = 'Apache-2.0'
    description = 'Run your application with zero overhead'
    generators = 'cmake'
    url = "http://www.includeos.org/"

    options = {
        "apple":['',True],
        "solo5":['ON','OFF'],
        "basic":['ON','OFF']
    }
    #actually we cant build without solo5 ?
    default_options= {
        "apple": '',
        "solo5": 'OFF',
        "basic": 'OFF'
    }
    no_copy_source=True
    #keep_imports=True
    def requirements(self):
        self.requires("libcxx/[>=5.0]@includeos/test")## do we need this or just headers
        self.requires("GSL/2.0.0@includeos/test")

        if self.options.basic == 'OFF':
            self.requires("rapidjson/1.1.0@includeos/test")
            self.requires("http-parser/2.8.1@includeos/test") #this one is almost free anyways
            self.requires("uzlib/v2.1.1@includeos/test")
            self.requires("protobuf/3.5.1.1@includeos/test")
            self.requires("botan/2.8.0@includeos/test")
            self.requires("openssl/1.1.1@includeos/test")
            self.requires("s2n/1.1.1@includeos/test")

        if (self.options.apple):
            self.requires("libgcc/1.0@includeos/stable")
        if (self.options.solo5):
            self.requires("solo5/0.4.1@includeos/test")

    def imports(self):
        self.copy("*")

    def source(self):
        repo = tools.Git(folder="includeos")
        repo.clone("https://github.com/hioa-cs/IncludeOS.git",branch="conan")

    def _configure_cmake(self):
        cmake = CMake(self)
        #glad True and False also goes but not recursily
        cmake.definitions['WITH_SOLO5']=self.options.solo5
        cmake.configure(source_folder=self.source_folder+"/includeos")
        return cmake;

    def build(self):
        cmake=self._configure_cmake()
        cmake.build()

    def package(self):
        cmake=self._configure_cmake()
        #we are doing something wrong this "shouldnt" trigger a new build
        cmake.install()
        #at this point we can copy things implace..
        #or we can use the "building with conan flag to deply things
        #in the right place"

        #arch include and arch lib is causing issues

    def deploy(self):
        self.copy("*",dst=".",src=".")
<|endoftext|>


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

import gzip
import os
import tempfile

from conary_test import recipes
from conary_test import rephelp

from conary import files
from conary.lib import sha1helper, util
from conary.repository import changeset
from conary.repository import errors
from conary.repository import filecontainer
from conary.repository import filecontents
from conary import deps
from conary import trove
from conary import versions

def open(fn, mode='r', buffering=False):
    return util.ExtendedFile(fn, mode, buffering)

class IntegrityTest(rephelp.RepositoryHelper):

    def testFileChanges(self):
        (built, d) = self.buildRecipe(recipes.testRecipe1, "TestRecipe1")
        (name, version, flavor) = built[0]
        version = versions.VersionFromString(version)

        (fd, path) = tempfile.mkstemp()
        os.close(fd)

        repos = self.openRepository()
        repos.createChangeSetFile(
            [(name, (None, None), (version, flavor), 1)], path)

        infc = filecontainer.FileContainer(open(path))
        os.unlink(path)

        (fd, path) = tempfile.mkstemp()
        os.close(fd)
        outfc = filecontainer.FileContainer(open(path, "w"))

        # first is the trove delta
        (name, tag, f) = infc.getNextFile()
        outfc.addFile(name, filecontents.FromFile(f), tag,
                      precompressed = True)

        # next let's modify the file a bit
        (name, tag, f) = infc.getNextFile()
        contents = gzip.GzipFile(None, "r", fileobj = f).read()
        contents = chr(ord(contents[0]) ^ 0xff) + contents[1:]
        outfc.addFile(name, filecontents.FromString(contents), tag)

        next = infc.getNextFile()
        while next is not None:
            (name, tag, f) = next
            outfc.addFile(name, filecontents.FromFile(f), tag,
                          precompressed = True)
            next = infc.getNextFile()

        infc.close()
        outfc.close()

        self.resetRepository()
        repos = self.openRepository()

        try:
            self.assertRaises(errors.IntegrityError,
                              self.updatePkg, self.rootDir, path)
            self.assertRaises(errors.IntegrityError,
                              repos.commitChangeSetFile, path)
        finally:
            os.unlink(path)

    def testFileObjMissing(self):
        # create an absolute changeset
        cs = changeset.ChangeSet()

        # add a pkg diff
        flavor = deps.deps.parseFlavor('')
        v = versions.VersionFromString('/%s/1.0-1-1'
                                       %self.cfg.buildLabel.asString()).copy()
        v.resetTimeStamps()
        t = trove.Trove('test:test', v, flavor, None)
        path = self.workDir + '/blah'
        f = open(path, 'w')
        f.write('hello, world!\n')
        f.close()
        pathId = sha1helper.md5String('/blah')
        f = files.FileFromFilesystem(path, pathId)
        # add the file, and SKIP including
        # the filestream by using cs.addFile().  This creates an
        # incomplete changeset
        t.addFile(pathId, '/blah', v, f.fileId())
        cs.addFileContents(pathId, f.fileId(), changeset.ChangedFileTypes.file,
                           filecontents.FromFilesystem(path),
                           f.flags.isConfig())

        t.computeDigests()
        diff = t.diff(None, absolute = 1)[0]
        cs.newTrove(diff)

        repos = self.openRepository()
        try:
            repos.commitChangeSet(cs)
            assert 0, "Did not raise IntegrityError"
        except errors.IntegrityError, e:
            assert(str(e).startswith("Incomplete changeset specified: missing pathId e806729b6a2b568fa7e77c3efa3a9684 fileId"))

    def testFileIdWrong(self):
        # create an absolute changeset
        cs = changeset.ChangeSet()

        # add a pkg diff
        flavor = deps.deps.parseFlavor('')
        v = versions.VersionFromString('/%s/1.0-1-1'
                                       %self.cfg.buildLabel.asString()).copy()
        v.resetTimeStamps()
        t = trove.Trove('test:test', v, flavor, None)
        path = self.workDir + '/blah'
        f = open(path, 'w')
        f.write('hello, world!\n')
        f.close()
        pathId = sha1helper.md5String('/blah')
        f = files.FileFromFilesystem(path, pathId)
        # add the file, but munge the fileid
        brokenFileId = ''.join(reversed(f.fileId()))
        cs.addFile(None, brokenFileId, f.freeze())
        t.addFile(pathId, '/blah', v, brokenFileId)
        t.computeDigests()

        diff = t.diff(None, absolute = 1)[0]
        cs.newTrove(diff)

        repos = self.openRepository()
        try:
            repos.commitChangeSet(cs)
            assert 0, "Integrity Error not raised"
        except errors.TroveIntegrityError, e:
            assert(str(e) == 'fileObj.fileId() != fileId in changeset for '
                             'pathId %s' % sha1helper.md5ToString(pathId))

    def testFileContentsMissing(self):
        # currently causes a 500 error
        #raise testhelp.SkipTestException
        # create an absolute changeset
        cs = changeset.ChangeSet()

        # add a pkg diff
        flavor = deps.deps.parseFlavor('')
        v = versions.VersionFromString('/%s/1.0-1-1'
                                       %self.cfg.buildLabel.asString()).copy()
        v.resetTimeStamps()
        t = trove.Trove('test:test', v, flavor, None)
        path = self.workDir + '/blah'
        f = open(path, 'w')
        f.write('hello, world!\n')
        f.close()
        pathId = sha1helper.md5String('/blah')
        f = files.FileFromFilesystem(path, pathId)
        # add the file, but munge the fileid
        fileId = f.fileId()
        cs.addFile(None, fileId, f.freeze())
        t.addFile(pathId, '/blah', v, fileId)
        # skip adding the file contents
        t.computeDigests()

        diff = t.diff(None, absolute = 1)[0]
        cs.newTrove(diff)

        repos = self.openRepository()
        try:
            repos.commitChangeSet(cs)
            assert 0, "Did not raise integrity error"
        except errors.IntegrityError, e:
            assert(str(e).startswith("Missing file contents for pathId e806729b6a2b568fa7e77c3efa3a9684, fileId"))

    def testSourceItemCollision(self):
        repos = self.openRepository()
        # add the conflicting source item troves
        self.addComponent("foo:source", "1.0")
        self.addComponent("test:runtime", "1.0", "foo,!bar",
                          sourceName="foo:source")
        self.addComponent("test:lib", "1.0", "foo,!bar",
                          sourceName="foo:source")
        self.addCollection("test", "1.0", [
            ("test:runtime", "1.0", "foo,!bar"),
            ("test:lib", "1.0", "foo,!bar"), ])
        # same troves, different flavor based on a different source
        self.addComponent("bar:source", "1.0")
        self.assertRaises(errors.InvalidSourceNameError, self.addComponent,
                          "test:runtime", "1.0", "!foo,bar", sourceName = "bar:source")
<commit_msg>Fix IntegrityError test<commit_after>#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import gzip
import os
import tempfile

from conary_test import recipes
from conary_test import rephelp

from conary import files
from conary.lib import sha1helper, util
from conary.repository import changeset
from conary.repository import errors
from conary.repository import filecontainer
from conary.repository import filecontents
from conary import deps
from conary import trove
from conary import versions

def open(fn, mode='r', buffering=False):
    return util.ExtendedFile(fn, mode, buffering)

class IntegrityTest(rephelp.RepositoryHelper):

    def testFileChanges(self):
        (built, d) = self.buildRecipe(recipes.testRecipe1, "TestRecipe1")
        (name, version, flavor) = built[0]
        version = versions.VersionFromString(version)

        (fd, path) = tempfile.mkstemp()
        os.close(fd)

        repos = self.openRepository()
        repos.createChangeSetFile(
            [(name, (None, None), (version, flavor), 1)], path)

        infc = filecontainer.FileContainer(open(path))
        os.unlink(path)

        (fd, path) = tempfile.mkstemp()
        os.close(fd)
        outfc = filecontainer.FileContainer(open(path, "w"))

        n = 0
        while True:
            next = infc.getNextFile()
            if not next:
                break
            (name, tag, f) = next
            n += 1
            if n == 2 or n == 5:
                # modify the file a bit
                contents = gzip.GzipFile(None, "r", fileobj = f).read()
                contents = chr(ord(contents[0]) ^ 0xff) + contents[1:]
                outfc.addFile(name, filecontents.FromString(contents), tag)
            else:
                contents = filecontents.FromFile(f)
                outfc.addFile(name, filecontents.FromFile(f), tag,
                        precompressed=True)

        infc.close()
        outfc.close()

        self.resetRepository()
        repos = self.openRepository()

        try:
            self.assertRaises(errors.IntegrityError,
                              self.updatePkg, self.rootDir, path)
            self.assertRaises(errors.IntegrityError,
                              repos.commitChangeSetFile, path)
        finally:
            os.unlink(path)

    def testFileObjMissing(self):
        # create an absolute changeset
        cs = changeset.ChangeSet()

        # add a pkg diff
        flavor = deps.deps.parseFlavor('')
        v = versions.VersionFromString('/%s/1.0-1-1'
                                       %self.cfg.buildLabel.asString()).copy()
        v.resetTimeStamps()
        t = trove.Trove('test:test', v, flavor, None)
        path = self.workDir + '/blah'
        f = open(path, 'w')
        f.write('hello, world!\n')
        f.close()
        pathId = sha1helper.md5String('/blah')
        f = files.FileFromFilesystem(path, pathId)
        # add the file, and SKIP including
        # the filestream by using cs.addFile().  This creates an
        # incomplete changeset
        t.addFile(pathId, '/blah', v, f.fileId())
        cs.addFileContents(pathId, f.fileId(), changeset.ChangedFileTypes.file,
                           filecontents.FromFilesystem(path),
                           f.flags.isConfig())

        t.computeDigests()
        diff = t.diff(None, absolute = 1)[0]
        cs.newTrove(diff)

        repos = self.openRepository()
        try:
            repos.commitChangeSet(cs)
            assert 0, "Did not raise IntegrityError"
        except errors.IntegrityError, e:
            assert(str(e).startswith("Incomplete changeset specified: missing pathId e806729b6a2b568fa7e77c3efa3a9684 fileId"))

    def testFileIdWrong(self):
        # create an absolute changeset
        cs = changeset.ChangeSet()

        # add a pkg diff
        flavor = deps.deps.parseFlavor('')
        v = versions.VersionFromString('/%s/1.0-1-1'
                                       %self.cfg.buildLabel.asString()).copy()
        v.resetTimeStamps()
        t = trove.Trove('test:test', v, flavor, None)
        path = self.workDir + '/blah'
        f = open(path, 'w')
        f.write('hello, world!\n')
        f.close()
        pathId = sha1helper.md5String('/blah')
        f = files.FileFromFilesystem(path, pathId)
        # add the file, but munge the fileid
        brokenFileId = ''.join(reversed(f.fileId()))
        cs.addFile(None, brokenFileId, f.freeze())
        t.addFile(pathId, '/blah', v, brokenFileId)
        t.computeDigests()

        diff = t.diff(None, absolute = 1)[0]
        cs.newTrove(diff)

        repos = self.openRepository()
        try:
            repos.commitChangeSet(cs)
            assert 0, "Integrity Error not raised"
        except errors.TroveIntegrityError, e:
            assert(str(e) == 'fileObj.fileId() != fileId in changeset for '
                             'pathId %s' % sha1helper.md5ToString(pathId))

    def testFileContentsMissing(self):
        # currently causes a 500 error
        #raise testhelp.SkipTestException
        # create an absolute changeset
        cs = changeset.ChangeSet()

        # add a pkg diff
        flavor = deps.deps.parseFlavor('')
        v = versions.VersionFromString('/%s/1.0-1-1'
                                       %self.cfg.buildLabel.asString()).copy()
        v.resetTimeStamps()
        t = trove.Trove('test:test', v, flavor, None)
        path = self.workDir + '/blah'
        f = open(path, 'w')
        f.write('hello, world!\n')
        f.close()
        pathId = sha1helper.md5String('/blah')
        f = files.FileFromFilesystem(path, pathId)
        # add the file, but munge the fileid
        fileId = f.fileId()
        cs.addFile(None, fileId, f.freeze())
        t.addFile(pathId, '/blah', v, fileId)
        # skip adding the file contents
        t.computeDigests()

        diff = t.diff(None, absolute = 1)[0]
        cs.newTrove(diff)

        repos = self.openRepository()
        try:
            repos.commitChangeSet(cs)
            assert 0, "Did not raise integrity error"
        except errors.IntegrityError, e:
            assert(str(e).startswith("Missing file contents for pathId e806729b6a2b568fa7e77c3efa3a9684, fileId"))

    def testSourceItemCollision(self):
        repos = self.openRepository()
        # add the conflicting source item troves
        self.addComponent("foo:source", "1.0")
        self.addComponent("test:runtime", "1.0", "foo,!bar",
                          sourceName="foo:source")
        self.addComponent("test:lib", "1.0", "foo,!bar",
                          sourceName="foo:source")
        self.addCollection("test", "1.0", [
            ("test:runtime", "1.0", "foo,!bar"),
            ("test:lib", "1.0", "foo,!bar"), ])
        # same troves, different flavor based on a different source
        self.addComponent("bar:source", "1.0")
        self.assertRaises(errors.InvalidSourceNameError, self.addComponent,
                          "test:runtime", "1.0", "!foo,bar", sourceName = "bar:source")
<|endoftext|>


<commit_before>number=input("Give me a number")
number=float(number)

if number%2==0:
    print(str(number)+" is even")
else:
    print(str(number)+" is odd")
<commit_msg>update<commit_after>number=input("Give me a number")
number=float(number)

if number%2==0:
    print(str(number)+" is even")
else:
    print(str(number)+" is odd")

if number<17:
    print(str(number)+" is smaller than 17")
else:
    print(str(number)+" is greater than 17")
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.utils.timezone
from django.conf import settings
import uuid
import json

VERBOSE = False

def migrate_to_new_fields(apps, schema_editor):
    Application = apps.get_model("core", "Application")
    ApplicationThreshold = apps.get_model("core", "ApplicationThreshold")
    ApplicationVersion = apps.get_model("core", "ApplicationVersion")
    ApplicationVersionMembership = apps.get_model(
        "core",
        "ApplicationVersionMembership")
    Group = apps.get_model("core", "Group")
    MachineRequest = apps.get_model("core", "MachineRequest")
    ProviderMachine = apps.get_model("core", "ProviderMachine")
    ProviderMachineMembership = apps.get_model(
        "core",
        "ProviderMachineMembership")
    update_application_versions(
        ProviderMachine,
        ProviderMachineMembership,
        ApplicationVersion,
        ApplicationVersionMembership,
        Application)
    update_machine_requests(
        MachineRequest,
        Group,
        ApplicationVersion,
        ApplicationThreshold)
    pass

def update_machine_requests(
        MachineRequest,
        Group,
        ApplicationVersion,
        ApplicationThreshold):
    for request in MachineRequest.objects.order_by('id'):
        update_machine_request(
            request,
            Group,
            MachineRequest,
            ApplicationVersion)

    for threshold in ApplicationThreshold.objects.order_by('id'):
        threshold.application_version = threshold.application.versions.last()
        threshold.save()

def _update_request(machine_request, Group):
    if machine_request.new_machine:
        current_version = machine_request.new_machine.application_version
        machine_request.new_application_version = current_version
    machine_request.new_application_visibility = machine_request.new_machine_visibility
    machine_request.new_version_name = machine_request.new_machine_version
    machine_request.new_application_name = machine_request.new_machine_name
    machine_request.new_version_tags = machine_request.new_machine_tags
    machine_request.new_application_description = machine_request.new_machine_description
    machine_request.new_version_change_log = machine_request.new_machine_description
    if machine_request.access_list:
        if '[' in machine_request.access_list:
            list_str = machine_request.access_list.replace(
                "'",
                '"').replace(
                'u"',
                '"')
            usernames = json.loads(list_str)
        else:
            usernames = machine_request.access_list.split(',')
        for name in usernames:
            try:
                name = name.strip()
                group = Group.objects.get(name=name)
                machine_request.new_version_membership.add(group)
            except Group.DoesNotExist:
                print 'Skipped user %s on request %s - DoesNotExist' % (name, machine_request.id)
    machine_request.save()

def update_machine_request(
        machine_request,
        Group,
        MachineRequest,
        ApplicationVersion):
    # Update the request
    _update_request(machine_request, Group)
    # Update the version
    _fill_version_using_machine_request(machine_request, ApplicationVersion)

def _many_to_many_copy(machine_manager, version_manager):
    if not machine_manager.count():
        return
    for x in machine_manager.order_by('id'):
        version_manager.add(x)

def _fill_version_using_machine_request(machine_request, ApplicationVersion):
    current_version = None
    if machine_request.new_machine:
        current_version = machine_request.new_machine.application_version

    parent_instance = machine_request.instance
    parent_version = parent_instance.source.providermachine.application_version

    if not current_version:
        return
    if not current_version.parent:
        current_version.parent = ApplicationVersion.objects.get(
            id=parent_version.id)
    # Double-check this..
    if not current_version.parent:
        print "WARN: Could not set fork version for MachineRequest %s." % machine_request.id

    current_version.change_log = machine_request.new_version_change_log
    current_version.allow_imaging = machine_request.new_version_allow_imaging

    current_version.iplant_system_files = machine_request.iplant_sys_files
    current_version.installed_software = machine_request.installed_software
    current_version.exclude_files = machine_request.exclude_files
    current_version.save()

def update_application_versions(
        ProviderMachine,
        ProviderMachineMembership,
        ApplicationVersion,
        ApplicationVersionMembership,
        Application):
    machines = ProviderMachine.objects.all()
    create_count = 0
    for machine in machines:
        created = update_application_version(
            machine,
            ApplicationVersion,
            ApplicationVersionMembership,
            ProviderMachineMembership)
        create_count += created
    # NOTE: comma at the end to intentionally leave all text on one line.
    print "Converted %s ProviderMachines into %s ApplicationVersions on %s applications" % (ProviderMachine.objects.count(), ApplicationVersion.objects.count(), Application.objects.count()),

def update_application_version(
        machine,
        ApplicationVersion,
        ApplicationVersionMembership,
        ProviderMachineMembership):
    source = machine.instance_source
    app = machine.application
    if machine.version == '1.0.0':
        machine.version = '1.0'
    app_version, created = ApplicationVersion.objects.get_or_create(
        application=app,
        name=machine.version,
        created_by=app.created_by,
        created_by_identity=app.created_by_identity)
    if VERBOSE:
        print "ProviderMachine: %s+%s Version: %s "\
              "= ApplicationVersion %s for App %s (%s)" %\
              (source.provider.location, source.identifier, machine.version, app_version.id,
               app.name, app.uuid)
    if not machine.allow_imaging:
        app_version.allow_imaging = False
    if not app_version.start_date or app_version.start_date > source.start_date:
        app_version.start_date = source.start_date
    if (not app_version.end_date and source.end_date) or (
            app_version.end_date and source.end_date and app_version.end_date < source.end_date):
        app_version.end_date = source.end_date
    app_version.save()
    # Update machine association
    machine.application_version = app_version
    machine.save()
    # Save remaining associations
    if machine.licenses.count():
        for license in machine.licenses.all():
            app_version.licenses.add(license)
    machine_members = ProviderMachineMembership.objects.filter(
        provider_machine__id=machine.id)
    if machine_members.count():
        for pm_membership in machine_members:
            membership, _ = ApplicationVersionMembership.objects.get_or_create(
                application_version_id=app_version.id,
                group_id=pm_membership.group.id,
                can_share=pm_membership.can_share)
    return 1 if created else 0

def do_nothing(apps, schema_editor):
    pass

class Migration(migrations.Migration):

    dependencies = [
        ('core', '0023_add_application_version'),
    ]

    operations = [
        migrations.RunPython(
            migrate_to_new_fields,
            migrations.RunPython.noop
        ),
    ]
<commit_msg>Suppress print statement in migrations to avoid unneeded output in the test output<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.utils.timezone
from django.conf import settings
import uuid
import json

VERBOSE = False

def migrate_to_new_fields(apps, schema_editor):
    Application = apps.get_model("core", "Application")
    ApplicationThreshold = apps.get_model("core", "ApplicationThreshold")
    ApplicationVersion = apps.get_model("core", "ApplicationVersion")
    ApplicationVersionMembership = apps.get_model(
        "core",
        "ApplicationVersionMembership")
    Group = apps.get_model("core", "Group")
    MachineRequest = apps.get_model("core", "MachineRequest")
    ProviderMachine = apps.get_model("core", "ProviderMachine")
    ProviderMachineMembership = apps.get_model(
        "core",
        "ProviderMachineMembership")
    update_application_versions(
        ProviderMachine,
        ProviderMachineMembership,
        ApplicationVersion,
        ApplicationVersionMembership,
        Application)
    update_machine_requests(
        MachineRequest,
        Group,
        ApplicationVersion,
        ApplicationThreshold)
    pass

def update_machine_requests(
        MachineRequest,
        Group,
        ApplicationVersion,
        ApplicationThreshold):
    for request in MachineRequest.objects.order_by('id'):
        update_machine_request(
            request,
            Group,
            MachineRequest,
            ApplicationVersion)

    for threshold in ApplicationThreshold.objects.order_by('id'):
        threshold.application_version = threshold.application.versions.last()
        threshold.save()

def _update_request(machine_request, Group):
    if machine_request.new_machine:
        current_version = machine_request.new_machine.application_version
        machine_request.new_application_version = current_version
    machine_request.new_application_visibility = machine_request.new_machine_visibility
    machine_request.new_version_name = machine_request.new_machine_version
    machine_request.new_application_name = machine_request.new_machine_name
    machine_request.new_version_tags = machine_request.new_machine_tags
    machine_request.new_application_description = machine_request.new_machine_description
    machine_request.new_version_change_log = machine_request.new_machine_description
    if machine_request.access_list:
        if '[' in machine_request.access_list:
            list_str = machine_request.access_list.replace(
                "'",
                '"').replace(
                'u"',
                '"')
            usernames = json.loads(list_str)
        else:
            usernames = machine_request.access_list.split(',')
        for name in usernames:
            try:
                name = name.strip()
                group = Group.objects.get(name=name)
                machine_request.new_version_membership.add(group)
            except Group.DoesNotExist:
                print 'Skipped user %s on request %s - DoesNotExist' % (name, machine_request.id)
    machine_request.save()

def update_machine_request(
        machine_request,
        Group,
        MachineRequest,
        ApplicationVersion):
    # Update the request
    _update_request(machine_request, Group)
    # Update the version
    _fill_version_using_machine_request(machine_request, ApplicationVersion)

def _many_to_many_copy(machine_manager, version_manager):
    if not machine_manager.count():
        return
    for x in machine_manager.order_by('id'):
        version_manager.add(x)

def _fill_version_using_machine_request(machine_request, ApplicationVersion):
    current_version = None
    if machine_request.new_machine:
        current_version = machine_request.new_machine.application_version

    parent_instance = machine_request.instance
    parent_version = parent_instance.source.providermachine.application_version

    if not current_version:
        return
    if not current_version.parent:
        current_version.parent = ApplicationVersion.objects.get(
            id=parent_version.id)
    # Double-check this..
    if not current_version.parent:
        print "WARN: Could not set fork version for MachineRequest %s." % machine_request.id

    current_version.change_log = machine_request.new_version_change_log
    current_version.allow_imaging = machine_request.new_version_allow_imaging

    current_version.iplant_system_files = machine_request.iplant_sys_files
    current_version.installed_software = machine_request.installed_software
    current_version.exclude_files = machine_request.exclude_files
    current_version.save()

def update_application_versions(
        ProviderMachine,
        ProviderMachineMembership,
        ApplicationVersion,
        ApplicationVersionMembership,
        Application):
    machines = ProviderMachine.objects.all()
    create_count = 0
    for machine in machines:
        created = update_application_version(
            machine,
            ApplicationVersion,
            ApplicationVersionMembership,
            ProviderMachineMembership)
        create_count += created
    # NOTE: comma at the end to intentionally leave all text on one line.
    # print "Converted %s ProviderMachines into %s ApplicationVersions on %s applications" % (ProviderMachine.objects.count(), ApplicationVersion.objects.count(), Application.objects.count()),

def update_application_version(
        machine,
        ApplicationVersion,
        ApplicationVersionMembership,
        ProviderMachineMembership):
    source = machine.instance_source
    app = machine.application
    if machine.version == '1.0.0':
        machine.version = '1.0'
    app_version, created = ApplicationVersion.objects.get_or_create(
        application=app,
        name=machine.version,
        created_by=app.created_by,
        created_by_identity=app.created_by_identity)
    if VERBOSE:
        print "ProviderMachine: %s+%s Version: %s "\
              "= ApplicationVersion %s for App %s (%s)" %\
              (source.provider.location, source.identifier, machine.version, app_version.id,
               app.name, app.uuid)
    if not machine.allow_imaging:
        app_version.allow_imaging = False
    if not app_version.start_date or app_version.start_date > source.start_date:
        app_version.start_date = source.start_date
    if (not app_version.end_date and source.end_date) or (
            app_version.end_date and source.end_date and app_version.end_date < source.end_date):
        app_version.end_date = source.end_date
    app_version.save()
    # Update machine association
    machine.application_version = app_version
    machine.save()
    # Save remaining associations
    if machine.licenses.count():
        for license in machine.licenses.all():
            app_version.licenses.add(license)
    machine_members = ProviderMachineMembership.objects.filter(
        provider_machine__id=machine.id)
    if machine_members.count():
        for pm_membership in machine_members:
            membership, _ = ApplicationVersionMembership.objects.get_or_create(
                application_version_id=app_version.id,
                group_id=pm_membership.group.id,
                can_share=pm_membership.can_share)
    return 1 if created else 0

def do_nothing(apps, schema_editor):
    pass

class Migration(migrations.Migration):

    dependencies = [
        ('core', '0023_add_application_version'),
    ]

    operations = [
        migrations.RunPython(
            migrate_to_new_fields,
            migrations.RunPython.noop
        ),
    ]
<|endoftext|>


<commit_before>from __future__ import print_function
import numpy as np
np.random.seed(1337)  # for reproducibility

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten, Reshape
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.utils import np_utils

from keras.layers.convolutional_transpose import Convolution2D_Transpose

"""
   modified from https://github.com/loliverhennigh/All-Convnet-Autoencoder-Example
   An autoencoder with 2D Convolution-Transpose layer in TF
"""

batch_size = 100 # total number of elements in the X_ and Y_ (60000 train, 10000 test) arrays must be a multiple of batch_size!
nb_classes = 10
nb_epoch = 12

# input image dimensions
img_rows, img_cols = 28, 28
# number of convolutional filters to use
nb_filters = 28 * 14
# size of pooling area for max pooling
nb_pool = 2
# convolution kernel size
nb_conv = 2

# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()

X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

#Y_train = np_utils.to_categorical(y_train, nb_classes)
#Y_test = np_utils.to_categorical(y_test, nb_classes)
Y_train = X_train
Y_test  = X_test

print("Y SHAPE",Y_train.shape)

model = Sequential()
nb_filter = 32

# input  28 * 28, output 24 * 24
model.add(Convolution2D(nb_filter, 5, 5, input_shape=((1, img_rows, img_cols)), border_mode = 'valid'))
model.add(Activation('relu'))

# input  24 * 24, output 20 * 20
model.add(Convolution2D(nb_filter, 5, 5, border_mode = 'valid'))
model.add(Activation('relu'))

# input  20 * 20, output 16 * 16
model.add(Convolution2D(nb_filter, 5, 5, border_mode = 'valid'))
model.add(Activation('relu'))

# input  16 * 16, output 14 * 14
model.add(Convolution2D(nb_filter, 3, 3, border_mode = 'valid'))
model.add(Activation('relu'))

# input  14 * 14 * 4, output 14 * 14 * 2
model.add(Convolution2D(2, 1, 1, border_mode = 'valid'))
model.add(Activation('relu'))

# input  input 14 * 14 * 2, output 28 * 28 * 2 ?
W_shape = [2, 2, 2, 2] # (self.nb_filter, input_dim, self.filter_length, 1)
b_shape = [2]
strides = [1,1,1,1]
deconv_shape = [2,2,2,2]
deconv_shape = [batch_size, 14, 14, 2]
model.add(Convolution2D_Transpose(deconv_shape=deconv_shape,  W_shape=W_shape, b_shape=b_shape, strides=strides, padding="SAME")) # should be lower capital same

model.add(Flatten())
model.add(Dense(784))
model.add(Reshape((1,28,28)))

"""
  W_shape --- shape of the weights - should be calculated internally
   from conv_2d:  (self.nb_filter, input_dim, self.filter_length, x)

   [0] ... nb_filter
   [1] ... input_dim
   [2] ... filter_length
   [3] ... 1

  b_shape ... shape of the biases - should be calculated internally
   [0] ... nb_filter ?

  deconv_shape
       this is output_shape of TF conv2d_transpose
       [ batch_size, input_cols, input_rows, input_depth]

Also U can set the output_shape(deconv_shape) according to:

def conv_transpose_out_length(input_size, filter_size, border_mode, stride):
    if input_size is None:
        return None
    if border_mode == 'VALID':
        output_size = (input_size - 1) * stride + filter_size
    elif border_mode == 'SAME':
        output_size = input_size
    return output_size

"""

##model.add(Dropout(0.25))
##model.add(Convolution2D_Transpose(deconv_shape=[128,18,18,1], W_shape=[3,3,1,16], b_shape=[1]))
##model.add(Activation('relu'))

print(model.summary())
#  OLD MNIST MODEL
#model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
#                        border_mode='valid',
#                        input_shape=(1, img_rows, img_cols)))
#model.add(Activation('relu'))
#model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
#model.add(Activation('relu'))
#model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
#model.add(Dropout(0.25))

#model.add(Flatten())
#model.add(Dense(128))
#model.add(Activation('relu'))
#model.add(Dropout(0.5))
#model.add(Dense(nb_classes))
#model.add(Activation('softmax'))

model.compile(loss='mse', optimizer='sgd')
print("Before FIT")

#model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=1, validation_data=(X_test, Y_test))
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=1)
score = model.evaluate(X_test, Y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
<commit_msg>Batch size also in evaluate necessary<commit_after>from __future__ import print_function
import numpy as np
np.random.seed(1337)  # for reproducibility

from keras.datasets import mnist
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten, Reshape
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.utils import np_utils

from keras.layers.convolutional_transpose import Convolution2D_Transpose

"""
   modified from https://github.com/loliverhennigh/All-Convnet-Autoencoder-Example
   An autoencoder with 2D Convolution-Transpose layer in TF
"""

batch_size = 100 # total number of elements in the X_ and Y_ (60000 train, 10000 test) arrays must be a multiple of batch_size!
nb_classes = 10
nb_epoch = 12

# input image dimensions
img_rows, img_cols = 28, 28
# number of convolutional filters to use
nb_filters = 28 * 14
# size of pooling area for max pooling
nb_pool = 2
# convolution kernel size
nb_conv = 2

# the data, shuffled and split between train and test sets
(X_train, y_train), (X_test, y_test) = mnist.load_data()

X_train = X_train.reshape(X_train.shape[0], 1, img_rows, img_cols)
X_test = X_test.reshape(X_test.shape[0], 1, img_rows, img_cols)
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
print('X_train shape:', X_train.shape)
print(X_train.shape[0], 'train samples')
print(X_test.shape[0], 'test samples')

#Y_train = np_utils.to_categorical(y_train, nb_classes)
#Y_test = np_utils.to_categorical(y_test, nb_classes)
Y_train = X_train
Y_test  = X_test

print("Y SHAPE",Y_train.shape)

model = Sequential()
nb_filter = 32

# input  28 * 28, output 24 * 24
model.add(Convolution2D(nb_filter, 5, 5, input_shape=((1, img_rows, img_cols)), border_mode = 'valid'))
model.add(Activation('relu'))

# input  24 * 24, output 20 * 20
model.add(Convolution2D(nb_filter, 5, 5, border_mode = 'valid'))
model.add(Activation('relu'))

# input  20 * 20, output 16 * 16
model.add(Convolution2D(nb_filter, 5, 5, border_mode = 'valid'))
model.add(Activation('relu'))

# input  16 * 16, output 14 * 14
model.add(Convolution2D(nb_filter, 3, 3, border_mode = 'valid'))
model.add(Activation('relu'))

# input  14 * 14 * 4, output 14 * 14 * 2
model.add(Convolution2D(2, 1, 1, border_mode = 'valid'))
model.add(Activation('relu'))

# input  input 14 * 14 * 2, output 28 * 28 * 2 ?
W_shape = [2, 2, 2, 2] # (self.nb_filter, input_dim, self.filter_length, 1)
b_shape = [2]
strides = [1,1,1,1]
deconv_shape = [2,2,2,2]
deconv_shape = [batch_size, 14, 14, 2]
model.add(Convolution2D_Transpose(deconv_shape=deconv_shape,  W_shape=W_shape, b_shape=b_shape, strides=strides, padding="SAME")) # should be lower capital same

model.add(Flatten())
model.add(Dense(784))
model.add(Reshape((1,28,28)))

"""
  W_shape --- shape of the weights - should be calculated internally
   from conv_2d:  (self.nb_filter, input_dim, self.filter_length, x)

   [0] ... nb_filter
   [1] ... input_dim
   [2] ... filter_length
   [3] ... 1

  b_shape ... shape of the biases - should be calculated internally
   [0] ... nb_filter ?

  deconv_shape
       this is output_shape of TF conv2d_transpose
       [ batch_size, input_cols, input_rows, input_depth]

Also U can set the output_shape(deconv_shape) according to:

def conv_transpose_out_length(input_size, filter_size, border_mode, stride):
    if input_size is None:
        return None
    if border_mode == 'VALID':
        output_size = (input_size - 1) * stride + filter_size
    elif border_mode == 'SAME':
        output_size = input_size
    return output_size

"""

##model.add(Dropout(0.25))
##model.add(Convolution2D_Transpose(deconv_shape=[128,18,18,1], W_shape=[3,3,1,16], b_shape=[1]))
##model.add(Activation('relu'))

print(model.summary())
#  OLD MNIST MODEL
#model.add(Convolution2D(nb_filters, nb_conv, nb_conv,
#                        border_mode='valid',
#                        input_shape=(1, img_rows, img_cols)))
#model.add(Activation('relu'))
#model.add(Convolution2D(nb_filters, nb_conv, nb_conv))
#model.add(Activation('relu'))
#model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool)))
#model.add(Dropout(0.25))

#model.add(Flatten())
#model.add(Dense(128))
#model.add(Activation('relu'))
#model.add(Dropout(0.5))
#model.add(Dense(nb_classes))
#model.add(Activation('softmax'))

model.compile(loss='mse', optimizer='sgd')
print("Before FIT")

#model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=1, validation_data=(X_test, Y_test))
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch, verbose=1)
score = model.evaluate(X_test, Y_test, verbose=0, batch_size=batch_size)
print('Test score:', score[0])
print('Test accuracy:', score[1])
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
#
#    Copyright 2013, 2014 Camptocamp SA
#
#    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/>.
#
#

{"name": "Purchase Requisition Bid Selection",
 "version": "0.2",
 "author": "Camptocamp",
 "license": "AGPL-3",
 "category": "Purchase Management",
 "complexity": "normal",
 "images": [],
 "description": """
Purchase Requisition Bid Selection
==================================

This module allows to make calls for bids by generating an RFQ for selected
suppliers, encode the bids, compare and select bids, generate draft POs.

First, a list of products is established. The call for bid is then confirmed
and RFQs can be generated. They are in the state 'Draft RFQ' until sent to the
supplier and then marked as 'RFQ Sent'. The bids have to be encoded and moved
to state 'Bid Encoded'. When closing the call for bids, in order to start the
bids selection, all RFQ that have not been sent will be canceled. However, sent
RFQs can still be encoded. Bids that are not received will remain in state 'RFQ
Sent' and can be manually canceled.

Afterwards, the bids selection can be started by choosing product lines. The
workflow has been modified to allow to mark that the selection of bids has
occurred but without having to generate the POs yet. Those can be created at a
new later state called 'Bids Selected'.

When generating POs, they are created in the state 'Draft PO' introduced by the
module purchase_rfq_bid_workflow.

Some fields have been added to specify with more details the call for bids and
prefill fields of the generated RFQs.

A link has been added between a call for bids line and the corresponding line
of each generated RFQ. This is used for the bids comparison in order to compare
bid lines and group then properly.

For running the tests the nose python package is required.
""",
 "depends": ["purchase_requisition",
             "stock",  # For incoterms
             "purchase_rfq_bid_workflow",  # for field incoterms place
             ],
 "demo": [],
 "data": ["wizard/modal.xml",
          "wizard/purchase_requisition_partner_view.xml",
          "view/purchase_requisition.xml",
          "view/purchase_order.xml",
          "workflow/purchase_requisition.xml",
          "data/purchase.cancelreason.yml",
          ],
 "auto_install": False,
 "test": ["test/process/restricted.yml",
          ],
 "installable": True,
 "certificate": "",
 }
<commit_msg>bump purchase_requisition_bid_selection<commit_after># -*- coding: utf-8 -*-
#
#
#    Copyright 2013, 2014 Camptocamp SA
#
#    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/>.
#
#

{"name": "Purchase Requisition Bid Selection",
 "version": "0.3",
 "author": "Camptocamp",
 "license": "AGPL-3",
 "category": "Purchase Management",
 "complexity": "normal",
 "images": [],
 "description": """
Purchase Requisition Bid Selection
==================================

This module allows to make calls for bids by generating an RFQ for selected
suppliers, encode the bids, compare and select bids, generate draft POs.

First, a list of products is established. The call for bid is then confirmed
and RFQs can be generated. They are in the state 'Draft RFQ' until sent to the
supplier and then marked as 'RFQ Sent'. The bids have to be encoded and moved
to state 'Bid Encoded'. When closing the call for bids, in order to start the
bids selection, all RFQ that have not been sent will be canceled. However, sent
RFQs can still be encoded. Bids that are not received will remain in state 'RFQ
Sent' and can be manually canceled.

Afterwards, the bids selection can be started by choosing product lines. The
workflow has been modified to allow to mark that the selection of bids has
occurred but without having to generate the POs yet. Those can be created at a
new later state called 'Bids Selected'.

When generating POs, they are created in the state 'Draft PO' introduced by the
module purchase_rfq_bid_workflow.

Some fields have been added to specify with more details the call for bids and
prefill fields of the generated RFQs.

A link has been added between a call for bids line and the corresponding line
of each generated RFQ. This is used for the bids comparison in order to compare
bid lines and group then properly.

For running the tests the nose python package is required.
""",
 "depends": ["purchase_requisition",
             "stock",  # For incoterms
             "purchase_rfq_bid_workflow",  # for field incoterms place
             ],
 "demo": [],
 "data": ["wizard/modal.xml",
          "wizard/purchase_requisition_partner_view.xml",
          "view/purchase_requisition.xml",
          "view/purchase_order.xml",
          "workflow/purchase_requisition.xml",
          "data/purchase.cancelreason.yml",
          ],
 "auto_install": False,
 "test": ["test/process/restricted.yml",
          ],
 "installable": True,
 "certificate": "",
 }
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright 2013-2014 Camptocamp SA
#
#    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 import models, fields, api, exceptions, osv
from openerp.tools.translate import _

STATE_SELECTION = [
    ('draft', 'Draft RFQ'),
    ('sent', 'RFQ Sent'),
    ('draftbid', 'Draft Bid'),  # added
    ('bid', 'Bid Encoded'),  # Bid Received renamed into Bid Encoded
    ('bid_selected', 'Bid selected'),  # added
    ('draftpo', 'Draft PO'),  # added
    ('confirmed', 'Waiting Approval'),
    ('approved', 'Purchase Confirmed'),
    ('except_picking', 'Shipping Exception'),
    ('except_invoice', 'Invoice Exception'),
    ('done', 'Done'),
    ('cancel', 'Canceled')
]
TYPE_SELECTION = [
    ('rfq', 'Request for Quotation'),
    ('bid', 'Bid'),
    ('purchase', 'Purchase Order')
]

class PurchaseOrderClassic(osv.orm.Model):
    _inherit = "purchase.order"

    _columns = {
        'state': osv.fields.selection(
            STATE_SELECTION,
            'Status',
            readonly=True,
            help="The status of the purchase order or the quotation request. "
            "A quotation is a purchase order in a 'Draft' status. Then the "
            "order has to be confirmed by the user, the status switch to "
            "'Confirmed'. Then the supplier must confirm the order to change "
            "the status to 'Approved'. When the purchase order is paid and "
            "received, the status becomes 'Done'. If a cancel action occurs "
            "in the invoice or in the reception of goods, the status becomes "
            "in exception.",
            select=True,
            copy=False),
    }

    def _default_state(self, cr, uid, context=None):
        if not context:
            return 'draft'
        elif context.get('draft_po'):
            return 'draftpo'
        elif context.get('draft_bid'):
            return 'draftbid'
        else:
            return 'draft'

    _defaults = {
        'state': _default_state,
    }

class PurchaseOrder(models.Model):
    _inherit = "purchase.order"

    def _default_type(self):
        if self._context.get('draft_po'):
            return 'purchase'
        elif self._context.get('draft_bid'):
            return 'bid'
        else:
            return 'rfq'

    type = fields.Selection(
        TYPE_SELECTION,
        'Type',
        required=True,
        readonly=True,
        default=_default_type)
    consignee_id = fields.Many2one(
        'res.partner', 'Consignee',
        help="The person to whom the shipment is to be delivered.")
    incoterm_address = fields.Char(
        'Incoterms Place',
        help="Incoterms Place of Delivery. "
             "International Commercial Terms are a series of "
             "predefined commercial terms used in "
             "international transactions.")
    cancel_reason_id = fields.Many2one(
        'purchase.cancel_reason', 'Reason for Cancellation', readonly=True)

    @api.model
    def create(self, values):
        # Document can be created as Draft RFQ or Draft PO. We need to log the
        # right message.
        description = self._description
        if self._context.get('draft_bid'):
            self._description = 'Draft Bid'
        elif not self._context.get('draft_po'):
            self._description = 'Request for Quotation'
        order = super(PurchaseOrder, self).create(values)
        self._description = description
        if self._context.get('draft_bid'):
            order.signal_workflow('draft_bid')
        if self._context.get('draft_po'):
            order.signal_workflow('draft_po')
        return order

    @api.one
    def copy(self, default=None):
        newpo = super(PurchaseOrder, self).copy(default=default)

        if newpo.type == 'rfq':
            for line in newpo.order_line:
                line.price_unit = 0.0

        return newpo

    @api.multi
    def wkf_draft_po(self):
        self.message_post(body=_("Converted to draft Purchase Order"),
                          subtype="mail.mt_comment")
        return self.write({'state': 'draftpo', 'type': 'purchase'})

    @api.multi
    def action_cancel(self):
        """ Ask a cancel reason
        """
        model_obj = self.env['ir.model.data']
        view_id = (model_obj
                   .sudo()
                   .get_object_reference('purchase_rfq_bid_workflow',
                                         'action_modal_cancel_reason'))[1]
        ctx = self._context.copy()
        ctx['action'] = 'action_cancel_ok'
        # TODO: filter based on po type
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'purchase.action_modal.cancel_reason',
            'view_id': view_id,
            'views': [(view_id, 'form')],
            'target': 'new',
            'context': ctx,
        }

    @api.multi
    def action_cancel_ok(self):
        act_modal_cancel_obj = self.env['purchase.action_modal.cancel_reason']
        assert self._context.get('active_id')
        action_modal = act_modal_cancel_obj.browse(self._context['active_id'])
        self.cancel_reason_id = action_modal.reason_id

        self.signal_workflow('purchase_cancel')

    @api.multi
    def wkf_action_cancel(self):
        for element in self:
            if element.state in ('draft', 'sent'):
                message = _("Request for Quotation")
            elif element.state == 'bid':
                message = _("Bid")
            else:
                message = self._description
            message += " " + _("canceled")
            element.message_post(body=message, subtype="mail.mt_comment")
        return super(PurchaseOrder, self).wkf_action_cancel()

    @api.multi
    def bid_received(self):
        ctx = self._context.copy()
        ctx.update({
            'action': 'bid_received_ok',
            'default_datetime': (self.bid_date
                                 or fields.Date.context_today(self)),
        })
        view = self.env.ref('purchase_rfq_bid_workflow.action_modal_bid_date')

        # those will be set by the web layer unless they are already defined
        for e in ('active_model', 'active_ids', 'active_id'):
            if e in ctx:
                del ctx[e]
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'purchase.action_modal.datetime',
            'view_id': view.id,
            'views': [(view.id, 'form')],
            'target': 'new',
            'context': ctx,
        }

    @api.multi
    def bid_received_ok(self):
        # TODO: send warning if not all lines have a price
        Wizard = self.env['purchase.action_modal.datetime']
        assert self._context.get('active_id')
        wizard = Wizard.browse(self._context['active_id'])

        self.bid_date = wizard.datetime

        self.message_post(body=_("Bid received and encoded"),
                          subtype="mail.mt_comment")
        self.signal_workflow('bid_received')
        return {}

    @api.multi
    def wkf_bid_received(self):
        # XXX do we need bid_date ?
        return self.write({'state': 'bid', 'type': 'bid'})

    @api.multi
    def _has_lines(self):
        """ Check if all request for quotation have at least a line """
        for rfq in self:
            if not rfq.order_line:
                return False
        return True

    @api.multi
    def wkf_send_rfq(self):
        if not self._has_lines():
            raise exceptions.except_orm(
                _('Error!'),
                _('You cannot send a Request for Quotation without any product'
                  ' line.'))
        return super(PurchaseOrder, self).wkf_send_rfq()

    @api.multi
    def print_quotation(self):
        if not self._has_lines():
            raise exceptions.except_orm(
                _('Error!'),
                _('You cannot print a Request for Quotation without any '
                  'product line.'))
        self.message_post(body=_("Request for Quotation printed"),
                          subtype="mail.mt_comment")
        return super(PurchaseOrder, self).print_quotation()

    def onchange_picking_type_id(self, cr, uid, ids, picking_type_id,
                                 context=None):
        PickType = self.pool['stock.picking.type']

        result = super(PurchaseOrder, self).onchange_picking_type_id(
            cr, uid, ids, picking_type_id, context)

        if picking_type_id:
            pick_type = PickType.browse(cr, uid, picking_type_id,
                                        context=context)

            if pick_type.warehouse_id and pick_type.warehouse_id.partner_id:
                dest_address_id = pick_type.warehouse_id.partner_id.id

                result['value']['dest_address_id'] = dest_address_id

        return result

    @api.multi
    def po_tender_requisition_selected(self):
        """Workflow function that write state 'bid selected'"""
        return self.write({'state': 'bid_selected'})

class PurchaseOrderLine(models.Model):
    _inherit = 'purchase.order.line'

    def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty,
                            uom_id, partner_id, date_order=False,
                            fiscal_position_id=False, date_planned=False,
                            name=False, price_unit=False, state='draftpo',
                            context=None):

        order_type = context.get('order_type') or 'rfq'

        res = super(PurchaseOrderLine, self).onchange_product_id(
            cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id,
            date_order, fiscal_position_id, date_planned, name, price_unit,
            context=context)

        if state == 'draft' and order_type == 'rfq':
            res['value'].update({'price_unit': 0.0})

        elif state in ('sent', 'draftbid', 'bid'):
            if 'price_unit' in res['value']:
                del res['value']['price_unit']

        return res
<commit_msg>fix copy if type='purchase'<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    Copyright 2013-2014 Camptocamp SA
#
#    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 import models, fields, api, exceptions, osv
from openerp.tools.translate import _

STATE_SELECTION = [
    ('draft', 'Draft RFQ'),
    ('sent', 'RFQ Sent'),
    ('draftbid', 'Draft Bid'),  # added
    ('bid', 'Bid Encoded'),  # Bid Received renamed into Bid Encoded
    ('bid_selected', 'Bid selected'),  # added
    ('draftpo', 'Draft PO'),  # added
    ('confirmed', 'Waiting Approval'),
    ('approved', 'Purchase Confirmed'),
    ('except_picking', 'Shipping Exception'),
    ('except_invoice', 'Invoice Exception'),
    ('done', 'Done'),
    ('cancel', 'Canceled')
]
TYPE_SELECTION = [
    ('rfq', 'Request for Quotation'),
    ('bid', 'Bid'),
    ('purchase', 'Purchase Order')
]

class PurchaseOrderClassic(osv.orm.Model):
    _inherit = "purchase.order"

    _columns = {
        'state': osv.fields.selection(
            STATE_SELECTION,
            'Status',
            readonly=True,
            help="The status of the purchase order or the quotation request. "
            "A quotation is a purchase order in a 'Draft' status. Then the "
            "order has to be confirmed by the user, the status switch to "
            "'Confirmed'. Then the supplier must confirm the order to change "
            "the status to 'Approved'. When the purchase order is paid and "
            "received, the status becomes 'Done'. If a cancel action occurs "
            "in the invoice or in the reception of goods, the status becomes "
            "in exception.",
            select=True,
            copy=False),
    }

    def _default_state(self, cr, uid, context=None):
        if not context:
            return 'draft'
        elif context.get('draft_po'):
            return 'draftpo'
        elif context.get('draft_bid'):
            return 'draftbid'
        else:
            return 'draft'

    _defaults = {
        'state': _default_state,
    }

class PurchaseOrder(models.Model):
    _inherit = "purchase.order"

    def _default_type(self):
        if self._context.get('draft_po'):
            return 'purchase'
        elif self._context.get('draft_bid'):
            return 'bid'
        else:
            return 'rfq'

    type = fields.Selection(
        TYPE_SELECTION,
        'Type',
        required=True,
        readonly=True,
        default=_default_type)
    consignee_id = fields.Many2one(
        'res.partner', 'Consignee',
        help="The person to whom the shipment is to be delivered.")
    incoterm_address = fields.Char(
        'Incoterms Place',
        help="Incoterms Place of Delivery. "
             "International Commercial Terms are a series of "
             "predefined commercial terms used in "
             "international transactions.")
    cancel_reason_id = fields.Many2one(
        'purchase.cancel_reason', 'Reason for Cancellation', readonly=True)

    @api.model
    def create(self, values):
        # Document can be created as Draft RFQ or Draft PO. We need to log the
        # right message.
        description = self._description
        if self._context.get('draft_bid'):
            self._description = 'Draft Bid'
        elif not self._context.get('draft_po'):
            self._description = 'Request for Quotation'
        order = super(PurchaseOrder, self).create(values)
        self._description = description
        if self._context.get('draft_bid'):
            order.signal_workflow('draft_bid')
        if self._context.get('draft_po'):
            order.signal_workflow('draft_po')
        return order

    @api.one
    def copy(self, default=None):

        if default.get('type') == 'purchase':
            self = self.with_context(draft_po=True)

        newpo = super(PurchaseOrder, self).copy(default=default)

        if newpo.type == 'rfq':
            for line in newpo.order_line:
                line.price_unit = 0.0

        return newpo

    @api.multi
    def wkf_draft_po(self):
        self.message_post(body=_("Converted to draft Purchase Order"),
                          subtype="mail.mt_comment")
        return self.write({'state': 'draftpo', 'type': 'purchase'})

    @api.multi
    def action_cancel(self):
        """ Ask a cancel reason
        """
        model_obj = self.env['ir.model.data']
        view_id = (model_obj
                   .sudo()
                   .get_object_reference('purchase_rfq_bid_workflow',
                                         'action_modal_cancel_reason'))[1]
        ctx = self._context.copy()
        ctx['action'] = 'action_cancel_ok'
        # TODO: filter based on po type
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'purchase.action_modal.cancel_reason',
            'view_id': view_id,
            'views': [(view_id, 'form')],
            'target': 'new',
            'context': ctx,
        }

    @api.multi
    def action_cancel_ok(self):
        act_modal_cancel_obj = self.env['purchase.action_modal.cancel_reason']
        assert self._context.get('active_id')
        action_modal = act_modal_cancel_obj.browse(self._context['active_id'])
        self.cancel_reason_id = action_modal.reason_id

        self.signal_workflow('purchase_cancel')

    @api.multi
    def wkf_action_cancel(self):
        for element in self:
            if element.state in ('draft', 'sent'):
                message = _("Request for Quotation")
            elif element.state == 'bid':
                message = _("Bid")
            else:
                message = self._description
            message += " " + _("canceled")
            element.message_post(body=message, subtype="mail.mt_comment")
        return super(PurchaseOrder, self).wkf_action_cancel()

    @api.multi
    def bid_received(self):
        ctx = self._context.copy()
        ctx.update({
            'action': 'bid_received_ok',
            'default_datetime': (self.bid_date
                                 or fields.Date.context_today(self)),
        })
        view = self.env.ref('purchase_rfq_bid_workflow.action_modal_bid_date')

        # those will be set by the web layer unless they are already defined
        for e in ('active_model', 'active_ids', 'active_id'):
            if e in ctx:
                del ctx[e]
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'purchase.action_modal.datetime',
            'view_id': view.id,
            'views': [(view.id, 'form')],
            'target': 'new',
            'context': ctx,
        }

    @api.multi
    def bid_received_ok(self):
        # TODO: send warning if not all lines have a price
        Wizard = self.env['purchase.action_modal.datetime']
        assert self._context.get('active_id')
        wizard = Wizard.browse(self._context['active_id'])

        self.bid_date = wizard.datetime

        self.message_post(body=_("Bid received and encoded"),
                          subtype="mail.mt_comment")
        self.signal_workflow('bid_received')
        return {}

    @api.multi
    def wkf_bid_received(self):
        # XXX do we need bid_date ?
        return self.write({'state': 'bid', 'type': 'bid'})

    @api.multi
    def _has_lines(self):
        """ Check if all request for quotation have at least a line """
        for rfq in self:
            if not rfq.order_line:
                return False
        return True

    @api.multi
    def wkf_send_rfq(self):
        if not self._has_lines():
            raise exceptions.except_orm(
                _('Error!'),
                _('You cannot send a Request for Quotation without any product'
                  ' line.'))
        return super(PurchaseOrder, self).wkf_send_rfq()

    @api.multi
    def print_quotation(self):
        if not self._has_lines():
            raise exceptions.except_orm(
                _('Error!'),
                _('You cannot print a Request for Quotation without any '
                  'product line.'))
        self.message_post(body=_("Request for Quotation printed"),
                          subtype="mail.mt_comment")
        return super(PurchaseOrder, self).print_quotation()

    def onchange_picking_type_id(self, cr, uid, ids, picking_type_id,
                                 context=None):
        PickType = self.pool['stock.picking.type']

        result = super(PurchaseOrder, self).onchange_picking_type_id(
            cr, uid, ids, picking_type_id, context)

        if picking_type_id:
            pick_type = PickType.browse(cr, uid, picking_type_id,
                                        context=context)

            if pick_type.warehouse_id and pick_type.warehouse_id.partner_id:
                dest_address_id = pick_type.warehouse_id.partner_id.id

                result['value']['dest_address_id'] = dest_address_id

        return result

    @api.multi
    def po_tender_requisition_selected(self):
        """Workflow function that write state 'bid selected'"""
        return self.write({'state': 'bid_selected'})

class PurchaseOrderLine(models.Model):
    _inherit = 'purchase.order.line'

    def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty,
                            uom_id, partner_id, date_order=False,
                            fiscal_position_id=False, date_planned=False,
                            name=False, price_unit=False, state='draftpo',
                            context=None):

        order_type = context.get('order_type') or 'rfq'

        res = super(PurchaseOrderLine, self).onchange_product_id(
            cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id,
            date_order, fiscal_position_id, date_planned, name, price_unit,
            context=context)

        if state == 'draft' and order_type == 'rfq':
            res['value'].update({'price_unit': 0.0})

        elif state in ('sent', 'draftbid', 'bid'):
            if 'price_unit' in res['value']:
                del res['value']['price_unit']

        return res
<|endoftext|>