<commit_before>from neo4j.v1 import GraphDatabase, basic_auth
import datetime
import time

# Drop all data
def drop(session):
    session.run("MATCH (n) DETACH DELETE n")

# Print all data
def print_all(session):
    print('The program have inserted the following nodes:')
    for item in session.run('MATCH (n) RETURN n'):
        print(item)

# Create a part node with parameters specified
def create_part(session, identifier, partkey, mfgr, type, size):
    session.run("CREATE (" + identifier + ":Part {partkey:'" + partkey +
                "', mfgr:'" + mfgr + "', type: '" + type + "', size: " + size + "})")

# Create a supplier node with parameters specified
def create_supplier(session, identifier, suppkey, name, accbal, adress, phone, comment, n_name, r_name):
    session.run("CREATE (" + identifier + ":Supplier {suppkey: '" + suppkey +
                "', name: '" + name + "', accbal: " + accbal + ", adress: '" + adress +
                "', phone: '" + phone + "', comment: '" + comment +
                "', n_name: '" + n_name + "', r_name: '" + r_name + "'})")

# Create an order node with parameters specified
def create_order(session, identifier, orderkey, orderdate, shippriority, c_marketsegment, n_name):
    session.run("CREATE (" + identifier + ":Order {orderkey: '" + orderkey + "', orderdate: {date}, shippriority:'" +
                shippriority + "', c_marketsegment: '" + c_marketsegment + "', n_name: '" + n_name + "'})",
                {"date": orderdate})

# Create a line item node with parameters specified
def create_lineitem(session, identifier, orderkey, suppkey, returnflag, quantity,
                    extendedPrice, discount, tax, shipdate, linestatus):
    session.run("CREATE (" + identifier + ":LineItem {orderkey: '" + orderkey +
                "', suppkey: '" + suppkey + "', returnflag: '" + returnflag + "', quantity: " + quantity +
                ", extendedPrice: " + extendedPrice + ", discount: " + discount + ", tax: " + tax +
                ", shipdate: {date2}, linestatus: '" + linestatus + "'})", {"date2": shipdate})

# Create a edge between supplier and part nodes specified in parameters
def create_edge_supplier_part(session, supplier, suppkey, part, partkey, supplycost):
    session.run(
        "MATCH (" + supplier + ":Supplier {suppkey: '" + suppkey + "'}), (" + part + ":Part {partkey: '" + partkey +
        "'}) CREATE (" + supplier + ")-[:ps {supplycost: {suppcost} }]->(" + part + ")",
        {"suppcost": supplycost})

# Create a edge between order and line item nodes specified in parameters
def create_edge_order_lineitem(session, order, orderkey, lineitem):
    session.run("MATCH (" + order + ":Order {orderkey: '" + orderkey + "'}), (" + lineitem +
                ":LineItem {orderkey: '" + orderkey + "'}) CREATE (" + order + ")-[:has]->(" + lineitem + ")")

# Create a edge between line item and supplier nodes specified in parameters
def create_edge_lineitem_supplier(session, lineitem, supplier, suppkey):
    session.run("MATCH (" + lineitem + ":LineItem {suppkey: '" + suppkey + "'}), (" + supplier +
                ":Supplier {suppkey: '" + suppkey + "'}) CREATE (" + lineitem + ")-[:isFrom]->(" + supplier + ")")

# Insert some data in database
def inserts(db):
    print('Starting inserts...')
    session = db.session()

    date = datetime.datetime(2016, 11, 24)
    date2 = datetime.datetime(2016, 11, 25)
    timestamp = time.mktime(date.timetuple())
    timestamp2 = time.mktime(date2.timetuple())

    drop(session)
    create_part(session, 'p1', '1', 'aaaa', 'A', '10')
    create_part(session, 'p2', '2', 'bbbb', 'B', '15')
    create_part(session, 'p3', '3', 'cccc', 'C', '5')
    create_part(session, 'p4', '4', 'dddd', 'D', '2')
    create_supplier(session, 's1', 's1', 'supp1', '1.00', 'Main Street', '111111', 'nothing', 'Spain', 'Barcelona')
    create_supplier(session, 's2', 's2', 'supp2', '2.00', 'Main Street 2', '2222222 ', 'nothing 2', 'Spain',
                    'Barcelona')
    create_order(session, 'o1', 'o1', timestamp, '1', 'MKT1', 'Spain')
    create_order(session, 'o2', 'o2', timestamp, '2', 'MKT1', 'Spain')
    create_lineitem(session, 'l1', 'o1', 's1', 'a', '10', '10.0', '0.1', '2.0', timestamp2, 'a')
    create_lineitem(session, 'l2', 'o1', 's1', 'a', '5', '18.0', '0.5', '3.0', timestamp2, 'a')
    create_lineitem(session, 'l3', 'o1', 's1', 'a', '5', '5.0', '0.05', '1.0', timestamp2, 'a')
    create_lineitem(session, 'l4', 'o2', 's2', 'b', '10', '20.0', '0.3', '3.0', timestamp2, 'b')
    create_lineitem(session, 'l5', 'o2', 's2', 'b', '20', '40.0', '0.5', '1.0', timestamp2, 'b')
    create_lineitem(session, 'l6', 'o2', 's2', 'b', '5', '10.0', '0.2', '2.0', timestamp2, 'b')

    create_edge_supplier_part(session, 's1', 's1', 'p1', '1', 10)
    create_edge_supplier_part(session, 's1', 's1', 'p2', '2', 20)
    create_edge_supplier_part(session, 's1', 's1', 'p3', '3', 30)
    create_edge_supplier_part(session, 's1', 's1', 'p4', '4', 40)
    create_edge_supplier_part(session, 's2', 's2', 'p1', '1', 5)
    create_edge_supplier_part(session, 's2', 's2', 'p2', '2', 10)
    create_edge_supplier_part(session, 's2', 's2', 'p3', '3', 15)
    create_edge_supplier_part(session, 's2', 's2', 'p4', '4', 20)
    create_edge_order_lineitem(session, 'o1', 'o1', 'l1')
    create_edge_order_lineitem(session, 'o2', 'o2', 'l4')
    create_edge_lineitem_supplier(session, 'l1', 's1', 's1')
    create_edge_lineitem_supplier(session, 'l2', 's2', 's2')

    print_all(session)
    print('Finish inserts!\n')

    session.close()
    return db

# Create the neo4j database
def create():
    print('Create and connect with Database')

    db = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "neo4j"))
    return inserts(db)

# Query 1 code
def query1(db, date):
    print('Query 1 starting...')
    result = db.session().run(" MATCH " +
                              "      ( li:LineItem ) " +
                              " WHERE " +
                              "      li.shipdate <= {date} " +
                              " WITH " +
                              "      li.returnflag                                    AS l_returnflag, " +
                              "      li.linestatus                                    AS l_linestatus, " +
                              "      SUM(li.quantity)                                 AS sum_qty, " +
                              "      SUM(li.extendedPrice)                            AS sum_base_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount))            AS sum_disc_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount)*(1+li.tax)) AS sum_charge, " +
                              "      AVG(li.quantity)                                 AS avg_qty, " +
                              "      AVG(li.extendedPrice)                            AS avg_price, " +
                              "      AVG(li.discount)                                 AS avg_disc, " +
                              "      COUNT(*)                                         AS count_order " +
                              " RETURN " +
                              "      l_returnflag, " +
                              "      l_linestatus, " +
                              "      sum_qty, " +
                              "      sum_base_price, " +
                              "      sum_disc_price, " +
                              "      sum_charge, " +
                              "      avg_qty, " +
                              "      avg_price, " +
                              "      avg_disc, " +
                              "      count_order " +
                              " ORDER BY " +
                              "      l_returnflag, " +
                              "      l_linestatus ",
                              {"date": time.mktime(date.timetuple())})

    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for first query")
    print()

# Query 2 code
def query2(db, region, type, size):
    print('Query 2 starting...')
    subquery = db.session().run("MATCH (su: Supplier)-[res:ps]->()" +
                                "WHERE su.r_name = {region} " +
                                "RETURN MIN(res.supplycost) ",
                                {"region": region})

    i = 0

    for item in subquery:
        i += 1
        #print(item)
        mincost = item['MIN(res.supplycost)']

    result = db.session().run("MATCH (su: Supplier)-[res:ps]->(p1: Part) " +
                              "WHERE p1.size = {size} " +
                              " AND p1.type = {type} " +
                              " AND res.supplycost = {suppcost} " +
                              "RETURN " +
                              "     su.accbal AS s_accbal, " +
                              "     su.name AS s_name, " +
                              "     su.n_name AS n_name, " +
                              "     p1.partkey AS p_partkey, " +
                              "     p1.mfgr AS p_mfgr, " +
                              "     su.adress AS s_adress, " +
                              "     su.phone AS s_phone, " +
                              "     su.comment AS s_comment " +
                              "ORDER BY " +
                              "     su.accbal DESC, " +
                              "     su.n_name , " +
                              "     p1.partkey ",
                              {"size": size, "type": type, "suppcost": mincost})
    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for second query")

    print()

# Query 3 code
def query3(db, date1, date2, segment):
    print('Query 3 starting...')
    # orderdate  datetime.datetime(2016, 11, 24)
    # shipdates  datetime.datetime(2016, 11, 25)
    result = db.session().run(" MATCH (o1:Order)-[:has]->(l1:LineItem) " +
                              " WHERE " +
                              "      l1.shipdate > {date2} " +
                              "      AND o1.orderdate < {date1} " +
                              "      AND o1.c_marketsegment = {segment} " +
                              "      AND o1.orderkey = l1.orderkey"
                              " WITH " +
                              "      l1.orderkey                                   AS l_orderkey, " +
                              "      SUM(l1.extendedPrice*(1-l1.discount))         AS revenue, " +
                              "      o1.orderdate                                  AS o_orderdate, " +
                              "      o1.shippriority                               As o_shippriority " +
                              " RETURN " +
                              "      l_orderkey, " +
                              "      revenue, " +
                              "      o_orderdate, " +
                              "      o_shippriority " +
                              " ORDER BY " +
                              "      revenue DESC, " +
                              "      o_orderdate ",
                              {"date1": time.mktime(date1.timetuple()),
                              "date2": time.mktime(date2.timetuple()),
                              "segment": segment})

    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for third query")
    print()

# Query 4 code
def query4(db, region, date):
    print('Query 4 starting...')

    result = db.session().run(" MATCH " +
                              "      ( o:Order ) - [:has] -> ( li:LineItem ) - [:isFrom] -> ( s:Supplier )" +
                              " WHERE " +
                              "      s.r_name = " + region + " and "
                              "      o.orderdate >= " + region + ", "
                              " WITH " +
                              "      li.returnflag                                    AS l_returnflag, " +
                              "      li.linestatus                                    AS l_linestatus, " +
                              "      SUM(li.quantity)                                 AS sum_qty, " +
                              "      SUM(li.extendedPrice)                            AS sum_base_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount))            AS sum_disc_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount)*(1+li.tax)) AS sum_charge, " +
                              "      AVG(li.quantity)                                 AS avg_qty, " +
                              "      AVG(li.extendedPrice)                            AS avg_price, " +
                              "      AVG(li.discount)                                 AS avg_disc, " +
                              "      COUNT(*)                                         AS count_order " +
                              " RETURN " +
                              "      l_returnflag, " +
                              "      l_linestatus, " +
                              "      sum_qty, " +
                              "      sum_base_price, " +
                              "      sum_disc_price, " +
                              "      sum_charge, " +
                              "      avg_qty, " +
                              "      avg_price, " +
                              "      avg_disc, " +
                              "      count_order " +
                              " ORDER BY " +
                              "      l_returnflag, " +
                              "      l_linestatus ",
                              {"date": time.mktime(date.timetuple())})

    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for first query")

    print()

# Main functiond
def run():
    print('Neo4J Laboratory\n')
    db = create()
    query1(db, datetime.datetime(2016, 11, 28))
    query2(db, 'Barcelona','A', 10)
    query3(db, datetime.datetime(2016, 11, 28), datetime.datetime(2016,11,20), 'MKT1')
    # query4(db, "Barcelona", datetime.datetime(2016, 11, 28))
    print('THE END')

if __name__ == '__main__':
    run()
<commit_msg>refactor code<commit_after>from neo4j.v1 import GraphDatabase, basic_auth
import datetime
import time

# Drop all data
def drop(session):
    session.run("MATCH (n) DETACH DELETE n")

# Print all data
def print_all(session):
    print('The program have inserted the following nodes:')
    for item in session.run('MATCH (n) RETURN n'):
        print(item)

# Create a part node with parameters specified
def create_part(session, identifier, partkey, mfgr, type, size):
    session.run("CREATE (" + identifier + ":Part {partkey:'" + partkey +
                "', mfgr:'" + mfgr + "', type: '" + type + "', size: " + size + "})")

# Create a supplier node with parameters specified
def create_supplier(session, identifier, suppkey, name, accbal, adress, phone, comment, n_name, r_name):
    session.run("CREATE (" + identifier + ":Supplier {suppkey: '" + suppkey +
                "', name: '" + name + "', accbal: " + accbal + ", adress: '" + adress +
                "', phone: '" + phone + "', comment: '" + comment +
                "', n_name: '" + n_name + "', r_name: '" + r_name + "'})")

# Create an order node with parameters specified
def create_order(session, identifier, orderkey, orderdate, shippriority, c_marketsegment, n_name):
    session.run("CREATE (" + identifier + ":Order {orderkey: '" + orderkey + "', orderdate: {date}, shippriority:'" +
                shippriority + "', c_marketsegment: '" + c_marketsegment + "', n_name: '" + n_name + "'})",
                {"date": orderdate})

# Create a line item node with parameters specified
def create_lineitem(session, identifier, orderkey, suppkey, returnflag, quantity,
                    extendedPrice, discount, tax, shipdate, linestatus):
    session.run("CREATE (" + identifier + ":LineItem {orderkey: '" + orderkey +
                "', suppkey: '" + suppkey + "', returnflag: '" + returnflag + "', quantity: " + quantity +
                ", extendedPrice: " + extendedPrice + ", discount: " + discount + ", tax: " + tax +
                ", shipdate: {date2}, linestatus: '" + linestatus + "'})", {"date2": shipdate})

# Create a edge between supplier and part nodes specified in parameters
def create_edge_supplier_part(session, supplier, suppkey, part, partkey, supplycost):
    session.run(
        "MATCH (" + supplier + ":Supplier {suppkey: '" + suppkey + "'}), (" + part + ":Part {partkey: '" + partkey +
        "'}) CREATE (" + supplier + ")-[:ps {supplycost: {suppcost} }]->(" + part + ")",
        {"suppcost": supplycost})

# Create a edge between order and line item nodes specified in parameters
def create_edge_order_lineitem(session, order, orderkey, lineitem):
    session.run("MATCH (" + order + ":Order {orderkey: '" + orderkey + "'}), (" + lineitem +
                ":LineItem {orderkey: '" + orderkey + "'}) CREATE (" + order + ")-[:has]->(" + lineitem + ")")

# Create a edge between line item and supplier nodes specified in parameters
def create_edge_lineitem_supplier(session, lineitem, supplier, suppkey):
    session.run("MATCH (" + lineitem + ":LineItem {suppkey: '" + suppkey + "'}), (" + supplier +
                ":Supplier {suppkey: '" + suppkey + "'}) CREATE (" + lineitem + ")-[:isFrom]->(" + supplier + ")")

# Insert some data in database
def inserts(db):
    print('Starting inserts...')
    session = db.session()

    date = datetime.datetime(2016, 11, 24)
    date2 = datetime.datetime(2016, 11, 25)
    timestamp = time.mktime(date.timetuple())
    timestamp2 = time.mktime(date2.timetuple())

    drop(session)
    create_part(session, 'p1', '1', 'aaaa', 'A', '10')
    create_part(session, 'p2', '2', 'bbbb', 'B', '15')
    create_part(session, 'p3', '3', 'cccc', 'C', '5')
    create_part(session, 'p4', '4', 'dddd', 'D', '2')
    create_supplier(session, 's1', 's1', 'supp1', '1.00', 'Main Street', '111111', 'nothing', 'Spain', 'Barcelona')
    create_supplier(session, 's2', 's2', 'supp2', '2.00', 'Main Street 2', '2222222 ', 'nothing 2', 'Spain',
                    'Barcelona')
    create_order(session, 'o1', 'o1', timestamp, '1', 'MKT1', 'Spain')
    create_order(session, 'o2', 'o2', timestamp, '2', 'MKT1', 'Spain')
    create_lineitem(session, 'l1', 'o1', 's1', 'a', '10', '10.0', '0.1', '2.0', timestamp2, 'a')
    create_lineitem(session, 'l2', 'o1', 's1', 'a', '5', '18.0', '0.5', '3.0', timestamp2, 'a')
    create_lineitem(session, 'l3', 'o1', 's1', 'a', '5', '5.0', '0.05', '1.0', timestamp2, 'a')
    create_lineitem(session, 'l4', 'o2', 's2', 'b', '10', '20.0', '0.3', '3.0', timestamp2, 'b')
    create_lineitem(session, 'l5', 'o2', 's2', 'b', '20', '40.0', '0.5', '1.0', timestamp2, 'b')
    create_lineitem(session, 'l6', 'o2', 's2', 'b', '5', '10.0', '0.2', '2.0', timestamp2, 'b')

    create_edge_supplier_part(session, 's1', 's1', 'p1', '1', 10)
    create_edge_supplier_part(session, 's1', 's1', 'p2', '2', 20)
    create_edge_supplier_part(session, 's1', 's1', 'p3', '3', 30)
    create_edge_supplier_part(session, 's1', 's1', 'p4', '4', 40)
    create_edge_supplier_part(session, 's2', 's2', 'p1', '1', 5)
    create_edge_supplier_part(session, 's2', 's2', 'p2', '2', 10)
    create_edge_supplier_part(session, 's2', 's2', 'p3', '3', 15)
    create_edge_supplier_part(session, 's2', 's2', 'p4', '4', 20)
    create_edge_order_lineitem(session, 'o1', 'o1', 'l1')
    create_edge_order_lineitem(session, 'o2', 'o2', 'l4')
    create_edge_lineitem_supplier(session, 'l1', 's1', 's1')
    create_edge_lineitem_supplier(session, 'l2', 's2', 's2')

    print_all(session)
    print('Finish inserts!\n')

    session.close()
    return db

# Create the neo4j database
def create():
    print('Create and connect with Database')

    db = GraphDatabase.driver("bolt://localhost", auth=basic_auth("neo4j", "neo4j"))
    return inserts(db)

# Query 1 code
def query1(db, date):
    print('Query 1 starting...')
    result = db.session().run(" MATCH " +
                              "      ( li:LineItem ) " +
                              " WHERE " +
                              "      li.shipdate <= {date} " +
                              " WITH " +
                              "      li.returnflag                                    AS l_returnflag, " +
                              "      li.linestatus                                    AS l_linestatus, " +
                              "      SUM(li.quantity)                                 AS sum_qty, " +
                              "      SUM(li.extendedPrice)                            AS sum_base_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount))            AS sum_disc_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount)*(1+li.tax)) AS sum_charge, " +
                              "      AVG(li.quantity)                                 AS avg_qty, " +
                              "      AVG(li.extendedPrice)                            AS avg_price, " +
                              "      AVG(li.discount)                                 AS avg_disc, " +
                              "      COUNT(*)                                         AS count_order " +
                              " RETURN " +
                              "      l_returnflag, " +
                              "      l_linestatus, " +
                              "      sum_qty, " +
                              "      sum_base_price, " +
                              "      sum_disc_price, " +
                              "      sum_charge, " +
                              "      avg_qty, " +
                              "      avg_price, " +
                              "      avg_disc, " +
                              "      count_order " +
                              " ORDER BY " +
                              "      l_returnflag       ASC, " +
                              "      l_linestatus       ASC ",
                              {"date": time.mktime(date.timetuple())})

    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for first query")
    print()

# Query 2 code
def query2(db, region, type, size):
    print('Query 2 starting...')
    subquery_result = db.session().run(" MATCH " +
                                       "    (su: Supplier)-[res:ps]->() " +
                                       " WHERE " +
                                       "    su.r_name = {region} " +
                                       " RETURN " +
                                       "    MIN(res.supplycost) ",
                                       {"region": region})

    global min_cost
    for item in subquery_result:
        min_cost = item['MIN(res.supplycost)']

    result = db.session().run(" MATCH " +
                              "     (su: Supplier)-[res:ps]->(p1: Part) " +
                              " WHERE " +
                              "     p1.size = {size} AND " +
                              "     p1.type = {type} AND " +
                              "     res.supplycost = {suppcost} " +
                              " RETURN " +
                              "     su.accbal   AS s_accbal, " +
                              "     su.name     AS s_name, " +
                              "     su.n_name   AS n_name, " +
                              "     p1.partkey  AS p_partkey, " +
                              "     p1.mfgr     AS p_mfgr, " +
                              "     su.adress   AS s_adress, " +
                              "     su.phone    AS s_phone, " +
                              "     su.comment  AS s_comment " +
                              " ORDER BY " +
                              "     su.accbal   DESC, " +
                              "     su.n_name   ASC, " +
                              "     p1.partkey  ASC ",
                              {"size": size, "type": type, "suppcost": min_cost})
    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for second query")

    print()

# Query 3 code
def query3(db, date1, date2, segment):
    print('Query 3 starting...')
    result = db.session().run(" MATCH " +
                              "     (o1:Order)-[:has]->(l1:LineItem) " +
                              " WHERE " +
                              "     l1.shipdate > {date2} AND " +
                              "     o1.orderdate < {date1} AND " +
                              "     o1.c_marketsegment = {segment} AND " +
                              "     o1.orderkey = l1.orderkey "
                              " WITH " +
                              "      l1.orderkey                                   AS l_orderkey, " +
                              "      o1.orderdate                                  AS o_orderdate, " +
                              "      o1.shippriority                               As o_shippriority, " +
                              "      SUM(l1.extendedPrice*(1-l1.discount))         AS revenue " +
                              " RETURN " +
                              "      l_orderkey, " +
                              "      o_orderdate, " +
                              "      o_shippriority, " +
                              "      revenue " +
                              " ORDER BY " +
                              "      revenue        DESC, " +
                              "      o_orderdate    ASC ",
                              {"date1": time.mktime(date1.timetuple()),
                               "date2": time.mktime(date2.timetuple()),
                               "segment": segment})

    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for third query")
    print()

# Query 4 code
def query4(db, region, date):
    print('Query 4 starting...')

    result = db.session().run(" MATCH " +
                              "      ( o:Order ) - [:has] -> ( li:LineItem ) - [:isFrom] -> ( s:Supplier )" +
                              " WHERE " +
                              "      s.r_name = " + region + " and "
                                                             "      o.orderdate >= " + region + ", "
                                                                                " WITH " +
                              "      li.returnflag                                    AS l_returnflag, " +
                              "      li.linestatus                                    AS l_linestatus, " +
                              "      SUM(li.quantity)                                 AS sum_qty, " +
                              "      SUM(li.extendedPrice)                            AS sum_base_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount))            AS sum_disc_price, " +
                              "      SUM(li.extendedPrice*(1-li.discount)*(1+li.tax)) AS sum_charge, " +
                              "      AVG(li.quantity)                                 AS avg_qty, " +
                              "      AVG(li.extendedPrice)                            AS avg_price, " +
                              "      AVG(li.discount)                                 AS avg_disc, " +
                              "      COUNT(*)                                         AS count_order " +
                              " RETURN " +
                              "      l_returnflag, " +
                              "      l_linestatus, " +
                              "      sum_qty, " +
                              "      sum_base_price, " +
                              "      sum_disc_price, " +
                              "      sum_charge, " +
                              "      avg_qty, " +
                              "      avg_price, " +
                              "      avg_disc, " +
                              "      count_order " +
                              " ORDER BY " +
                              "      l_returnflag, " +
                              "      l_linestatus ",
                              {"date": time.mktime(date.timetuple())})

    i = 0
    for item in result:
        i += 1
        print(item)

    if i == 0:
        print("No results for fourth query")

    print()

# Main function
def run():
    print('Neo4J Laboratory\n')
    db = create()
    query1(db, datetime.datetime(2016, 11, 28))
    query2(db, 'Barcelona', 'A', 10)
    query3(db, datetime.datetime(2016, 11, 28), datetime.datetime(2016, 11, 20), 'MKT1')
    # query4(db, "Barcelona", datetime.datetime(2016, 11, 28))
    print('THE END')

if __name__ == '__main__':
    run()
<|endoftext|>


<commit_before>import ipaddress
from netbox import exceptions

class Ipam(object):

    def __init__(self, netbox_con):

        self.netbox_con = netbox_con

    def get_ip_addresses(self, **kwargs):
        """Return all ip addresses"""
        return self.netbox_con.get('/ipam/ip-addresses/', **kwargs)

    def get_ip_by_device(self, device_name):
        """Get IPs which are associated to a device

        :param device_name: Name of the device
        :return: ip address information
        """
        return self.netbox_con.get('/ipam/ip-addresses', device=device_name)

    def get_ip_by_virtual_machine(self, vm_name):
        """Get IPs which are associated to a device

        :param vm_name: Name of the virtual machine
        :return: ip address information
        """
        return self.netbox_con.get('/ipam/ip-addresses', virtual_machine=vm_name)

    def create_ip_address(self, address, **kwargs):
        """Create a new ip address

        :param address: IP address
        :param kwargs: Optional arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"address": address}
        return self.netbox_con.post('/ipam/ip-addresses/', required_fields, **kwargs)

    def update_ip(self, ip_address, **kwargs):
        """Update ip address

        :param ip_address: ip address with prefix. Format: 1.1.1.1/32
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            ip_id = self.get_ip_addresses(address=ip_address)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip: {}'.format(ip_address)) from None
        return self.netbox_con.patch('/ipam/ip-addresses/', ip_id, **kwargs)

    def delete_ip_address(self, ip_address):
        """Delete IP address

        :param ip_address: IP address to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            ip_id = self.get_ip_addresses(address=ip_address)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip: {}'.format(ip_address)) from None
        return self.netbox_con.delete('/ipam/ip-addresses/', ip_id)

    def delete_ip_by_id(self, ip_id):
        """Delete IP address

        :param ip_id: ID of ip address to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        return self.netbox_con.delete('/ipam/ip-addresses/', ip_id)

    def get_ip_prefixes(self, **kwargs):
        """Return all ip prefixes"""
        return self.netbox_con.get('/ipam/prefixes/', **kwargs)

    def create_ip_prefix(self, prefix, **kwargs):
        """Create a new ip prefix

        :param prefix: A valid ip prefix format. The syntax will be checked with the ipaddress module
        :param kwargs: Optional arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"prefix": prefix}

        if ipaddress.ip_network(prefix, strict=True):
            return self.netbox_con.post('/ipam/prefixes/', required_fields, **kwargs)

    def delete_ip_prefix(self, **kwargs):
        """Delete IP prefix

        :param kwargs: Delete prefix based on filter values
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            ip_prefix_id = self.get_ip_prefixes(**kwargs)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip-prefix') from None
        return self.netbox_con.delete('/ipam/prefixes/', ip_prefix_id)

    def update_ip_prefix(self, ip_prefix, **kwargs):
        """Update ip address

        :param ip_prefix: ip prefix to update
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            ip_prefix_id = self.get_ip_prefixes(q=ip_prefix)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip-prefix: {}'.format(ip_prefix)) from None
        return self.netbox_con.patch('/ipam/prefixes/', ip_prefix_id, **kwargs)

    def get_next_available_ip(self, **kwargs):
        """Return next available ip in prefix

        :param kwargs: Use the filter fields from the get_prefixes call
        :return: next available ip
        """
        try:
            prefix_id = self.get_ip_prefixes(**kwargs)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip-prefix') from None

        param = '/ipam/prefixes/{}/available-ips/'.format(prefix_id)
        return self.netbox_con.get(param, limit=1)[0]['address']

    def get_vrfs(self, **kwargs):
        """Get all vrfs"""
        return self.netbox_con.get('/ipam/vrfs/', **kwargs)

    def create_vrf(self, name, rd, **kwargs):
        """Create a new vrf

        :param name: Name of the vrf
        :param rd: Route distinguisher in any format
        :param kwargs: Optional arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "rd": rd}
        return self.netbox_con.post('/ipam/vrfs/', required_fields, **kwargs)

    def delete_vrf(self, vrf_name):
        """Delete vrf

        :param vrf_name: Name of vrf to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            vrf_id = self.get_vrfs(name=vrf_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vrf: {}'.format(vrf_name)) from None
        return self.netbox_con.delete('/ipam/vrfs/', vrf_id)

    def update_vrf(self, vrf_name, **kwargs):
        """Update vrf

        :param vrf_name: name of the vrf to update
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            vrf_id = self.get_vrfs(name=vrf_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vrf: {}'.format(vrf_name)) from None
        return self.netbox_con.patch('/ipam/vrfs/', vrf_id, **kwargs)

    def get_aggregates(self, **kwargs):
        """Return all aggregates"""
        return self.netbox_con.get('/ipam/aggregates/', **kwargs)

    def create_aggregate(self, prefix, rir, **kwargs):
        """Creates a new aggregate

        :param prefix: IP Prefix
        :param rir: Name of the RIR
        :param kwargs: Optional Arguments
        :return:
        """
        rir_id = self.get_rirs(name=rir)[0]['id']
        required_fields = {"prefix": prefix, "rir": rir_id}

        if ipaddress.ip_network(prefix, strict=True):
            return self.netbox_con.post('/ipam/aggregates/', required_fields, **kwargs)

    def update_aggregate(self, prefix, **kwargs):
        """Update aggregate

        :param prefix: Prefix of the aggregate
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            aggregate_id = self.get_aggregates(prefix=prefix)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('aggregate: {}'.format(prefix)) from None
        return self.netbox_con.patch('/ipam/aggregates/', aggregate_id, **kwargs)

    def get_rirs(self, **kwargs):
        """Return all rirs"""
        return self.netbox_con.get('/ipam/rirs/', **kwargs)

    def create_rir(self, name, slug):
        """Create new rir

        :param name: Name of the rir
        :param slug: Name of the slug
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "slug": slug}
        return self.netbox_con.post('/ipam/rirs/', required_fields)

    def delete_rir(self, rir_name):
        """Delete rir

        :param rir_name: rir name to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            rir_id = self.get_rirs(name=rir_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('rir: {}'.format(rir_name)) from None
        return self.netbox_con.delete('/ipam/rirs/', rir_id)

    def update_rir(self, rir_name, **kwargs):
        """Update rir

        :param rir_name: Name of the rir
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            rir_id = self.get_rirs(name=rir_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('rir: {}'.format(rir_name)) from None
        return self.netbox_con.patch('/ipam/rirs/', rir_id, **kwargs)

    def get_roles(self, **kwargs):
        """Return all roles"""
        return self.netbox_con.get('/ipam/roles/', **kwargs)

    def create_role(self, name, slug, **kwargs):
        """Create new prefix/vlan role

        :param name: Name of the prefix/vlan role
        :param slug: Name of the slug
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "slug": slug}
        return self.netbox_con.post('/ipam/roles/', required_fields, **kwargs)

    def delete_role(self, role_name):
        """Delete prefix/vlan role

        :param role_name: prefix/vlan role to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            role_id = self.get_roles(name=role_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('prefix/vlan role: {}'.format(role_name)) from None
        return self.netbox_con.delete('/ipam/role/', role_id)

    def update_role(self, role_name, **kwargs):
        """Update prefix role

        :param role_name: Name of the prefix/vlan role
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            prefix_role_id = self.get_roles(name=role_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('prefix/vlan role: {}'.format(role_name)) from None
        return self.netbox_con.patch('/ipam/roles/', prefix_role_id, **kwargs)

    def get_vlans(self, **kwargs):
        """Return all vlans"""
        return self.netbox_con.get('/ipam/vlans/', **kwargs)

    def create_vlan(self, vid, vlan_name, **kwargs):
        """Create new vlan

        :param vid: ID of the new vlan
        :param vlan_name: Name of the vlan
        :param kwargs: Optional Arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"vid": vid, "name": vlan_name}
        return self.netbox_con.post('/ipam/vlans/', required_fields, **kwargs)

    def delete_vlan(self, vid):
        """Delete VLAN based on VLAN ID

        :param vid: vlan id to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            vid_id = self.get_vlans(vid=vid)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vlan: {}'.format(vid)) from None
        return self.netbox_con.delete('/ipam/vlans/', vid_id)

    def update_vlan(self, vlan_name, **kwargs):
        """Update vlan

        :param vlan_name: Name of the vlan
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            vlan_id = self.get_vlans(name=vlan_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vlan: {}'.format(vlan_name)) from None
        return self.netbox_con.patch('/ipam/vlans/', vlan_id, **kwargs)

    def get_vlan_groups(self, **kwargs):
        """Return all vlans"""
        return self.netbox_con.get('/ipam/vlan-groups/', **kwargs)

    def create_vlan_group(self, name, slug, **kwargs):
        """Create new vlan-group

        :param name: name of the vlan group
        :param slug: slug
        :param kwargs: Optional Arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "slug": slug}
        return self.netbox_con.post('/ipam/vlan-groups/', required_fields, **kwargs)

    def delete_vlan_group(self, name):
        """Delete VLAN group

        :param name: name of the vlan-group to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            vgrp_id = self.get_vlan_groups(name=name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vlan: {}'.format(name)) from None
        return self.netbox_con.delete('/ipam/vlan-groups/', vgrp_id)

    def update_vlan_group(self, name, **kwargs):
        """Update vlan-group

        :param name: name of the vlan-group
        :param kwargs: arguments
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            vgrp_ip = self.get_vlan_groups(name=name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('name: {}'.format(name)) from None
        return self.netbox_con.patch('/ipam/vlan-groups/', vgrp_ip, **kwargs)
<commit_msg>added function get_services<commit_after>import ipaddress
from netbox import exceptions

class Ipam(object):

    def __init__(self, netbox_con):

        self.netbox_con = netbox_con

    def get_services(self, **kwargs):
         """Return all services"""
         return self.netbox_con.get('/ipam/services/', **kwargs)

    def get_ip_addresses(self, **kwargs):
        """Return all ip addresses"""
        return self.netbox_con.get('/ipam/ip-addresses/', **kwargs)

    def get_ip_by_device(self, device_name):
        """Get IPs which are associated to a device

        :param device_name: Name of the device
        :return: ip address information
        """
        return self.netbox_con.get('/ipam/ip-addresses', device=device_name)

    def get_ip_by_virtual_machine(self, vm_name):
        """Get IPs which are associated to a device

        :param vm_name: Name of the virtual machine
        :return: ip address information
        """
        return self.netbox_con.get('/ipam/ip-addresses', virtual_machine=vm_name)

    def create_ip_address(self, address, **kwargs):
        """Create a new ip address

        :param address: IP address
        :param kwargs: Optional arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"address": address}
        return self.netbox_con.post('/ipam/ip-addresses/', required_fields, **kwargs)

    def update_ip(self, ip_address, **kwargs):
        """Update ip address

        :param ip_address: ip address with prefix. Format: 1.1.1.1/32
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            ip_id = self.get_ip_addresses(address=ip_address)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip: {}'.format(ip_address)) from None
        return self.netbox_con.patch('/ipam/ip-addresses/', ip_id, **kwargs)

    def delete_ip_address(self, ip_address):
        """Delete IP address

        :param ip_address: IP address to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            ip_id = self.get_ip_addresses(address=ip_address)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip: {}'.format(ip_address)) from None
        return self.netbox_con.delete('/ipam/ip-addresses/', ip_id)

    def delete_ip_by_id(self, ip_id):
        """Delete IP address

        :param ip_id: ID of ip address to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        return self.netbox_con.delete('/ipam/ip-addresses/', ip_id)

    def get_ip_prefixes(self, **kwargs):
        """Return all ip prefixes"""
        return self.netbox_con.get('/ipam/prefixes/', **kwargs)

    def create_ip_prefix(self, prefix, **kwargs):
        """Create a new ip prefix

        :param prefix: A valid ip prefix format. The syntax will be checked with the ipaddress module
        :param kwargs: Optional arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"prefix": prefix}

        if ipaddress.ip_network(prefix, strict=True):
            return self.netbox_con.post('/ipam/prefixes/', required_fields, **kwargs)

    def delete_ip_prefix(self, **kwargs):
        """Delete IP prefix

        :param kwargs: Delete prefix based on filter values
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            ip_prefix_id = self.get_ip_prefixes(**kwargs)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip-prefix') from None
        return self.netbox_con.delete('/ipam/prefixes/', ip_prefix_id)

    def update_ip_prefix(self, ip_prefix, **kwargs):
        """Update ip address

        :param ip_prefix: ip prefix to update
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            ip_prefix_id = self.get_ip_prefixes(q=ip_prefix)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip-prefix: {}'.format(ip_prefix)) from None
        return self.netbox_con.patch('/ipam/prefixes/', ip_prefix_id, **kwargs)

    def get_next_available_ip(self, **kwargs):
        """Return next available ip in prefix

        :param kwargs: Use the filter fields from the get_prefixes call
        :return: next available ip
        """
        try:
            prefix_id = self.get_ip_prefixes(**kwargs)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('ip-prefix') from None

        param = '/ipam/prefixes/{}/available-ips/'.format(prefix_id)
        return self.netbox_con.get(param, limit=1)[0]['address']

    def get_vrfs(self, **kwargs):
        """Get all vrfs"""
        return self.netbox_con.get('/ipam/vrfs/', **kwargs)

    def create_vrf(self, name, rd, **kwargs):
        """Create a new vrf

        :param name: Name of the vrf
        :param rd: Route distinguisher in any format
        :param kwargs: Optional arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "rd": rd}
        return self.netbox_con.post('/ipam/vrfs/', required_fields, **kwargs)

    def delete_vrf(self, vrf_name):
        """Delete vrf

        :param vrf_name: Name of vrf to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            vrf_id = self.get_vrfs(name=vrf_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vrf: {}'.format(vrf_name)) from None
        return self.netbox_con.delete('/ipam/vrfs/', vrf_id)

    def update_vrf(self, vrf_name, **kwargs):
        """Update vrf

        :param vrf_name: name of the vrf to update
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            vrf_id = self.get_vrfs(name=vrf_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vrf: {}'.format(vrf_name)) from None
        return self.netbox_con.patch('/ipam/vrfs/', vrf_id, **kwargs)

    def get_aggregates(self, **kwargs):
        """Return all aggregates"""
        return self.netbox_con.get('/ipam/aggregates/', **kwargs)

    def create_aggregate(self, prefix, rir, **kwargs):
        """Creates a new aggregate

        :param prefix: IP Prefix
        :param rir: Name of the RIR
        :param kwargs: Optional Arguments
        :return:
        """
        rir_id = self.get_rirs(name=rir)[0]['id']
        required_fields = {"prefix": prefix, "rir": rir_id}

        if ipaddress.ip_network(prefix, strict=True):
            return self.netbox_con.post('/ipam/aggregates/', required_fields, **kwargs)

    def update_aggregate(self, prefix, **kwargs):
        """Update aggregate

        :param prefix: Prefix of the aggregate
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            aggregate_id = self.get_aggregates(prefix=prefix)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('aggregate: {}'.format(prefix)) from None
        return self.netbox_con.patch('/ipam/aggregates/', aggregate_id, **kwargs)

    def get_rirs(self, **kwargs):
        """Return all rirs"""
        return self.netbox_con.get('/ipam/rirs/', **kwargs)

    def create_rir(self, name, slug):
        """Create new rir

        :param name: Name of the rir
        :param slug: Name of the slug
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "slug": slug}
        return self.netbox_con.post('/ipam/rirs/', required_fields)

    def delete_rir(self, rir_name):
        """Delete rir

        :param rir_name: rir name to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            rir_id = self.get_rirs(name=rir_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('rir: {}'.format(rir_name)) from None
        return self.netbox_con.delete('/ipam/rirs/', rir_id)

    def update_rir(self, rir_name, **kwargs):
        """Update rir

        :param rir_name: Name of the rir
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            rir_id = self.get_rirs(name=rir_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('rir: {}'.format(rir_name)) from None
        return self.netbox_con.patch('/ipam/rirs/', rir_id, **kwargs)

    def get_roles(self, **kwargs):
        """Return all roles"""
        return self.netbox_con.get('/ipam/roles/', **kwargs)

    def create_role(self, name, slug, **kwargs):
        """Create new prefix/vlan role

        :param name: Name of the prefix/vlan role
        :param slug: Name of the slug
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "slug": slug}
        return self.netbox_con.post('/ipam/roles/', required_fields, **kwargs)

    def delete_role(self, role_name):
        """Delete prefix/vlan role

        :param role_name: prefix/vlan role to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            role_id = self.get_roles(name=role_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('prefix/vlan role: {}'.format(role_name)) from None
        return self.netbox_con.delete('/ipam/role/', role_id)

    def update_role(self, role_name, **kwargs):
        """Update prefix role

        :param role_name: Name of the prefix/vlan role
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            prefix_role_id = self.get_roles(name=role_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('prefix/vlan role: {}'.format(role_name)) from None
        return self.netbox_con.patch('/ipam/roles/', prefix_role_id, **kwargs)

    def get_vlans(self, **kwargs):
        """Return all vlans"""
        return self.netbox_con.get('/ipam/vlans/', **kwargs)

    def create_vlan(self, vid, vlan_name, **kwargs):
        """Create new vlan

        :param vid: ID of the new vlan
        :param vlan_name: Name of the vlan
        :param kwargs: Optional Arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"vid": vid, "name": vlan_name}
        return self.netbox_con.post('/ipam/vlans/', required_fields, **kwargs)

    def delete_vlan(self, vid):
        """Delete VLAN based on VLAN ID

        :param vid: vlan id to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            vid_id = self.get_vlans(vid=vid)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vlan: {}'.format(vid)) from None
        return self.netbox_con.delete('/ipam/vlans/', vid_id)

    def update_vlan(self, vlan_name, **kwargs):
        """Update vlan

        :param vlan_name: Name of the vlan
        :param kwargs: requests body dict
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            vlan_id = self.get_vlans(name=vlan_name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vlan: {}'.format(vlan_name)) from None
        return self.netbox_con.patch('/ipam/vlans/', vlan_id, **kwargs)

    def get_vlan_groups(self, **kwargs):
        """Return all vlans"""
        return self.netbox_con.get('/ipam/vlan-groups/', **kwargs)

    def create_vlan_group(self, name, slug, **kwargs):
        """Create new vlan-group

        :param name: name of the vlan group
        :param slug: slug
        :param kwargs: Optional Arguments
        :return: bool True if successful otherwise raise CreateException
        """
        required_fields = {"name": name, "slug": slug}
        return self.netbox_con.post('/ipam/vlan-groups/', required_fields, **kwargs)

    def delete_vlan_group(self, name):
        """Delete VLAN group

        :param name: name of the vlan-group to delete
        :return: bool True if successful otherwise raise DeleteException
        """
        try:
            vgrp_id = self.get_vlan_groups(name=name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('vlan: {}'.format(name)) from None
        return self.netbox_con.delete('/ipam/vlan-groups/', vgrp_id)

    def update_vlan_group(self, name, **kwargs):
        """Update vlan-group

        :param name: name of the vlan-group
        :param kwargs: arguments
        :return: bool True if successful otherwise raise UpdateException
        """
        try:
            vgrp_ip = self.get_vlan_groups(name=name)[0]['id']
        except IndexError:
            raise exceptions.NotFoundException('name: {}'.format(name)) from None
        return self.netbox_con.patch('/ipam/vlan-groups/', vgrp_ip, **kwargs)
<|endoftext|>


<commit_before>from datetime import timedelta, date
from pytz import timezone

# Django models
from django.db import models

# Our own models
from about.models import Member, Committee

"""
news.models module.

In this module we define the models for our Object-Relational Mapping (ORM) that
allows us to map python objects to a database which allows seamless database
interaction.
"""
class Post(models.Model):
    """
    Post model.

    This is the actual news post model, and contains a title, the post content,
    a published date, a post author and an option to not publish the post
    immediately.

    To interact with this object, make sure that it is imported, one can simply
    let the ORM do all the heavy lifing.
    Examples:

    >>> from news.models import Post
    # Imports the object

    >>> allPosts = Post.objects.all()
    # Gets all posts
    >>> allPublished = Post.objects.filter(published=True)
    # Gets all published posts
    >>> post14 = Post.objects.get(id=14)
    # Gets the fourteenth post
    """

    # Title of post
    title = models.CharField(max_length=100)
    # Content of post, could be html or anything
    content = models.TextField()
    # Date of when the post was published
    pub_date = models.DateTimeField('date published')
    # Link to the author that published the post
    author = models.ForeignKey(Member)
     # Whether the post is published or not
    published = models.BooleanField(default=False)

    @staticmethod
    def published_posts():
        """
        Retrieves all published posts from the current year.
        """
        year = date.today().year
        return Post.published_posts_by_year(year)

    @staticmethod
    def published_posts_by_year(year):
        """
        Retrieves all published posts from a specified year.
        """
        return Post.all_published_posts().filter(pub_date__year=int(year))

    @staticmethod
    def all_published_posts():
        """
        Retrieves all published posts

        All it does is filters out the unpublished posts.
        """
        return Post.objects.filter(published=True)

    @staticmethod
    def by_month(year, month):
        """
        Retrieve all posts published during a month.

        To get the last day in the month a little hack is used,
        we get the date of the first day in next month and then we
        subtract one day from the date. This gives us the date for
        the last day in the month so that we retrieve every post
        in a month without knowing the number of days in that month.

        Raises a ValueError if month is out of bounds.
        """
        first_day = date(int(year), int(month), 1)

        # last day = first day in next month - 1 day
        last_day = date(int(year), int(month)+1, 1) - timedelta(days=1)
        return Post.published_posts().filter(pub_date__date__range=(first_day, last_day))

    @staticmethod
    def by_day(year, month, day):
        """
        Retrieves the posts published during a day in a month.

        Raises a ValueError if month or day are out of bounds.
        """
        sthlm = timezone("Europe/Stockholm")

        date = date(int(year), int(month), int(day))
        return Post.published_posts().filter(pub_date__date=date)

    def publish(self):
        """
        Publishes a post.

        This function will publish a post and then save it,
        if the post already is published nothing happens.

        >>> p = Post(title="T", content="Some text", author=0)
        # Creates a new post
        >>> p.publish()
        # Sets its status to published and saves the post
        """
        if not self.published:
            self.published = True
            self.save()
        # If self is published, nothing will happen

    def unpublish(self):
        """
        Unpublishes a post.

        This function will unpublish a post and then save it,
        if the post is not published when this function is called nothing will
        happen.

        >>> p = Post.objects.latest('pub_date')
        # p = latest post (considering published date)
        >>> p.unpublish()
        # Sets its status to unpublished and saves the post
        """

        if self.published:
            self.published = False
            self.save()
        # If self is not published, nothing will happen

    def __str__(self):
        """
        To string function.
        This function is called when Python is trying to display a Post in text.

        With this function every time a post is displayed in a textual
        representation it is now called <Post: $title> or something like that.
        """
        return self.title
<commit_msg>Made Post sort posts in chronological order.<commit_after>from datetime import timedelta, date
from pytz import timezone

# Django models
from django.db import models

# Our own models
from about.models import Member, Committee

"""
news.models module.

In this module we define the models for our Object-Relational Mapping (ORM) that
allows us to map python objects to a database which allows seamless database
interaction.
"""
class Post(models.Model):
    """
    Post model.

    This is the actual news post model, and contains a title, the post content,
    a published date, a post author and an option to not publish the post
    immediately.

    To interact with this object, make sure that it is imported, one can simply
    let the ORM do all the heavy lifing.
    Examples:

    >>> from news.models import Post
    # Imports the object

    >>> allPosts = Post.objects.all()
    # Gets all posts
    >>> allPublished = Post.objects.filter(published=True)
    # Gets all published posts
    >>> post14 = Post.objects.get(id=14)
    # Gets the fourteenth post
    """

    # Title of post
    title = models.CharField(max_length=100)
    # Content of post, could be html or anything
    content = models.TextField()
    # Date of when the post was published
    pub_date = models.DateTimeField('date published')
    # Link to the author that published the post
    author = models.ForeignKey(Member)
     # Whether the post is published or not
    published = models.BooleanField(default=False)

    @staticmethod
    def published_posts():
        """
        Retrieves all published posts from the current year.
        """
        year = date.today().year
        return Post.published_posts_by_year(year).reverse()

    @staticmethod
    def published_posts_by_year(year):
        """
        Retrieves all published posts from a specified year.
        """
        return Post.all_published_posts().filter(pub_date__year=int(year))

    @staticmethod
    def all_published_posts():
        """
        Retrieves all published posts

        All it does is filters out the unpublished posts.
        """
        return Post.objects.filter(published=True).order_by("pub_date")

    @staticmethod
    def by_month(year, month):
        """
        Retrieve all posts published during a month.

        To get the last day in the month a little hack is used,
        we get the date of the first day in next month and then we
        subtract one day from the date. This gives us the date for
        the last day in the month so that we retrieve every post
        in a month without knowing the number of days in that month.

        Raises a ValueError if month is out of bounds.
        """
        first_day = date(int(year), int(month), 1)

        # last day = first day in next month - 1 day
        last_day = date(int(year), int(month)+1, 1) - timedelta(days=1)
        return Post.published_posts().filter(pub_date__date__range=(first_day, last_day))

    @staticmethod
    def by_day(year, month, day):
        """
        Retrieves the posts published during a day in a month.

        Raises a ValueError if month or day are out of bounds.
        """
        sthlm = timezone("Europe/Stockholm")

        date = date(int(year), int(month), int(day))
        return Post.published_posts().filter(pub_date__date=date)

    def publish(self):
        """
        Publishes a post.

        This function will publish a post and then save it,
        if the post already is published nothing happens.

        >>> p = Post(title="T", content="Some text", author=0)
        # Creates a new post
        >>> p.publish()
        # Sets its status to published and saves the post
        """
        if not self.published:
            self.published = True
            self.save()
        # If self is published, nothing will happen

    def unpublish(self):
        """
        Unpublishes a post.

        This function will unpublish a post and then save it,
        if the post is not published when this function is called nothing will
        happen.

        >>> p = Post.objects.latest('pub_date')
        # p = latest post (considering published date)
        >>> p.unpublish()
        # Sets its status to unpublished and saves the post
        """

        if self.published:
            self.published = False
            self.save()
        # If self is not published, nothing will happen

    def __str__(self):
        """
        To string function.
        This function is called when Python is trying to display a Post in text.

        With this function every time a post is displayed in a textual
        representation it is now called <Post: $title> or something like that.
        """
        return self.title
<|endoftext|>


<commit_before>#!/usr/bin/env python

import nfldb

db = nfldb.connect()

# Get a list of the teams in the NFL and place it in teams list
teams = []
unknown = 'UNK'
with nfldb.Tx(db) as cursor:
    cursor.execute('''
        SELECT %s FROM team WHERE city != %%s
        ''' % '*', (unknown,))
    for row in cursor.fetchall():
        teams.append(row)

weekly_data = {}
for week in range(1,5):
    weeks_data = {}
    # for all 17 weeks, calculate the winning percentage of each team t so far in the season (since week i+1)
    for t in teams:
        team = t['team_id']
        q = nfldb.Query(db)
        q.game(season_year=2009, season_type='Regular', week__lt=week)
        games_played = q.as_games()
        wins = len([g for g in games_played if g.winner == team])
        loses = len([g for g in games_played if g.loser == team])
        try:
            WP = (wins/float((wins+loses)))
        except ZeroDivisionError:
            WP = 0.0
        weeks_data[team] = {'wp': WP}

        q = nfldb.Query(db)
        this_team_played = nfldb.QueryOR(db).game(home_team=team).game(away_team=team)
        q.game(season_year=2009, season_type='Regular', week__lt=week)
        all_previous_games = q.andalso(this_team_played).as_games()
        opponents = [g.away_team if g.home_team == team else g.home_team for g in all_previous_games]
        opponents_records = []
        for o in opponents:
            q = nfldb.Query(db)
            opponent_played = nfldb.QueryOR(db).game(home_team=o).game(away_team=o)
            q.game(season_year=2009, season_type='Regular', week__lt=week, home_team__ne=team, away_team__ne=team)
            all_opponents_previous_games = q.andalso(opponent_played).as_games()
            wins = len([g for g in all_opponents_previous_games if g.winner == o])
            loses = len([g for g in all_opponents_previous_games if g.loser == o])
            try:
                record = (wins/float((wins+loses)))
            except ZeroDivisionError:
                record = 0.0
            opponents_records.append(record)
        try:
            OWP = sum(opponents_records)/float(len(opponents))
        except ZeroDivisionError:
            OWP = 0.0
        weeks_data[team]['owp'] = OWP

        opponents_by_week = dict([(g.week, g.away_team) if g.home_team == team else (g.week, g.home_team) for g in all_previous_games])
        owps = []
        for k,v in opponents_by_week.iteritems():
            owps.append(weekly_data[str(k)][v]['owp'])
        try:
            OOWP = sum(owps)/float(len(opponents_by_week))
        except ZeroDivisionError:
            OOWP = 0.0
        weeks_data[team]['oowp'] = OOWP
        weeks_data[team]['rpi'] = 0.25 * WP + 0.5 + OWP * 0.5 + 0.25 * OOWP
    weekly_data[str(week)] = weeks_data

for k, v in weekly_data.iteritems():
    print '\nWEEK %s' % k
    print '-------------------'
    for team, stats in v.iteritems():
        print 'TEAM: %s' % team
        for stat, val in stats.iteritems():
            print '%s: %s' %(stat, val)
<commit_msg>add turnover differential, offensive strategy and pyth wins.<commit_after>#!/usr/bin/env python

import nfldb

db = nfldb.connect()

# Get a list of the teams in the NFL and place it in teams list
teams = []
unknown = 'UNK'
with nfldb.Tx(db) as cursor:
    cursor.execute('''
        SELECT %s FROM team WHERE city != %%s
        ''' % '*', (unknown,))
    for row in cursor.fetchall():
        teams.append(row)

weekly_data = {}
for week in range(1,18):
    weeks_data = {}
    # for all 17 weeks, calculate the winning percentage of each team t so far in the season (since week i+1)
    for t in teams:
        team = t['team_id']
        q = nfldb.Query(db)
        this_team_played = nfldb.QueryOR(db).game(home_team=team).game(away_team=team)
        q.game(season_year=2009, season_type='Regular', week__lt=week)
        all_previous_games = q.andalso(this_team_played).as_games()
        wins = len([g for g in all_previous_games if g.winner == team])
        loses = len([g for g in all_previous_games if g.loser == team])
        try:
            WP = (wins/float((wins+loses)))
        except ZeroDivisionError:
            WP = 0.0
        weeks_data[team] = {'wp': WP}

        opponents = [g.away_team if g.home_team == team else g.home_team for g in all_previous_games]
        opponents_records = []
        for o in opponents:
            q = nfldb.Query(db)
            opponent_played = nfldb.QueryOR(db).game(home_team=o).game(away_team=o)
            q.game(season_year=2009, season_type='Regular', week__lt=week, home_team__ne=team, away_team__ne=team)
            all_opponents_previous_games = q.andalso(opponent_played).as_games()
            wins = len([g for g in all_opponents_previous_games if g.winner == o])
            loses = len([g for g in all_opponents_previous_games if g.loser == o])
            try:
                record = (wins/float((wins+loses)))
            except ZeroDivisionError:
                record = 0.0
            opponents_records.append(record)
        try:
            OWP = sum(opponents_records)/float(len(opponents))
        except ZeroDivisionError:
            OWP = 0.0
        weeks_data[team]['owp'] = OWP

        opponents_by_week = dict([(g.week, g.away_team) if g.home_team == team else (g.week, g.home_team) for g in all_previous_games])
        owps = []
        for k,v in opponents_by_week.iteritems():
            owps.append(weekly_data[str(k)][v]['owp'])
        try:
            OOWP = sum(owps)/float(len(opponents_by_week))
        except ZeroDivisionError:
            OOWP = 0.0
        weeks_data[team]['oowp'] = OOWP
        weeks_data[team]['rpi'] = 0.25 * WP + 0.5 + OWP * 0.5 + 0.25 * OOWP

        points_for = sum([g.home_score if g.home_team == team else g.away_score for g in all_previous_games])
        points_against = sum([g.away_score if g.home_team == team else g.home_score for g in all_previous_games])
        try:
            pyth_wins = pow(points_for, 2.37)/(pow(points_for, 2.37) + pow(points_against, 2.37))
        except ZeroDivisionError:
            pyth_wins = 0
        weeks_data[team]['pyth_wins'] = pyth_wins

        q = nfldb.Query(db)
        q.game(season_year=2015, season_type='Regular', week__lt=week, team=team)
        passing_attempts = 0
        rushing_attempts = 0
        for pp in q.drive(pos_team=team).as_aggregate():
            passing_attempts = passing_attempts + pp.passing_att
            rushing_attempts = rushing_attempts + pp.rushing_att
        try:
            offensive_strategy = passing_attempts/float(rushing_attempts)
        except ZeroDivisionError:
            offensive_strategy = 0.0
        weeks_data[team]['offensive_strategy'] = offensive_strategy

        q = nfldb.Query(db)
        q.game(season_year=2009, season_type='Regular', week__lt=week, team=team)
        interceptions = 0
        fumbles_recovered = 0
        for pp in q.drive(pos_team__ne=team).as_aggregate():
            interceptions = interceptions + pp.defense_int
            fumbles_recovered = fumbles_recovered + pp.defense_frec

        q = nfldb.Query(db)
        q.game(season_year=2009, season_type='Regular', week__lt=week, team=team)
        interceptions_lost = 0
        fumbles_lost = 0
        for pp in q.drive(pos_team=team).as_aggregate():
            interceptions_lost = interceptions_lost + pp.passing_int
            fumbles_lost = fumbles_lost + pp.fumbles_lost

        takeaways = interceptions + fumbles_recovered
        giveaways = interceptions_lost + fumbles_lost

        try:
            turnover_differential = takeaways/float(giveaways)
        except ZeroDivisionError:
            turnover_differential = 0.0
        weeks_data[team]['turnover_differential'] = turnover_differential

    weekly_data[str(week)] = weeks_data

for k, v in weekly_data.iteritems():
    print '\nWEEK %s' % k
    print '-------------------'
    for team, stats in v.iteritems():
        print 'TEAM: %s' % team
        for stat, val in stats.iteritems():
            print '%s: %s' %(stat, val)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Copyright © 2014—2016 Dontnod Entertainment

# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:

# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
''' Unreal Engine 4 related stuff '''

import os
import platform
import logging

import nimp.build
import nimp.system

def load_config(env):
    ''' Loads Unreal specific configuration values on env before parsing
        command-line arguments '''
    env.is_ue4 = hasattr(env, 'project_type') and env.project_type is 'UE4'
    return True

def load_arguments(env):
    ''' Loads Unreal specific environment parameters. '''
    if hasattr(env, 'project_type') and env.project_type == 'UE4':
        return _ue4_load_arguments(env)

    return True

def build(env):
    ''' Builds an Unreal Engine Project. config and platform arguments should
        be set on environment in order to call this function. You can use
        `nimp.environment.add_arguments` and `nimp.build.add_arguments` to do
        so.'''
    if not _check_for_unreal(env):
        return False
    return _ue4_build(env)

def commandlet(env, command, *args, heartbeat = 0):
    ''' Runs an Unreal Engine commandlet. It can be usefull to run it through
        nimp as OutputDebugString will be redirected to standard output. '''
    if not _check_for_unreal(env):
        return False
    return _ue4_commandlet(env, command, *args, heartbeat = heartbeat)

def is_unreal4_available(env):
    ''' Returns a tuple containing unreal availability and a help text
        giving a reason of why it isn't if it's the case '''
    return env.is_ue4, ('No .nimp.conf configured for Unreal 4 was found in '
                        'this directory or one of its parents. Check that you '
                        'are launching nimp from inside an UE4 project directory'
                        ' and that you have a properly configured .nimp.conf. '
                        'Check documentation for more details on .nimp.conf.')
def _check_for_unreal(env):
    if not env.is_ue4:
        logging.error('This doesn\'t seems to be a supported project type.')
        logging.error('Check that you are launching nimp from an UE project')
        logging.error('directory, and that you have a .nimp.conf file in the')
        logging.error('project root directory (see documentation for further')
        logging.error('details)')
        return False
    return True

def _ue4_build(env):
    assert hasattr(env, 'ue4_config')
    assert env.ue4_config is not None

    if env.disable_unity:
        os.environ['UBT_bUseUnityBuild'] = 'false'

    if env.fastbuild:
        os.environ['UBT_bAllowFastBuild'] = 'true'
        os.environ['UBT_bUseUnityBuild'] = 'false'

    nimp.environment.execute_hook('before_ue4_build', env)

    # Bootstrap if necessary
    if hasattr(env, 'bootstrap') and env.bootstrap:
        # Now generate project files
        if _ue4_generate_project(env) != 0:
            logging.error("Error generating UE4 project files")
            return False

    # Default to VS 2015, The Durango XDK does not support Visual Studio 2013 yet, so if UE4
    # detected it, it created VS 2012 project files and we have to use that
    # version to build the tools instead.
    vs_version = '14'
    try:
        for line in open(env.format(env.solution)):
            if '# Visual Studio 2012' in line:
                vs_version = '11'
                break
            if '# Visual Studio 2013' in line:
                vs_version = '12'
                break
            if '# Visual Studio 2015' in line:
                vs_version = '14'
                break
    except IOError:
        pass

    # The main solution file
    solution = env.format(env.solution)

    # We’ll try to build all tools even in case of failure
    success = True

    # List of tools to build
    tools = [ 'UnrealHeaderTool' ]

    # Some tools are necessary even when not building tools...
    need_ps4devkitutil = False
    need_ps4mapfileutil = env.platform == 'ps4'
    need_xboxonepdbfileutil = env.platform == 'xboxone'

    if env.target == 'tools':

        tools += [ 'UnrealFrontend',
                   'UnrealFileServer',
                   'ShaderCompileWorker',
                   'UnrealPak', ]

        if env.platform != 'mac':
            tools += [ 'UnrealLightmass', ] # doesn’t build (yet?)

        if env.platform == 'linux':
            tools += [ 'CrossCompilerTool', ]

        if env.platform == 'win64':
            tools += [ 'DotNETUtilities',
                       'AutomationTool',
                       'SymbolDebugger', ]
            need_ps4devkitutil = True
            need_ps4mapfileutil = True
            need_xboxonepdbfileutil = True

    # Some tools are necessary even when not building tools...
    if need_ps4devkitutil and os.path.exists(nimp.system.sanitize_path(env.format('{root_dir}/Engine/Source/Programs/PS4/PS4DevKitUtil/PS4DevKitUtil.csproj'))):
        tools += [ 'PS4DevKitUtil' ]

    if need_ps4mapfileutil and os.path.exists(nimp.system.sanitize_path(env.format('{root_dir}/Engine/Source/Programs/PS4/PS4MapFileUtil/PS4MapFileUtil.Build.cs'))):
        tools += [ 'PS4MapFileUtil' ]

    if need_xboxonepdbfileutil and os.path.exists(nimp.system.sanitize_path(env.format('{root_dir}/Engine/Source/Programs/XboxOne/XboxOnePDBFileUtil/XboxOnePDBFileUtil.Build.cs'))):
        tools += [ 'XboxOnePDBFileUtil' ]

    # Build tools from the main solution
    for tool in tools:
        if not _ue4_build_project(env, solution, tool,
                                  'Mac' if env.platform == 'mac'
                                  else 'Linux' if env.platform == 'linux'
                                  else 'Win64',
                                  'Development', vs_version, 'Build'):
            logging.error("Could not build %s", tool)
            success = False

    # Build tools from other solutions or with other flags
    if env.target == 'tools':

        if not nimp.build.vsbuild(env.format('{root_dir}/Engine/Source/Programs/NetworkProfiler/NetworkProfiler.sln'),
                                  'Any CPU', 'Development', None, vs_version, 'Build'):
            logging.error("Could not build NetworkProfiler")
            success = False

        if env.platform != 'mac':
            # This also builds AgentInterface.dll, needed by SwarmInterface.sln
            # XXX: try 10 times because of a race condition in there
            for attempt in range(10):
                swarm_success = True
                if nimp.build.vsbuild(env.format('{root_dir}/Engine/Source/Programs/UnrealSwarm/UnrealSwarm.sln'),
                                      'Any CPU', 'Development', None, vs_version, 'Build'):
                    break
                logging.error("Could not build UnrealSwarm")
                swarm_success = False

            if not swarm_success:
                success = False

            if not nimp.build.vsbuild(env.format('{root_dir}/Engine/Source/Editor/SwarmInterface/DotNET/SwarmInterface.sln'),
                                      'Any CPU', 'Development', None, vs_version, 'Build'):
                logging.error("Could not build SwarmInterface")
                success = False

        # These tools seem to be Windows only for now
        if env.platform == 'win64':

            if not _ue4_build_project(env, solution, 'BootstrapPackagedGame',
                                      'Win64', 'Shipping', vs_version, 'Build'):
                logging.error("Could not build BootstrapPackagedGame")
                success = False

            tmp = env.format('{root_dir}/Engine/Source/Programs/XboxOne/XboxOnePackageNameUtil/XboxOnePackageNameUtil.sln')
            if os.path.exists(nimp.system.sanitize_path(tmp)):
                if not nimp.build.vsbuild(tmp, 'x64', 'Development', None, '11', 'Build') \
                   and not nimp.build.vsbuild(tmp, 'x64', 'Development', None, '14', 'Build'):
                    logging.error("Could not build XboxOnePackageNameUtil")
                    success = False

    if not success:
        return success

    if env.target == 'game':
        if not _ue4_build_project(env, solution, env.game, env.ue4_platform,
                                  env.ue4_config, vs_version, 'Build'):
            success = False

    if env.target == 'editor':
        if env.platform in ['linux', 'mac']:
            project = env.game + 'Editor'
            config = env.ue4_config
        else:
            project = env.game
            config = env.ue4_config + ' Editor'

        if not _ue4_build_project(env, solution, project, env.ue4_platform,
                                  config, vs_version, 'Build'):
            success = False

    nimp.environment.execute_hook('after_ue4_build', env, success)

    return success

def _ue4_commandlet(env, command, *args, heartbeat = 0):
    ''' Runs an UE4 commandlet '''
    if nimp.system.is_windows():
        exe = 'Engine/Binaries/Win64/UE4Editor.exe'
    elif platform.system() == 'Darwin':
        exe = 'Engine/Binaries/Mac/UE4Editor'
    else:
        exe = 'Engine/Binaries/Linux/UE4Editor'

    cmdline = [nimp.system.sanitize_path(os.path.join(env.format(env.root_dir), exe)),
               env.game,
               '-run=%s' % command]

    cmdline += list(args)
    cmdline += ['-nopause', '-buildmachine', '-forcelogflush', '-unattended', '-noscriptcheck']

    return nimp.system.call_process('.', cmdline, heartbeat = heartbeat) == 0

def _ue4_generate_project(env):
    if nimp.system.is_windows():
        return nimp.system.call_process(env.root_dir, ['cmd', '/c', 'GenerateProjectFiles.bat'])
    else:
        return nimp.system.call_process(env.root_dir, ['/bin/sh', './GenerateProjectFiles.sh'])

def _ue4_build_project(env, sln_file, project, build_platform,
                       configuration, vs_version, target = 'Rebuild'):

    if nimp.system.is_windows():
        return nimp.build.vsbuild(sln_file, build_platform, configuration,
                                  project, vs_version, target)

    if platform.system() == 'Darwin':
        host_platform = 'Mac'
    else:
        host_platform = 'Linux'

    return nimp.system.call_process(env.root_dir,
                                    ['/bin/sh', './Engine/Build/BatchFiles/%s/Build.sh' % (host_platform),
                                     project, build_platform, configuration]) == 0

def _ue4_load_arguments(env):
    ''' Sets some variables for use with unreal 4 '''
    def _get_ue4_config(config):
        configs = { "debug"    : "Debug",
                    "devel"    : "Development",
                    "test"     : "Test",
                    "shipping" : "Shipping", }
        if config not in configs:
            logging.warning('Unsupported UE4 build config “%s”', config)
            return None
        return configs[config]

    def _get_ue4_platform(in_platform):
        platforms = { "ps4"     : "PS4",
                      "xboxone" : "XboxOne",
                      "win64"   : "Win64",
                      "win32"   : "Win32",
                      "linux"   : "Linux",
                      "mac"     : "Mac", }
        if in_platform not in platforms:
            logging.warning('Unsupported UE4 build platform “%s”', in_platform)
            return None
        return platforms[in_platform]

    if hasattr(env, 'platform'):
        env.ue4_platform = '+'.join(map(_get_ue4_platform, env.platform.split('+')))

    if hasattr(env, 'configuration'):
        if env.configuration is None:
            env.configuration = 'devel'
        env.ue4_config = '+'.join(map(_get_ue4_config, env.configuration.split('+')))

    if not hasattr(env, 'target') or env.target is None and env.is_ue4:
        if env.platform in ['win64', 'mac', 'linux']:
            env.target = 'editor'
        else:
            env.target = 'game'

    return True
<commit_msg>.sln file (Microsoft Visual Studio Solution File): at some point (between Format Version 9.00 and 12.00 I guess...), the comment near the beginning of the file seems to have changed from e.g. # Visual Studio 2015 to # Visual Studio 14 So let's be a bit more flexible in our parsing (even though we could, you know, try and read VisualStudioVersion instead of a comment...)<commit_after># -*- coding: utf-8 -*-
# Copyright © 2014—2016 Dontnod Entertainment

# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:

# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
''' Unreal Engine 4 related stuff '''

import os
import platform
import logging

import nimp.build
import nimp.system

def load_config(env):
    ''' Loads Unreal specific configuration values on env before parsing
        command-line arguments '''
    env.is_ue4 = hasattr(env, 'project_type') and env.project_type is 'UE4'
    return True

def load_arguments(env):
    ''' Loads Unreal specific environment parameters. '''
    if hasattr(env, 'project_type') and env.project_type == 'UE4':
        return _ue4_load_arguments(env)

    return True

def build(env):
    ''' Builds an Unreal Engine Project. config and platform arguments should
        be set on environment in order to call this function. You can use
        `nimp.environment.add_arguments` and `nimp.build.add_arguments` to do
        so.'''
    if not _check_for_unreal(env):
        return False
    return _ue4_build(env)

def commandlet(env, command, *args, heartbeat = 0):
    ''' Runs an Unreal Engine commandlet. It can be usefull to run it through
        nimp as OutputDebugString will be redirected to standard output. '''
    if not _check_for_unreal(env):
        return False
    return _ue4_commandlet(env, command, *args, heartbeat = heartbeat)

def is_unreal4_available(env):
    ''' Returns a tuple containing unreal availability and a help text
        giving a reason of why it isn't if it's the case '''
    return env.is_ue4, ('No .nimp.conf configured for Unreal 4 was found in '
                        'this directory or one of its parents. Check that you '
                        'are launching nimp from inside an UE4 project directory'
                        ' and that you have a properly configured .nimp.conf. '
                        'Check documentation for more details on .nimp.conf.')
def _check_for_unreal(env):
    if not env.is_ue4:
        logging.error('This doesn\'t seems to be a supported project type.')
        logging.error('Check that you are launching nimp from an UE project')
        logging.error('directory, and that you have a .nimp.conf file in the')
        logging.error('project root directory (see documentation for further')
        logging.error('details)')
        return False
    return True

def _ue4_build(env):
    assert hasattr(env, 'ue4_config')
    assert env.ue4_config is not None

    if env.disable_unity:
        os.environ['UBT_bUseUnityBuild'] = 'false'

    if env.fastbuild:
        os.environ['UBT_bAllowFastBuild'] = 'true'
        os.environ['UBT_bUseUnityBuild'] = 'false'

    nimp.environment.execute_hook('before_ue4_build', env)

    # Bootstrap if necessary
    if hasattr(env, 'bootstrap') and env.bootstrap:
        # Now generate project files
        if _ue4_generate_project(env) != 0:
            logging.error("Error generating UE4 project files")
            return False

    # Default to VS 2015, The Durango XDK does not support Visual Studio 2013 yet, so if UE4
    # detected it, it created VS 2012 project files and we have to use that
    # version to build the tools instead.
    vs_version = '14'
    try:
        for line in open(env.format(env.solution)):
            if ('# Visual Studio 2012' in line or
                '# Visual Studio 11' in line):
                vs_version = '11'
                break
            if ('# Visual Studio 2013' in line or
                '# Visual Studio 12' in line):
                vs_version = '12'
                break
            if ('# Visual Studio 2015' in line or
                '# Visual Studio 14' in line):
                vs_version = '14'
                break
    except IOError:
        pass

    # The main solution file
    solution = env.format(env.solution)

    # We’ll try to build all tools even in case of failure
    success = True

    # List of tools to build
    tools = [ 'UnrealHeaderTool' ]

    # Some tools are necessary even when not building tools...
    need_ps4devkitutil = False
    need_ps4mapfileutil = env.platform == 'ps4'
    need_xboxonepdbfileutil = env.platform == 'xboxone'

    if env.target == 'tools':

        tools += [ 'UnrealFrontend',
                   'UnrealFileServer',
                   'ShaderCompileWorker',
                   'UnrealPak', ]

        if env.platform != 'mac':
            tools += [ 'UnrealLightmass', ] # doesn’t build (yet?)

        if env.platform == 'linux':
            tools += [ 'CrossCompilerTool', ]

        if env.platform == 'win64':
            tools += [ 'DotNETUtilities',
                       'AutomationTool',
                       'SymbolDebugger', ]
            need_ps4devkitutil = True
            need_ps4mapfileutil = True
            need_xboxonepdbfileutil = True

    # Some tools are necessary even when not building tools...
    if need_ps4devkitutil and os.path.exists(nimp.system.sanitize_path(env.format('{root_dir}/Engine/Source/Programs/PS4/PS4DevKitUtil/PS4DevKitUtil.csproj'))):
        tools += [ 'PS4DevKitUtil' ]

    if need_ps4mapfileutil and os.path.exists(nimp.system.sanitize_path(env.format('{root_dir}/Engine/Source/Programs/PS4/PS4MapFileUtil/PS4MapFileUtil.Build.cs'))):
        tools += [ 'PS4MapFileUtil' ]

    if need_xboxonepdbfileutil and os.path.exists(nimp.system.sanitize_path(env.format('{root_dir}/Engine/Source/Programs/XboxOne/XboxOnePDBFileUtil/XboxOnePDBFileUtil.Build.cs'))):
        tools += [ 'XboxOnePDBFileUtil' ]

    # Build tools from the main solution
    for tool in tools:
        if not _ue4_build_project(env, solution, tool,
                                  'Mac' if env.platform == 'mac'
                                  else 'Linux' if env.platform == 'linux'
                                  else 'Win64',
                                  'Development', vs_version, 'Build'):
            logging.error("Could not build %s", tool)
            success = False

    # Build tools from other solutions or with other flags
    if env.target == 'tools':

        if not nimp.build.vsbuild(env.format('{root_dir}/Engine/Source/Programs/NetworkProfiler/NetworkProfiler.sln'),
                                  'Any CPU', 'Development', None, vs_version, 'Build'):
            logging.error("Could not build NetworkProfiler")
            success = False

        if env.platform != 'mac':
            # This also builds AgentInterface.dll, needed by SwarmInterface.sln
            # XXX: try 10 times because of a race condition in there
            for attempt in range(10):
                swarm_success = True
                if nimp.build.vsbuild(env.format('{root_dir}/Engine/Source/Programs/UnrealSwarm/UnrealSwarm.sln'),
                                      'Any CPU', 'Development', None, vs_version, 'Build'):
                    break
                logging.error("Could not build UnrealSwarm")
                swarm_success = False

            if not swarm_success:
                success = False

            if not nimp.build.vsbuild(env.format('{root_dir}/Engine/Source/Editor/SwarmInterface/DotNET/SwarmInterface.sln'),
                                      'Any CPU', 'Development', None, vs_version, 'Build'):
                logging.error("Could not build SwarmInterface")
                success = False

        # These tools seem to be Windows only for now
        if env.platform == 'win64':

            if not _ue4_build_project(env, solution, 'BootstrapPackagedGame',
                                      'Win64', 'Shipping', vs_version, 'Build'):
                logging.error("Could not build BootstrapPackagedGame")
                success = False

            tmp = env.format('{root_dir}/Engine/Source/Programs/XboxOne/XboxOnePackageNameUtil/XboxOnePackageNameUtil.sln')
            if os.path.exists(nimp.system.sanitize_path(tmp)):
                if not nimp.build.vsbuild(tmp, 'x64', 'Development', None, '11', 'Build') \
                   and not nimp.build.vsbuild(tmp, 'x64', 'Development', None, '14', 'Build'):
                    logging.error("Could not build XboxOnePackageNameUtil")
                    success = False

    if not success:
        return success

    if env.target == 'game':
        if not _ue4_build_project(env, solution, env.game, env.ue4_platform,
                                  env.ue4_config, vs_version, 'Build'):
            success = False

    if env.target == 'editor':
        if env.platform in ['linux', 'mac']:
            project = env.game + 'Editor'
            config = env.ue4_config
        else:
            project = env.game
            config = env.ue4_config + ' Editor'

        if not _ue4_build_project(env, solution, project, env.ue4_platform,
                                  config, vs_version, 'Build'):
            success = False

    nimp.environment.execute_hook('after_ue4_build', env, success)

    return success

def _ue4_commandlet(env, command, *args, heartbeat = 0):
    ''' Runs an UE4 commandlet '''
    if nimp.system.is_windows():
        exe = 'Engine/Binaries/Win64/UE4Editor.exe'
    elif platform.system() == 'Darwin':
        exe = 'Engine/Binaries/Mac/UE4Editor'
    else:
        exe = 'Engine/Binaries/Linux/UE4Editor'

    cmdline = [nimp.system.sanitize_path(os.path.join(env.format(env.root_dir), exe)),
               env.game,
               '-run=%s' % command]

    cmdline += list(args)
    cmdline += ['-nopause', '-buildmachine', '-forcelogflush', '-unattended', '-noscriptcheck']

    return nimp.system.call_process('.', cmdline, heartbeat = heartbeat) == 0

def _ue4_generate_project(env):
    if nimp.system.is_windows():
        return nimp.system.call_process(env.root_dir, ['cmd', '/c', 'GenerateProjectFiles.bat'])
    else:
        return nimp.system.call_process(env.root_dir, ['/bin/sh', './GenerateProjectFiles.sh'])

def _ue4_build_project(env, sln_file, project, build_platform,
                       configuration, vs_version, target = 'Rebuild'):

    if nimp.system.is_windows():
        return nimp.build.vsbuild(sln_file, build_platform, configuration,
                                  project, vs_version, target)

    if platform.system() == 'Darwin':
        host_platform = 'Mac'
    else:
        host_platform = 'Linux'

    return nimp.system.call_process(env.root_dir,
                                    ['/bin/sh', './Engine/Build/BatchFiles/%s/Build.sh' % (host_platform),
                                     project, build_platform, configuration]) == 0

def _ue4_load_arguments(env):
    ''' Sets some variables for use with unreal 4 '''
    def _get_ue4_config(config):
        configs = { "debug"    : "Debug",
                    "devel"    : "Development",
                    "test"     : "Test",
                    "shipping" : "Shipping", }
        if config not in configs:
            logging.warning('Unsupported UE4 build config “%s”', config)
            return None
        return configs[config]

    def _get_ue4_platform(in_platform):
        platforms = { "ps4"     : "PS4",
                      "xboxone" : "XboxOne",
                      "win64"   : "Win64",
                      "win32"   : "Win32",
                      "linux"   : "Linux",
                      "mac"     : "Mac", }
        if in_platform not in platforms:
            logging.warning('Unsupported UE4 build platform “%s”', in_platform)
            return None
        return platforms[in_platform]

    if hasattr(env, 'platform'):
        env.ue4_platform = '+'.join(map(_get_ue4_platform, env.platform.split('+')))

    if hasattr(env, 'configuration'):
        if env.configuration is None:
            env.configuration = 'devel'
        env.ue4_config = '+'.join(map(_get_ue4_config, env.configuration.split('+')))

    if not hasattr(env, 'target') or env.target is None and env.is_ue4:
        if env.platform in ['win64', 'mac', 'linux']:
            env.target = 'editor'
        else:
            env.target = 'game'

    return True
<|endoftext|>