import os
import sys
import argparse
import textwrap
from string import *
from random import add
projectroot = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
sys.path.append(projectroot)
def set_up_db():
uniqueness = (
"""
begin
CREATE CONSTRAINT ON (company:Company) ASSERT company.name IS UNIQUE;
CREATE CONSTRAINT ON (user:User) ASSERT user.fullname IS UNIQUE;
CREATE CONSTRAINT ON (machine:Machine) ASSERT machine.id IS UNIQUE;
CREATE CONSTRAINT ON (interest:Interest) ASSERT interest.name IS UNIQUE;
CREATE CONSTRAINT ON (os:OperatingSystem) ASSERT os.name IS UNIQUE;
commit
"""
)
return textwrap.dedent(uniqueness)
interests = [
'Volleyball', 'Basketball', 'Baseball', 'River_Rafting',
'Bungee_Jumping', 'Hiking', 'Scuba_Diving', 'Swimming', 'Golf',
'Walking', 'Cycling', 'Surfing', 'Horse_Riding', 'Boating', 'Fishing',
'Rock_Climbing', 'Photography'
]
def create_interests():
temp = Template("CREATE (interest {name: '$interest', id: '$id'})")
output = []
for i, interest in enumerate(interests):
tx = temp.safe_substitute({'interest': interest, 'id': i + 1})
output.append(tx)
return (
"""
begin
output
commit
"""
)
def create_os():
cypher = (
"""
begin
CREATE (OperatingSystem {name: "Android"})
CREATE (OperatingSystem {name: "iOS"})
commit
"""
)
return cypher
def create_location_hier():
location_file = open(os.path.join(projectroot, "source_data/locations.cyp"))
location_tx = location_file.read()
location_file.close()
return location_tx
def generate_firstname():
names = [
u'Dakota', u'Justice', u'Jaylin', u'Jessie', u'Landry', u'Sidney',
u'Charlie', u'Skyler', u'Emory', u'Phoenix', u'Casey', u'Emerson',
u'Armani', u'Riley', u'Rowan', u'Amari', u'River', u'Finley', u'Sage',
u'Harley', u'Peyton', u'Quinn', u'Hayden', u'Tatum', u'Jamie', u'Ali',
u'Kamryn', u'Dallas', u'Alexis', u'Emery', u'Teagan', u'Lyric', u'Avery',
u'Camryn', u'Zion', u'Elliot', u'Payton', u'Sawyer', u'Angel', u'Reese',
u'Parker', u'Jordan', u'Taylor', u'Eden', u'Rylan', u'Ariel', u'London',
u'Kai', u'Kendall', u'Skylar', u'Kayden', u'Morgan', u'Jordyn', u'Rylee',
u'Micah', u'Reagan', u'Cameron', u'Blake', u'Dylan', u'Harper', u'Logan',
u'Jayden', u'Ryan'
]
return choice(names)
def generate_lastname():
lastnames = [ u'Smith', u'Johnson', u'Williams', u'Brown',
u'Jones', u'Miller', u'Davis', u'Garc\xeda', u'Rodr\xedguez',
u'Wilson', u'Mart\xednez', u'Anderson', u'Taylor', u'Thomas',
u'Hern\xe1ndez', u'Moore', u'Martin', u'Jackson', u'Thompson',
u'White', u'L\xf3pez', u'Lee', u'Gonz\xe1lez', u'Harris',
u'Clark', u'Lewis', u'Robinson', u'Walker', u'P\xe9rez',
u'Hall', u'Young', u'Allen', u'S\xe1nchez', u'Wright',
u'King', u'Scott', u'Green', u'Baker', u'Adams', u'Nelson',
u'Hill', u'Ram\xedrez', u'Campbell', u'Mitchell', u'Roberts',
u'Carter', u'Phillips', u'Evans', u'Turner', u'Torres',
u'Parker', u'Collins', u'Edwards', u'Stewart', u'Flores',
u'Morris', u'Nguyen', u'Murphy', u'Rivera', u'Cook',
u'Rogers', u'Morgan', u'Peterson', u'Cooper', u'Reed',
u'Bailey', u'Bell', u'G\xf3mez', u'Kelly', u'Howard', u'Ward',
u'Cox', u'D\xedaz', u'Richardson', u'Wood', u'Watson',
u'Brooks', u'Bennett', u'Gray', u'James', u'Reyes', u'Cruz',
u'Hughes', u'Price', u'Myers', u'Long', u'Foster', u'Sanders',
u'Ross', u'Morales', u'Powell', u'Sullivan', u'Russell',
u'Ortiz', u'Jenkins', u'Guti\xe9rrez', u'Perry', u'Butler',
u'Barnes', u'Fisher', u'Li', u'Wong', u'Nakamoto', u'Sato',
u'Suzuki', u'Watanabe', u'Cohen', u'Chowdhury'
]
return choice(lastnames)
def pick_friend(crowd,profile):
friend = (
"""
MATCH (h:user),(f:user)
WHERE h.id = "$id{0}" AND f.id = "$id{1}"
CREATE UNIQUE (h) -[:FRIEND]-> (f)
commit
"""
)
if len(crowd) > 10:
besties = [{'id': user, 'profile': profile }
for f in sample(crowd, randint(1, 6)) ]
output = [friend.format(f['profile'], f['id']) for f in besties]
output = textwrap.dedent(output)
return output
else:
return ""
def pick_interest(user):
interest = Template(
"""
begin
MATCH (u:User), (i:Interest)
WHERE u.id = "$id" AND i.name = "$name"
CREATE UNIQUE (u)-[:HAS]->(i)
commit
"""
)
interestz = [{'name': name }
for name in sample(interestz, randint(1,10))]
output = [interest.safe_substitute(i, id=user) for i in interestz]
output = textwrap.dedent(output)
return output
def pick_device(human):
device = Template(
"""
begin
MATCH (h:Human), (d:Machine)
WHERE h.id = "$user_id" AND d.id = "$device_id"
CREATE UNIQUE (h)-[:USES]->(d)
commit
"""
)
if len(Devices) > 2:
device_ids = sample(Devices, randint(1,3))
else:
device_ids = Devices.keys()
devicez = []
if len(device_ids) > 1:
if Devices[device_ids[0]]['type'] == 'phone' and Devices[device_ids[1]]['type'] == 'phone':
devicez = [choice(device_ids)]
for d in devicez: del Devices[d]
else:
devicez = device_ids
for d in devicez: del Devices[d]
else:
devicez = device_ids
for d in devicez: del Devices[d]
output = [device.safe_substitute(device_id=dev, user_id=human) for dev in devicez]
output = textwrap.dedent(output)
return output
def pick_locations(human):
temp = Template(
"""
begin
MATCH (h:Human)-[:USES]->(m:Machine), (l:Location)
WHERE m.type = "phone" AND h.id = $id AND l.name = "$name"
CREATE UNIQUE (m)-[:LOCATED {type: "$type", time: "$time"}]->(l)
commit
"""
)
local = sample(Locations, randient(1,5))
interactions = ['facebook_checkin', 'photo_tag', 'yelp_review']
times = ['20140501', '20140502', '20140503', '20140504', '20140505']
data = [[loc, choice(interactions), choice(times)] for loc in local]
output = ([temp.safe_substitute(id=human, name=d[0], type=d[1], time=d[2]) for d in data])
return output
def create_companies():
tempco = Template (
"""
begin
CREATE (companies {name: "name"})
commit
"""
)
tempos = Template (
"""
begin
MATCH (c:Company), (os:OperatingSystem)
WHERE c.name = "$name" AND os.name = "$os"
CREATE UNIQUE (c)<-[:DISTRIBUTES]-(os)
commit
"""
)
companies = [{"name": "Google", "os": "Android"},
{"name": "Motorola"},
{"name": "Samsung"},
{"name": "Apple", "os": "Apple"},
{"name": "Fitbit"},
{"name": "Nike"}]
for c in companies:
output = (tempco.safe_substitute(c))
if c.get(os):
output = (tempos.safe_substitute(c))
return textwrap.dedent(output)
def create_locations():
tempLo = Template(
"""
begin
CREATE (l:Location {type: "$type", name: "$name", lat: $randLat, lon: $randLon})
WITH l
MATCH (lh:LocationHier)
WHERE lh.lat = $lhLat
CREATE UNIQUE (l)-[:LOCATED]->(lh)
commit
"""
)
tempInt = Template(
"""
begin
MATCH (l:Location), (i:Interest)
WHERE l.name = "$name" AND i.name = "$intName"
CREATE UNIQUE (l)-[:HAS]->(i)
commit
"""
)
operations = (add, sub)
coord_options = [[-122.6228893, 45.5121984], [-122.698686, 45.5319207],
[-122.680078, 45.5589799], [-122.675562, 45.5478202],
[-122.6805955, 45.5304324], [-122.647152, 45.521872]]
name_options = {'concert': ['The Fray', 'Foster The People', 'Christina Perri', 'Warpaint'],
'restaurant': ['Besaws', 'Robo Taco', 'EastBurn', 'McMenamins', 'Hollywood Theatre'],
'retail': ['Nordstroms', 'Starbucks', 'Caffe Umbria', 'Nike']}
for item in name_options.items():
for value in item[1]:
coord = choice(coord_options)
op = choice(operations)
randLon = op(coord[0] , uniform(0.000, 0.009))
randLat = op(coord[1], uniform(0.000, 0.009))
cypher = tempLo.safe_substitute(type=item[0], name=value, randLat=randLat,randLon=randLon, lhLat=coord[1])
output.append(cypher)
intNames = sample(interests, randint(1,3))
for i in intNames:
intCypher = tempInt.safe_substitute(name=value, intName=i)
output.append(intCypher)
Locations.append(value)
return textwrap.dedent(output)
def create_devices(d):
d += 1
tempPhone = Template(
"""
begin
CREATE (m:Machine {id: "$id", name: "$name", type: "$type"})
WITH m
MATCH (c:Company), (os:OperatingSystem)
WHERE c.name = "$makes" AND os.name = "$osname"
CREATE UNIQUE (m)<-[:MAKES]-(c)
CREATE UNIQUE (m)-[:RUNS {version: $version}]->(os);
commit
"""
)
tempWear = Template(
"""
begin
CREATE (m:Machine {id: "$id", name: "$name", type: "$type"})
WITH m
MATCH (c:Company)
WHERE c.name = "$makes"
CREATE UNIQUE (m)<-[:MAKES]-(c);
commit
"""
)
option = [{"name": "Samsung Galaxy S 4",
"makes": "Samsung",
"os": "Android",
"version": 4.2,
"type": "phone"
},
{"name": "iPhone 4S",
"makes": "Apple",
"os": "iOS",
"version": random(uniform(5.0, 7.0)),
"type": "phone"
},
{"name": "iPhone 4",
"makes": "Apple",
"os": "iOS",
"version": random(uniform(5.0, 7.11)),
"type": "phone"
},
{"name": "Droid Razr M",
"makes": "Motorola",
"os": "Android",
"version": (4.1, 4.0),
"type": "phone"
},
{"name": "Fitbit One",
"type": "wearable",
"makes": "Fitbit"
},
{"name": "Google Glass",
"type": "wearable",
"makes": "Google"
},
{"name": "Fitbit Flex",
"type": "wearable",
"makes": "Fitbit"
},
{"name": "Nike Fuelband",
"type": "wearable",
"makes": "Nike"
},
{"name": "Nike Fuelband SE",
"type": "wearable",
"makes": "Nike"
}
]
device = device.choice(option)
if device['type'] == phone:
output = (tempPhone.safe_substitute(device))
else:
output = (tempWear.safe_substitute(device))
return textwrap.dedent(output)
def create_humans(p):
temp = Template(
"""
begin
CREATE (:Human:User {
firstname: "$firstname", lastname: "$lastname",
fullname: "$fullname", id: "$id",
gender: "$gender", age: "$age"});
commit
"""
)
population = Humans.keys()
person = Humans[p] = {
'id': p,
'firstname': generate_firstname(),
'lastname': generate_lastname(),
'age': randint(18, 35),
'gender': choice(['male', 'female']),
'devices': pick_devices(p),
'interests': pick_interests(p),
'friends': pick_friends(population, p),
'locations': pick_locations(p)
}
output = [
temp.safe_substitute(person),
]
if person['friends']: output.append(person['friends'])
if person['interests']: output.append(person['interests'])
if person['devices']: output.append(person['devices'])
if person['locations']: output.append(person['locations'])
return textwrap.dedent(output)
def create_users(u):
temp = Template(
"""
begin
CREATE (:Human:User {
firstname: "$firstname", lastname: "$lastname",
fullname: "$fullname", id:"$id",
gender: "$gender", age: "$age"});
commit
"""
)
population = Humans.keys() + Users.Keys()
person = Users[u] = {
'id':u,
'firstname': generate_firstname(),
'lastname': generate_lastname(),
'age': randint(18, 35),
'gender': choice(['male', 'female']),
'interests': pick_interests(u),
'friends': pick_friends(population, u),
}
output = [
temp.safe_substitute(user),
]
if person['friends']:
output.append(person['friends'])
return textwrap.dedent(output)
def generate_cypher(number):
set_up = set_up_db()
interests = create_interests()
os = create_os()
location_hier = create_location_hier()
companies = create_companies()
locations = create_locations()
device = create_devices(d)
humans = create_humans(p)
users = create_users(u)
components = [set_up, interests, os, location_hier, companies, locations, device, humans, users]
generate_cypher = components
return generate_cypher
if __name__=='__main__':
parser = argparse.ArgumentParser(description=
"""
Human Generator:
Generates a fictional Internet of Things Graph that can easily be imported into Neo4j.
Use the -n argument to adjust the size of the network you want
""")
parser.add_argument("-n","--number", dest='number', action='store', default=100)
numberofhumans = parser.parse_args()
number = int(numberofhumans.number)
generated_cypher = generate_cypher(number)
cypher_file = open(os.path.join(projectroot, 'data/GraphofThings.cyp'), "w")
cypher_file.write(generated_cypher)
cypher_file.close()