示例#1
0
def getplace(id):
    print('id:',id)
    result = shareds.driver.session().run(cypher_getplace,id=id).single()
    print('result:',result)
    if not result: return dict(status="Error",resultCount=0)
    p = result.get('p')
    largerPlaces = result['largerPlaces']
    smallerPlaces = result['smallerPlaces']
    places1 = []
    for h1,largerPlace,id2 in largerPlaces: 
        if largerPlace is None: break
        name2 = largerPlace['pname']
        type2 = largerPlace['type']
        place = dict(name=name2,type=type2,id=id2)
        datetype = h1['datetype']
        if datetype:
            date1 = h1['date1']
            date2 = h1['date2']
            d = DateRange(datetype, date1, date2)
            timespan = d.__str__()
            date1 = DateRange.DateInt(h1['date1']).long_date()
            date2 = str(DateRange.DateInt(h1['date2']))
            place['datetype'] = datetype
            place['date1'] = date1
            place['date2'] = date2
            place['timespan'] = timespan
        places1.append(place)
    places2 = []
    for h2,smallerPlace,id2 in smallerPlaces: 
        if smallerPlace is None: break
        name2 = smallerPlace['pname']
        type2 = smallerPlace['type']
        place = dict(name=name2,type=type2,id=id2)
        datetype = h2['datetype']
        if datetype:
            date1 = h2['date1']
            date2 = h2['date2']
            d = DateRange(datetype, date1, date2)
            timespan = d.__str__()
            date1 = str(DateRange.DateInt(h2['date1']))
            date2 = str(DateRange.DateInt(h2['date2']))
            place['datetype'] = datetype
            place['date1'] = date1
            place['date2'] = date2
            place['timespan'] = timespan
        places2.append(place)
    #names = [dict(name=pn['name'],lang=pn['lang']) for pn in result['names']]
    place = PlaceBl.from_node(p)
    place.names = [PlaceName.from_node(pn) for pn in result['names']]
    print(smallerPlaces)
    if smallerPlaces == [[None,None,None]]: smallerPlaces = []
    place.surrounds = [PlaceName.from_node(p2) for (h2,p2,id2) in smallerPlaces]
    place.surrounds=sorted(places2,key=itemgetter('name'))
    return {"status":"OK",
     "statusText":"OK",
     "resultCount": 1,
     "place": place, 
    }
示例#2
0
def list_top_level_places():
    result = shareds.driver.session().run(cypher_list_top_level_places)
    places = []
    for rec in  result:
        place_node = rec['p']
        place = PlaceBl.from_node(place_node)
        place.names = [PlaceName.from_node(pn) for (r,pn) in rec['names']]
        places.append(place) 
    return {"status":"OK",
         "statusText":"OK",
         "resultCount": len(places),
         "places":sorted(places, key=attrgetter('pname'))
    }
示例#3
0
 def mergeplaces(self, id1, id2):
     cypher_delete_namelinks = """
         match (node) -[r:NAME_LANG]-> (pn)
         where id(node) = $id
         delete r
     """
     cypher_mergeplaces = """
         match (p1:Place)        where id(p1) = $id1 
         match (p2:Place)        where id(p2) = $id2
         call apoc.refactor.mergeNodes([p1,p2],
             {properties:'discard',mergeRels:true})
         yield node
         with node
         match (node) -[r2:NAME]-> (pn2)
         return node, collect(pn2) as names
     """
     self.tx.run(cypher_delete_namelinks, id=id1).single()
     rec = self.tx.run(cypher_mergeplaces, id1=id1, id2=id2).single()
     node = rec['node']
     place = PlaceBl.from_node(node)
     name_nodes = rec['names']
     name_objects = [PlaceName.from_node(n) for n in name_nodes]
     return place, name_objects
示例#4
0
def get_object_from_node(node):
    '''
        Noe4j database returns node objects, which are converted to
        corresponding objects by this function
    '''
    try:
        label = list(node.labels)[0]
    except Exception as e:
        print("{} Empty node? {}".format(e, node))
        return None

    if label == "Event":
        return Event_combo.from_node(node)
    elif label == "Name":
        return Name.from_node(node)
    elif label == "Person":
        return Person_combo.from_node(node)
#     elif label == "Refname":
#         return Refname.from_node(node)
    elif label == "Citation":
        return Citation.from_node(node)
    elif label == "Source":
        return Source.from_node(node)
    elif label == "Repository":
        return Repository.from_node(node)
    elif label == "Place":
        return PlaceBl.from_node(node)
    elif label == "Place_name":
        return PlaceName.from_node(node)
    elif label == "Note":
        return Note.from_node(node)
    elif label == "Family":
        return Family_combo.from_node(node)
    elif label == "Media":
        return Media.from_node(node)
    else:
        return None
示例#5
0
    def get_family_data(
            uuid,
            context: UserContext):  # -> bl.family.FamilyReader.get_family_data
        """ Read Family information including Events, Children, Notes and Sources.
        
            1) read 
                (f:Family) --> (e:Event)
                (f:Family) -[:PARENT]-> (pp:Person) -> (np:Name)
                (f:Family) -[:CHILD]->  (pc:Person) -> (nc:Name)
                (f:Family) --> (fn:Note)
                (e:Event) --> (en:Note)
                (f:Family) --> (fac:Citation) --> (fas:Source) --> (far:Repository)
                (e:Event) --> (evc:Citation) --> (evs:Source) --> (evr:Repository)
 
            2) read
                (pp:Person) --> (ppe:Event) --> (:Place)
                (pc:Person) --> (pce:Event) --> (:Place)

            3) build
                Family_combo.mother, .names, event_birth, event_death
                Family_combo.father, .names, event_birth, event_death
                Family_combo.events
                Family_combo.notes
                Family_combo.sources / citation -> source -> repocitory ?
                Family_combo.children, .names, event_birth, event_death
            Returns a Family object with other objects included
        """
        # Import here to handle circular dependency
        from .person_combo import Person_combo

        def set_birth_death(person, birth_node, death_node):
            '''
            Set person.birth and person.death events from db nodes
            '''
            if birth_node:
                person.event_birth = Event_combo.from_node(birth_node)
            if death_node:
                person.event_death = Event_combo.from_node(death_node)

        #------------

        family = None
        with shareds.driver.session() as session:
            try:
                result = session.run(Cypher_family.get_family_data, pid=uuid)
                for record in result:
                    if record['f']:
                        # <Node id=272710 labels={'Family'}
                        #    properties={'father_sortname': '#Andersson#Anders',
                        #        'change': 1519839324, 'rel_type': 'Married', 'handle': '_dcf94f357ea7b126cd8277f4495',
                        #        'id': 'F0268', 'mother_sortname': 'Gröndahl#Juhantytär#Fredrika',
                        #        'datetype': 3, 'date2': 1878089, 'date1': 1875043}>
                        node = record['f']
                        family = Family_combo.from_node(node)

                        for event_node, place_node in record['family_event']:
                            if event_node:
                                # event_node:
                                # <Node id=242570 labels={'Event'}
                                #    properties={'datetype': 0, 'change': 1528183878, 'description': '',
                                #        'handle': '_dcf94f35ea262b7e1a0a0066d6e', 'id': 'E1692',
                                #        'date2': 1875043, 'type': 'Marriage', 'date1': 1875043}>
                                e = Event_combo.from_node(event_node)
                                if place_node:
                                    # place_node: <Node id=73479 labels={'Place'} properties={'coord':
                                    # [60.5625, 21.609722222222224], 'id': 'P0468', 'type': 'City', 'uuid':
                                    # 'd1d0693de1714a47acf6442d64246a50', 'pname': 'Taivassalo', 'change':
                                    # 1556953682}>
                                    e.place = PlaceBl.from_node(place_node)

                                    # Look for surrounding place:
                                    res = session.run(Cypher_person.get_places,
                                                      uid_list=[e.uniq_id])
                                    for rec in res:
                                        e.place.names = place_names_from_nodes(
                                            rec['pnames'])
                                        if rec['pi']:
                                            pl_in = PlaceBl.from_node(
                                                rec['pi'])
                                            pl_in.names = place_names_from_nodes(
                                                rec['pinames'])
                                            e.place.uppers.append(pl_in)

                                family.events.append(e)

                        uniq_id = -1
                        for role, person_node, name_node, birth_node, death_node in record[
                                'parent']:
                            # ['mother',
                            #    <Node id=235105 labels={'Person'}
                            #        properties={'sortname': 'Gröndahl#Juhantytär#Fredrika', 'datetype': 19,
                            #            'confidence': '2.0', 'sex': 2, 'change': 1536161195,
                            #            'handle': '_dcf94f357d9f565664a975f99f', 'id': 'I2475',
                            #            'date2': 1937706, 'date1': 1856517}>,
                            #    <Node id=235106 labels={'Name'}
                            #        properties={'firstname': 'Fredrika', 'type': 'Married Name',
                            #            'suffix': 'Juhantytär', 'prefix': '', 'surname': 'Gröndahl', 'order': 0}>,
                            #    <Node id=242532 labels={'Event'}
                            #        properties={'datetype': 0, 'change': 1519151217, 'description': '',
                            #            'handle': '_dcf94f357db6f3c846e6472915f', 'id': 'E1531',
                            #            'date2': 1856517, 'type': 'Birth', 'date1': 1856517}>,
                            #    <Node id=242536 labels={'Event'}
                            #        properties={'datetype': 0, 'change': 1519150640, 'description': '',
                            #            'handle': '_dcf94f357e2d61f5f76e1ba7cb', 'id': 'E1532',
                            #            'date2': 1937700, 'type': 'Death', 'date1': 1937700}>
                            # ]
                            if person_node:
                                if uniq_id != person_node.id:
                                    # Skip person with double default name
                                    p = Person_combo.from_node(person_node)
                                    p.role = role
                                    if name_node:
                                        p.names.append(
                                            Name.from_node(name_node))

                                    set_birth_death(p, birth_node, death_node)

                                    if role == 'father':
                                        family.father = p
                                    elif role == 'mother':
                                        family.mother = p

                        if not context.use_common():
                            if family.father: family.father.too_new = False
                            if family.mother: family.mother.too_new = False

                        family.no_of_children = 0
                        family.num_hidden_children = 0
                        for person_node, name_node, birth_node, death_node in record[
                                'child']:
                            # record['child'][0]:
                            # [<Node id=235176 labels={'Person'}
                            #    properties={'sortname': '#Andersdotter#Maria Christina',
                            #        'datetype': 19, 'confidence': '2.0', 'sex': 2, 'change': 1532009600,
                            #        'handle': '_dd2a65b2f8c7e05bc664bd49d54', 'id': 'I0781', 'date2': 1877226, 'date1': 1877219}>,
                            #  <Node id=235177 labels={'Name'}
                            #    properties={'firstname': 'Maria Christina', 'type': 'Birth Name', 'suffix': 'Andersdotter',
                            #        'prefix': '', 'surname': '', 'order': 0}>,
                            #  <Node id=242697 labels={'Event'}
                            #    properties={'datetype': 0, 'change': 1532009545, 'description': '', 'handle': '_dd2a65b218a14e81692d77955d2',
                            #        'id': 'E1886', 'date2': 1877219, 'type': 'Birth', 'date1': 1877219}>,
                            #  <Node id=242702 labels={'Event'}
                            #    properties={'datetype': 0, 'change': 1519916327, 'description': '', 'handle': '_dd2a65b218a4e85ab141faeab48',
                            #        'id': 'E1887', 'date2': 1877226, 'type': 'Death', 'date1': 1877226}>
                            # ]
                            if person_node:
                                family.no_of_children += 1
                                p = Person_combo.from_node(person_node)
                                if name_node:
                                    p.names.append(Name.from_node(name_node))
                                set_birth_death(p, birth_node, death_node)
                                if context.use_common():
                                    if p.too_new:
                                        family.num_hidden_children += 1
                                        continue
                                else:
                                    p.too_new = False
                                family.children.append(p)

                        #family.no_of_children = len(family.children)

                        for repository_node, source_node, citation_node in record[
                                'sources']:
                            # record['sources'][0]:
                            # [<Node id=253027 labels={'Repository'}
                            #    properties={'handle': '_dcad22f5914b34fe61c341dad0', 'id': 'R0068', 'rname': 'Taivassalon seurakunnan arkisto',
                            #        'type': 'Archive', 'change': '1546265916'}>,
                            #  <Node id=247578 labels={'Source'}
                            #    properties={'handle': '_e085cd6d68d256a94afecd2162d', 'id': 'S1418',
                            #        'stitle': 'Taivassalon seurakunnan syntyneiden ja kastettujen luettelot 1790-1850 (I C:4)',
                            #        'change': '1543186596'}>,
                            #  <Node id=246371 labels={'Citation'}
                            #    properties={'handle': '_dd12b0b88d5741ee11d8bef1ca5', 'id': 'C0854', 'page': 'Vigde år 1831 April 4',
                            #        /* dates missing here */, 'change': 1543186596, 'confidence': '2'}>
                            # ]
                            if repository_node:
                                source = Source.from_node(source_node)
                                cita = Citation.from_node(citation_node)
                                repo = Repository.from_node(repository_node)
                                source.repositories.append(repo)
                                source.citations.append(cita)
                                family.sources.append(source)

                        for node in record['note']:
                            note = Note.from_node(node)
                            family.notes.append(note)

            except Exception as e:
                print('Error get_family_data: {} {}'.format(
                    e.__class__.__name__, e))
                raise

        return family
示例#6
0
    def get_one(oid):
        """ Read a Media object, selected by UUID or uniq_id.
        
            Luetaan tallenteen tiedot
        """
        class MediaReferee():
            ''' Carrier for a referee of media object. '''
            def __init__(self):
                # Referencing object label, object
                self.obj = None
                self.label = None
                self.crop = None
                # If the referring object is Event, also list of:
                # - connected objects
                self.next_objs = []

        if not oid:
            return None

        with shareds.driver.session(default_access_mode='READ') as session:
            # Use UUID
            record = session.run(Cypher_media.get_by_uuid, rid=oid).single()
            # RETURN media,
            #     COLLECT(DISTINCT [properties(r), n]) as m_ref, # Referring event or object
            #     COLLECT(DISTINCT [ID(n), m]) AS e_ref          # Event Person or Family
            if not record:
                return None

            #Record[0]: the Media object
            # <Node id=435174 labels={'Media'}
            #    properties={'src': 'Albumi-Silius/kuva002.jpg', 'batch_id': '2020-02-14.001',
            #        'mime': 'image/jpeg', 'change': 1574187478, 'description': 'kuva002',
            #        'id': 'O0024', 'uuid': 'fa2e240493434912986c2540b52a9464'}>
            media = Media.from_node(record['media'])
            referees = record['m_ref']
            referees_next = record['e_ref']

            # 1. If referrer is an Event, there is also secundary next objects
            event_refs = {}
            for referee_id, node_next in referees_next:
                #record[2]: Indirectly referring Person and Families
                # [  [29373,
                #     <Node id=29387 labels=frozenset({'Person'})
                #        properties={'sortname': 'Silius#Carl Gustaf#', 'death_high': 1911,
                #            'sex': 1, 'change': 1557753049, 'confidence': '2.0', 'birth_low': 1852,
                #            'birth_high': 1852, 'id': 'I0036', 'uuid': '9fdcfc81bd17435e8e051325ac3e6eae',
                #            'death_low': 1911}>],
                #    [29373, <Node id=30773 labels=frozenset({'Person'}) properties={...}>]
                # ]
                if not node_next:
                    continue
                if "Person" in node_next.labels:
                    obj_next = Person.from_node(node_next)
                    obj_next.label = "Person"
                elif "Family" in node_next.labels:
                    obj_next = FamilyBl.from_node(node_next)
                    obj_next.label = "Family"
                else:
                    print(
                        f'models.gen.media.Media.get_one: unknown type {list(obj_next.labels)}'
                    )
                    continue
                if not referee_id in event_refs.keys():
                    # A new Event having indirect referees
                    event_refs[referee_id] = [obj_next]
                else:
                    event_refs[referee_id].append(obj_next)

            # 2. Gather the directly referring objects
            media.ref = []
            for prop, node in referees:
                #Record[1]:
                # [ [{'order': 0},
                #        <Node id=29373 labels=frozenset({'Event'})
                #            properties={'datetype': 4, 'change': 1515865582, 'description': '',
                #                'id': 'E0858', 'date2': 1999040, 'date1': 1928384,
                #                'type': 'Burial', 'uuid': '934415b2ccf4476fa9d8d9f4d93938b7'}>
                # ] ]
                if not node:
                    continue
                mref = MediaReferee()
                mref.label, = node.labels  # Get the 1st label
                if mref.label == 'Person':
                    mref.obj = Person.from_node(node)
                    mref.obj.label = "Person"
                elif mref.label == 'Place':
                    mref.obj = PlaceBl.from_node(node)
                    mref.obj.label = "Place"
                elif mref.label == 'Event':
                    mref.obj = EventBl.from_node(node)
                    mref.obj.label = "Event"
                # Has the relation cropping properties?
                left = prop.get('left')
                if left != None:
                    upper = prop.get('upper')
                    right = prop.get('right')
                    lower = prop.get('lower')
                    mref.crop = (left, upper, right, lower)
                # Eventuel next objects for this Event
                mref.next_objs = event_refs.get(mref.obj.uniq_id, [])
                #                 # A list [object label, object, relation properties]
                #                 media.ref.append([label,obj,crop])
                media.ref.append(mref)
            return media
示例#7
0
    def read_object_places(self):
        ''' Read Place hierarchies for all objects in objs.
        '''
        try:
            uids = list(self.objs.keys())
            results = self.session.run(Cypher_person.get_places, uid_list=uids)
            for record in results:
                # <Record label='Event' uniq_id=426916
                #    pl=<Node id=306042 labels={'Place'}
                #        properties={'id': 'P0456', 'type': 'Parish', 'uuid': '7aeb4e26754d46d0aacfd80910fa1bb1',
                #            'pname': 'Helsingin seurakunnat', 'change': 1543867969}>
                #    pnames=[
                #        <Node id=306043 labels={'Place_name'}
                #            properties={'name': 'Helsingin seurakunnat', 'lang': ''}>,
                #        <Node id=306043 labels={'Place_name'}
                #            properties={'name': 'Helsingin seurakunnat', 'lang': ''}>
                #    ]
                ##    ri=<Relationship id=631695
                ##        nodes=(
                ##            <Node id=306042 labels={'Place'} properties={'id': 'P0456', ...>,
                ##            <Node id=307637 labels={'Place'}
                ##                properties={'coord': [60.16664166666666, 24.94353611111111],
                ##                    'id': 'P0366', 'type': 'City', 'uuid': '93c25330a25f4fa49c1efffd7f4e941b',
                ##                    'pname': 'Helsinki', 'change': 1556954884}>
                ##        )
                ##        type='IS_INSIDE' properties={}>
                #    pi=<Node id=307637 labels={'Place'}
                #        properties={'coord': [60.16664166666666, 24.94353611111111], 'id': 'P0366',
                #            'type': 'City', 'uuid': '93c25330a25f4fa49c1efffd7f4e941b', 'pname': 'Helsinki', 'change': 1556954884}>
                #    pinames=[
                #        <Node id=305800 labels={'Place_name'} properties={'name': 'Helsingfors', 'lang': ''}>,
                #        <Node id=305799 labels={'Place_name'} properties={'name': 'Helsinki', 'lang': 'sv'}>
                #    ]>

                src_label = record['label']
                if src_label != "Event":
                    traceback.print_exc()
                    raise TypeError(f'An Event excepted, got {src_label}')
                src_uniq_id = record['uniq_id']
                src = None

                # Use the Event from Person events
                for e in self.person.events:
                    if e.uniq_id == src_uniq_id:
                        src = e
                        break
                if not src:
                    traceback.print_exc()
                    raise LookupError(f"ERROR: Unknown Event {src_uniq_id}!?")

                pl = PlaceBl.from_node(record['pl'])
                if not pl.uniq_id in self.objs.keys():
                    # A new place
                    self.objs[pl.uniq_id] = pl
                    #print(f"# new place (x:{src_label} {src.uniq_id} {src}) --> (pl:Place {pl.uniq_id} type:{pl.type})")
                    pl.names = place_names_from_nodes(record['pnames'])
                #else:
                #   print(f"# A known place (x:{src_label} {src.uniq_id} {src}) --> ({list(record['pl'].labels)[0]} {objs[pl.uniq_id]})")
                src.place_ref.append(pl.uniq_id)

                # Surrounding places
                if record['pi']:
                    pl_in = PlaceBl.from_node(record['pi'])
                    ##print(f"# Hierarchy ({pl}) -[:IS_INSIDE]-> (pi:Place {pl_in})")
                    if pl_in.uniq_id in self.objs:
                        pl.uppers.append(self.objs[pl_in.uniq_id])
                        ##print(f"# - Using a known place {objs[pl_in.uniq_id]}")
                    else:
                        pl.uppers.append(pl_in)
                        self.objs[pl_in.uniq_id] = pl_in
                        pl_in.names = place_names_from_nodes(record['pinames'])
                        #print(f"#  ({pl_in} names {pl_in.names})")
                pass

        except Exception as e:
            print(
                f"Could not read places for person {self.person.id} objects {self.objs}: {e}"
            )
        return