<commit_before>#!/usr/bin/env python
import sqlite3
import sys
import codecs
from datetime import datetime

out = codecs.getwriter('UTF-8')(sys.stdout)

conn = sqlite3.connect('test.db')

c = conn.cursor()
for row in c.execute('SELECT guid, currency_guid, num, post_date, enter_date, description FROM transactions'):
	#guid,currency_guid,post_data,enter_date,description = row
	pass

class Account(object):
	def __init__(self):
		self.childs = []
		self.parent = None
		self.name = ""
		self.splits = []
		self.type = None
		self.dummy = True

	def __str__(self):
		return self.name

class Commodity(object):
	def __init__(self):
		self.fullname = ""
		self.namespace = ""
		self.dummy = True

	def __str__(self):
		return self.mnemonic

class Transaction(object):
	def __init__(self):
		self.dummy = True
		self.splits = []

class Split(object):
	def __init__(self):
		self.dummy = True

accounts = dict()
commodities = dict()
transactions = dict()
splits = dict()

def get(objdict, constructor, guid):
	acc = objdict.get(guid)
	if acc is None:
		acc = constructor()
		acc.guid = guid
		objdict[guid] = acc
	return acc

def get_account(guid):
	return get(accounts, Account, guid)

def get_commodity(guid):
	return get(commodities, Commodity, guid)

def get_transaction(guid):
	return get(transactions, Transaction, guid)

def get_split(guid):
	return get(splits, Split, guid)

for row in c.execute('SELECT guid, namespace, mnemonic, fullname FROM commodities'):
	guid,namespace,mnemonic,fullname = row
	comm = get_commodity(guid)
	comm.namespace = namespace
	comm.mnemonic = mnemonic
	comm.fullname = fullname
	comm.dummy = comm.namespace == "template"

for row in c.execute('SELECT guid, name, account_type, commodity_guid, commodity_scu, non_std_scu, parent_guid, code, description FROM accounts'):
	guid,name,account_type,commodity_guid,commodity_scu,non_std_scu,parent_guid,code,description = row
	acc = get_account(guid)
	acc.name = name
	acc.parent = get_account(parent_guid)
	acc.parent.childs.append(acc)
	acc.description = description
	acc.commodity = get_commodity(commodity_guid)
	acc.type = account_type
	acc.dummy = acc.commodity.dummy

def parse_time(time):
	return datetime.strptime(time, "%Y%m%d%H%M%S")

for row in c.execute('SELECT guid, currency_guid, num, post_date, description FROM transactions'):
	guid,currency_guid,num,post_date,description = row
	trans = get_transaction(guid)
	trans.currency = get_commodity(currency_guid)
	trans.num = num
	trans.post_date = parse_time(post_date)
	trans.description = description
	trans.dummy = False

for row in c.execute('SELECT guid, tx_guid, account_guid, value_num, value_denom, quantity_num, quantity_denom FROM splits'):
	guid,tx_guid,account_guid,value_num,value_denom,quantity_num,quantity_denom = row
	split = get_split(guid)
	split.transaction = get_transaction(tx_guid)
	split.transaction.splits.append(split)
	split.account = get_account(account_guid)
	split.account.splits.append(split)
	split.value_num = int(value_num)
	split.value_denom = int(value_denom)
	split.value = float(value_num)/float(value_denom)
	split.quantity_num = int(quantity_num)
	split.quantity_denom = int(quantity_denom)
	split.quantity = float(quantity_num)/float(quantity_denom)

def full_acc_name(acc, maxdepth=1000):
	if acc.parent is None or maxdepth == 0:
		return ""
	result = full_acc_name(acc.parent, maxdepth-1)
	result += ":"+acc.name
	return result

# Calculate dividend amounts per account
def calc_dividends(acc):
	# Collect transactions involving currency and no number on this account
	sum_value = 0.0
	sum_fees = 0.0
	sum_dividends = 0.0
	count = 0
	for split in acc.splits:
		trans = split.transaction
		if split.quantity != 0:
			continue
		value = 0.0
		fees = 0.0
		dividends = 0.0
		for ssplit in trans.splits:
			if ssplit is split:
				continue
			#date = trans.post_date.strftime("%d.%m.%Y")
			#out.write("   %s %-30s   value %.2f quantity %.2f\n" %
			#		  (date, trans.description, ssplit.value, ssplit.quantity))
			acctype = ssplit.account.type
			if acctype == "EXPENSE":
				fees += abs(ssplit.value)
			elif acctype == "BANK":
				value += abs(ssplit.value)
			elif acctype == "INCOME":
				dividends += abs(ssplit.value)
			else:
				out.write("UNKNOWN TYPE: %s (acc %s)\n" % (acctype, acc))
				date = trans.post_date.strftime("%d.%m.%Y")
				out.write("\t%s %-30s   value %.2f quantity %.2f\n" %
						  (date, trans.description, ssplit.value, ssplit.quantity))
				assert False
		count += 1
		sum_value += value
		sum_fees += fees
		sum_dividends += dividends
		date = trans.post_date.strftime("%d.%m.%Y")
		out.write("\t%s DIV   %7.2f %s fees %7.2f\n" % (date, value, trans.currency, fees))

	assert abs(sum_value+sum_fees - sum_dividends) < .0001
	return (count, sum_value, sum_fees)

def calc_realized_wins(acc):
	for split in acc.splits:
		trans = split.transaction
		# quantity == 0 is probably a dividend, we don't care here
		if split.quantity == 0:
			continue
		date = trans.post_date.strftime("%d.%m.%Y")
		curr = trans.currency
		is_buy = split.quantity > 0

		# Classify remaining splits into taxes+fees and real costs
		fees=0.0
		costs=0.0
		atype = "BUY " if is_buy else "SELL"
		ignore_trans = False
		for ssplit in trans.splits:
			if ssplit is split or ssplit.value == 0:
				continue
			acctype = ssplit.account.type
			if acctype == "EXPENSE":
				fees += abs(ssplit.value)
			elif acctype == "BANK" or acctype == "ASSET":
				costs += abs(ssplit.value)
			elif acctype == "STOCK":
				# moved to different depot? or a stock split?
				if ssplit.account == acc:
					# probably a split, ignore
					ignore_trans = True
				else:
					# moved to/from different depot, handle like a SELL
					assert costs == 0
					atype = "MIN " if is_buy else "MOUT"
					costs += abs(ssplit.value)
			else:
				out.write("UNKNOWN TYPE: %s (acc %s)\n" % (acctype, acc))
				date = trans.post_date.strftime("%d.%m.%Y")
				out.write("\t%s %-30s   value %.2f quantity %.2f\n" %
						  (date, trans.description, ssplit.value, ssplit.quantity))
				assert False

		if ignore_trans:
			continue

		quantity = abs(split.quantity)
		out.write("\t%s %s %7s shares costs %9.2f %s fees %7.2f\n" % (
		          date, atype, quantity, costs, curr, fees))

		#name = full_acc_name(ssplit.account, 2)
		#out.write("     acc %s value %.2f quantity %.2f\n" % (name, ssplit.value, ssplit.quantity))

# Select all stock accounts
gdiv_value = 0.0
gdiv_fees = 0.0
gdiv_count = 0
for acc in accounts.values():
	if acc.type != "STOCK":
		#out.write("IGNORE %s: %-40s\n" % (acc.type, full_acc_name(acc, 3)))
		continue
	name = full_acc_name(acc, 3)
	out.write("%-40s\n" % (name,))

	div_count, div_value, div_fees = calc_dividends(acc)
	acc.div_value = div_value
	acc.div_count = div_count
	acc.div_fees = div_fees
	gdiv_value += div_value
	gdiv_count += div_count
	gdiv_fees += div_fees
	#if div_value == 0.0:
	#	continue
	calc_realized_wins(acc)
#	for split in acc.splits:
#		trans = split.transaction
#		out.write("\t%-30s   vnum %s vdenom %s qnum %s qdenom %s\n" %
#		          (trans.description, split.value_num, split.value_denom,
#		          split.quantity_num, split.quantity_denom))
	out.write("  => %5.2f dividends [%5.2f fees]\n" % (acc.div_value, acc.div_fees))
out.write("-----------\n")
out.write("%5.2f EUR dividens [%5.2f dividend fees]" % (gdiv_value, gdiv_fees))

class Transaction(object):
	def __init__(self):
		pass
<commit_msg>cleanup<commit_after>#!/usr/bin/env python
import sqlite3
import sys
import codecs
from datetime import datetime

out = codecs.getwriter('UTF-8')(sys.stdout)

class Account(object):
	def __init__(self):
		self.childs = []
		self.parent = None
		self.name = ""
		self.splits = []
		self.type = None
		self.dummy = True

	def __str__(self):
		return self.name

class Commodity(object):
	def __init__(self):
		self.fullname = ""
		self.namespace = ""
		self.dummy = True

	def __str__(self):
		return self.mnemonic

class Transaction(object):
	def __init__(self):
		self.dummy = True
		self.splits = []

class Split(object):
	def __init__(self):
		self.dummy = True

accounts = dict()
commodities = dict()
transactions = dict()
splits = dict()

def get(objdict, constructor, guid):
	acc = objdict.get(guid)
	if acc is None:
		acc = constructor()
		acc.guid = guid
		objdict[guid] = acc
	return acc

def get_account(guid):
	return get(accounts, Account, guid)

def get_commodity(guid):
	return get(commodities, Commodity, guid)

def get_transaction(guid):
	return get(transactions, Transaction, guid)

def get_split(guid):
	return get(splits, Split, guid)

# Read Data
conn = sqlite3.connect('test.db')
c = conn.cursor()

for row in c.execute('SELECT guid, namespace, mnemonic, fullname FROM commodities'):
	guid,namespace,mnemonic,fullname = row
	comm = get_commodity(guid)
	comm.namespace = namespace
	comm.mnemonic = mnemonic
	comm.fullname = fullname
	comm.dummy = comm.namespace == "template"

for row in c.execute('SELECT guid, name, account_type, commodity_guid, commodity_scu, non_std_scu, parent_guid, code, description FROM accounts'):
	guid,name,account_type,commodity_guid,commodity_scu,non_std_scu,parent_guid,code,description = row
	acc = get_account(guid)
	acc.name = name
	acc.parent = get_account(parent_guid)
	acc.parent.childs.append(acc)
	acc.description = description
	acc.commodity = get_commodity(commodity_guid)
	acc.type = account_type
	acc.dummy = acc.commodity.dummy

def parse_time(time):
	return datetime.strptime(time, "%Y%m%d%H%M%S")

for row in c.execute('SELECT guid, currency_guid, num, post_date, description FROM transactions'):
	guid,currency_guid,num,post_date,description = row
	trans = get_transaction(guid)
	trans.currency = get_commodity(currency_guid)
	trans.num = num
	trans.post_date = parse_time(post_date)
	trans.description = description
	trans.dummy = False

for row in c.execute('SELECT guid, tx_guid, account_guid, value_num, value_denom, quantity_num, quantity_denom FROM splits'):
	guid,tx_guid,account_guid,value_num,value_denom,quantity_num,quantity_denom = row
	split = get_split(guid)
	split.transaction = get_transaction(tx_guid)
	split.transaction.splits.append(split)
	split.account = get_account(account_guid)
	split.account.splits.append(split)
	split.value_num = int(value_num)
	split.value_denom = int(value_denom)
	split.value = float(value_num)/float(value_denom)
	split.quantity_num = int(quantity_num)
	split.quantity_denom = int(quantity_denom)
	split.quantity = float(quantity_num)/float(quantity_denom)

# Analysis

def full_acc_name(acc, maxdepth=1000):
	if acc.parent is None or maxdepth == 0:
		return ""
	result = full_acc_name(acc.parent, maxdepth-1)
	result += ":"+acc.name
	return result

# Calculate dividend amounts per account
def calc_dividends(acc):
	# Collect transactions involving currency and no number on this account
	sum_value = 0.0
	sum_fees = 0.0
	sum_dividends = 0.0
	count = 0
	for split in acc.splits:
		trans = split.transaction
		if split.quantity != 0:
			continue
		value = 0.0
		fees = 0.0
		dividends = 0.0
		for ssplit in trans.splits:
			if ssplit is split:
				continue
			acctype = ssplit.account.type
			if acctype == "EXPENSE":
				fees += abs(ssplit.value)
			elif acctype == "BANK":
				value += abs(ssplit.value)
			elif acctype == "INCOME":
				dividends += abs(ssplit.value)
			else:
				out.write("UNKNOWN TYPE: %s (acc %s)\n" % (acctype, acc))
				date = trans.post_date.strftime("%d.%m.%Y")
				out.write("\t%s %-30s   value %.2f quantity %.2f\n" %
						  (date, trans.description, ssplit.value, ssplit.quantity))
				assert False
		count += 1
		sum_value += value
		sum_fees += fees
		sum_dividends += dividends
		date = trans.post_date.strftime("%d.%m.%Y")
		out.write("\t%s DIV   %7.2f %s fees %7.2f\n" % (date, value, trans.currency, fees))

	assert abs(sum_value+sum_fees - sum_dividends) < .0001
	return (count, sum_value, sum_fees)

def calc_realized_wins(acc):
	for split in acc.splits:
		trans = split.transaction
		# quantity == 0 is probably a dividend, we don't care here
		if split.quantity == 0:
			continue
		date = trans.post_date.strftime("%d.%m.%Y")
		curr = trans.currency
		is_buy = split.quantity > 0

		# Classify remaining splits into taxes+fees and real costs
		fees=0.0
		costs=0.0
		atype = "BUY " if is_buy else "SELL"
		ignore_trans = False
		for ssplit in trans.splits:
			if ssplit is split or ssplit.value == 0:
				continue
			acctype = ssplit.account.type
			if acctype == "EXPENSE":
				fees += abs(ssplit.value)
			elif acctype == "BANK" or acctype == "ASSET":
				costs += abs(ssplit.value)
			elif acctype == "STOCK":
				# moved to different depot? or a stock split?
				if ssplit.account == acc:
					# probably a split, ignore
					ignore_trans = True
				else:
					# moved to/from different depot, handle like a SELL
					assert costs == 0
					atype = "MIN " if is_buy else "MOUT"
					costs += abs(ssplit.value)
			else:
				out.write("UNKNOWN TYPE: %s (acc %s)\n" % (acctype, acc))
				date = trans.post_date.strftime("%d.%m.%Y")
				out.write("\t%s %-30s   value %.2f quantity %.2f\n" %
						  (date, trans.description, ssplit.value, ssplit.quantity))
				assert False

		if ignore_trans:
			continue

		quantity = abs(split.quantity)
		out.write("\t%s %s %7s shares costs %9.2f %s fees %7.2f\n" % (
		          date, atype, quantity, costs, curr, fees))

# Report
gdiv_value = 0.0
gdiv_fees = 0.0
gdiv_count = 0
for acc in accounts.values():
	if acc.type != "STOCK":
		#out.write("IGNORE %s: %-40s\n" % (acc.type, full_acc_name(acc, 3)))
		continue
	name = full_acc_name(acc, 3)
	out.write("%-40s\n" % (name,))

	div_count, div_value, div_fees = calc_dividends(acc)
	acc.div_value = div_value
	acc.div_count = div_count
	acc.div_fees = div_fees
	gdiv_value += div_value
	gdiv_count += div_count
	gdiv_fees += div_fees
	calc_realized_wins(acc)
	out.write("  => %5.2f dividends [%5.2f fees]\n" % (acc.div_value, acc.div_fees))
out.write("-----------\n")
out.write("%5.2f EUR dividens [%5.2f dividend fees]" % (gdiv_value, gdiv_fees))
<|endoftext|>


<commit_before>import six.moves as sm
from gem import vector

def flip(plane):
    ''' Flips the plane.'''
    fA = -plane.a
    fB = -plane.b
    fC = -plane.c
    fD = -plane.D
    fNormal = -plane.normal
    return [fA, fB, fC, fD, fNormal]

def normalize(pdata):
    ''' Return the normalized plane.'''
    vec = vector.Vector(3, data=[pdata[0], pdata[1], pdata[2]])
    vecN = vec.normalize()

    length = vecN.magnitude()

    if length is not 0:
        return [vecN.vector[0], vecN.vector[1], vecN.vector[2], pdata[3] / length]
    else:
        print("Plane fail to normalize due to zero division.")
        return [0.0, 0.0, 0.0, 0.0]

class Plane(object):
    def __init__(self, *args):
        ''' Define a plane using 3 vectors, return a 4 item 1D array. '''
        if isinstance(args[0], list):
            self.data = args[0]
        elif isinstance(args[0], vector.Vector):
            # Define using 3 vectors
            v1 = args[1] - args[0]
            v2 = args[2] - args[0]
            n = v1.cross(v2)
            n.i_normalize()
            self.data = [n.vector[0], n.vector[1], n.vector[2], (n * -1.0).dot(args[0])]
        else:
            self.data = [0.0, 0.0, 0.0, 0.0]

        self.normal = vector.Vector(3, data=[0.0, 0.0, 0.0])

    def i_flip(self):
        ''' Flip the plane in its place. '''
        data = flip(self)
        self.a = data[0]
        self.b = data[1]
        self.c = data[2]
        self.d = data[3]
        self.normal = data[4]
        return self

    def flip(self):
        ''' Return a flipped plane. '''
        return Plane(flip(self))

    def dot(self, vec):
        ''' Return the dot product between a plane and 4D vector. '''
        return self.data[0] * vec.vector[0] + self.data[1] * vec.vector[1] + self.data[2] * vec.vector[2] + self.data[3] * vec.vector[3]

    def i_normalize(self):
        ''' Normalize the vector in place. '''
        self.data = normalize(self.data)
        return self

    def normalize(self):
        ''' Return the normalized plane.'''
        return Plane(normalize(self.data))

    def bestFitNormal(self, vecList):
        ''' Pass in a list of vectors to find the best fit normal. '''
        output = vector.Vector(3).zero()
        for i in sm.range(len(vecList)):
            output.vector[0] += (vecList[i].vector[2] + vecList[i + 1].vector[2]) * (vecList[i].vector[1] - vecList[i + 1].vector[1])
            output.vector[1] += (vecList[i].vector[0] + vecList[i + 1].vector[0]) * (vecList[i].vector[2] - vecList[i + 1].vector[2])
            output.vector[2] += (vecList[i].vector[1] + vecList[i + 1].vector[1]) * (vecList[i].vector[0] - vecList[i + 1].vector[0])
        return output.normalize()

    def bestFitD(self, vecList, bestFitNormal):
        ''' Returns the best fit D from a list of vectors using the best fit normal. '''
        val = 0.0
        for vec in vecList:
            val += vec.dot(bestFitNormal)
        return val / len(vecList)

    def point_location(self, plane, point):
        ''' Returns the location of the point. '''
        # If s > 0 then the point is on the same side as the normal. (front)
        # If s < 0 then the point is on the opposide side of the normal. (back)
        # If s = 0 then the point lies on the plane.
        s = plane.data[0] * point[0] + plane.data[1] * point[1] + plane.data[2] * point[2] + plane.data[3]

        if s > 0:
            return 1
        elif s < 0:
            return -1
        elif s == 0:
            return 0
        else:
            print("Not a clue where the point is.")

<commit_msg>Updated plane class. v0.1.8<commit_after>import six.moves as sm
from gem import vector

def flip(plane):
    ''' Flips the plane.'''
    fA = -plane.a
    fB = -plane.b
    fC = -plane.c
    fD = -plane.D
    fNormal = -plane.normal
    return [fA, fB, fC, fD, fNormal]

def normalize(pdata):
    ''' Return the normalized plane.'''
    vec = vector.Vector(3, data=pdata)
    vecN = vec.normalize()

    length = vecN.magnitude()

    if length is not 0:
        return vecN.vector[0], vecN.vector[1], vecN.vector[2], pdata[3] / length
    else:
        print("Plane fail to normalize due to zero division.")
        return 0.0, 0.0, 0.0, 0.0

class Plane(object):
    def __init__(self):
        ''' Plane class constructor. '''
        self.normal = vector.Vector(3, data=[0.0, 0.0, 0.0])
        self.a = 0
        self.b = 0
        self.c = 0
        self.d = 0

    def clone(self):
        '''Create a new Plane with similar propertise.'''
        nPlane = Plane()
        nPlane.normal = self.normal.clone()
        nPlane.a = self.a
        nPlane.b = self.b
        nPlane.c = self.c
        nPLane.d = self.d
        return nPlane

    def fromCoeffs(self, a, b, c, d):
        ''' Create the plane from A,B,C,D. '''
        self.a = a
        self.b = b
        self.c = c
        self.d = d
        self.normal = vector.cross(b - a, c - a).normalize()

    def fromPoints(self, a, b, c):
        '''Calculate the plane from A,B,C.'''
        self.a = a
        self.b = b
        self.c = c
        self.normal = vector.cross(b - a, c - a).normalize()
        self.d = self.normal.dot(self.a)

    def i_flip(self):
        ''' Flip the plane in its place. '''
        self.data = flip(self)
        self.a = data[0]
        self.b = data[1]
        self.c = data[2]
        self.d = data[3]
        self.normal = data[4]
        return self

    def flip(self):
        ''' Return a flipped plane. '''
        nPlane = Plane()
        data = flip(self)
        nPlane.a = data[0]
        nPlane.b = data[1]
        nPlane.c = data[2]
        nPlane.d = data[3]
        nPlane.normal = data[4]
        return nPlane

    def dot(self, vec):
        ''' Return the dot product between a plane and 4D vector. '''
        return self.a * vec.vector[0] + self.b * vec.vector[1] + self.c * vec.vector[2] + self.d * vec.vector[3]

    def i_normalize(self):
        ''' Normalize the vector in place. '''
        pdata = [self.a, self.b, self.c, self.d]
        self.a, self.b, self.c, self.d = normalize(pdata)
        return self

    def normalize(self):
        ''' Return the normalized plane.'''
        nPlane = Plane().clone()
        pdata = [self.a, self.b, self.c, self.d]
        nPlane.a, nPlane.b, nPlane.c, nPlane.d = normalize(pdata)
        return nPlane

    def bestFitNormal(self, vecList):
        ''' Pass in a list of vectors to find the best fit normal. '''
        output = vector.Vector(3).zero()
        for i in sm.range(len(vecList)):
            output.vector[0] += (vecList[i].vector[2] + vecList[i + 1].vector[2]) * (vecList[i].vector[1] - vecList[i + 1].vector[1])
            output.vector[1] += (vecList[i].vector[0] + vecList[i + 1].vector[0]) * (vecList[i].vector[2] - vecList[i + 1].vector[2])
            output.vector[2] += (vecList[i].vector[1] + vecList[i + 1].vector[1]) * (vecList[i].vector[0] - vecList[i + 1].vector[0])
        return output.normalize()

    def bestFitD(self, vecList, bestFitNormal):
        ''' Returns the best fit D from a list of vectors using the best fit normal. '''
        val = 0.0
        for vec in vecList:
            val += vec.dot(bestFitNormal)
        return val / len(vecList)

    def point_location(self, plane, point):
        ''' Returns the location of the point. Point is a tuple. '''
        # If s > 0 then the point is on the same side as the normal. (front)
        # If s < 0 then the point is on the opposide side of the normal. (back)
        # If s = 0 then the point lies on the plane.
        s = plane.a * point[0] + plane.b * point[1] + plane.c * point[2] + plane.d

        if s > 0:
            return 1
        elif s < 0:
            return -1
        elif s == 0:
            return 0
        else:
            print("Not a clue where the point is.")

<|endoftext|>


<commit_before>from pprint import pprint

from utils.functions.models import dictlist
from utils.functions.queries import debug_cursor_execute
from utils.functions.strings import only_digits

class LotesEmEstoque():

    def __init__(
        self,
        cursor,
        tipo=None,
        ref=None,
        get=None,
        colecao=None,
        modelo=None,
        fields_tuple=None,
        lote=None,
        endereco=None,
    ):
        self.cursor = cursor
        self.tipo = tipo
        self.ref = ref
        self.get = get
        self.colecao = colecao
        self.modelo = modelo
        self.fields_tuple = fields_tuple
        self.lote = lote
        self.endereco = endereco

        self.sql_em_stq = SqlEmEstoque(
            tipo=self.tipo,
            ref=self.ref,
            get=self.get,
            colecao=self.colecao,
            fields_tuple=self.fields_tuple,
            lote=self.lote,
            endereco=self.endereco,
        )

    def dados(self):
        sql = self.sql_em_stq.sql()

        debug_cursor_execute(self.cursor, sql)
        dados = dictlist(self.cursor)

        if self.modelo:
            dados_modelo = []
        for row in dados:
            try:
                ref_modelo = int(only_digits(row['ref']))
            except ValueError:
                ref_modelo = 0
            row['modelo'] = ref_modelo
            if ref_modelo == self.modelo:
                dados_modelo.append(row)
        if self.modelo:
            return dados_modelo
        else:
            return dados

class SqlEmEstoque():
    """Monta SQL base de selecão de lotes
    - endereçados; e
    - no estágio 63
    Recebe:
    tipo
        i = inventário: todos os lotes endereçados e com quantidade no estágio 63
        p = lotes que aparece no inventário (opção acima) e são de OPs de Pedidos
        s = solicitado (situação 2, 3 ou 4) de OP com estágio 63
        iq = inventário: todos os lotes endereçados e com quantidade em qq estágio
        None = todos os lotes
    ref: filtro de referências, caso não None
        iterable = uma lista de cond_expr
        string = cond_expr[, cond_expr]
            É transformada em uma lista de cond_expr
        Obs.:
            cond_expr = [condição] valor = filtro de uma referência
            condição: altera o funcionamento do filtro
                None = igualdade
                Várias condições válidas no SQL como '<', '>', '>='...
    get
        ref = busca apenas o campo referência (com distinct)
        None = busca apenas o campo referência (sem distinct)
        lote_qtd = busca op, lote, item e quantidades
        # loc = busca op, lote, item, quantidades e informação de endereçamento
    sinal: positivo ou negativo
        '+' = quantidades como estão no banco de dados
        '-' = inverte o sinal das quantidades
    fields_tuple
        Lista de fields que devem ser retornados
        Field pode ter alias a ser utilizado. Ex.: "qtd quanti"
        obs.: ref sempre é retornado
    """

    def __init__(
        self,
        tipo=None,
        ref=None,
        get=None,
        colecao=None,
        sinal='+',
        fields_tuple=None,
        lote=None,
        endereco=None,
    ):
        self.tipo = tipo
        self.ref = ref
        self.get = get
        self.colecao = colecao
        self.sinal = sinal
        self.fields_tuple = fields_tuple
        self.lote = lote
        self.endereco = endereco

        self.available_fields = {
            'ref': "l.PROCONF_GRUPO",
            'per': "l.PERIODO_PRODUCAO",
            'oc': "l.ORDEM_CONFECCAO",
            'lote': "lp.ORDEM_CONFECCAO",
            'palete': """--
                CASE
                  WHEN lp.COD_CONTAINER IS NOT NULL
                   AND lp.COD_CONTAINER <> '0'
                  THEN lp.COD_CONTAINER
                  ELSE '-'
                END
            """,
            'tam': "l.PROCONF_SUBGRUPO",
            'ordem_tam': "tam.ORDEM_TAMANHO",
            'cor': "l.PROCONF_ITEM",
            'op': "l.ORDEM_PRODUCAO",
            'qtd_prog': "l.QTDE_PECAS_PROG",
            'qtd_dbaixa': "l.QTDE_DISPONIVEL_BAIXA",
            'rota': "COALESCE(e.ROTA, '-')",
            'endereco': "COALESCE(ec.COD_ENDERECO, '-')",
            'estagio': "coalesce(l.CODIGO_ESTAGIO, 999)"
        }

    def condicao_valor(self, ref):
        if len(ref.split()) == 2:
            condicao = ref.split()[0]
            ref = str(ref.split()[1])
        else:
            condicao = '='
        return condicao, ref

    def sql(self):
        filter_ref = ''
        ref_conds = []
        ref_in = []
        if isinstance(self.ref, str):
            self.ref = map(
                str.strip,
                self.ref.split(','),
            )
        if self.ref is not None:  # iterable
            for r in self.ref:
                condicao, valor = self.condicao_valor(r)
                if condicao == '=':
                    ref_in.append(valor)
                else:
                    ref_conds.append(f"l.PROCONF_GRUPO {condicao} '{valor}'")
        if ref_in:
            refs = ', '.join([f"'{r}'" for r in ref_in])
            ref_conds.append(f"l.PROCONF_GRUPO in ({refs})")
        if ref_conds:
            filters_ref = " AND ".join(ref_conds)
            filter_ref = f"AND {filters_ref}"

        join_para_colecao = ""
        filter_colecao = ""
        if self.colecao is not None:
            join_para_colecao = """
                JOIN BASI_030 r
                  ON r.NIVEL_ESTRUTURA = 1
                 AND r.REFERENCIA = l.PROCONF_GRUPO
            """
            filter_colecao = f"AND r.COLECAO = '{self.colecao}'"

        filter_lote = ""
        if self.lote is not None:
            filter_lote = f"AND lp.ORDEM_CONFECCAO = '{self.lote}'"

        filter_endereco = ""
        if self.endereco is not None:
            filter_endereco = f"AND ec.COD_ENDERECO = '{self.endereco}'"

        self.fields_tuple = self.fields_tuple if self.fields_tuple else []
        fields_set = {'ref'}.union(self.fields_tuple)

        distinct = False
        if self.get == 'ref':
            distinct = True
        elif self.get == 'lote_qtd':
            fields_set = fields_set.union([
                'per',
                'oc',
                'tam',
                'ordem_tam',
                'cor',
                'op',
                'qtd_prog',
                'qtd_dbaixa',
            ])

        filtra_estagio = "AND l.CODIGO_ESTAGIO = 63"
        if self.tipo == 'p':
            field_qtd = f"""--
                , {self.sinal}l.QTDE_DISPONIVEL_BAIXA qtd
            """
            tipo_join = """--
                JOIN PCPC_020 op
                  ON op.ORDEM_PRODUCAO = lp.ORDEM_PRODUCAO
            """
            tipo_filter = """--
                AND op.PEDIDO_VENDA <> 0
                AND l.QTDE_DISPONIVEL_BAIXA > 0
            """
        elif self.tipo == 's':
            field_qtd = f"""--
                , {self.sinal}sl.QTDE qtd
            """
            tipo_join = """--
                JOIN PCPC_044 sl
                  ON sl.ORDEM_PRODUCAO = lp.ORDEM_PRODUCAO
                 AND sl.ORDEM_CONFECCAO = MOD(lp.ORDEM_CONFECCAO, 100000)
            """
            tipo_filter = """--
                AND sl.SITUACAO IN (2, 3, 4)
            """
        elif self.tipo and self.tipo.startswith('i'):
            field_qtd = f"""--
                , {self.sinal}l.QTDE_DISPONIVEL_BAIXA qtd
            """
            tipo_join = ""
            tipo_filter = """--
                AND l.QTDE_DISPONIVEL_BAIXA > 0
            """
            if 'q' in self.tipo:
                filtra_estagio = ''
        else:
            field_qtd = ""
            tipo_join = ""
            tipo_filter = """--
                AND l.QTDE_DISPONIVEL_BAIXA > 0
            """

        fields = "\n, ".join(
            [
                f"{self.available_fields[field.split()[0]]} {field.split()[-1]}"
                for field in fields_set
            ]
        )

        sql = f"""
            SELECT {"DISTINCT" if distinct else ""}
            {fields} -- fields
            {field_qtd} -- field_qtd
            FROM ENDR_014 lp
            JOIN PCPC_040 l
              ON l.ORDEM_PRODUCAO = lp.ORDEM_PRODUCAO
             AND l.ORDEM_CONFECCAO = MOD(lp.ORDEM_CONFECCAO, 100000)
            LEFT JOIN ENDR_015 ec -- endereço/container
              ON ec.COD_CONTAINER = lp.COD_CONTAINER
            LEFT JOIN ENDR_013 e -- endereço
              ON e.COD_ENDERECO = ec.COD_ENDERECO
            {tipo_join} -- tipo_join
            {join_para_colecao} -- join_para_colecao
            LEFT JOIN BASI_220 tam -- cadastro de tamanhos
              ON tam.TAMANHO_REF = l.PROCONF_SUBGRUPO
            WHERE 1=1
            {filtra_estagio} -- filtra_estagio
            {tipo_filter} -- tipo_filter
            {filter_ref} -- filter_ref
            {filter_colecao} -- filter_colecao
            {filter_lote} -- filter_lote
            {filter_endereco} -- filter_endereco
        """
        return sql
<commit_msg>view NovoEstoque se nada selecionado, retorna<commit_after>from pprint import pprint

from utils.functions.models import dictlist
from utils.functions.queries import debug_cursor_execute
from utils.functions.strings import only_digits

class LotesEmEstoque():

    def __init__(
        self,
        cursor,
        tipo=None,
        ref=None,
        get=None,
        colecao=None,
        modelo=None,
        fields_tuple=None,
        lote=None,
        endereco=None,
    ):
        self.cursor = cursor
        self.tipo = tipo
        self.ref = ref
        self.get = get
        self.colecao = colecao
        self.modelo = modelo
        self.fields_tuple = fields_tuple
        self.lote = lote
        self.endereco = endereco

        self.sql_em_stq = SqlEmEstoque(
            tipo=self.tipo,
            ref=self.ref,
            get=self.get,
            colecao=self.colecao,
            fields_tuple=self.fields_tuple,
            lote=self.lote,
            endereco=self.endereco,
        )

    def dados(self):
        sql = self.sql_em_stq.sql()

        debug_cursor_execute(self.cursor, sql)
        dados = dictlist(self.cursor)

        if self.modelo:
            dados_modelo = []
        for row in dados:
            try:
                ref_modelo = int(only_digits(row['ref']))
            except ValueError:
                ref_modelo = 0
            row['modelo'] = ref_modelo
            if ref_modelo == self.modelo:
                dados_modelo.append(row)
        if self.modelo:
            return dados_modelo
        else:
            return dados

class SqlEmEstoque():
    """Monta SQL base de selecão de lotes
    - endereçados; e
    - no estágio 63
    Recebe:
    tipo
        i = inventário: todos os lotes endereçados e com quantidade no estágio 63
        p = lotes que aparece no inventário (opção acima) e são de OPs de Pedidos
        s = solicitado (situação 2, 3 ou 4) de OP com estágio 63
        iq = inventário: todos os lotes endereçados e com quantidade em qq estágio
        None = todos os lotes
    ref: filtro de referências, caso não None
        iterable = uma lista de cond_expr
        string = cond_expr[, cond_expr]
            É transformada em uma lista de cond_expr
        Obs.:
            cond_expr = [condição] valor = filtro de uma referência
            condição: altera o funcionamento do filtro
                None = igualdade
                Várias condições válidas no SQL como '<', '>', '>='...
    get
        ref = busca apenas o campo referência (com distinct)
        None = busca apenas o campo referência (sem distinct)
        lote_qtd = busca op, lote, item e quantidades
        # loc = busca op, lote, item, quantidades e informação de endereçamento
    sinal: positivo ou negativo
        '+' = quantidades como estão no banco de dados
        '-' = inverte o sinal das quantidades
    fields_tuple
        Lista de fields que devem ser retornados
        Field pode ter alias a ser utilizado. Ex.: "qtd quanti"
        obs.: ref sempre é retornado
    """

    def __init__(
        self,
        tipo=None,
        ref=None,
        get=None,
        colecao=None,
        sinal='+',
        fields_tuple=None,
        lote=None,
        endereco=None,
    ):
        self.tipo = tipo
        self.ref = ref
        self.get = get
        self.colecao = colecao
        self.sinal = sinal
        self.fields_tuple = fields_tuple
        self.lote = lote
        self.endereco = endereco

        self.available_fields = {
            'ref': "l.PROCONF_GRUPO",
            'per': "l.PERIODO_PRODUCAO",
            'oc': "l.ORDEM_CONFECCAO",
            'lote': "lp.ORDEM_CONFECCAO",
            'palete': """--
                CASE
                  WHEN lp.COD_CONTAINER IS NOT NULL
                   AND lp.COD_CONTAINER <> '0'
                  THEN lp.COD_CONTAINER
                  ELSE '-'
                END
            """,
            'tam': "l.PROCONF_SUBGRUPO",
            'ordem_tam': "tam.ORDEM_TAMANHO",
            'cor': "l.PROCONF_ITEM",
            'op': "l.ORDEM_PRODUCAO",
            'qtd_prog': "l.QTDE_PECAS_PROG",
            'qtd_dbaixa': "l.QTDE_DISPONIVEL_BAIXA",
            'rota': "COALESCE(e.ROTA, '-')",
            'endereco': "COALESCE(ec.COD_ENDERECO, '-')",
            'estagio': "coalesce(l.CODIGO_ESTAGIO, 999)",
            'solicitacoes': """--
                ( select
                  pcpc_044 sl -- solicitação / lote

            """
        }

    def condicao_valor(self, ref):
        if len(ref.split()) == 2:
            condicao = ref.split()[0]
            ref = str(ref.split()[1])
        else:
            condicao = '='
        return condicao, ref

    def sql(self):
        filter_ref = ''
        ref_conds = []
        ref_in = []
        if isinstance(self.ref, str):
            self.ref = map(
                str.strip,
                self.ref.split(','),
            )
        if self.ref is not None:  # iterable
            for r in self.ref:
                condicao, valor = self.condicao_valor(r)
                if condicao == '=':
                    ref_in.append(valor)
                else:
                    ref_conds.append(f"l.PROCONF_GRUPO {condicao} '{valor}'")
        if ref_in:
            refs = ', '.join([f"'{r}'" for r in ref_in])
            ref_conds.append(f"l.PROCONF_GRUPO in ({refs})")
        if ref_conds:
            filters_ref = " AND ".join(ref_conds)
            filter_ref = f"AND {filters_ref}"

        join_para_colecao = ""
        filter_colecao = ""
        if self.colecao is not None:
            join_para_colecao = """
                JOIN BASI_030 r
                  ON r.NIVEL_ESTRUTURA = 1
                 AND r.REFERENCIA = l.PROCONF_GRUPO
            """
            filter_colecao = f"AND r.COLECAO = '{self.colecao}'"

        filter_lote = ""
        if self.lote is not None:
            filter_lote = f"AND lp.ORDEM_CONFECCAO = '{self.lote}'"

        filter_endereco = ""
        if self.endereco is not None:
            filter_endereco = f"AND ec.COD_ENDERECO = '{self.endereco}'"

        self.fields_tuple = self.fields_tuple if self.fields_tuple else []
        fields_set = {'ref'}.union(self.fields_tuple)

        distinct = False
        if self.get == 'ref':
            distinct = True
        elif self.get == 'lote_qtd':
            fields_set = fields_set.union([
                'per',
                'oc',
                'tam',
                'ordem_tam',
                'cor',
                'op',
                'qtd_prog',
                'qtd_dbaixa',
            ])

        filtra_estagio = "AND l.CODIGO_ESTAGIO = 63"
        if self.tipo == 'p':
            field_qtd = f"""--
                , {self.sinal}l.QTDE_DISPONIVEL_BAIXA qtd
            """
            tipo_join = """--
                JOIN PCPC_020 op
                  ON op.ORDEM_PRODUCAO = lp.ORDEM_PRODUCAO
            """
            tipo_filter = """--
                AND op.PEDIDO_VENDA <> 0
                AND l.QTDE_DISPONIVEL_BAIXA > 0
            """
        elif self.tipo == 's':
            field_qtd = f"""--
                , {self.sinal}sl.QTDE qtd
            """
            tipo_join = """--
                JOIN PCPC_044 sl
                  ON sl.ORDEM_PRODUCAO = lp.ORDEM_PRODUCAO
                 AND sl.ORDEM_CONFECCAO = MOD(lp.ORDEM_CONFECCAO, 100000)
            """
            tipo_filter = """--
                AND sl.SITUACAO IN (2, 3, 4)
            """
        elif self.tipo and self.tipo.startswith('i'):
            field_qtd = f"""--
                , {self.sinal}l.QTDE_DISPONIVEL_BAIXA qtd
            """
            tipo_join = ""
            tipo_filter = """--
                AND l.QTDE_DISPONIVEL_BAIXA > 0
            """
            if 'q' in self.tipo:
                filtra_estagio = ''
        else:
            field_qtd = ""
            tipo_join = ""
            tipo_filter = """--
                AND l.QTDE_DISPONIVEL_BAIXA > 0
            """

        fields = "\n, ".join(
            [
                f"{self.available_fields[field.split()[0]]} {field.split()[-1]}"
                for field in fields_set
            ]
        )

        sql = f"""
            SELECT {"DISTINCT" if distinct else ""}
            {fields} -- fields
            {field_qtd} -- field_qtd
            FROM ENDR_014 lp
            JOIN PCPC_040 l
              ON l.ORDEM_PRODUCAO = lp.ORDEM_PRODUCAO
             AND l.ORDEM_CONFECCAO = MOD(lp.ORDEM_CONFECCAO, 100000)
            LEFT JOIN ENDR_015 ec -- endereço/container
              ON ec.COD_CONTAINER = lp.COD_CONTAINER
            LEFT JOIN ENDR_013 e -- endereço
              ON e.COD_ENDERECO = ec.COD_ENDERECO
            {tipo_join} -- tipo_join
            {join_para_colecao} -- join_para_colecao
            LEFT JOIN BASI_220 tam -- cadastro de tamanhos
              ON tam.TAMANHO_REF = l.PROCONF_SUBGRUPO
            WHERE 1=1
            {filtra_estagio} -- filtra_estagio
            {tipo_filter} -- tipo_filter
            {filter_ref} -- filter_ref
            {filter_colecao} -- filter_colecao
            {filter_lote} -- filter_lote
            {filter_endereco} -- filter_endereco
        """
        return sql
<|endoftext|>


<commit_before>from simpleabc import simple_abc
import simple_model
import numpy as np
import pickle
from scipy import stats
import time
import sys

name = sys.argv[1]
steps = int(sys.argv[2])
start_step = int(sys.argv[3])
min_part = int(sys.argv[4])
n_procs = int(sys.argv[5])
known = sys.argv[6]
osamp_num = int(sys.argv[7])
job_particles = int(sys.argv[8])

#print known, type(known)

if known == "True":
    known = True
else:
    known = False
#print known, type(known)

stars = pickle.load(file('stars.pkl'))

model = simple_model.MyModel(stars)

if known:
    obs = pickle.load(file('RUNS/{0}/KNOWN/obs_data.pkl'.format(name), 'r'))

else:
    obs = pickle.load(file('RUNS/{0}/SCIENCE/obs_data.pkl'.format(name), 'r'))

model.set_prior([stats.uniform(0, 90.0),
                 stats.uniform(0, 1),
                 stats.uniform(0, 20)])

model.set_data(obs)

start = time.time()

if known:
    PT = pickle.load(file(
                'RUNS/{0}/KNOWN/{0}_{1}samples_{2}.pkl'.format(name, min_part,
                start_step), 'r'))
else:
    PT = pickle.load(file(
                'RUNS/{0}/SCIENCE/{0}_{1}samples_{2}.pkl'.format(name, min_part,
                start_step),'r'))

OT = simple_abc.pmc_abc(model, obs, epsilon_0=1, min_samples=job_particles,
                    resume=PT, steps=1, parallel=False, n_procs=n_procs,
                    sample_only=True)
if known:
    out_pickle = file(
        'RUNS/{0}/KNOWN/{0}_{1}_oversample{3}_{2}.pkl'.format(name, min_part, osamp_num, start_step+1),
        'w')
else:
    out_pickle = file(
        'RUNS/{0}/SCIENCE/{0}_{1}_oversamples{3}_{2}.pkl'.format(name, min_part, osamp_num, start_step+1),
        'w')

pickle.dump(OT, out_pickle)
out_pickle.close()

end = time.time()
print 'This run took {}s'.format(end - start)
<commit_msg>Updare prior<commit_after>from simpleabc import simple_abc
import simple_model
import numpy as np
import pickle
from scipy import stats
import time
import sys

name = sys.argv[1]
steps = int(sys.argv[2])
start_step = int(sys.argv[3])
min_part = int(sys.argv[4])
n_procs = int(sys.argv[5])
known = sys.argv[6]
osamp_num = int(sys.argv[7])
job_particles = int(sys.argv[8])

#print known, type(known)

if known == "True":
    known = True
else:
    known = False
#print known, type(known)

stars = pickle.load(file('stars.pkl'))

model = simple_model.MyModel(stars)

if known:
    obs = pickle.load(file('RUNS/{0}/KNOWN/obs_data.pkl'.format(name), 'r'))

else:
    obs = pickle.load(file('RUNS/{0}/SCIENCE/obs_data.pkl'.format(name), 'r'))

model.set_prior([stats.uniform(0, 90.0),
                 stats.uniform(0, 10),
                 stats.uniform(0, 20),
                 stats.uniform(0, 1)])

model.set_data(obs)

start = time.time()

if known:
    PT = pickle.load(file(
                'RUNS/{0}/KNOWN/{0}_{1}samples_{2}.pkl'.format(name, min_part,
                start_step), 'r'))
else:
    PT = pickle.load(file(
                'RUNS/{0}/SCIENCE/{0}_{1}samples_{2}.pkl'.format(name, min_part,
                start_step),'r'))

OT = simple_abc.pmc_abc(model, obs, epsilon_0=1, min_samples=job_particles,
                    resume=PT, steps=1, parallel=False, n_procs=n_procs,
                    sample_only=True)
if known:
    out_pickle = file(
        'RUNS/{0}/KNOWN/{0}_{1}_oversample{3}_{2}.pkl'.format(name, min_part, osamp_num, start_step+1),
        'w')
else:
    out_pickle = file(
        'RUNS/{0}/SCIENCE/{0}_{1}_oversamples{3}_{2}.pkl'.format(name, min_part, osamp_num, start_step+1),
        'w')

pickle.dump(OT, out_pickle)
out_pickle.close()

end = time.time()
print 'This run took {}s'.format(end - start)
<|endoftext|>


<commit_before># encoding: utf-8

from datetime import datetime

__author__ = "Tsuyoshi Hombashi"
__copyright__ = "Copyright 2016-{}, {}".format(datetime.now().year, __author__)
__license__ = "MIT License"
__version__ = "0.38.0"
__maintainer__ = __author__
__email__ = "tsuyoshi.hombashi@gmail.com"
<commit_msg>Bump version<commit_after># encoding: utf-8

from datetime import datetime

__author__ = "Tsuyoshi Hombashi"
__copyright__ = "Copyright 2016-{}, {}".format(datetime.now().year, __author__)
__license__ = "MIT License"
__version__ = "0.39.0"
__maintainer__ = __author__
__email__ = "tsuyoshi.hombashi@gmail.com"
<|endoftext|>


<commit_before>from django.conf import settings
from restclients.pws import PWS
from restclients.gws import GWS
from restclients.models.canvas import CanvasUser
from restclients.exceptions import DataFailureException, InvalidGroupID
from sis_provisioner.exceptions import UserPolicyException,\
    MissingLoginIdException, TemporaryNetidException, InvalidLoginIdException
from nameparser import HumanName
import re

RE_ADMIN_NETID = re.compile(r"^[a-z]adm_[a-z][a-z0-9]{0,7}$", re.I)
RE_APPLICATION_NETID = re.compile(r"^a_[\w]{1,18}$", re.I)
RE_TEMPORARY_NETID = re.compile(r"^(?:css|wire|lib|event)[0-9]{4,}$", re.I)
RE_CANVAS_ID = re.compile(r"^\d+$")

def is_group_member(group_id, login_id):
    return GWS().is_effective_member(group_id, login_id)

def valid_net_id(login_id):
    if not login_id:
        raise MissingLoginIdException('Missing UWNetID')

    if RE_TEMPORARY_NETID.match(login_id):
        raise TemporaryNetidException('Temporary UWNetID not permitted')

    if not PWS().valid_uwnetid(login_id):
        raise InvalidLoginIdException('Not a valid UWNetID')

def valid_admin_net_id(login_id):
    if RE_ADMIN_NETID.match(login_id) is None:
        raise InvalidLoginIdException('Not a valid Admin UWNetID')

def valid_application_net_id(login_id):
    if RE_APPLICATION_NETID.match(login_id) is None:
        raise InvalidLoginIdException('Not a valid Application UWNetID')

def valid_nonpersonal_net_id(netid):
    try:
        valid_admin_net_id(netid)
    except UserPolicyException:
        try:
            valid_application_net_id(netid)
        except InvalidLoginIdException:
            group = getattr(settings, 'NONPERSONAL_NETID_EXCEPTION_GROUP', '')
            try:
                if not is_group_member(group, netid):
                    raise InvalidLoginIdException('UWNetID not permitted')
            except InvalidGroupID:
                raise InvalidLoginIdException('UWNetID not permitted')

def valid_reg_id(regid):
    if not PWS().valid_uwregid(regid):
        raise InvalidLoginIdException('UWNetID not permitted')

def valid_gmail_id(login_id):
    try:
        (username, domain) = login_id.lower().split("@")
        username = username.split("+", 1)[0].replace(".", "")
        if not len(username):
            raise InvalidLoginIdException("Invalid username: %s" % login_id)
    except:
        raise InvalidLoginIdException("Invalid username: %s" % login_id)

    if domain not in getattr(settings, 'LOGIN_DOMAIN_WHITELIST', []):
        raise InvalidLoginIdException("Invalid domain: %s" % login_id)

    return "%s@%s" % (username, domain)

def valid_canvas_user_id(canvas_id):
    if (RE_CANVAS_ID.match(str(canvas_id)) is None):
        raise UserPolicyException("Invalid Canvas ID: %s" % canvas_id)

def user_sis_id(user):
    return user.uwregid if hasattr(user, 'uwregid') else user.sis_user_id

def user_email(user):
    if hasattr(user, 'uwnetid'):
        return '%s@uw.edu' % user.uwnetid
    elif hasattr(user, 'email'):
        return user.email  # CanvasUser
    else:
        raise UserPolicyException('Invalid user')

def user_fullname(user):
    if hasattr(user, 'display_name'):
        if ((user.display_name is None or not len(user.display_name) or
                user.display_name.isupper()) and hasattr(user, 'first_name')):
            fullname = HumanName('%s %s' % (user.first_name, user.surname))
            fullname.capitalize()
            fullname.string_format = '{first} {last}'
            return fullname
        else:
            return user.display_name
    elif hasattr(user, 'email'):
        return user.email.split('@')[0]  # CanvasUser
    else:
        raise UserPolicyException('Invalid user')

def get_person_by_netid(netid):
    pws = PWS()
    try:
        valid_net_id(netid)
        person = pws.get_person_by_netid(netid)

    except DataFailureException, err:
        if err.status == 404:  # Non-personal netid?
            valid_nonpersonal_net_id(netid)
            person = pws.get_entity_by_netid(netid)
        else:
            raise

    return person

def get_person_by_regid(regid):
    pws = PWS()
    try:
        person = pws.get_person_by_regid(regid)
        valid_net_id(person.uwnetid)

    except DataFailureException, err:
        if err.status == 404:  # Non-personal regid?
            person = pws.get_entity_by_regid(regid)
            valid_nonpersonal_net_id(person.netid)
        else:
            raise

    return person

def get_person_by_gmail_id(gmail_id):
    return CanvasUser(sis_user_id=valid_gmail_id(gmail_id),
                      login_id=gmail_id.lower(),
                      email=gmail_id)
<commit_msg>return fullname as str<commit_after>from django.conf import settings
from restclients.pws import PWS
from restclients.gws import GWS
from restclients.models.canvas import CanvasUser
from restclients.exceptions import DataFailureException, InvalidGroupID
from sis_provisioner.exceptions import UserPolicyException,\
    MissingLoginIdException, TemporaryNetidException, InvalidLoginIdException
from nameparser import HumanName
import re

RE_ADMIN_NETID = re.compile(r"^[a-z]adm_[a-z][a-z0-9]{0,7}$", re.I)
RE_APPLICATION_NETID = re.compile(r"^a_[\w]{1,18}$", re.I)
RE_TEMPORARY_NETID = re.compile(r"^(?:css|wire|lib|event)[0-9]{4,}$", re.I)
RE_CANVAS_ID = re.compile(r"^\d+$")

def is_group_member(group_id, login_id):
    return GWS().is_effective_member(group_id, login_id)

def valid_net_id(login_id):
    if not login_id:
        raise MissingLoginIdException('Missing UWNetID')

    if RE_TEMPORARY_NETID.match(login_id):
        raise TemporaryNetidException('Temporary UWNetID not permitted')

    if not PWS().valid_uwnetid(login_id):
        raise InvalidLoginIdException('Not a valid UWNetID')

def valid_admin_net_id(login_id):
    if RE_ADMIN_NETID.match(login_id) is None:
        raise InvalidLoginIdException('Not a valid Admin UWNetID')

def valid_application_net_id(login_id):
    if RE_APPLICATION_NETID.match(login_id) is None:
        raise InvalidLoginIdException('Not a valid Application UWNetID')

def valid_nonpersonal_net_id(netid):
    try:
        valid_admin_net_id(netid)
    except UserPolicyException:
        try:
            valid_application_net_id(netid)
        except InvalidLoginIdException:
            group = getattr(settings, 'NONPERSONAL_NETID_EXCEPTION_GROUP', '')
            try:
                if not is_group_member(group, netid):
                    raise InvalidLoginIdException('UWNetID not permitted')
            except InvalidGroupID:
                raise InvalidLoginIdException('UWNetID not permitted')

def valid_reg_id(regid):
    if not PWS().valid_uwregid(regid):
        raise InvalidLoginIdException('UWNetID not permitted')

def valid_gmail_id(login_id):
    try:
        (username, domain) = login_id.lower().split("@")
        username = username.split("+", 1)[0].replace(".", "")
        if not len(username):
            raise InvalidLoginIdException("Invalid username: %s" % login_id)
    except:
        raise InvalidLoginIdException("Invalid username: %s" % login_id)

    if domain not in getattr(settings, 'LOGIN_DOMAIN_WHITELIST', []):
        raise InvalidLoginIdException("Invalid domain: %s" % login_id)

    return "%s@%s" % (username, domain)

def valid_canvas_user_id(canvas_id):
    if (RE_CANVAS_ID.match(str(canvas_id)) is None):
        raise UserPolicyException("Invalid Canvas ID: %s" % canvas_id)

def user_sis_id(user):
    return user.uwregid if hasattr(user, 'uwregid') else user.sis_user_id

def user_email(user):
    if hasattr(user, 'uwnetid'):
        return '%s@uw.edu' % user.uwnetid
    elif hasattr(user, 'email'):
        return user.email  # CanvasUser
    else:
        raise UserPolicyException('Invalid user')

def user_fullname(user):
    if hasattr(user, 'display_name'):
        if ((user.display_name is None or not len(user.display_name) or
                user.display_name.isupper()) and hasattr(user, 'first_name')):
            fullname = HumanName('%s %s' % (user.first_name, user.surname))
            fullname.capitalize()
            fullname.string_format = '{first} {last}'
            return str(fullname)
        else:
            return user.display_name
    elif hasattr(user, 'email'):
        return user.email.split('@')[0]  # CanvasUser
    else:
        raise UserPolicyException('Invalid user')

def get_person_by_netid(netid):
    pws = PWS()
    try:
        valid_net_id(netid)
        person = pws.get_person_by_netid(netid)

    except DataFailureException, err:
        if err.status == 404:  # Non-personal netid?
            valid_nonpersonal_net_id(netid)
            person = pws.get_entity_by_netid(netid)
        else:
            raise

    return person

def get_person_by_regid(regid):
    pws = PWS()
    try:
        person = pws.get_person_by_regid(regid)
        valid_net_id(person.uwnetid)

    except DataFailureException, err:
        if err.status == 404:  # Non-personal regid?
            person = pws.get_entity_by_regid(regid)
            valid_nonpersonal_net_id(person.netid)
        else:
            raise

    return person

def get_person_by_gmail_id(gmail_id):
    return CanvasUser(sis_user_id=valid_gmail_id(gmail_id),
                      login_id=gmail_id.lower(),
                      email=gmail_id)
<|endoftext|>


<commit_before>import os
import base64
from flask import Flask , request, render_template
import nbconvert.nbconvert as nbconvert
import requests
from nbformat import current as nbformat
from flask import Flask, redirect, abort
from flaskext.cache import Cache
import re
import github as gh
from gist import render_content

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'null'
app.config['CACHE_MEMCACHED_SERVERS'] = os.environ.get('MEMCACHE_SERVERS') or ['127.0.0.1']
    #os.environ.get('MEMCACHE_USERNAME')
    #os.environ.get('MEMCACHE_PASSWORD')
cache = Cache(app)
github = gh.Github()

#@cache.cached(50)
def full_url(user,repo=None, blob=None, branch=None, subpath=None):
    if not subpath and (not branch or branch=='master') :
        return '/%(user)s/%(repo)s/' % {'user':user,\
         'repo':repo}

    string = '/%(user)s/%(repo)s/%(blob)s/%(branch)s/%(subpath)s' % \
        {'user':user,\
         'repo':repo,\
         'blob':blob,\
         'branch':branch,\
         'subpath':subpath}
    sp = string.replace('//','/')

    return sp

@app.route('/')
#@cache.cached(50)
def render_url():
    return 'you are at root'

#@app.route('/<user>/')
#def user(user):
#    return github.get_user(user).name

@app.route('/<user>/<repo>/')
@cache.cached(500)
def repo(user,repo):
    return file(user, repo, 'tree','master', None )
    #return redirect('/%(user)s/%(repo)s/tree/master/'%{'user':user, 'repo':repo})

@app.route('/<user>/<repo>/<tree>/<branch>/')
@cache.cached(500)
def dummy1(user,repo,tree,branch):
    if user == 'static':
        return app.send_static_file('%s/%s/%s'%(repo,tree,branch))
        #return open('static/%s/%s/%s'%(repo,tree,branch)).read()
    return browse_tree_blob(user,repo,tree,branch,None)

#@app.route('/<user>/<repo>/tree/<branch>/<path:subfile>')
def bowse_tree(user,repo,branch,subfile, parent=None):
    pass

#@app.route('/<user>/<repo>/blob/<branch>/<path:subfile>')
def show_blob(user,repo,branch,subfile):
    pass

#@app.route('/<user>/<repo>/branches')
def browse_branches(user,repo):
    pass

@app.route('/<usern>/<repon>/<tree>/<branchn>/<path:subfile>')
@cache.cached(500)
def browse_tree_blob(usern,repon,tree,branchn, subfile):
    if (not subfile) and (branchn == 'master'):
        return redirect('/%s/%s/'%(usern,repon))
    print("================")
    print(usern,repon,tree,branchn, subfile)
    print("================")
    return file(usern,repon,tree,branchn, subfile)

def file(usern,repon,tree,branchn, subfile):
    #we don't care about tree or branch now...

    #convert names to objects
    user = github.get_user(usern)
    repo = user.get_repo(repon)

    master = branchn if branchn else repo.master_branch

    #if not subfile and branchn == repo.master_branch :
        #return redirect(full_url(usern, repon))

    branch = [b for b in repo.get_branches() if b.name == master][0]

    if subfile:
        atroot = False
        e = rwt(repo, branch.commit.sha, subfile.strip('/').split('/'))
    else :
        atroot = True
        e = repo.get_git_tree(branch.commit.sha);
        subfile = ''

    if hasattr(e,'type') and e.type == 'blob' :
        f = repo.get_git_blob(e.sha)
        return render_content(base64.decodestring(f.content))
    else :
        entries = []
        for en in e.tree:
            var = {}
            var['path'] = en.path
            var['type'] = type_for_tree(en)
            var['class']= class_for_tree(en)
            var['url']  = full_url(usern,repon,var['type'],branchn,subfile+'/'+relative_url_for_tree(en))
            entries.append(var)
        return render_template('treelist.html', entries=entries, atroot=atroot)

def relative_url_for_tree(obj):
    if hasattr(obj, 'type') and obj.type == 'blob' :
        return obj.path
    else :
        return obj.path+'/'

def type_for_tree(obj):
    if hasattr(obj, 'type') and obj.type == 'blob' :
        return 'blob'
    else :
        return 'tree'

def class_for_tree(obj):
    if hasattr(obj, 'type') and obj.type == 'blob' :
        return 'icon-file'
    else :
        return 'icon-folder-open'
#recursively walk tree....
def rwt(repo,sha,path):
    tree = repo.get_git_tree(sha)
    if len(path)==0:
        return tree
    subpath = path[1:]
    key = path[0]
    nodes = tree.tree
    for n in nodes :
        if n.path == key:
            if n.type == 'tree':
                return rwt(repo, n.sha, subpath)
            else :
                return n

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    debug = os.path.exists('.debug')
    if debug :
        print 'DEBUG MODE IS ACTIVATED !!!'
    else :
        print 'debug is not activated'
    app.run(host='0.0.0.0', port=port, debug=debug)
<commit_msg>add ability to browse an user/organisation list of project<commit_after>import os
import base64
from flask import Flask , request, render_template
import nbconvert.nbconvert as nbconvert
import requests
from nbformat import current as nbformat
from flask import Flask, redirect, abort
from flaskext.cache import Cache
import re
import github as gh
from gist import render_content

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'null'
app.config['CACHE_MEMCACHED_SERVERS'] = os.environ.get('MEMCACHE_SERVERS') or ['127.0.0.1']
    #os.environ.get('MEMCACHE_USERNAME')
    #os.environ.get('MEMCACHE_PASSWORD')
cache = Cache(app)
github = gh.Github()

#@cache.cached(50)
def full_url(user,repo=None, blob=None, branch=None, subpath=None):
    if not subpath and (not branch or branch=='master') :
        return '/%(user)s/%(repo)s/' % {'user':user,\
         'repo':repo}

    string = '/%(user)s/%(repo)s/%(blob)s/%(branch)s/%(subpath)s' % \
        {'user':user,\
         'repo':repo,\
         'blob':blob,\
         'branch':branch,\
         'subpath':subpath}
    sp = string.replace('//','/')

    return sp

@app.route('/')
#@cache.cached(50)
def render_url():
    return 'you are at root'

@app.route('/<user>/')
def user(user):
    rs = github.get_user(user).get_repos();
    l = [];
    for r in rs :
        var = {}
        var['url'] = r.name+'/'
        var['name'] = r.name
        l.append(var)
    return render_template('userview.html', entries=l)

@app.route('/<user>/<repo>/')
@cache.cached(500)
def repo(user,repo):
    return file(user, repo, 'tree','master', None )
    #return redirect('/%(user)s/%(repo)s/tree/master/'%{'user':user, 'repo':repo})

@app.route('/<user>/<repo>/<tree>/<branch>/')
@cache.cached(500)
def dummy1(user,repo,tree,branch):
    if user == 'static':
        return app.send_static_file('%s/%s/%s'%(repo,tree,branch))
        #return open('static/%s/%s/%s'%(repo,tree,branch)).read()
    return browse_tree_blob(user,repo,tree,branch,None)

#@app.route('/<user>/<repo>/tree/<branch>/<path:subfile>')
def bowse_tree(user,repo,branch,subfile, parent=None):
    pass

#@app.route('/<user>/<repo>/blob/<branch>/<path:subfile>')
def show_blob(user,repo,branch,subfile):
    pass

#@app.route('/<user>/<repo>/branches')
def browse_branches(user,repo):
    pass

@app.route('/<usern>/<repon>/<tree>/<branchn>/<path:subfile>')
@cache.cached(500)
def browse_tree_blob(usern,repon,tree,branchn, subfile):
    if (not subfile) and (branchn == 'master'):
        return redirect('/%s/%s/'%(usern,repon))
    print("================")
    print(usern,repon,tree,branchn, subfile)
    print("================")
    return file(usern,repon,tree,branchn, subfile)

def file(usern,repon,tree,branchn, subfile):
    #we don't care about tree or branch now...

    #convert names to objects
    user = github.get_user(usern)
    repo = user.get_repo(repon)

    master = branchn if branchn else repo.master_branch

    #if not subfile and branchn == repo.master_branch :
        #return redirect(full_url(usern, repon))

    branch = [b for b in repo.get_branches() if b.name == master][0]

    if subfile:
        atroot = False
        e = rwt(repo, branch.commit.sha, subfile.strip('/').split('/'))
    else :
        atroot = True
        e = repo.get_git_tree(branch.commit.sha);
        subfile = ''

    if hasattr(e,'type') and e.type == 'blob' :
        f = repo.get_git_blob(e.sha)
        return render_content(base64.decodestring(f.content))
    else :
        entries = []
        for en in e.tree:
            var = {}
            var['path'] = en.path
            var['type'] = type_for_tree(en)
            var['class']= class_for_tree(en)
            var['url']  = full_url(usern,repon,var['type'],branchn,subfile+'/'+relative_url_for_tree(en))
            entries.append(var)
        return render_template('treelist.html', entries=entries, atroot=atroot)

def relative_url_for_tree(obj):
    if hasattr(obj, 'type') and obj.type == 'blob' :
        return obj.path
    else :
        return obj.path+'/'

def type_for_tree(obj):
    if hasattr(obj, 'type') and obj.type == 'blob' :
        return 'blob'
    else :
        return 'tree'

def class_for_tree(obj):
    if hasattr(obj, 'type') and obj.type == 'blob' :
        return 'icon-file'
    else :
        return 'icon-folder-open'
#recursively walk tree....
def rwt(repo,sha,path):
    tree = repo.get_git_tree(sha)
    if len(path)==0:
        return tree
    subpath = path[1:]
    key = path[0]
    nodes = tree.tree
    for n in nodes :
        if n.path == key:
            if n.type == 'tree':
                return rwt(repo, n.sha, subpath)
            else :
                return n

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    debug = os.path.exists('.debug')
    if debug :
        print 'DEBUG MODE IS ACTIVATED !!!'
    else :
        print 'debug is not activated'
    app.run(host='0.0.0.0', port=port, debug=debug)
<|endoftext|>


<commit_before>import sys, os, urllib.request, re
from enum import Enum

name_gitignore = '.gitignore'
ext_gitignore = name_gitignore
file_gitignore = None

junk_lines = []
gitignores = dict()

class Option(Enum):
    NONE = 0
    UNKNOWN = 1
    ADD = 2
    CREATE = 3
    REMOVE = 4
    UPDATE = 5
    CLEAR = 6

def main(argc, argv):
    option = get_option(argc, argv)
    if option == Option.NONE:
        sys.exit('no argument provided')
    elif option == Option.UNKNOWN:
        sys.exit('unknown option "%s"' % argv[1])
    elif not valid_argc(argc, option):
        sys.exit('invalid number of arguments for "%s"' % argv[1])
    elif not check_file_gitignore(option):
        sys.exit('no %s file found' % name_gitignore)

    global file_gitignore

    if option == Option.ADD:
        [add(name) for name in argv[2:]]
    elif option == Option.CREATE:
        if argc == 2:
            file_gitignore = open(name_gitignore, 'w')
            print("%s created" % name_gitignore)
            sys.exit(0)
        [add(name) for name in argv[2:]]
    elif option == Option.REMOVE:
        [remove(name) for name in argv[2:]]
    elif option == Option.UPDATE:
        update()
    elif option == Option.CLEAR:
        clear()
#    file_gitignore.close()

def get_option(argc, argv):
    if argc <= 1:
        return Option.NONE
    return {
        'add': Option.ADD,
        'create': Option.CREATE,
        'remove': Option.REMOVE,
        'update': Option.UPDATE,
        'clear': Option.CLEAR
    }.get(argv[1].lower(), Option.UNKNOWN)

def valid_argc(argc, option):
    if option == Option.ADD:
        return argc > 2
    elif option == Option.CREATE:
        return argc >= 2
    elif option == Option.REMOVE:
        return argc > 2
    elif option == Option.UPDATE:
        return argc == 2
    else:
        return argc == 2

def check_file_gitignore(option):
    if option == Option.CREATE:
        return True
    if os.path.isfile(name_gitignore):
        parse_file(name_gitignore, 'r')
        return True
    return option == Option.ADD

re_start = re.compile(r'\s*#\s*gitignore-start\s*:\s*([!-.0-~]+/)*([!-.0-~]+)\.gitignore.*\n')
def parse_file(filename):
    f = open(filename, 'r')
    it = iter(f.readlines())
    f.close()
    while True:
        try:
            line = next(it)
            m = re_start.match(line)
            if m is None:
                junk_lines.append(line)
            else:
                parse_gitignore(it, m.group(2).lower());
        except StopIteration:
            break

re_end = re.compile(r'\s*#\s*gitignore-end\s*:\s*([!-.0-~]+/)*([!-.0-~]+)\.gitignore.*\n')
def parse_gitignore(it, name):
    gitignore_lines = []
    while True:
        try:
            line = next(it)
            m = re_end.match(line)
            if m is None or m.group(2) != name:
                gitignore_lines.append(line)
            else:
                gitignores.update({name.lower(): lines})
        except StopIteration:
            sys.exit('the start tag for "%s" is not matched by a corresponding end tag' % name)

def add(name):
    lower = name.lower()
    if lower not in names:
        exit_error('unknown gitignore ' + name)
    item = names[lower] + ext_gitignore
    url = link + item
    data = urllib.request.urlopen(url).read().decode('utf-8')
    file_gitignore.write('#gitignore-start:%s\n' % item)
    file_gitignore.write(data)
    file_gitignore.write('#gitignore-end:%s\n' % item)
    print('added', item)

def remove(name):
    lower = name.lower()
    if lower not in names:
        exit_error('unknown gitignore ' + name)
    pass

def update():
    file_gitignore = check_file_gitignore()
    pass

def clear():
    file_gitignore = check_file_gitignore()
    pass

link = 'https://raw.githubusercontent.com/github/gitignore/master/'

names = {
    'actionscript' : 'Actionscript',
    'ada' : 'Ada',
    'agda' : 'Agda',
    'android' : 'Android',
    'appengine' : 'AppEngine',
    'appceleratortitanium' : 'AppceleratorTitanium',
    'archlinuxpackages' : 'ArchLinuxPackages',
    'autotools' : 'Autotools',
    'c++' : 'C++',
    'cpp' : 'C++',
    'c' : 'C',
    'cfwheels' : 'CFWheels',
    'cmake' : 'CMake',
    'cuda' : 'CUDA',
    'cakephp' : 'CakePHP',
    'chefcookbook' : 'ChefCookbook',
    'clojure' : 'Clojure',
    'codeigniter' : 'CodeIgniter',
    'commonlisp' : 'CommonLisp',
    'composer' : 'Composer',
    'concrete5' : 'Concrete5',
    'coq' : 'Coq',
    'craftcms' : 'CraftCMS',
    'd' : 'D',
    'dm' : 'DM',
    'dart' : 'Dart',
    'delphi' : 'Delphi',
    'drupal' : 'Drupal',
    'episerver' : 'EPiServer',
    'eagle' : 'Eagle',
    'elisp' : 'Elisp',
    'elixir' : 'Elixir',
    'elm' : 'Elm',
    'erlang' : 'Erlang',
    'expressionengine' : 'ExpressionEngine',
    'extjs' : 'ExtJs',
    'fancy' : 'Fancy',
    'finale' : 'Finale',
    'forcedotcom' : 'ForceDotCom',
    'fortran' : 'Fortran',
    'fuelphp' : 'FuelPHP',
    'gwt' : 'GWT',
    'gcov' : 'Gcov',
    'gitbook' : 'GitBook',
    'go' : 'Go',
    'gradle' : 'Gradle',
    'grails' : 'Grails',
    'haskell' : 'Haskell',
    'igorpro' : 'IGORPro',
    'idris' : 'Idris',
    'java' : 'Java',
    'jboss' : 'Jboss',
    'jekyll' : 'Jekyll',
    'joomla' : 'Joomla',
    'julia' : 'Julia',
    'kicad' : 'KiCad',
    'kohana' : 'Kohana',
    'labview' : 'LabVIEW',
    'laravel' : 'Laravel',
    'leiningen' : 'Leiningen',
    'lemonstand' : 'LemonStand',
    'lilypond' : 'Lilypond',
    'lithium' : 'Lithium',
    'lua' : 'Lua',
    'magento' : 'Magento',
    'maven' : 'Maven',
    'mercury' : 'Mercury',
    'metaprogrammingsystem' : 'MetaProgrammingSystem',
    'nanoc' : 'Nanoc',
    'nim' : 'Nim',
    'node' : 'Node',
    'ocaml' : 'OCaml',
    'objective-c' : 'Objective-C',
    'opa' : 'Opa',
    'opencart' : 'OpenCart',
    'oracleforms' : 'OracleForms',
    'packer' : 'Packer',
    'perl' : 'Perl',
    'phalcon' : 'Phalcon',
    'playframework' : 'PlayFramework',
    'plone' : 'Plone',
    'prestashop' : 'Prestashop',
    'processing' : 'Processing',
    'purescript' : 'PureScript',
    'python' : 'Python',
    'qooxdoo' : 'Qooxdoo',
    'qt' : 'Qt',
    'r' : 'R',
    'ros' : 'ROS',
    'rails' : 'Rails',
    'rhodesrhomobile' : 'RhodesRhomobile',
    'ruby' : 'Ruby',
    'rust' : 'Rust',
    'scons' : 'SCons',
    'sass' : 'Sass',
    'scala' : 'Scala',
    'scheme' : 'Scheme',
    'scrivener' : 'Scrivener',
    'sdcc' : 'Sdcc',
    'seamgen' : 'SeamGen',
    'sketchup' : 'SketchUp',
    'smalltalk' : 'Smalltalk',
    'stella' : 'Stella',
    'sugarcrm' : 'SugarCRM',
    'swift' : 'Swift',
    'symfony' : 'Symfony',
    'symphonycms' : 'SymphonyCMS',
    'tex' : 'TeX',
    'terraform' : 'Terraform',
    'textpattern' : 'Textpattern',
    'turbogears2' : 'TurboGears2',
    'typo3' : 'Typo3',
    'umbraco' : 'Umbraco',
    'unity' : 'Unity',
    'unrealengine' : 'UnrealEngine',
    'vvvv' : 'VVVV',
    'visualstudio' : 'VisualStudio',
    'waf' : 'Waf',
    'wordpress' : 'WordPress',
    'xojo' : 'Xojo',
    'yeoman' : 'Yeoman',
    'yii' : 'Yii',
    'zendframework' : 'ZendFramework',
    'zephir' : 'Zephir',

    'anjuta' : 'Global/Anjuta',
    'ansible' : 'Global/Ansible',
    'archives' : 'Global/Archives',
    'bazaar' : 'Global/Bazaar',
    'bricxcc' : 'Global/BricxCC',
    'cvs' : 'Global/CVS',
    'calabash' : 'Global/Calabash',
    'cloud9' : 'Global/Cloud9',
    'codekit' : 'Global/CodeKit',
    'darteditor' : 'Global/DartEditor',
    'dreamweaver' : 'Global/Dreamweaver',
    'dropbox' : 'Global/Dropbox',
    'eclipse' : 'Global/Eclipse',
    'eiffelstudio' : 'Global/EiffelStudio',
    'emacs' : 'Global/Emacs',
    'ensime' : 'Global/Ensime',
    'espresso' : 'Global/Espresso',
    'flexbuilder' : 'Global/FlexBuilder',
    'gpg' : 'Global/GPG',
    'jdeveloper' : 'Global/JDeveloper',
    'jetbrains' : 'Global/JetBrains',
    'kdevelop4' : 'Global/KDevelop4',
    'kate' : 'Global/Kate',
    'lazarus' : 'Global/Lazarus',
    'libreoffice' : 'Global/LibreOffice',
    'linux' : 'Global/Linux',
    'lyx' : 'Global/LyX',
    'matlab' : 'Global/Matlab',
    'mercurial' : 'Global/Mercurial',
    'microsoftoffice' : 'Global/MicrosoftOffice',
    'modelsim' : 'Global/ModelSim',
    'momentics' : 'Global/Momentics',
    'monodevelop' : 'Global/MonoDevelop',
    'netbeans' : 'Global/NetBeans',
    'ninja' : 'Global/Ninja',
    'notepadpp' : 'Global/NotepadPP',
    'otto' : 'Global/Otto',
    'redcar' : 'Global/Redcar',
    'redis' : 'Global/Redis',
    'sbt' : 'Global/SBT',
    'svn' : 'Global/SVN',
    'slickedit' : 'Global/SlickEdit',
    'stata' : 'Global/Stata',
    'sublimetext' : 'Global/SublimeText',
    'synopsysvcs' : 'Global/SynopsysVCS',
    'tags' : 'Global/Tags',
    'textmate' : 'Global/TextMate',
    'tortoisegit' : 'Global/TortoiseGit',
    'vagrant' : 'Global/Vagrant',
    'vim' : 'Global/Vim',
    'virtualenv' : 'Global/VirtualEnv',
    'visualstudiocode' : 'Global/VisualStudioCode',
    'webmethods' : 'Global/WebMethods',
    'windows' : 'Global/Windows',
    'xcode' : 'Global/Xcode',
    'xilinxise' : 'Global/XilinxISE',
    'macos' : 'Global/macOS'
}

if __name__ == '__main__':
    main(len(sys.argv), sys.argv)<commit_msg>Writing to file<commit_after>import sys, os, urllib.request, re
from enum import Enum

name_gitignore = '.gitignore'
ext_gitignore = name_gitignore
file_gitignore = None

junk_lines = []
gitignores = dict()

class Option(Enum):
    NONE = 0
    UNKNOWN = 1
    ADD = 2
    CREATE = 3
    REMOVE = 4
    UPDATE = 5
    CLEAR = 6

def main(argc, argv):
    option = get_option(argc, argv)
    if option == Option.NONE:
        sys.exit('no argument provided')
    elif option == Option.UNKNOWN:
        sys.exit('unknown option "%s"' % argv[1])
    elif not valid_argc(argc, option):
        sys.exit('invalid number of arguments for "%s"' % argv[1])
    elif not check_file_gitignore(option):
        sys.exit('no %s file found' % name_gitignore)

    global file_gitignore

    if option == Option.ADD:
        [add(name) for name in argv[2:]]
    elif option == Option.CREATE:
        if argc == 2:
            file_gitignore = open(name_gitignore, 'w')
            print("%s created" % name_gitignore)
            sys.exit(0)
        [add(name) for name in argv[2:]]
    elif option == Option.REMOVE:
        [remove(name) for name in argv[2:]]
    elif option == Option.UPDATE:
        update()
    elif option == Option.CLEAR:
        clear()
    write_file(name_gitignore)

def get_option(argc, argv):
    if argc <= 1:
        return Option.NONE
    return {
        'add': Option.ADD,
        'create': Option.CREATE,
        'remove': Option.REMOVE,
        'update': Option.UPDATE,
        'clear': Option.CLEAR
    }.get(argv[1].lower(), Option.UNKNOWN)

def valid_argc(argc, option):
    if option == Option.ADD:
        return argc > 2
    elif option == Option.CREATE:
        return argc >= 2
    elif option == Option.REMOVE:
        return argc > 2
    elif option == Option.UPDATE:
        return argc == 2
    else:
        return argc == 2

def check_file_gitignore(option):
    if option == Option.CREATE:
        return True
    if os.path.isfile(name_gitignore):
        parse_file(name_gitignore, 'r')
        return True
    return option == Option.ADD

re_start = re.compile(r'\s*#\s*gitignore-start\s*:\s*([!-.0-~]+/)*([!-.0-~]+)\.gitignore.*\n')
def parse_file(filename):
    f = open(filename, 'r')
    it = iter(f.readlines())
    f.close()
    while True:
        try:
            line = next(it)
            m = re_start.match(line)
            if m is None:
                junk_lines.append(line)
            else:
                parse_gitignore(it, m.group(2).lower());
        except StopIteration:
            break

re_end = re.compile(r'\s*#\s*gitignore-end\s*:\s*([!-.0-~]+/)*([!-.0-~]+)\.gitignore.*\n')
def parse_gitignore(it, name):
    gitignore_lines = []
    while True:
        try:
            line = next(it)
            m = re_end.match(line)
            if m is None or m.group(2) != name:
                gitignore_lines.append(line)
            else:
                gitignores.update({name.lower(): lines})
        except StopIteration:
            sys.exit('the start tag for "%s" is not matched by a corresponding end tag' % name)

def write_file(filename):
    f = open(filename, 'w')
    for line in junk_lines:
        f.write(line)
    for name, lines in gitignores.items():
        f.write('#gitignore-start:%s\n' % names[name])
        for line in lines:
            f.write(line)
        f.write('#gitignore-end:%s\n' % names[name])

def add(name):
    lower = name.lower()
    if lower not in names:
        exit_error('unknown gitignore ' + name)
    item = names[lower] + ext_gitignore
    url = link + item
    data = urllib.request.urlopen(url).read().decode('utf-8')
    file_gitignore.write('#gitignore-start:%s\n' % item)
    file_gitignore.write(data)
    file_gitignore.write('#gitignore-end:%s\n' % item)
    print('added', item)

def remove(name):
    lower = name.lower()
    if lower not in names:
        exit_error('unknown gitignore ' + name)
    pass

def update():
    file_gitignore = check_file_gitignore()
    pass

def clear():
    file_gitignore = check_file_gitignore()
    pass

link = 'https://raw.githubusercontent.com/github/gitignore/master/'

names = {
    'actionscript' : 'Actionscript',
    'ada' : 'Ada',
    'agda' : 'Agda',
    'android' : 'Android',
    'appengine' : 'AppEngine',
    'appceleratortitanium' : 'AppceleratorTitanium',
    'archlinuxpackages' : 'ArchLinuxPackages',
    'autotools' : 'Autotools',
    'c++' : 'C++',
    'cpp' : 'C++',
    'c' : 'C',
    'cfwheels' : 'CFWheels',
    'cmake' : 'CMake',
    'cuda' : 'CUDA',
    'cakephp' : 'CakePHP',
    'chefcookbook' : 'ChefCookbook',
    'clojure' : 'Clojure',
    'codeigniter' : 'CodeIgniter',
    'commonlisp' : 'CommonLisp',
    'composer' : 'Composer',
    'concrete5' : 'Concrete5',
    'coq' : 'Coq',
    'craftcms' : 'CraftCMS',
    'd' : 'D',
    'dm' : 'DM',
    'dart' : 'Dart',
    'delphi' : 'Delphi',
    'drupal' : 'Drupal',
    'episerver' : 'EPiServer',
    'eagle' : 'Eagle',
    'elisp' : 'Elisp',
    'elixir' : 'Elixir',
    'elm' : 'Elm',
    'erlang' : 'Erlang',
    'expressionengine' : 'ExpressionEngine',
    'extjs' : 'ExtJs',
    'fancy' : 'Fancy',
    'finale' : 'Finale',
    'forcedotcom' : 'ForceDotCom',
    'fortran' : 'Fortran',
    'fuelphp' : 'FuelPHP',
    'gwt' : 'GWT',
    'gcov' : 'Gcov',
    'gitbook' : 'GitBook',
    'go' : 'Go',
    'gradle' : 'Gradle',
    'grails' : 'Grails',
    'haskell' : 'Haskell',
    'igorpro' : 'IGORPro',
    'idris' : 'Idris',
    'java' : 'Java',
    'jboss' : 'Jboss',
    'jekyll' : 'Jekyll',
    'joomla' : 'Joomla',
    'julia' : 'Julia',
    'kicad' : 'KiCad',
    'kohana' : 'Kohana',
    'labview' : 'LabVIEW',
    'laravel' : 'Laravel',
    'leiningen' : 'Leiningen',
    'lemonstand' : 'LemonStand',
    'lilypond' : 'Lilypond',
    'lithium' : 'Lithium',
    'lua' : 'Lua',
    'magento' : 'Magento',
    'maven' : 'Maven',
    'mercury' : 'Mercury',
    'metaprogrammingsystem' : 'MetaProgrammingSystem',
    'nanoc' : 'Nanoc',
    'nim' : 'Nim',
    'node' : 'Node',
    'ocaml' : 'OCaml',
    'objective-c' : 'Objective-C',
    'opa' : 'Opa',
    'opencart' : 'OpenCart',
    'oracleforms' : 'OracleForms',
    'packer' : 'Packer',
    'perl' : 'Perl',
    'phalcon' : 'Phalcon',
    'playframework' : 'PlayFramework',
    'plone' : 'Plone',
    'prestashop' : 'Prestashop',
    'processing' : 'Processing',
    'purescript' : 'PureScript',
    'python' : 'Python',
    'qooxdoo' : 'Qooxdoo',
    'qt' : 'Qt',
    'r' : 'R',
    'ros' : 'ROS',
    'rails' : 'Rails',
    'rhodesrhomobile' : 'RhodesRhomobile',
    'ruby' : 'Ruby',
    'rust' : 'Rust',
    'scons' : 'SCons',
    'sass' : 'Sass',
    'scala' : 'Scala',
    'scheme' : 'Scheme',
    'scrivener' : 'Scrivener',
    'sdcc' : 'Sdcc',
    'seamgen' : 'SeamGen',
    'sketchup' : 'SketchUp',
    'smalltalk' : 'Smalltalk',
    'stella' : 'Stella',
    'sugarcrm' : 'SugarCRM',
    'swift' : 'Swift',
    'symfony' : 'Symfony',
    'symphonycms' : 'SymphonyCMS',
    'tex' : 'TeX',
    'terraform' : 'Terraform',
    'textpattern' : 'Textpattern',
    'turbogears2' : 'TurboGears2',
    'typo3' : 'Typo3',
    'umbraco' : 'Umbraco',
    'unity' : 'Unity',
    'unrealengine' : 'UnrealEngine',
    'vvvv' : 'VVVV',
    'visualstudio' : 'VisualStudio',
    'waf' : 'Waf',
    'wordpress' : 'WordPress',
    'xojo' : 'Xojo',
    'yeoman' : 'Yeoman',
    'yii' : 'Yii',
    'zendframework' : 'ZendFramework',
    'zephir' : 'Zephir',

    'anjuta' : 'Global/Anjuta',
    'ansible' : 'Global/Ansible',
    'archives' : 'Global/Archives',
    'bazaar' : 'Global/Bazaar',
    'bricxcc' : 'Global/BricxCC',
    'cvs' : 'Global/CVS',
    'calabash' : 'Global/Calabash',
    'cloud9' : 'Global/Cloud9',
    'codekit' : 'Global/CodeKit',
    'darteditor' : 'Global/DartEditor',
    'dreamweaver' : 'Global/Dreamweaver',
    'dropbox' : 'Global/Dropbox',
    'eclipse' : 'Global/Eclipse',
    'eiffelstudio' : 'Global/EiffelStudio',
    'emacs' : 'Global/Emacs',
    'ensime' : 'Global/Ensime',
    'espresso' : 'Global/Espresso',
    'flexbuilder' : 'Global/FlexBuilder',
    'gpg' : 'Global/GPG',
    'jdeveloper' : 'Global/JDeveloper',
    'jetbrains' : 'Global/JetBrains',
    'kdevelop4' : 'Global/KDevelop4',
    'kate' : 'Global/Kate',
    'lazarus' : 'Global/Lazarus',
    'libreoffice' : 'Global/LibreOffice',
    'linux' : 'Global/Linux',
    'lyx' : 'Global/LyX',
    'matlab' : 'Global/Matlab',
    'mercurial' : 'Global/Mercurial',
    'microsoftoffice' : 'Global/MicrosoftOffice',
    'modelsim' : 'Global/ModelSim',
    'momentics' : 'Global/Momentics',
    'monodevelop' : 'Global/MonoDevelop',
    'netbeans' : 'Global/NetBeans',
    'ninja' : 'Global/Ninja',
    'notepadpp' : 'Global/NotepadPP',
    'otto' : 'Global/Otto',
    'redcar' : 'Global/Redcar',
    'redis' : 'Global/Redis',
    'sbt' : 'Global/SBT',
    'svn' : 'Global/SVN',
    'slickedit' : 'Global/SlickEdit',
    'stata' : 'Global/Stata',
    'sublimetext' : 'Global/SublimeText',
    'synopsysvcs' : 'Global/SynopsysVCS',
    'tags' : 'Global/Tags',
    'textmate' : 'Global/TextMate',
    'tortoisegit' : 'Global/TortoiseGit',
    'vagrant' : 'Global/Vagrant',
    'vim' : 'Global/Vim',
    'virtualenv' : 'Global/VirtualEnv',
    'visualstudiocode' : 'Global/VisualStudioCode',
    'webmethods' : 'Global/WebMethods',
    'windows' : 'Global/Windows',
    'xcode' : 'Global/Xcode',
    'xilinxise' : 'Global/XilinxISE',
    'macos' : 'Global/macOS'
}

if __name__ == '__main__':
    main(len(sys.argv), sys.argv)<|endoftext|>