def person_create(request): user = request.user if request.method == "POST": person = Person() person.created_by = user.id form = PersonForm(instance=person, data=request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(reverse("persons_index")) else: # GET form = PersonForm() return render(request, "person_form.html", {"form": form})
def _person_find(person_name, exact_match=False): """ Searches the DB for a person whose name matches the given name :param person_name: :return: """ person_name = person_name.lower() person_name_tokens = [w for w in person_name.split()] if exact_match: if len(person_name_tokens) > 2: query = "MATCH (p:Person) WHERE LOWER(p.last_name) IN { person_tokens } AND LOWER(p.first_name) IN { person_tokens } AND LOWER(p.middle_name) IN { person_tokens } RETURN p LIMIT 20" else: query = "MATCH (p:Person) WHERE LOWER(p.last_name) IN { person_tokens } AND LOWER(p.first_name) IN { person_tokens } RETURN p LIMIT 20" else: query = "MATCH (p:Person) WHERE LOWER(p.last_name) IN { person_tokens } OR LOWER(p.first_name) IN { person_tokens } OR LOWER(p.middle_name) IN { person_tokens } RETURN p LIMIT 20" results, meta = db.cypher_query(query, dict(person_tokens=person_name_tokens)) if len(results) > 0: print("Found {} matching people".format(len(results))) people = [Person.inflate(row[0]) for row in results] return people else: return None
def assign_host(lunchdate): immune_date = lunchdate - datetime.timedelta(days=IMMUNITY_PERIOD) people = Person.objects.filter(active=True, last_hosted__lte=immune_date) denominator = 0 # total chances of anybody being picked to host for peep in people: denominator += peep.num_guest_actions - HOST_COEFFICIENT * peep.num_host_actions if denominator > 0: selected = random.randint(0, denominator) chances = 0 for peep in people: chances += peep.num_guest_actions - HOST_COEFFICIENT * peep.num_host_actions if selected <= chances: actions = HostAction.objects.filter(date=lunchdate) if actions.exists(): ha = actions[0] ha.host = peep # caveat: we aren't decrementing hosted counts because # only 'unassigned' should ever be auto-reassigned else: ha = HostAction(date=lunchdate, host=peep) ha.save() peep.num_host_actions = peep.num_host_actions + 1 peep.last_hosted = lunchdate peep.save() return else: # If we weren't able to assign anybody, give to "unassigned" unassigned_name = 'unassigned' nobodies = Person.objects.filter(name=unassigned_name) nobody = None if nobodies.exists(): nobody = nobodies[0] else: nobody = Person(name=unassigned_name, active=False) nobody.save() # if day is already given to "unassigned", don't duplicate it, just return host_action = HostAction.objects.filter(date=lunchdate) if host_action.exists() and (host_action[0].host.name == 'unassigned'): return ha = HostAction(date=lunchdate, host=nobody) ha.save()
def test_create_delete_in_db(self): """ For this test, a neo4j database must be running """ person = Person(first_name="first", last_name="last") self.assertTrue(person) # This will create an entry in the db. person.save() # Check if the person was added to the DB by querying for it based on the first_name people = Person.nodes.filter(first_name="first") # A person should be found self.assertEquals(len(people), 1) # Delete the person from db people[0].delete() # test the person is removed people = Person.nodes.filter(first_name="first") self.assertTrue(len(people) == 0)
def get_paper_authors(paper): query = "MATCH (:Paper {title: {paper_title}})<--(a:Person) RETURN a" results, meta = db.cypher_query(query, dict(paper_title=paper.title)) if len(results) > 0: authors = [Person.inflate(row[0]) for row in results] else: authors = [] # pdb.set_trace() authors = [ '{}. {}'.format(author.first_name[0], author.last_name) for author in authors ] return authors
def person_detail(request, id): # Retrieve the paper from the database papers_authored = [] query = "MATCH (a) WHERE ID(a)={id} RETURN a" results, meta = db.cypher_query(query, dict(id=id)) if len(results) > 0: # There should be only one results because ID should be unique. Here we check that at # least one result has been returned and take the first result as the correct match. # Now, it should not happen that len(results) > 1 since IDs are meant to be unique. # For the MVP we are going to ignore the latter case and just continue but ultimately, # we should be checking for > 1 and failing gracefully. all_people = [Person.inflate(row[0]) for row in results] person = all_people[0] else: # go back to the paper index page return render( request, "people.html", { "people": Person.nodes.all(), "num_people": len(Person.nodes.all()) }, ) # # Retrieve all papers co-authored by this person and list them # query = "MATCH (a:Person)-[r:authors]->(p:Paper) where id(a)={id} return p" results, meta = db.cypher_query(query, dict(id=id)) if len(results) > 0: papers_authored = [Paper.inflate(row[0]) for row in results] print("Number of papers co-authored by {}: {}".format( person.last_name, len(papers_authored))) for p in papers_authored: print("Title: {}".format(p.title)) else: print("No papers found for author {}".format(person.last_name)) request.session["last-viewed-person"] = id return render(request, "person_detail.html", { "person": person, "papers": papers_authored })
def test_across_edges(self): """ For this test, a neo4j database must be running """ paper = Paper( title="Paper", abstract="The abstract is missing.", keywords="test, paper", download_link="https://google.com", ) self.assertTrue(paper) person = Person(first_name="first", last_name="last") self.assertTrue(person) dataset = Dataset(name="set", keywords="ML", description="machine learning papers", source_type="N") self.assertTrue(dataset) venue = Venue(name="paper", publication_date=dt.date(2019, 4, 17), type="J", publisher="CSIRO", keywords="J", peer_reviewed="N") self.assertTrue(venue) # Save all entries to the db. paper.save() person.save() dataset.save() venue.save() # There should be no edge across entries now in the db self.assertEquals(len(paper.evaluates_on), 0) self.assertEquals(len(paper.was_published_at), 0) self.assertEquals(len(paper.published), 0) self.assertEquals(len(person.authors), 0) # Add edge paper -> evaluates_on -> dataset paper.evaluates_on.connect(dataset) # Test it self.assertEquals(len(paper.evaluates_on), 1) # Test that duplicate edges cannot exist in the database paper.evaluates_on.connect(dataset) self.assertEquals(len(paper.evaluates_on), 1) # Add edge paper -> was_published_at -> venue paper.was_published_at.connect(venue) # Test it self.assertEquals(len(paper.was_published_at), 1) # Test that duplicate edges cannot exist in the database paper.was_published_at.connect(venue) self.assertEquals(len(paper.was_published_at), 1) # Add edge paper -> published -> dataset paper.published.connect(dataset) # Test it self.assertEquals(len(paper.published), 1) # Test that duplicate edges cannot exist in the database paper.published.connect(dataset) self.assertEquals(len(paper.published), 1) # Add edge person -> authors -> paper person.authors.connect(paper) # Test it self.assertEquals(len(person.authors), 1) # Test that duplicate edges cannot exist in the database person.authors.connect(paper) self.assertEquals(len(person.authors), 1) # Delete the entries from the DB # This should also delete all the edges paper.delete() person.delete() dataset.delete() venue.delete() # check if the entries were indeed deleted papers = Paper.nodes.filter(title="Paper") self.assertEquals(len(papers), 0) people = Person.nodes.filter(first_name="first") self.assertEquals(len(people), 0) datasets = Dataset.nodes.filter(name="set") self.assertEquals(len(datasets), 0) venues = Venue.nodes.filter(name="Paper") self.assertEquals(len(venues), 0)
def test_create_duplicate(self): """ Testing if the same person can be added twice. For this test, a neo4j database must be running """ person = Person(first_name="first", last_name="last") # This will create an entry in the db. person.save() people = Person.nodes.filter(first_name="first") self.assertEquals(len(people), 1) # This will not create an entry in the db. person.save() people = Person.nodes.filter(first_name="first") self.assertEquals(len(people), 1) person = Person(first_name="first", last_name="last") # This will create an entry in the db. person.save() people = Person.nodes.filter(first_name="first") self.assertEquals(len(people), 2) for person in people: person.delete() people = Person.nodes.filter(first_name="first") self.assertEquals(len(people), 0)
def test_object_create(self): """ For this test, a neo4j database must be running """ # test the creation of a person instance person = Person() person.first_name = "first" person.last_name = "last" person.affiliation = "" person.website = "" person.id = "01" url = person.get_absolute_url() self.assertEquals(person.__str__(), "first last") self.assertFalse(person.affiliation) self.assertFalse(person.website) person.middle_name = "middle" self.assertEquals(person.__str__(), "first middle last") # test first_name is required person.first_name = None try: # It is missing required property first_name person.save() except RequiredProperty: assert True else: assert False # test last_name is required person.first_name = "first" person.last_name = None try: # It is missing required property last_name person.save() except RequiredProperty: assert True else: assert False
def test_create_delete_edge_db(self): """ For this test, a neo4j database must be running """ p1 = Person(first_name="first", last_name="last") p2 = Person(first_name="first", last_name="last") # This will create two entries in the db. p1.save() p2.save() # There should be no edge between these two person in the db. # Check that this is true. self.assertEquals(len(p1.co_authors_with), 0) self.assertEquals(len(p2.co_authors_with), 0) # Add edge p1 -> co_authors_with -> p2 p1.co_authors_with.connect(p2) # This is a directed edge from p1 to p2. Test this. self.assertEquals(len(p1.co_authors_with), 1) self.assertEquals(len(p2.co_authors_with), 0) # Delete the person from the DB # This should also delete the edge between the two people p1.delete() p2.delete() # check if the people was indeed deleted people = Person.nodes.filter(first_name="first") self.assertEquals(len(people), 0)
def person_update(request, id): # retrieve paper by ID # https://github.com/neo4j-contrib/neomodel/issues/199 query = "MATCH (a) WHERE ID(a)={id} RETURN a" results, meta = db.cypher_query(query, dict(id=id)) if len(results) > 0: all_people = [Person.inflate(row[0]) for row in results] person_inst = all_people[0] else: person_inst = Person() # if this is POST request then process the Form data if request.method == "POST": form = PersonForm(request.POST) if form.is_valid(): person_inst.first_name = form.cleaned_data["first_name"] person_inst.middle_name = form.cleaned_data["middle_name"] person_inst.last_name = form.cleaned_data["last_name"] person_inst.affiliation = form.cleaned_data["affiliation"] person_inst.website = form.cleaned_data["website"] person_inst.save() return HttpResponseRedirect(reverse("persons_index")) # GET request else: query = "MATCH (a) WHERE ID(a)={id} RETURN a" results, meta = db.cypher_query(query, dict(id=id)) if len(results) > 0: all_people = [Person.inflate(row[0]) for row in results] person_inst = all_people[0] else: person_inst = Person() form = PersonForm( initial={ "first_name": person_inst.first_name, "middle_name": person_inst.middle_name, "last_name": person_inst.last_name, "affiliation": person_inst.affiliation, "website": person_inst.website, }) return render(request, "person_update.html", { "form": form, "person": person_inst })