{"id":13739434,"url":"https://github.com/woodbri/family-tree-nodejs","last_synced_at":"2025-04-07T07:32:14.411Z","repository":{"id":72552947,"uuid":"158009873","full_name":"woodbri/family-tree-nodejs","owner":"woodbri","description":"Application for loading GEDCOM files and serving them on the web as navigable family trees.","archived":false,"fork":false,"pushed_at":"2024-09-17T22:14:27.000Z","size":426,"stargazers_count":17,"open_issues_count":3,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-22T14:34:51.962Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/woodbri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-17T17:50:37.000Z","updated_at":"2024-09-05T15:28:36.000Z","dependencies_parsed_at":"2024-08-20T06:21:13.110Z","dependency_job_id":"34328e22-ddd5-432d-bd48-044b613917e3","html_url":"https://github.com/woodbri/family-tree-nodejs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodbri%2Ffamily-tree-nodejs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodbri%2Ffamily-tree-nodejs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodbri%2Ffamily-tree-nodejs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/woodbri%2Ffamily-tree-nodejs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/woodbri","download_url":"https://codeload.github.com/woodbri/family-tree-nodejs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247612346,"owners_count":20966724,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T04:00:33.963Z","updated_at":"2025-04-07T07:32:14.093Z","avatar_url":"https://github.com/woodbri.png","language":"JavaScript","funding_links":[],"categories":["Parsers"],"sub_categories":["JavaScript/Node.js"],"readme":"# family-tree-nodejs\n\nThis application is a Node.js webserver that serves family tree information from a GEDCOM loaded into a Sqlite database.\nIt can be configured to serve multiple separate databases and each database can its own configuration.\n\nPerformance is generally very good, 100-200 ms on most requests with the exception of the descendants listing that can take several minutes for a large number of descendants due to the fact that the query is recursive and needs to collect all the children of all families down through all generations from the selected individual. For example in my database, six generations and about 150 individuals in the list took about 3 seconds using a sqlite database.\n\nThis was built to work with my GEDCOM files and it might need changes and/or additions to work with other GEDCOM files. I use Family Tree Maker as my master repository then export that to GEDCOM files to load into this application.\n\nCollaboration and/or pull requests are welcome.\n\n## ISSUES\n\nThe loading of NOTE and probably SOUR ged records needs to be reviewed, for how they are loaded and dumped. I'm see records like:\n\n```\n0 @NS247761@ NOTE The original ownership of this Bible is uncertain.  The earliest handwriting does not match that of Christoph Friederich Klett (Frederick, Sr.), and has yet to be identified.  Several entries are in t\n1 CONC he same hand, which suggests that the events were recorded all at once and not as they happened.  Other events in varying handwriting styles appear to have been entered at different times, whether the\n1 CONC se records were entered at the time of the event or later has not been established with any certainty.\n\n0 @S24776@ SOUR\n1 ABBR Klett Family Bible\n1 TITL \u003ci\u003eKlett Family Bible\u003c/i\u003e\n1 _SUBQ \u003ci\u003eKlett Family Bible\u003c/i\u003e\n1 _BIBL \u003ci\u003eKlett Family Bible\u003c/i\u003e.\n1 NOTE The original ownership of this Bible is uncertain.  The earliest handwr\n2 CONC iting does not match that of Christoph Friederich Klett (Frederick, Sr.\n2 CONC ), and has yet to be identified.  Several entries are in the same hand, w\n2 CONC hich suggests that the events were recorded all at once and not as they h\n2 CONC appened.  Other events in varying handwriting styles appear to have bee\n2 CONC n entered at different times, whether these records were entered at the t\n2 CONC ime of the event or later has not been established with any certainty.\n```\n\nAlso RootsMagic puts a LOT of tags that are not in the original Family Tree Maker GED files that were used when this was originally written, so some additional thought needs to go into handling them.\n\n\n## Installation\n\n### Package Dependencies\n\nSee the package.json file for up to date list and versions.\n\n* any-db\n* any-db-pool\n* any-db-sqlite3\n* async\n* cookie-parser\n* debug\n* express\n* express-handlebars\n* express-session\n* formidable\n* glob-fs\n* fs\n* hbs\n* http-errors\n* metaphone\n* morgan\n* node-htmlencode\n* nodemailer\n* path\n* sharp\n\n### Download and Install\n\n```\ngit clone https://github.com/woodbri/family-tree-nodejs.git\ncd family-tree-nodejs\nnpm install\n# once you have it configured as below you can start a local server with\n./start\n```\n\n### Running with Docker\n\nAlternatively, a `docker-compose.yml` file is provided which will install and\nrun the app inside a Docker container, accessible at `http://localhost:3000`.\n\nYou will need to have Docker and Docker Compose installed to use this method.\n\nTo run in Docker, use the following command:\n\n```\nsudo docker-compose up\n```\n\nThis will create a `db` folder that is mounted into the container. Follow the\nconfiguration instructions below and put your database and configuration in\nthat folder.\n\n## Configuring the Server\n\nThe section describes how to load a GEDCOM file and configure the server to use it.\nThe development and testing has been based on using Sqlite databases that are quick and\neasy to work with and minimize the configuration dependencies and setup. Most page\nrequests are served in under 200 ms, but this is obviously based on system performance\nand load, so your mileage may vary.\n\nThe system supports multiple databases and each can be configured independently of\nthe other.\n\n### Loading a GEDCOM File\n\nDatabases are stored in ./db/\u0026lt;dbname\u0026gt;/\u0026lt;dbname\u0026gt;.\\*. There are typically 3 files here:\n\n* \u0026lt;dbname\u0026gt;.db - the sqlite database\n* \u0026lt;dbname\u0026gt;.cfg - database specific configuration information\n* \u0026lt;dbname\u0026gt;.about - html about this database that gets displayed as part of the home page for this database\n\nTo load a GEDCOM file, run these commands and then edit mygedcom.cfg (see below for details) and mygedcom.about as appropriate for your GEDCOM:\n\n```\nbin/load-gedcom \u003c path/to/mygedcom.ged\nbin/build-graphdb\nmkdir -p db/mygedcom\nmv test.db db/mygedcom/mygedcom.db\nmv graphdb.json db/mygedcom/mygedcom.json\ncp sample-db.cfg db/mygedcom/mygedcom.cfg\ncp sample-db.about db/mygedcom/mygedcom.about\n```\n\n### Updating your database with photo tables\n\nSince all the info about photos and links to individuals is stored in the database, you need\nto make sure you don't delete or loose it. This process deals with update your database\nwith an updated GEDCOM when you have photos linked to the GEDCOM file.\n\n    NOTE: because we link photos to the unique Ixxxx assigned each individual in the GEDCOM\n    file it is CRITICAL that your DO NOT renumber the individuals in your genealogy program\n    or it will MESS UP you linkages!!!!\n\n```\ncp db/\u003cdbname\u003e/\u003cdbname\u003e.db test.db\nbin/load-gedcom \u003c path/to/mygedcom.ged\nbin/build-graphdb\nmv test.db db/\u003cdbname\u003e/\u003cdbname\u003e.db\nmv graphdb.json db/\u003cdbname\u003e/\u003cdbname\u003e.json\n```\n\nThe first command copies your existing database with the photo tables in it. Then the next command\ndrops the genealogy tables only leaving the photos in place and reloads the genealogy tables\nfrom the GEDCOM. The last two command moves the updated test.db back into place and you should\nhave both the new genealogy data and you existing photo tables and moves the new graph database\nin place.\n\n### Integrating Photos with your Genealogy Data\n\nThis code currently does not support GEDCOM 5.5 support for media links. This could be\nadded in the future. For now there is a photo management system included if you turn it on\nin ``db-config.js`` by setting ``hasPhotos: true``. This enable a ``Photos`` link on the\nmain menu bar. From here your users logged in with admin rights can upload photos, link\nthem to individuals, view them and edit attributes associated with the photos.\n\n### Configuring Databases in the Server\n\nIn the db-config.js file edit the databases section so it has your database(s) defined.\nIn the example below there are two databases configured 'woodbridge' and\n'woodbridge\\_record'. Leave the 'adapter' set to 'sqlite3', in the future this might\nalso allow using 'mysql' and/or 'postgresql' databases. Edit the 'database' variable\nto point your database as installed above.\n\nVersion 0.1.0+ has support for integrating photos with you genealogy. If you use this\nDO NOT renumber your indiviual ID in your genealogy program as these are used to link\nto photos. In the ``db-config.js`` file set option ``hasPhotos: true`` if you plan to\nuse the photo management option or ``hasPhotos: false`` if not.\n\n```\nvar databases = {\n    woodbridge: {\n        adapter: 'sqlite3',\n        read_only: 1,\n        database: 'db/woodbridge/woodbridge.db',\n        title: 'Woodbridge Family Tree',\n        owner: 'Stephen Woodbridge',\n        email: 'stephenwoodbridge37 (at) gmail (dot) com',\n        copyright: \"Family Data Copyright 2001-2018 by Stephen Woodbridge, All Rights Reservered.\",\n        hasPhotos: true\n    },\n    woodbridge_record: {\n        adapter: 'sqlite3',\n        read_only: 1,\n        database: 'db/woodbridge_record/woodbridge_record.db',\n        title: 'Woodbridge Family Tree',\n        owner: 'Stephen Woodbridge',\n        email: 'stephenwoodbridge37 (at) gmail (dot) com',\n        copyright: \"Family Data Copyright 2001-2018 by Stephen Woodbridge, All Rights Reservered.\",\n        hasPhotos false\n    }\n};\n```\n\nLeave the rest of the file alone.\n\n### Configuring Login Users\n\nThe software will compute if people are living based on the following rules:\n\n* no birth and no death date, then presumed dead\n* death date, then dead\n* birth but no death and age \u003c 115 years, then presumed living\n\nThis is used to hide people in your database that are presumed living unless the user\nhas logged into the system. Logged in users can see everything.\n\nUsers are configured with static logins configured in the db/\u0026lt;dbname\u0026gt;/\u0026lt;dbname\u0026gt;.cfg file\nin the database directory. the sample-db.cfg you copied has a default user \"test\" with a password \"test\", CHANGE THIS!, in the auth section of that file. The admin flag is\nrequired if you want to allow this user to upload, edit and manage photos associated with\nyour family tree.\n\n\n```\nvar dbConfig = {\n    auth: {\n        test: {\n            password: 'test',\n            admin: false                                                                        }\n    },\n```\n\n### Setting up email for Feedback\n\nI added basic feedback via email and made a test using mailgun, but there are other\ntransports available including talking to an smtp server. Read up on nodemailer for\nconfiguration details. You will likely need to make changes to routes/feedbackpost.js\nthat handles sending the email.\n\nYou can configure mailers in the \"mailers\" section and then reference that in the code.\nthe \"options\" section, sets up the basic email envelope and the dummy options.text is\nwhere the email body text will replace based on the form contents.\n\nYou can configure \"requireLoginForFeedback\" to true or false to only allow logged in\nusers the ability to send you feedback or to allow all users to send feedback.\n\n```\nvar dbConfig = {\n    auth: {\n        ...\n    },\n    requireLoginForFeedback: false,\n    mailer: {\n        mailgun: {\n            auth: {\n                api_key: 'secret',\n                domain: 'sandbox.mailgun.org'\n            }\n        },\n        options: {\n            from: 'youremail@example.com',\n            to: 'youremail@example.com',\n            subject: 'Feedback on \"mygenealogy\" genealogy database',\n            text: 'nothing here'\n        }\n    }\n};\n```\n\n### Using find-relationship\n\nFind-relationship searches the graph database version of your gedcom file to find a path\nfrom one individual to another. The command runs like:\n\n```\nUsage: find-relationship database indi_from indi_to\n```\n\nas in this example:\n\n```\n$ bin/find-relationship woodbridge I0169 I2825\nfind-relationship:  { iter: 5619,\n  distance: 12,\n  path:\n   [ { indi: 'I0169', name: 'Stephen Eliot Woodbridge' },\n     { indi: 'I2788', name: 'Joseph Eliot Woodbridge' },\n     { indi: 'I3365', name: 'Donald Eliot Woodbridge' },\n     { indi: 'I0002', name: 'Joseph Lester Woodbridge' },\n     { indi: 'I1857', name: 'Irene Augusta Cartwright' },\n     { indi: 'I2792', name: 'David Gardner Cartwright' },\n     { indi: 'I2796', name: 'Thomas Cartwright' },\n     { indi: 'I2798', name: 'Benjamin Cartwright' },\n     { indi: 'I2801', name: 'Hezadiah Cartwright' },\n     { indi: 'I2816', name: 'Bethia Pratt' },\n     { indi: 'I2819', name: 'Joseph Pratt' },\n     { indi: 'I2823', name: 'Mary Priest' },\n     { indi: 'I2825', name: 'Degory Priest' } ] }\n```\n\n## File Structure\n\nThe sqlite databases are stored in ``./db/\u0026lt;DBName\u0026gt;/`` along with its cfg and about\nfiles. If you are using the Photo management options the photos are stored in\n``./media/\u0026lt;DBName\u0026gt;/`` and photo attributes are stored in the respective database.\n\n```\n./app.js\n./bin/load-gedcom\n./bin/www\n./db/woodbridge/woodbridge.about\n./db/woodbridge/woodbridge.cfg\n./db/woodbridge/woodbridge.db\n./db/woodbridge_record/woodbridge_record.about\n./db/woodbridge_record/woodbridge_record.cfg\n./db/woodbridge_record/woodbridge_record.db\n./db-config.js\n./LICENSE\n./media/README.md\n./package.json\n./package-lock.json\n./public/images/favicon.ico\n./public/images/favicon-16x16.png\n./public/images/favicon-32x32.png\n./public/javascripts/helpers.js\n./public/stylesheets/style.css\n./README.md\n./routes/about.js\n./routes/birthdays.js\n./routes/descendants.js\n./routes/feedback.js\n./routes/feedbackpost.js\n./routes/getgroups.js\n./routes/help.js\n./routes/home.js\n./routes/index.js\n./routes/indi.js\n./routes/mediadelete.js\n./routes/mediadeletepost.js\n./routes/mediaedit.js\n./routes/mediaeditpost.js\n./routes/mediagroupspost.js\n./routes/mediaimage.js\n./routes/medialink.js\n./routes/medialist.js\n./routes/mediasummary.js\n./routes/mediaupload.js\n./routes/mediauploadpost.js\n./routes/names.js\n./routes/notes.js\n./routes/search.js\n./routes/source.js\n./routes/surnames.js\n./sample-db.about\n./sample-db.cfg\n./schema.txt\n./schema-photos.txt\n./start\n./utils.js\n./views/about.hbs\n./views/birthdays.hbs\n./views/descendants.hbs\n./views/error.hbs\n./views/feedback.hbs\n./views/help.hbs\n./views/home.hbs\n./views/index.hbs\n./views/indi.hbs\n./views/layouts/layout.hbs\n./views/login.hbs\n./views/mediadelete.hbs\n./views/mediaedit.hbs\n./views/medialist1.hbs\n./views/medialist2.hbs\n./views/medialist3.hbs\n./views/mediasummary.hbs\n./views/mediaupload.hbs\n./views/mediaview.hbs\n./views/names.hbs\n./views/notes.hbs\n./views/partials/footer.hbs\n./views/partials/header.hbs\n./views/search.hbs\n./views/source.hbs\n./views/surnames.hbs\n```\n\n## Some Interesting Queries in SQLite\n\n```\n-- list indi record and age for all presumed living people older then 80\nselect \\*, strftime('%Y', 'now') - strftime('%Y', bdate) as age\n  from indi\n where living and strftime('%Y', 'now') - strftime('%Y', bdate) \u003e 80\n order by age desc, lname, fname;\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoodbri%2Ffamily-tree-nodejs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwoodbri%2Ffamily-tree-nodejs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwoodbri%2Ffamily-tree-nodejs/lists"}