예제 #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 read_place_w_names(uniq_id):
        """ Reads Place_combo nodes or selected node with PlaceName objects.

            TODO Remove: Not in use
        """
        result = None
        with shareds.driver.session() as session:
            if uniq_id:
                result = session.run(Cypher_place.place_get_one, pid=uniq_id)
            else:
                result = session.run(Cypher_place.place_get_all)

        places = []

        for record in result:
            # Create a Place_combo object from record
            node = record['p']
            pl = Place_combo.from_node(node)
            names = []
            for node in record['names']:
                # <Node id=78278 labels={'Place_name'} properties={'lang': '',
                #    'name': 'Kangasalan srk'}>
                plname = PlaceName.from_node(node)
                names.append(str(plname))
                pl.names.append(plname)
            pl.clearname = ' • '.join(names)
            places.append(pl)

        return places
예제 #3
0
    def get_w_notes(locid):
        """ Returns the Place_combo with Notes and PlaceNames included.

            #TODO: Luetaan Notes ja Citations vasta get_persondata_by_id() lopuksi?
        """
        #if isinstance(locid,int):
        #    p.uniq_id = locid
        #else:
        #    p.uuid = locid

        with shareds.driver.session() as session:
            if isinstance(locid, int):
                place_result = session.run(Cypher_place.get_w_names_notes,
                                           place_id=locid)
            else:
                place_result = session.run(Cypher_place.get_w_names_notes_uuid,
                                           uuid=locid)

            for place_record in place_result:
                # <Record
                #    place=<Node id=287246 labels={'Place'}
                #        properties={'coord': [60.375, 21.943],
                #            'handle': '_da3b305b41147508033e318249b', 'id': 'P0335',
                #            'type': 'City', 'pname': 'Rymättylä', 'change': 1556954336}>
                #    names=[
                #        <Node id=287247 labels={'Place_name'}
                #            properties={'name': 'Rymättylä', 'lang': ''}>,
                #        <Node id=287248 labels={'Place_name'}
                #            properties={'name': 'Rimito', 'lang': 'sv'}> ]
                #    notes=[]>

                node = place_record["place"]
                pl = Place_combo.from_node(node)

                for names_node in place_record["names"]:
                    pl.names.append(PlaceName.from_node(names_node))
#                     if pl.names[-1].lang in ['fi', '']:
#                         #TODO: use current_user's lang
#                         pl.pname = pl.names[-1].name

                for notes_node in place_record['notes']:
                    n = Note.from_node(notes_node)
                    pl.notes.append(n)

                for medias_node in place_record['medias']:
                    m = Media.from_node(medias_node)
                    pl.media_ref.append(m)

                if not (pl.type and pl.id):
                    logger.error(
                        f"Place_combo.read_w_notes: missing data for {pl}")

        try:
            return pl
        except Exception:
            logger.error(
                f"Place_combo.read_w_notes: no Place with locid={locid}")
            return None
예제 #4
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'))
    }
예제 #5
0
파일: place.py 프로젝트: hexaroi/stk-upload
def place_names_from_nodes(nodes):
    ''' Filter Name objects from a list of Cypher nodes.
    
        Create a list of place_bl.names with PlaceNames by following rules:
        1. Place_names using lang == current_user.language
        2. Place_names using lang == ""
        3. If none found, use the last Place_name
        Place_names using other languages are discarded

        nodes=[
            <Node id=305800 labels={'Place_name'} properties={'name': 'Helsingfors', 'lang': ''}>, 
            <Node id=305799 labels={'Place_name'} properties={'name': 'Helsinki', 'lang': 'sv'}>
        ]>
    '''
    from bl.place import PlaceName
    ret = []
    own_lang = []
    no_lang = []
    alien_lang = []
    for node in nodes:
        pn = PlaceName.from_node(node)
        if pn.lang == "":
            no_lang.append(pn)
            ##print(f"# - no lang {len(place_bl.names)} (Place_name {pn.uniq_id} {pn})")
        elif pn.lang == current_user.language:
            own_lang.append(pn)
            ##print(f"# - my lang (Place_name {pn.uniq_id} {pn})")
        else:
            alien_lang.append(pn)
            ##print(f"# - alien lang (Place_name {pn})")

    if own_lang:
        ret = own_lang
    elif no_lang:
        ret = no_lang
    else:
        ret = alien_lang
#     for pn in ret:
#         print(f"#  PlaceNames: {pn}")

    return ret
예제 #6
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
예제 #7
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
예제 #8
0
    def handle_places(self):
        ''' Get all the places in the collection.
        
            To create place hierarchy links, there must be a dictionary of 
            Place handles and uniq_ids created so far. The link may use
            previous node or create a new one.
        '''

        place_keys = {}  # place_keys[handle] = uniq_id

        places = self.collection.getElementsByTagName("placeobj")

        print("***** {} Places *****".format(len(places)))
        t0 = time.time()
        counter = 0

        # Print detail of each placeobj
        for placeobj in places:

            pl = Place_gramps()
            # Extract handle, change and id
            self._extract_base(placeobj, pl)
            pl.type = placeobj.getAttribute("type")

            # List of upper places in hierarchy as {hlink, dates} dictionaries
            pl.surround_ref = []

            # Note. The ptitle is never saved to Place object!
            if len(placeobj.getElementsByTagName('ptitle')) == 1:
                placeobj_ptitle = placeobj.getElementsByTagName('ptitle')[0]
                pl.ptitle = placeobj_ptitle.childNodes[0].data
            elif len(placeobj.getElementsByTagName('ptitle')) > 1:
                self.blog.log_event({
                    'title': "More than one ptitle in a place",
                    'level': "WARNING",
                    'count': pl.id
                })

            place_order = 0
            for placeobj_pname in placeobj.getElementsByTagName('pname'):
                if placeobj_pname.hasAttribute("value"):
                    placename = PlaceName()
                    placename.order = place_order
                    place_order += 1
                    placename.name = placeobj_pname.getAttribute("value")
                    #print(f"# placeobj {pl.id} pname {place_order} {placename.name}")
                    if placename.name:
                        if pl.pname == '':
                            # First name is default pname for Place node
                            pl.pname = placename.name
                        placename.lang = placeobj_pname.getAttribute("lang")
                        pl.names.append(placename)
                    else:
                        self.blog.log_event({
                            'title': "An empty place name discarded",
                            'level': "WARNING",
                            'count': f"{pl.id}({place_order})"
                        })
                        place_order -= 1

                try:
                    # Returns Gramps_DateRange or None
                    placename.dates = self._extract_daterange(placeobj_pname)
                    #TODO: val="1700-luvulla" muunnettava Noteksi
                except:
                    placename.dates = None

            for placeobj_coord in placeobj.getElementsByTagName('coord'):
                if placeobj_coord.hasAttribute("lat") \
                   and placeobj_coord.hasAttribute("long"):
                    lat = placeobj_coord.getAttribute("lat")
                    long = placeobj_coord.getAttribute("long")
                    if pl.coord:
                        self.blog.log_event({
                            'title': "More than one coordinates in a place",
                            'level': "WARNING",
                            'count': pl.id
                        })
                    else:
                        try:
                            pl.coord = Point(lat, long)
                        except Exception as e:
                            self.blog.log_event({
                                'title':
                                "Invalid coordinates - {}".format(e),
                                'level':
                                "WARNING",
                                'count':
                                pl.id
                            })

            for placeobj_url in placeobj.getElementsByTagName('url'):
                n = Note()
                n.priv = get_priv(placeobj_url)
                n.url = placeobj_url.getAttribute("href")
                n.type = placeobj_url.getAttribute("type")
                n.text = placeobj_url.getAttribute("description")
                if n.url:
                    pl.notes.append(n)

            for placeobj_placeref in placeobj.getElementsByTagName('placeref'):
                # Traverse links to surrounding (upper) places
                hlink = placeobj_placeref.getAttribute("hlink")
                dates = self._extract_daterange(placeobj_placeref)
                # surround_ref elements example
                # {'hlink': '_ddd3...', 'dates': <Gramps_DateRange object>}
                pl.surround_ref.append({'hlink': hlink, 'dates': dates})
                ##print(f'# Place {pl.id} is surrouded by {pl.surround_ref[-1]["hlink"]}')

            for placeobj_noteref in placeobj.getElementsByTagName('noteref'):
                if placeobj_noteref.hasAttribute("hlink"):
                    pl.noteref_hlink.append(
                        placeobj_noteref.getAttribute("hlink"))
                    ##print(f'# Place {pl.id} has note {pl.noteref_hlink[-1]}')

            # Handle <objref>
            pl.media_refs = self._extract_mediaref(placeobj)

            if pl.media_refs:
                print(f'# saving Place {pl.id}: media_refs {pl.media_refs}')

            # Save Place, Place_names, Notes and connect to hierarchy
            self.save_and_link_handle(pl,
                                      batch_id=self.batch_id,
                                      place_keys=place_keys)
            # The place_keys has been updated
            counter += 1

        self.blog.log_event({
            'title': "Places",
            'count': counter,
            'elapsed': time.time() - t0
        })  #, 'percent':1})