joeyaurel / python-gedcom

Python module for parsing, analyzing, and manipulating GEDCOM files
https://gedcom.joeyaurel.dev
GNU General Public License v2.0
154 stars 39 forks source link

Difference between `get_parent_element()` and `get_parents()` #22

Closed blotfi closed 5 years ago

blotfi commented 5 years ago

Hi What is the use of the function record.get_parent_element()

We can only use : parents = gedcom.get_parents(record)

KeithPetro commented 5 years ago

get_parent_element() and get_parents() do two very different things.

get_parent_element() provides you with the parent of an element.

get_parents() provides you with the parents of a GEDCOM individual.

blotfi commented 5 years ago

what is the difference between individual and element?

damonbrodie commented 5 years ago

You should familiarize yourself with the GEDCOM specification and the concepts of linked grammar.

“Individuals” are people in your family tree.

Each individual in your tree will have certain facts stored against them like “BIRT” birth. The way GEDCOM works is to allow each of the facts to have optional attributes. For example date, location. All of these details are “elements”.

So if you wanted an individuals birth date, you need to navigate through their elements, find the ones called “BIRT” and then go through the “child” elements of those BIRT elements and look for the DATE elements. So this module gives you the ability to navigate through the parent and child elements and the methods are so named.

It is confusing to have the same language for both people/individuals and data/elements, but that ship has sailed :-)

I may take another stab at the documentation to clarify this. I know it was confusing to me as well when I started using it.

blotfi commented 5 years ago

thanks a lot If you can put your answer in the Wiki, it would be great Well, I used this lib to parse my .ged file and found the birthdays of my family on the day and send emails with these information, also on the first day of a month, it send an email of all the anniversary I can share this file with you, but where? I can put it in my github, do you think people can be interested?

blotfi commented 5 years ago

Here is the program I made `

! /usr/bin/python3

from gedcom import Gedcom
import datetime
import smtplib

# https://github.com/nickreynke/python-gedcom
# https://www.w3schools.com/python/python_datetime.asp
# http://naelshiab.com/tutorial-send-email-python/
# https://realpython.com/python-send-email/

emailfile = 'email_list.txt'
file_path = 'xxxx.ged'

today = datetime.datetime.today().strftime('%d %b %Y')
print ("Aujourd'hui : "+today)

year = int(datetime.datetime.today().strftime('%Y'))
month = datetime.datetime.today().strftime('%b').upper() 
day = int(datetime.datetime.today().strftime('%d'))

month ='MAY' #debug
day =1   #debug

gedcom = Gedcom(file_path)
liste=""
liste_du_mois=""
found=0
all_records = gedcom.get_root_child_elements()
for record in all_records:
        if record.is_individual():
            (birth_date, birth_place, birth_src) = record.get_birth_data()
            death_year = record.get_death_year()
            birth_date_split = birth_date.split(' ', 2)
            #print (birth_date_split)
            if len(birth_date_split)>=2:
                try:  
                    birth_day = int(birth_date_split[0])
                except:
                    birth_day = 0

                birth_th_mounth_ = birth_date_split
                birth_mounth = birth_date_split[1]
                if (birth_mounth == month):
                    (first, last) = record.get_name()
                    foundmois=0
                    if death_year!=-1:
                        #print ("===>"+ str(int(year)-death_year))
                        if (year-death_year)<21:    #il y a moins de 20 ans on affiche
                            liste_du_mois = liste_du_mois + "<b>"+first+"</b> " + last+ " : "\
                            +  birth_date+ ', <font color="#0000ff">décédé(e)</font> en '+ str(death_year) +"<br>\n";
                            foundmois=1
                    else:
                        foundmois=1
                        liste_du_mois = liste_du_mois + "<b>"+first+"</b> "+ last+ " : "+  birth_date + "<br>\n";
                    #parents:
                    if foundmois:
                        parents = gedcom.get_parents(record) #record.get_parent_element()
                        liste_du_mois = liste_du_mois + "&nbsp;&nbsp;&nbsp;&nbsp;parents : "
                        for p in parents:
                            (pfirst, plast) = p.get_name()
                            (pbirth_date, pbirth_place, pbirth_src) = p.get_birth_data()
                            liste_du_mois = liste_du_mois + pfirst + " " + plast+'('+pbirth_date+')&nbsp;&nbsp;'
                        liste_du_mois = liste_du_mois +  "<br>\n";

            if (birth_day == day and birth_mounth == month):
                (first, last) = record.get_name()
                if death_year!=-1:
                    if (year-death_year)<21:    #il y a moins de 20 ans on affiche
                        liste = liste + "<b>"+first+"</b> "+ last+ " : "\
                         +  birth_date+ ', <font color="#0000ff">décédé(e)</font> en '+ str(death_year) +"<br>\n";
                        found=1
                else:
                    liste = liste + "<b>"+first+"</b> "+ last+ " : "+  birth_date+"<br>\n";
#debug
                    print ("individu :"+ first + " " + last)
                    found=1
                #parents:
                if found:
                    parents = gedcom.get_parents(record) #record.get_parent_element()
                    liste = liste + "&nbsp;&nbsp;&nbsp;&nbsp;parents : "
                    for p in parents:
                        (pfirst, plast) = p.get_name()
                        (pbirth_date, pbirth_place, pbirth_src) = p.get_birth_data()
                        liste = liste + pfirst + " " + plast+'('+pbirth_date+')&nbsp; '
                    liste = liste +  "<br>\n";

##print ("____Anniversaire du mois____")
##print(liste_du_mois)
##print ("____Anniversaire du jour____")
##print(liste)

print ("____emails____")
liste_emails = []
try:  
    fp = open(emailfile)
    for cnt, line in enumerate(fp):
        #print("Line {}: {}".format(cnt, line.strip()))
        liste_emails.append(line.strip())
finally:  
    fp.close()
print (liste_emails)

server = smtplib.SMTP('serveraddress.com', 587)
server.starttls()
server.login("mail@serveraddress.com", "yourpassword")

if day==1:
    msg ="""\
Subject: Anniversaires du mois
Content-Type: text/html; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

<font color='#ff0000'><u>La liste des anniversaires de ce mois est :</u></font><br>
"""
    msg=msg+liste_du_mois+"<br><br>\n\n"  #.encode('utf-8')

else:
    msg ="""\
Subject: Anniversaire du jour
Content-Type: text/html; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

"""
msg1 =""" 
<font color='#ff0000'><u>La liste des anniversaires d'aujourd'hui est :</u></font><br>
"""
msg=msg+msg1+liste
if found==1:
    server.sendmail("mail@serveraddress.com", liste_emails, msg.encode('utf-8'))
server.quit()

print(msg)

`

joeyaurel commented 5 years ago

Thank you @blotfi for the question and @nomadyow and @KeithPetro for the answers :)

Yes, it's correct that it is a bit confusing but with version 1.0.0 (which I am still working on) it will become more clear since there will be Element and derived IndividualElement classes.

An Element class holds information about itself, its child and parent elements. An IndividualElement would then also have methods to retrieve the birth of a person and so on. But this will all be documented well.

It will be a big change. The current changelog (from within a branch that represents the current state of version 1.0.0) can be seen here: https://github.com/nickreynke/python-gedcom/blob/release/v1.0.0/CHANGELOG.md#v100 (It currently does not contain the documentation for new Element derivates.)

Keep up the good work and thank you for sharing the code with us @blotfi ! :) The next time you could create a public "Gist" under https://gist.github.com/