Example #1
0
        internal static Adoption ParseAdoption(this ResultContainer resultContainer, GedcomChunk adoptionChunk)
        {
            var adoption = new Adoption {
                DatePlace = resultContainer.ParseDatePlace(adoptionChunk)
            };

            foreach (var chunk in adoptionChunk.SubChunks)
            {
                switch (chunk.Type)
                {
                case "NOTE":
                    adoption.Note = resultContainer.ParseNote(adoption.Note, chunk);
                    break;

                case "TYPE":
                    adoption.Type = chunk.Data;
                    break;

                // Deliberately skipped for now
                case "DATE":
                case "FAMC":
                case "PLAC":
                case "SOUR":
                    resultContainer.Warnings.Add($"Skipped Adoption Type='{chunk.Type}");
                    break;

                default:
                    resultContainer.Errors.Add($"Failed to handle Adoption Type='{chunk.Type}");
                    break;
                }
            }

            return(adoption);
        }
Example #2
0
        internal static Address ParseAddress(this ResultContainer resultContainer, GedcomChunk addressChunk)
        {
            // Top level node can also contain a full address or first part of it ...
            var address = new Address {
                Street = addressChunk.Data
            };

            foreach (var chunk in addressChunk.SubChunks)
            {
                switch (chunk.Type)
                {
                case "CONT":
                case "ADR1":
                case "ADR2":
                case "ADR3":
                    address.Street += Environment.NewLine + chunk.Data;
                    break;

                case "CITY":
                    address.City += chunk.Data;
                    break;

                case "STAE":
                    address.State += chunk.Data;
                    break;

                case "POST":
                    address.ZipCode += chunk.Data;
                    break;

                case "CTRY":
                    address.Country += chunk.Data;
                    break;

                case "PHON":
                    address.Phone.Add(chunk.Data);
                    break;

                case "EMAIL":
                    address.Email.Add(chunk.Data);
                    break;

                case "FAX":
                    address.Fax.Add(chunk.Data);
                    break;

                case "WWW":
                    address.Web.Add(chunk.Data);
                    break;

                default:
                    resultContainer.Errors.Add($"Failed to handle Address Type='{chunk.Type}");
                    break;
                }
            }

            return(address);
        }
Example #3
0
        private static HashSet <string> GetType(this GedcomChunk chunk, IDictionary <string, HashSet <string> > types)
        {
            if (!types.ContainsKey(chunk.Type))
            {
                types.Add(chunk.Type, new HashSet <string>());
            }

            return(types[chunk.Type]);
        }
Example #4
0
        private static void ParseTypeNodes(this GedcomChunk chunk, IDictionary <string, HashSet <string> > types)
        {
            var type = chunk.GetType(types);

            foreach (var subChunk in chunk.SubChunks)
            {
                type.Add(subChunk.Type);
                subChunk.ParseTypeNodes(types);
            }
        }
Example #5
0
        private static int Priority(GedcomChunk chunk)
        {
            switch (chunk.Type)
            {
            case "NOTE":
                return(0);

            case "INDI":
                return(1);

            case "FAM":
                return(2);

            default:
                return(0);
            }
        }
Example #6
0
        internal static IEnumerable <GedcomChunk> GetChunks(IEnumerable <GedcomLine> gedcomLines)
        {
            var gedcomChunkLevels = new GedcomChunkLevels();

            var topChunks = new List <GedcomChunk>();

            foreach (var gedcomLine in gedcomLines)
            {
                var chunk = new GedcomChunk(gedcomLine);
                if (gedcomLine.Level == 0)
                {
                    topChunks.Add(chunk);
                }
                else
                {
                    var parent = gedcomChunkLevels.GetParentChunk(chunk);
                    parent.SubChunks.Add(chunk);
                }

                gedcomChunkLevels.Set(chunk);
            }

            return(topChunks);
        }
Example #7
0
        internal static void ParseFamily(this ResultContainer resultContainer, GedcomChunk famChunk)
        {
            DatePlace marriage = null;
            string    relation = null;
            string    note     = null;
            DatePlace divorce  = null;
            var       parents  = new List <Person>();
            var       children = new List <Person>();

            foreach (var chunk in famChunk.SubChunks)
            {
                switch (chunk.Type)
                {
                case "CHIL":
                    var child = resultContainer.Persons.SingleOrDefault(p => p.Id == chunk.Reference);
                    if (child != null)
                    {
                        children.Add(child);
                    }

                    break;

                case "DIV":
                    divorce = resultContainer.ParseDatePlace(chunk);
                    break;

                case "HUSB":
                    var husband = resultContainer.Persons.SingleOrDefault(p => p.Id == chunk.Reference);
                    if (husband != null)
                    {
                        parents.Add(husband);
                    }

                    break;

                case "_REL":
                    relation = chunk.Data;
                    break;

                case "MARR":
                    marriage = resultContainer.ParseDatePlace(chunk);
                    break;

                case "NOTE":
                    note = resultContainer.ParseNote(note, chunk);
                    break;

                case "WIFE":
                    var wife = resultContainer.Persons.SingleOrDefault(p => p.Id == chunk.Reference);
                    if (wife != null)
                    {
                        parents.Add(wife);
                    }

                    break;

                // Deliberately skipped for now
                case "CHAN":
                case "DSCR":
                case "EVEN":
                case "FAMS":
                case "FAMC":
                case "HIST":
                case "MARS":
                case "NCHI":
                case "NMR":
                case "OBJE":
                case "PAGE":
                case "SOUR":
                    resultContainer.Warnings.Add($"Skipped Family Type='{chunk.Type}");
                    break;

                default:
                    resultContainer.Errors.Add($"Failed to handle Family Type='{chunk.Type}");
                    break;
                }
            }

            // Spouses
            if (parents.Count == 2)
            {
                resultContainer.SpouseRelations.Add(new SpouseRelation
                {
                    FamilyId = famChunk.Id,
                    From     = parents[0],
                    To       = parents[1],
                    Marriage = marriage,
                    Divorce  = divorce,
                    Relation = relation,
                    Note     = note
                });
            }

            // Parents / Children
            foreach (var parent in parents)
            {
                foreach (var child in children)
                {
                    var childRelation = new ChildRelation {
                        FamilyId = famChunk.Id, From = child, To = parent
                    };
                    AddStatus(resultContainer, childRelation);
                    resultContainer.ChildRelations.Add(childRelation);
                }
            }

            // Siblings
            foreach (var child1 in children)
            {
                foreach (var child2 in children.Where(c => c.Id != child1.Id))
                {
                    resultContainer.SiblingRelations.Add(new SiblingRelation {
                        FamilyId = famChunk.Id, From = child1, To = child2
                    });
                }
            }
        }
Example #8
0
 private static bool IsUnwantedBlob(this GedcomChunk chunk)
 {
     // TODO: We should probably make this check more intelligent
     return(chunk.Data?.Contains("<span") ?? false);
 }
Example #9
0
        internal static string ParseNote(this ResultContainer resultContainer, string previousNote, GedcomChunk incomingChunk)
        {
            var noteChunk = incomingChunk;

            if (incomingChunk.Reference.IsSpecified())
            {
                noteChunk = resultContainer.GetIdChunk(noteChunk.Reference);
                if (noteChunk == null)
                {
                    throw new Exception($"Unable to find Note with Id='{incomingChunk.Reference}'");
                }
            }

            var sb = new StringBuilder();

            foreach (var chunk in noteChunk.SubChunks)
            {
                if (chunk.IsUnwantedBlob())
                {
                    sb.AppendLine("(Skipped blob content)");
                    break;
                }

                switch (chunk.Type)
                {
                case "CONC":
                    sb.Append(" " + chunk.Data);
                    break;

                case "CONT":
                    sb.AppendLine(chunk.Data);
                    break;

                // Deliberately skipped for now
                case "_PLC":
                case "DATE":
                case "PLAC":
                case "SOUR":
                    resultContainer.Warnings.Add($"Skipped Note Type='{chunk.Type}'");
                    break;

                default:
                    resultContainer.Errors.Add($"Failed to handle Note Type='{chunk.Type}'");
                    break;
                }
            }

            return(previousNote.IsSpecified() ? previousNote + Environment.NewLine + sb : sb.ToString());
        }
Example #10
0
        internal static DatePlace ParseDatePlace(this ResultContainer resultContainer, GedcomChunk chunk)
        {
            var datePlace = new DatePlace
            {
                Date  = chunk.SubChunks.SingleOrDefault(c => c.Type == "DATE")?.Data,
                Place = chunk.SubChunks.SingleOrDefault(c => c.Type == "PLAC")?.Data
            };
            var map = chunk.SubChunks.SingleOrDefault(c => c.Type == "MAP");

            if (map != null)
            {
                datePlace.Latitude  = map.SubChunks.SingleOrDefault(c => c.Type == "LATI")?.Data;
                datePlace.Longitude = map.SubChunks.SingleOrDefault(c => c.Type == "LONG")?.Data;
            }

            var note = chunk.SubChunks.SingleOrDefault(c => c.Type == "NOTE");

            if (note != null)
            {
                datePlace.Note = resultContainer.ParseNote(datePlace.Note, note);
            }

            return(datePlace);
        }
Example #11
0
 internal static string ParseDateTime(this GedcomChunk chunk)
 {
     return((chunk.SubChunks.SingleOrDefault(c => c.Type == "DATE")?.Data + " " + chunk.SubChunks.SingleOrDefault(c => c.Type == "TIME")?.Data).Trim());
 }
Example #12
0
        internal static void ParsePerson(this ResultContainer resultContainer, GedcomChunk indiChunk)
        {
            var person = new Person {
                Id = indiChunk.Id
            };

            foreach (var chunk in indiChunk.SubChunks)
            {
                switch (chunk.Type)
                {
                case "_UID":
                    person.Uid = chunk.Data;
                    break;

                case "ADOP":
                    person.Adoption = resultContainer.ParseAdoption(chunk);
                    break;

                case "BAPM":
                    person.Baptized = resultContainer.ParseDatePlace(chunk);
                    break;

                case "BIRT":
                    person.Birth = resultContainer.ParseDatePlace(chunk);
                    break;

                case "BURI":
                    person.Buried = resultContainer.ParseDatePlace(chunk);
                    break;

                case "CHAN":
                    person.Changed = chunk.ParseDateTime();
                    break;

                case "CHR":
                    person.Baptized = resultContainer.ParseDatePlace(chunk);
                    break;

                case "DEAT":
                    person.Death = resultContainer.ParseDatePlace(chunk);
                    break;

                case "EDUC":
                    person.Education = chunk.Data;
                    break;

                case "EMIG":
                    person.Emigrated = resultContainer.ParseDatePlace(chunk);
                    break;

                case "FACT":
                    person.Note = resultContainer.ParseNote(person.Note, chunk);
                    break;

                case "GRAD":
                    person.Graduation = resultContainer.ParseDatePlace(chunk);
                    break;

                case "HEAL":
                    person.Health = chunk.Data;
                    break;

                case "IDNO":
                    person.IdNumber = chunk.Data;
                    break;

                case "IMMI":
                    person.Immigrated = resultContainer.ParseDatePlace(chunk);
                    break;

                case "NAME":
                    var nameSections = chunk.Data.Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                    if (nameSections.Length > 0)
                    {
                        person.FirstName = nameSections[0];
                    }

                    if (nameSections.Length > 1)
                    {
                        person.LastName = nameSections[1];
                    }

                    break;

                case "NATU":
                    person.BecomingCitizen = resultContainer.ParseDatePlace(chunk);
                    break;

                case "NOTE":
                    person.Note = resultContainer.ParseNote(person.Note, chunk);
                    break;

                case "OCCU":
                    person.Occupation = chunk.Data;
                    break;

                case "RESI":
                    person.Residence = resultContainer.ParseDatePlace(chunk);
                    break;

                case "RELI":
                    person.Religion = chunk.Data;
                    break;

                case "SEX":
                    person.Gender = chunk.Data;
                    break;

                case "TITL":
                    person.Title = chunk.Data;
                    break;

                // Deliberately skipped for now
                case "_GRP":
                case "CONF":
                case "DSCR":
                case "EVEN":
                case "FAMS":
                case "FAMC":
                case "HIST":
                case "NCHI":
                case "NMR":
                case "OBJE":
                case "PAGE":
                case "RIN":
                case "SOUR":
                    resultContainer.Warnings.Add($"Skipped Person Type='{chunk.Type}");
                    break;

                default:
                    resultContainer.Errors.Add($"Failed to handle Person Type='{chunk.Type}");
                    break;
                }
            }

            resultContainer.Persons.Add(person);
        }