示例#1
0
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})
示例#2
0
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
示例#3
0
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()
示例#4
0
    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)
示例#5
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
示例#6
0
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
    })
示例#7
0
    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)
示例#8
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)
示例#9
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
示例#10
0
    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)
示例#11
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
    })