├── .coveralls.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.html ├── package.json ├── src ├── search.js ├── sites │ ├── americanancestors.js │ ├── ancestry.js │ ├── archives.js │ ├── billiongraves.js │ ├── chroniclingamerica.js │ ├── familysearch.js │ ├── findagrave.js │ ├── findmypast.co.uk.js │ ├── findmypast.com.js │ ├── findmypast.js │ ├── fold3.js │ ├── genealogieonline.js │ ├── genealogybank.js │ ├── geneanet.en.js │ ├── gengophers.js │ ├── geni.js │ ├── google.js │ ├── myheritage.js │ ├── newspapers.js │ ├── nlatrove.js │ ├── openarchives.js │ ├── usgenweb.js │ ├── werelate.js │ ├── wikitree.js │ └── worldvitalrecords.js └── utils.js ├── test ├── search.js ├── sites │ ├── americanancestors.js │ ├── ancestry.js │ ├── archives.js │ ├── billiongraves.js │ ├── chroniclingamerica.js │ ├── familysearch.js │ ├── findagrave.js │ ├── findmypast.co.uk.js │ ├── findmypast.com.js │ ├── fold3.js │ ├── genealogieonline.js │ ├── genealogybank.js │ ├── geneanet.en.js │ ├── gengophers.js │ ├── geni.js │ ├── google.js │ ├── myheritage.js │ ├── newspapers.js │ ├── nlatrove.js │ ├── openarchives.js │ ├── usgenweb.js │ ├── werelate.js │ ├── wikitree.js │ └── worldvitalrecords.js ├── test-data.js ├── tester.js └── utils.js └── webpack.config.js /.coveralls.yml: -------------------------------------------------------------------------------- 1 | repo_token: taKCrAT5tk9Vq52zaP5GjvG5MzpyfeRP0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .c9 3 | coverage 4 | npm-debug.log 5 | dist -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '4.3' 4 | script: 5 | - 'npm run coveralls' 6 | notifications: 7 | email: 8 | on_success: never 9 | on_failure: always -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 RootsDev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm](https://img.shields.io/npm/v/gensearch.svg?maxAge=2592000)](https://www.npmjs.com/package/gensearch) 2 | [![Build Status](https://travis-ci.org/rootsdev/gensearch.svg)](https://travis-ci.org/rootsdev/gensearch) 3 | [![Coverage Status](https://coveralls.io/repos/rootsdev/gensearch/badge.svg)](https://coveralls.io/r/rootsdev/gensearch) 4 | 5 | # gensearch 6 | 7 | Generate search links for a many genealogy websites. 8 | 9 | ### __[Try the Demo](http://rootsdev.github.io/gensearch/)__ 10 | 11 | * [Usage](#usage) 12 | * [Installation Instructions](#install) 13 | * [Person Data Schema](#schema) 14 | * [Supported Sites](#sites) 15 | * [Contributor's Guide](#contribute) 16 | 17 | ## Usage 18 | 19 | ```javascript 20 | // Generate a search link for FamilySearch 21 | var url = gensearch('familysearch', { 22 | givenName: "Joe William", 23 | familyName: "Clark" 24 | }); 25 | 26 | // Some options can be changed. Here we modify the birth year range 27 | var url = gensearch('familysearch', data, { 28 | birthRange: 5 29 | }); 30 | 31 | // Or we can set the configuration option once and have it apply to all future searches. 32 | gensearch.config('familysearch', { 33 | birthRange: 5 34 | }); 35 | 36 | // We can also set options for multiple sites at once 37 | gensearch.config({ 38 | familysearch: { 39 | birthRange: 5 40 | }, 41 | archives: { 42 | deathRange: 10 43 | } 44 | }); 45 | ``` 46 | 47 | ## Install 48 | 49 | #### Web 50 | 51 | Via the CDN unpkg: 52 | 53 | ```html 54 | 55 | ``` 56 | 57 | #### Node 58 | 59 | ```shell 60 | npm install gensearch 61 | ``` 62 | 63 | ```javascript 64 | var genSearch = require('gensearch'); 65 | ``` 66 | 67 | ## Schema 68 | 69 | * `givenName` 70 | * `familyName` 71 | * `birthPlace` 72 | * `birthDate` 73 | * `deathPlace` 74 | * `deathDate` 75 | * `marriagePlace` 76 | * `marriageDate` 77 | * `fatherGivenName` 78 | * `fatherFamilyName` 79 | * `motherGivenName` 80 | * `motherFamilyName` 81 | * `spouseGivenName` 82 | * `spouseFamilyName` 83 | 84 | ## Sites 85 | 86 | * [americanancestors](#americanancestors) 87 | * [ancestry](#ancestry) 88 | * [archives](#archives) 89 | * [billiongraves](#billiongraves) 90 | * [chroniclingamerica](#chroniclingamerica) 91 | * [familysearch](#familysearch) 92 | * [findagrave](#findagrave) 93 | * [findmypast.co.uk](#findmypastcouk) 94 | * [findmypast.com](#findmypastcom) 95 | * [fold3](#fold3) 96 | * [genealogieonline](#genealogieonline) 97 | * [genealogybank](#genealogybank) 98 | * [geneanet.en](#geneaneten) 99 | * [gengophers](#gengophers) 100 | * [geni](#geni) 101 | * [google](#google) 102 | * [mocavo](#mocavo) 103 | * [myheritage](#myheritage) 104 | * [nla trove](#nla-trove) 105 | * [newspapers](#newspapers) 106 | * [openarchives](#openarchives) 107 | * [usgenweb](#usgenweb) 108 | * [werelate](#werelate) 109 | * [wikitree](#wikitree) 110 | * [worldvitalrecords](#worldvitalrecords) 111 | 112 | ### americanancestors 113 | 114 | http://www.americanancestors.org/ 115 | 116 | ```javascript 117 | var url = gensearch('americanancestors', data); 118 | ``` 119 | 120 | ### ancestry 121 | 122 | http://ancestry.com 123 | 124 | ```javascript 125 | var url = gensearch('ancestry', data, [options]); 126 | ``` 127 | 128 | | option | default | notes | 129 | |--------|---------|-------| 130 | | `db` | | Search within a specific database. This value equates to the 'db' parameter value used by Ancestry. | 131 | 132 | ### archives 133 | 134 | http://archives.com 135 | 136 | ```javascript 137 | var url = gensearch('archives', data); 138 | ``` 139 | 140 | | option | default | 141 | |--------|---------| 142 | | `birthRange` | 2 | 143 | | `deathRange` | 2 | 144 | 145 | ### billiongraves 146 | 147 | http://billiongraves.com/ 148 | 149 | ```javascript 150 | var url = gensearch('billiongraves', data, [options]); 151 | ``` 152 | 153 | | option | default | 154 | |--------|---------| 155 | | `yearRange` | 2 | 156 | 157 | ### chroniclingamerica 158 | 159 | http://chroniclingamerica.loc.gov/ 160 | 161 | ```javascript 162 | var url = gensearch('chroniclingamerica', data); 163 | ``` 164 | 165 | ### familysearch 166 | 167 | https://familysearch.org 168 | 169 | ```javascript 170 | var url = gensearch('familysearch', data, [options]); 171 | ``` 172 | 173 | | option | default | notes | 174 | |--------|---------|-------| 175 | | `birthRange` | 2 | 176 | | `deathRange` | 2 | 177 | | `marriageRange` | 2 | 178 | | `collectionId` | | Only search within a specific collection. | 179 | 180 | ### findagrave 181 | 182 | http://findagrave.com 183 | 184 | ```javascript 185 | var url = gensearch('findagrave', data); 186 | ``` 187 | 188 | ### findmypast.co.uk 189 | 190 | http://findmypast.co.uk 191 | 192 | ```javascript 193 | var url = gensearch('findmypast.co.uk', data, [options]); 194 | ``` 195 | 196 | | option | default | notes | 197 | |--------|---------|-------| 198 | | `event` | | Type of event to search for. Valid values are `birth`, `death`, and `other`. The `otherDate` and `otherPlace` options are used when `event` is `other`. 199 | | `birthRange` | 2 | 200 | | `deathRange` | 2 | 201 | | `otherRange` | 2 | 202 | | `otherDate` | | Only used when `event` is `other`. | 203 | | `otherPlace` | | Only used when `event` is `other`. | 204 | 205 | ### findmypast.com 206 | 207 | http://findmypast.com 208 | 209 | ```javascript 210 | var url = gensearch('findmypast.com', data, [options]); 211 | ``` 212 | 213 | | option | default | notes | 214 | |--------|---------|-------| 215 | | `event` | | Type of event to search for. Valid values are `birth`, `death`, and `other`. The `otherDate` and `otherPlace` options are used when `event` is `other`. 216 | | `birthRange` | 2 | 217 | | `deathRange` | 2 | 218 | | `otherRange` | 2 | 219 | | `otherDate` | | Only used when `event` is `other`. | 220 | | `otherPlace` | | Only used when `event` is `other`. | 221 | 222 | ### fold3 223 | 224 | http://fold3.com 225 | 226 | ```javascript 227 | var url = gensearch('fold3', data); 228 | ``` 229 | 230 | Only `givenName` and `familyName` are used for Fold3 searches. 231 | 232 | ### genealogieonline 233 | 234 | http://genealogieonline.nl/en/ 235 | 236 | ```javascript 237 | var url = gensearch('genealogieonline', data, [options]); 238 | ``` 239 | 240 | | option | default | 241 | |--------|---------| 242 | | `birthRange` | 5 | 243 | | `deathRange` | 5 | 244 | 245 | ### genealogybank 246 | 247 | http://genealogybank.com 248 | 249 | ```javascript 250 | var url = gensearch('genealogybank', data, [options]); 251 | ``` 252 | 253 | | option | default | notes | 254 | |--------|---------|-------| 255 | | `lifespan` | 90 | If either a `birthDate` or `deathDate` exists, but not both, then this value is used to approximate the missing year. For example, if the `birthDate` is `2 Feb 1766` and no `deathDate` is given then we would add `lifespan` to the birth year to get an approximate death year of `1856`. | 256 | | `datePadding` | 5 | This value is substracted from the calculated birth year and added to the calculated death year. | 257 | 258 | ### geneanet.en 259 | 260 | http://en.geneanet.org/ 261 | 262 | ```javascript 263 | var url = gensearch('geneanet.en', data, [options]); 264 | ``` 265 | 266 | | option | default | notes | 267 | |--------|---------|-------| 268 | | `place` | `birth` | Determines whether the birth or death place is used for searching. Values: `birth` or `death`. | 269 | 270 | ### gengophers 271 | 272 | https://www.gengophers.com 273 | 274 | ```javascript 275 | var url = gensearch('gengophers', data); 276 | ``` 277 | 278 | ### geni 279 | 280 | http://geni.com 281 | 282 | ```javascript 283 | var url = gensearch('geni', data); 284 | ``` 285 | 286 | Only `givenName` and `familyName` are used for Geni searches. 287 | 288 | ### google 289 | 290 | https://www.google.com 291 | 292 | ```javascript 293 | var url = gensearch('google', data); 294 | ``` 295 | 296 | ### mocavo 297 | 298 | http://www.mocavo.com/ 299 | 300 | ```javascript 301 | var url = gensearch('mocavo', data); 302 | ``` 303 | 304 | ### myheritage 305 | 306 | http://www.myheritage.com 307 | 308 | ```javascript 309 | var url = gensearch('myheritage', data); 310 | ``` 311 | 312 | ### newspapers 313 | 314 | http://www.newspapers.com/ 315 | 316 | ```javascript 317 | var url = gensearch('newspapers', data, [options]); 318 | ``` 319 | 320 | | option | default | notes | 321 | |--------|---------|-------| 322 | | `lifespan` | 90 | If either a `birthDate` or `deathDate` exists, but not both, then this value is used to approximate the missing year. For example, if the `birthDate` is `2 Feb 1766` and no `deathDate` is given then we would add `lifespan` to the birth year to get an approximate death year of `1856`. | 323 | | `datePadding` | 5 | This value is substracted from the calculated birth year and added to the calculated death year. | 324 | 325 | ### nla trove 326 | 327 | http://trove.nla.gov.au/ 328 | 329 | ```javascript 330 | var url = gensearch('nlatrove', data); 331 | ``` 332 | 333 | ### openarchives 334 | 335 | http://openarch.nl 336 | 337 | ```javascript 338 | var url = gensearch('openarchives', data); 339 | ``` 340 | 341 | Only `givenName` and `familyName` are used for Open Archive searches. 342 | 343 | ### usgenweb 344 | 345 | http://www.usgwarchives.net/ 346 | 347 | ```javascript 348 | var url = gensearch('usgenweb', data); 349 | ``` 350 | 351 | ### werelate 352 | 353 | http://werelate.org 354 | 355 | ```javascript 356 | var url = gensearch('werelate', data, [options]); 357 | ``` 358 | 359 | | option | default | 360 | |--------|---------| 361 | | `birthRange` | 2 | 362 | | `deathRange` | 2 | 363 | 364 | ### wikitree 365 | 366 | http://www.wikitree.com/ 367 | 368 | ```javascript 369 | var url = gensearch('wikitree', data); 370 | ``` 371 | 372 | ### worldvitalrecords 373 | 374 | http://worldvitalrecords.com 375 | 376 | ```javascript 377 | var url = gensearch('worldvitalrecords', data, [options]); 378 | ``` 379 | 380 | | option | default | 381 | |--------|---------| 382 | | `dateRange` | 2 | 383 | 384 | 385 | ## Contribute 386 | 387 | #### Setup 388 | 389 | ```shell 390 | git clone https://github.com/rootsdev/gen-search.git 391 | cd gen-search 392 | npm install 393 | ``` 394 | 395 | #### Add a site 396 | 397 | 1. Create the site file in the [src/sites](https://github.com/rootsdev/gen-search/tree/master/src/sites) directory. Look at [archives.js](https://github.com/rootsdev/gen-search/blob/master/src/sites/archives.js) for a simple example or [familysearch.js](https://github.com/rootsdev/gen-search/blob/master/src/sites/familysearch.js) for a more complex example. 398 | 2. Add the new site to the [src/search.js](https://github.com/rootsdev/gen-search/blob/master/src/search.js) site list, in alphabetical order please. 399 | 3. Add a test file in the [test/sites](https://github.com/rootsdev/gen-search/tree/master/test/sites) directory. Look at any of the other site test files for an example. 400 | 4. Run tests with `npm test`. The `gensearch.js` file will be automatically built with [browserify](https://github.com/substack/node-browserify) before the tests are run. 401 | 5. Document the new site in the README file, in alphabetical order please. Be sure to add a link in the site list just before the site specific docs. 402 | 6. Commit and submit a pull request. 403 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | gensearch demo 8 | 9 | 17 | 18 | 19 |
20 |

GenSearch Demo

21 | 22 |
23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 | 31 | Fork me on GitHub 32 | 33 | 34 | 35 | 36 | 117 | 118 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gensearch", 3 | "version": "2.4.3", 4 | "description": "Generate search links for genealogy websites", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/genealogysystems/gen-search" 8 | }, 9 | "bugs": "https://github.com/genealogysystems/gen-search/issues", 10 | "main": "src/search.js", 11 | "scripts": { 12 | "test": "mocha --recursive", 13 | "build": "npm run build:dev && npm run build:min", 14 | "build:dev": "webpack", 15 | "build:min": "webpack --env.production", 16 | "coverage": "istanbul cover ./node_modules/mocha/bin/_mocha -- --recursive", 17 | "coveralls": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- --recursive && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage", 18 | "prepublish": "npm test && npm run build" 19 | }, 20 | "files": [ 21 | "src", 22 | "dist" 23 | ], 24 | "keywords": [ 25 | "genealogy" 26 | ], 27 | "author": "Justin York", 28 | "license": "MIT", 29 | "devDependencies": { 30 | "bannerjs": "^1.0.5", 31 | "coveralls": "2.11.2", 32 | "istanbul": "0.3.8", 33 | "mocha": "2.2.1", 34 | "webpack": "^2.3.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/search.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils.js'), 2 | config = {}; 3 | 4 | // We have to explicitly list the sites, instead of 5 | // dynamically loading, so that browserify can see them 6 | var sites = { 7 | 'americanancestors': require('./sites/americanancestors.js'), 8 | 'ancestry': require('./sites/ancestry.js'), 9 | 'archives': require('./sites/archives.js'), 10 | 'billiongraves': require('./sites/billiongraves.js'), 11 | 'chroniclingamerica': require('./sites/chroniclingamerica.js'), 12 | 'familysearch': require('./sites/familysearch.js'), 13 | 'findagrave': require('./sites/findagrave.js'), 14 | 'findmypast.co.uk': require('./sites/findmypast.co.uk.js'), 15 | 'findmypast.com': require('./sites/findmypast.com.js'), 16 | 'fold3': require('./sites/fold3.js'), 17 | 'geneanet.en': require('./sites/geneanet.en.js'), 18 | 'genealogieonline': require('./sites/genealogieonline.js'), 19 | 'genealogybank': require('./sites/genealogybank.js'), 20 | 'gengophers': require('./sites/gengophers.js'), 21 | 'geni': require('./sites/geni.js'), 22 | 'google': require('./sites/google.js'), 23 | 'nlatrove': require('./sites/nlatrove.js'), 24 | 'myheritage': require('./sites/myheritage.js'), 25 | 'newspapers': require('./sites/newspapers.js'), 26 | 'openarchives': require('./sites/openarchives.js'), 27 | 'usgenweb': require('./sites/usgenweb.js'), 28 | 'werelate': require('./sites/werelate.js'), 29 | 'wikitree': require('./sites/wikitree.js'), 30 | 'worldvitalrecords': require('./sites/worldvitalrecords.js') 31 | }; 32 | 33 | // Main search link generation function 34 | var gensearch = module.exports = function(site, person, opts){ 35 | if(sites[site]){ 36 | return sites[site](utils.extend({}, config[site], opts), person); 37 | } 38 | }; 39 | 40 | /** 41 | * Set global config for a site. May be used in two ways: 42 | * config('site', {options}); 43 | * config({'site': options}); 44 | */ 45 | gensearch.config = function(site, siteConfig){ 46 | // config('site', {options}); 47 | if(utils.isString(site) && utils.isObject(siteConfig)){ 48 | config[site] = utils.extend({}, config[site], siteConfig); 49 | } 50 | 51 | // config({site: options}); 52 | else if(site && utils.isUndefined(siteConfig)) { 53 | var newConfig = site; 54 | utils.each(newConfig, function(siteConfig, site){ 55 | config[site] = utils.extend({}, config[site], siteConfig); 56 | }); 57 | } 58 | 59 | // config() 60 | else { 61 | return config; 62 | } 63 | }; 64 | 65 | /** 66 | * Expose sites list. 67 | */ 68 | gensearch.sites = sites; 69 | -------------------------------------------------------------------------------- /src/sites/americanancestors.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'http://www.americanancestors.org/search/database-search?'; 6 | var params = {}; 7 | 8 | if(data.givenName){ 9 | params.firstname = data.givenName; 10 | } 11 | 12 | if(data.familyName){ 13 | params.lastname = data.familyName; 14 | } 15 | 16 | if(data.birthDate){ 17 | params.fromyear = utils.getYear(data.birthDate); 18 | } 19 | 20 | if(data.deathDate){ 21 | params.toyear = utils.getYear(data.deathDate); 22 | } 23 | 24 | if(data.birthPlace){ 25 | params.location = data.birthPlace; 26 | } else if(data.deathPlace){ 27 | params.location = data.deathPlace; 28 | } 29 | 30 | return url + utils.queryString(params); 31 | }; -------------------------------------------------------------------------------- /src/sites/ancestry.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var ancestryURL = 'http://search.ancestry.com/cgi-bin/sse.dll?rank=1'; 6 | var query = ''; 7 | 8 | // Simple mappings from the person data object to ancestry params 9 | // These don't need any further processing 10 | var mappings = [ 11 | ['gsfn', 'givenName'], 12 | ['gsln', 'familyName'], 13 | ['msbpn__ftp', 'birthPlace'], 14 | ['msdpn__ftp', 'deathPlace'], 15 | ['msfng0', 'fatherGivenName'], 16 | ['msfns0', 'fatherFamilyName'], 17 | ['msmng0', 'motherGivenName'], 18 | ['msmns0', 'motherFamilyName'], 19 | ['mssng0', 'spouseGivenName'], 20 | ['mssns0', 'spouseFamilyName'], 21 | ['msgpn__ftp', 'marriagePlace'] 22 | ]; 23 | 24 | utils.each(mappings, function(map) { 25 | if( data[map[1]] ) { 26 | query = utils.addQueryParam(query, map[0], data[map[1]]); 27 | } 28 | }); 29 | 30 | // Process dates 31 | query = utils.addQueryParam(query, 'msbdy', utils.getYear(data.birthDate)); 32 | query = utils.addQueryParam(query, 'msddy', utils.getYear(data.deathDate)); 33 | query = utils.addQueryParam(query, 'msgdy', utils.getYear(data.marriageDate)); 34 | 35 | if(config.db){ 36 | query = utils.addQueryParam(query, 'db', config.db); 37 | } else { 38 | query = utils.addQueryParam(query, 'gl', 'allgs'); 39 | } 40 | 41 | return ancestryURL + query; 42 | 43 | }; 44 | -------------------------------------------------------------------------------- /src/sites/archives.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | birthRange: 2, 5 | deathRange: 2 6 | }; 7 | 8 | module.exports = function(config, data){ 9 | 10 | config = utils.defaults(config, defaultConfig); 11 | 12 | var url = 'http://www.archives.com/GA.aspx'; 13 | var query = '?_act=registerAS_org&Location=US'; 14 | 15 | if(data.givenName) { 16 | query = utils.addQueryParam(query, 'FirstName', data.givenName); 17 | } 18 | if(data.familyName) { 19 | query = utils.addQueryParam(query, 'LastName', data.familyName); 20 | } 21 | if(data.birthDate) { 22 | query = utils.addQueryParam(query, 'BirthYear', utils.getYear(data.birthDate)); 23 | query = utils.addQueryParam(query, 'BirthYearSpan', config.birthRange); 24 | } 25 | if(data.deathDate) { 26 | query = utils.addQueryParam(query, 'DeathYear', utils.getYear(data.deathDate)); 27 | query = utils.addQueryParam(query, 'DeathYearSpan', config.deathRange); 28 | } 29 | 30 | return url + query; 31 | 32 | }; 33 | -------------------------------------------------------------------------------- /src/sites/billiongraves.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | yearRange: 2 5 | }; 6 | 7 | module.exports = function(config, data){ 8 | 9 | config = utils.defaults(config, defaultConfig); 10 | 11 | var url = 'http://billiongraves.com/pages/search/index.php#year_range=' + config.yearRange + '&lim=0&action=search&exact=false&country=0&state=0&county=0'; 12 | var query = ''; 13 | 14 | if(data.givenName) { 15 | query = utils.addQueryParam(query, 'given_names', data.givenName); 16 | } 17 | if(data.familyName) { 18 | query = utils.addQueryParam(query, 'family_names', data.familyName); 19 | } 20 | 21 | if(data.birthDate) { 22 | query = utils.addQueryParam(query, 'birth_year', utils.getYear(data.birthDate)); 23 | } 24 | 25 | if(data.deathDate) { 26 | query = utils.addQueryParam(query, 'death_year', utils.getYear(data.deathDate)); 27 | } 28 | 29 | return url + query; 30 | 31 | }; 32 | -------------------------------------------------------------------------------- /src/sites/chroniclingamerica.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'http://chroniclingamerica.loc.gov/search/pages/results/'; 6 | 7 | // Necessary param to get the dates to work 8 | var query = '?dateFilterType=yearRange'; 9 | 10 | var nameParts = []; 11 | if(data.givenName) { 12 | nameParts.push(data.givenName); 13 | } 14 | if(data.familyName) { 15 | nameParts.push(data.familyName); 16 | } 17 | query = utils.addQueryParam(query, 'proxtext', nameParts.join(' ')); 18 | 19 | if(data.birthDate) { 20 | query = utils.addQueryParam(query, 'date1', utils.getYear(data.birthDate)); 21 | } 22 | if(data.deathDate) { 23 | query = utils.addQueryParam(query, 'date2', utils.getYear(data.deathDate)); 24 | } 25 | 26 | return url + query; 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /src/sites/familysearch.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | birthRange: 2, 5 | deathRange: 2, 6 | marriageRange: 2 7 | }; 8 | 9 | module.exports = function(config, data){ 10 | 11 | config = utils.defaults(config, defaultConfig); 12 | 13 | var fsURL = 'https://www.familysearch.org/search/record/results?'; 14 | var query = ''; 15 | 16 | // Simple mappings from the person data object to fs params 17 | // These don't need any special processing 18 | var simpleMappings = [ 19 | ['q.givenName', 'givenName'], 20 | ['q.surname', 'familyName'], 21 | ['q.birthLikePlace', 'birthPlace'], 22 | ['q.deathLikePlace', 'deathPlace'], 23 | ['q.fatherGivenName', 'fatherGivenName'], 24 | ['q.fatherSurname', 'fatherFamilyName'], 25 | ['q.motherGivenName', 'motherGivenName'], 26 | ['q.motherSurname', 'motherFamilyName'], 27 | ['q.spouseGivenName', 'spouseGivenName'], 28 | ['q.spouseSurname', 'spouseFamilyName'], 29 | ['q.marriageLikePlace', 'marriagePlace'] 30 | ]; 31 | utils.each(simpleMappings, function(map) { 32 | if( data[map[1]] ) { 33 | query = utils.addQueryParam(query, map[0], data[map[1]]); 34 | } 35 | }); 36 | 37 | // Process the birth year 38 | if(data.birthDate){ 39 | var birthYear = utils.getYearInt(data.birthDate); 40 | if( birthYear ) { 41 | query = utils.addQueryParam(query, 'q.birthLikeDate.from', birthYear - config.birthRange); 42 | query = utils.addQueryParam(query, 'q.birthLikeDate.to', birthYear + config.birthRange) 43 | } 44 | } 45 | 46 | // Process the death year 47 | if(data.deathDate){ 48 | var deathYear = utils.getYearInt(data.deathDate); 49 | if( deathYear ) { 50 | query = utils.addQueryParam(query, 'q.deathLikeDate.from', deathYear - config.deathRange); 51 | query = utils.addQueryParam(query, 'q.deathLikeDate.to', deathYear + config.deathRange); 52 | } 53 | } 54 | 55 | // Process the marriage year 56 | if(data.marriageDate){ 57 | var marriageYear = utils.getYearInt(data.marriageDate); 58 | if( marriageYear ) { 59 | query = utils.addQueryParam(query, 'q.marriageLikeDate.from', marriageYear - config.marriageRange); 60 | query = utils.addQueryParam(query, 'q.marriageLikeDate.to', marriageYear + config.marriageRange); 61 | } 62 | } 63 | 64 | if(config.collectionId){ 65 | query = utils.addQueryParam(query, 'f.collectionId', config.collectionId); 66 | } 67 | 68 | return fsURL + query.replace('&', ''); 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /src/sites/findagrave.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'http://www.findagrave.com/cgi-bin/fg.cgi?page=gsr&GScntry=0&GSst=0&GSgrid=&df=all&GSob=n'; 6 | var query = ''; 7 | 8 | if( data.givenName ) { 9 | query = utils.addQueryParam(query, 'GSfn', data.givenName); 10 | } 11 | if( data.familyName ) { 12 | query = utils.addQueryParam(query, 'GSln', data.familyName); 13 | } 14 | 15 | if( data.birthDate ) { 16 | query = utils.addQueryParam(query, 'GSbyrel', 'in'); 17 | query = utils.addQueryParam(query, 'GSby', utils.getYear(data.birthDate)); 18 | } 19 | if( data.deathDate ) { 20 | query = utils.addQueryParam(query, 'GSdyrel', 'in'); 21 | query = utils.addQueryParam(query, 'GSdy', utils.getYear(data.deathDate)); 22 | } 23 | 24 | return url + query; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /src/sites/findmypast.co.uk.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'), 2 | fmp = require('./findmypast.js'); 3 | 4 | var defaultConfig = { 5 | birthRange: 2, 6 | deathRange: 2, 7 | otherRange: 2 8 | }; 9 | 10 | module.exports = function(config, data){ 11 | config = utils.defaults(config, defaultConfig); 12 | return fmp(config, data, 'co.uk'); 13 | }; -------------------------------------------------------------------------------- /src/sites/findmypast.com.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'), 2 | fmp = require('./findmypast.js'); 3 | 4 | var defaultConfig = { 5 | birthRange: 2, 6 | deathRange: 2, 7 | otherRange: 2 8 | }; 9 | 10 | module.exports = function(config, data){ 11 | config = utils.defaults(config, defaultConfig); 12 | return fmp(config, data, 'com'); 13 | }; -------------------------------------------------------------------------------- /src/sites/findmypast.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This is not a site config. It is a common util for 3 | * the findmypast sites that only differ in the TLD. 4 | * .com vs .co.uk 5 | */ 6 | 7 | var utils = require('../utils.js'); 8 | 9 | module.exports = function(config, data, tld){ 10 | 11 | // TODO 12 | // * allow for record category 13 | // * restrict to record set(s)? 14 | 15 | var baseUrl = 'http://search.findmypast.'+tld+'/search/world-records?firstname_variants=true'; 16 | var query = ''; 17 | 18 | // Name 19 | if(data.givenName) { 20 | query = utils.addQueryParam(query, 'firstname', data.givenName); 21 | } 22 | if(data.familyName) { 23 | query = utils.addQueryParam(query, 'lastname', data.familyName); 24 | } 25 | 26 | // Birth 27 | if(config.event === 'birth'){ 28 | 29 | if(data.birthDate){ 30 | query = utils.addQueryParam(query, 'yearofbirth', utils.getYear(data.birthDate)); 31 | } 32 | 33 | if(data.birthPlace){ 34 | query = utils.addQueryParam(query, 'keywordsplace', data.birthPlace); 35 | } 36 | 37 | query = utils.addQueryParam(query, 'yearofbirth_offset', config.birthRange); 38 | } 39 | 40 | // Death 41 | else if(config.event === 'death'){ 42 | 43 | if(data.deathDate){ 44 | query = utils.addQueryParam(query, 'yearofdeath', utils.getYear(data.deathDate)); 45 | } 46 | 47 | if(data.deathPlace){ 48 | query = utils.addQueryParam(query, 'keywordsplace', data.deathPlace); 49 | } 50 | 51 | query = utils.addQueryParam(query, 'yearofdeath_offset', config.deathRange); 52 | } 53 | 54 | // Other event 55 | else if(config.event === 'other'){ 56 | 57 | if(config.otherDate){ 58 | query = utils.addQueryParam(query, 'eventyear', utils.getYear(config.otherDate)); 59 | } 60 | 61 | if(config.otherPlace){ 62 | query = utils.addQueryParam(query, 'keywordsplace', config.otherPlace); 63 | } 64 | 65 | query = utils.addQueryParam(query, 'eventyear_offset', config.otherRange); 66 | 67 | } 68 | 69 | return baseUrl + query; 70 | 71 | }; -------------------------------------------------------------------------------- /src/sites/fold3.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'http://go.fold3.com/query.php?query='; 6 | var query = ''; 7 | 8 | if(data.givenName) { 9 | query += data.givenName; 10 | } 11 | 12 | if(data.familyName) { 13 | if(query) { 14 | query += ' '; 15 | } 16 | query += data.familyName; 17 | } 18 | 19 | // Replace spaces with + 20 | query = query.replace(/ /g, '+'); 21 | 22 | return url + query; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /src/sites/genealogieonline.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | birthRange: 5, 5 | deathRange: 5 6 | }; 7 | 8 | module.exports = function(config, data){ 9 | 10 | config = utils.defaults(config, defaultConfig); 11 | 12 | var url = 'https://www.genealogieonline.nl/en/zoeken/?publication=0'; // defaults to English version of website 13 | var query = ''; 14 | 15 | if(data.givenName) { 16 | query = utils.addQueryParam(query, 'q', data.familyName); 17 | } 18 | 19 | if(data.familyName) { 20 | query = utils.addQueryParam(query, 'vn', data.givenName); 21 | } 22 | 23 | if(data.spouseFamilyName) { 24 | query = utils.addQueryParam(query, 'pa', data.spouseFamilyName); 25 | } 26 | 27 | var place=''; 28 | if (data.birthPlace) { 29 | place=data.birthPlace; 30 | } else { 31 | if (data.deathPlace) { 32 | place=data.deathPlace; 33 | } else { 34 | if (data.marriagePlace) { 35 | place=data.marriagePlace; 36 | } 37 | } 38 | } 39 | if (place) { 40 | query = utils.addQueryParam(query, 'pn', place); 41 | } 42 | 43 | if(data.birthDate) { 44 | query = utils.addQueryParam(query, 'gv', utils.getYear(data.birthDate)*1-config.birthRange); 45 | query = utils.addQueryParam(query, 'gt', utils.getYear(data.birthDate)*1+config.birthRange); 46 | } 47 | 48 | if(data.deathDate) { 49 | query = utils.addQueryParam(query, 'ov', utils.getYear(data.deathDate)*1-config.deathRange); 50 | query = utils.addQueryParam(query, 'ot', utils.getYear(data.deathDate)*1+config.deathRange); 51 | } 52 | 53 | return url + query; 54 | 55 | }; 56 | -------------------------------------------------------------------------------- /src/sites/genealogybank.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | lifespan: 90, 5 | datePadding: 5 6 | }; 7 | 8 | module.exports = function(config, data){ 9 | 10 | config = utils.defaults(config, defaultConfig); 11 | 12 | var baseUrl = 'http://www.genealogybank.com/gbnk/?dateType=range'; 13 | var query = ''; 14 | 15 | // Name 16 | query = utils.addQueryParam(query, 'fname', data.givenName); 17 | query = utils.addQueryParam(query, 'lname', data.familyName); 18 | 19 | // 20 | // Year range 21 | // 22 | 23 | var birthYear = utils.getYearInt(data.birthDate), 24 | deathYear = utils.getYearInt(data.deathDate); 25 | 26 | // We have a birth date 27 | if(birthYear) { 28 | 29 | // We also have death date so add padding 30 | if(deathYear){ 31 | deathYear += config.datePadding; 32 | } 33 | 34 | // We have a birth date but not a death date, so add 35 | // the lifespan value to the birth year 36 | else { 37 | deathYear = birthYear + config.lifespan; 38 | } 39 | 40 | // Pad the birth year 41 | birthYear -= config.datePadding 42 | } 43 | 44 | // We have a death year but not a birth year 45 | else if(deathYear) { 46 | 47 | // Subtract lifespan value from deathYear 48 | birthYear = deathYear - config.lifespan; 49 | 50 | // Pad the death year 51 | deathYear += config.datePadding; 52 | } 53 | 54 | if(birthYear && deathYear){ 55 | query = utils.addQueryParam(query, 'rgfromDate', birthYear); 56 | query = utils.addQueryParam(query, 'rgtoDate', deathYear); 57 | } 58 | 59 | return baseUrl + query; 60 | 61 | }; 62 | -------------------------------------------------------------------------------- /src/sites/geneanet.en.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | place: 'birth' 5 | }; 6 | 7 | module.exports = function(config, data){ 8 | 9 | config = utils.defaults(config, defaultConfig); 10 | 11 | var url = 'http://en.geneanet.org/search/', 12 | query = '?periode_type=entre'; 13 | 14 | if(data.familyName){ 15 | query = utils.addQueryParam(query, 'name', data.familyName); 16 | } 17 | 18 | if(config.place === 'birth'){ 19 | if(data.birthPlace){ 20 | query = utils.addQueryParam(query, 'place', data.birthPlace); 21 | } 22 | } 23 | 24 | else if(config.place === 'death'){ 25 | if(data.deathPlace){ 26 | query = utils.addQueryParam(query, 'place', data.deathPlace); 27 | } 28 | } 29 | 30 | if(data.birthDate){ 31 | query = utils.addQueryParam(query, 'annee_debut', utils.getYear(data.birthDate)); 32 | } 33 | 34 | if(data.deathDate){ 35 | query = utils.addQueryParam(query, 'annee_fin', utils.getYear(data.deathDate)); 36 | } 37 | 38 | return url + query; 39 | 40 | }; -------------------------------------------------------------------------------- /src/sites/gengophers.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'https://www.gengophers.com/#/search?'; 6 | 7 | var params = { 8 | page: 1 9 | }; 10 | 11 | if(data.givenName) { 12 | params.given = data.givenName; 13 | } 14 | if(data.familyName) { 15 | params.surname = data.familyName 16 | } 17 | 18 | return url + utils.queryString(params);; 19 | }; -------------------------------------------------------------------------------- /src/sites/geni.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'http://www.geni.com/search?search_type=people&names='; 6 | var name = ''; 7 | 8 | if( data.givenName ) { 9 | name += data.givenName; 10 | } 11 | 12 | if( data.familyName ) { 13 | if( name ) { 14 | name += ' '; 15 | } 16 | name += data.familyName; 17 | } 18 | 19 | // Replace spaces with + 20 | name = name.replace(/ /g, '+'); 21 | 22 | return url + name; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /src/sites/google.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'https://www.google.com/search?q='; 6 | 7 | var searchWords = ['~genealogy']; 8 | if(data.givenName) { 9 | searchWords.push(data.givenName); 10 | } 11 | if(data.familyName) { 12 | searchWords.push(data.familyName); 13 | } 14 | 15 | if(data.birthPlace) { 16 | searchWords.push(data.birthPlace); 17 | } 18 | 19 | return url += encodeURIComponent(searchWords.join(' ')); 20 | }; -------------------------------------------------------------------------------- /src/sites/myheritage.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'http://www.myheritage.com/research'; 6 | var query = '?formId=master&formMode=1&action=query&catId=1'; 7 | 8 | var name = ''; 9 | if(data.givenName) { 10 | name += '+fn.' + fixSpace(data.givenName); 11 | } 12 | if(data.familyName) { 13 | name += '+ln.' + fixSpace(data.familyName); 14 | } 15 | if(name){ 16 | query += '&qname=Name' + name; 17 | } 18 | 19 | var birth = ''; 20 | if(data.birthDate){ 21 | birth += '+ey.' + utils.getYear(data.birthDate); 22 | } 23 | if(data.birthPlace){ 24 | birth += '+ep.' + fixSpace(data.birthPlace); 25 | } 26 | if(birth){ 27 | query += '&qevents-event1=Event+et.birth' + birth + '+epmo.similar'; 28 | } 29 | 30 | var death = ''; 31 | if(data.deathDate){ 32 | death += '+ey.' + utils.getYear(data.deathDate); 33 | } 34 | if(data.deathPlace){ 35 | death += '+ep.' + fixSpace(data.deathPlace); 36 | } 37 | if(death){ 38 | query += '&qevents-any%2F1event_1=Event+et.death' + death + '+epmo.similar'; 39 | } 40 | 41 | var marriage = ''; 42 | if(data.marriageDate){ 43 | marriage += '+ey.' + utils.getYear(data.marriageDate); 44 | } 45 | if(data.marriagePlace){ 46 | marriage += '+ep.' + fixSpace(data.marriagePlace); 47 | } 48 | if(marriage){ 49 | query += '&qevents-any%2F1event_2=Event+et.marriage' + marriage + '+epmo.similar'; 50 | } 51 | 52 | // Yes, this really does have to be here 53 | query += '&qevents=List'; 54 | 55 | var father = ''; 56 | if(data.fatherGivenName) { 57 | father += '+fn.' + fixSpace(data.fatherGivenName); 58 | } 59 | if(data.fatherFamilyName) { 60 | father += '+ln.' + fixSpace(data.fatherFamilyName); 61 | } 62 | if(father){ 63 | query += '&qrelative_relativeName=Name' + father + '+lnmsrs.false&qrelatives-relative=Relative+rt.father+rn.*qrelative_relativeName'; 64 | } 65 | 66 | var mother = ''; 67 | if(data.motherGivenName) { 68 | mother += '+fn.' + fixSpace(data.motherGivenName); 69 | } 70 | if(data.motherFamilyName) { 71 | mother += '+ln.' + fixSpace(data.motherFamilyName); 72 | } 73 | if(mother){ 74 | query += '&qaddRelative_1_addRelativeName=Name' + mother + '+lnmsrs.false&qrelatives-addRelative_1=Relative+rt.mother+rn.*qaddRelative_1_addRelativeName'; 75 | } 76 | 77 | var spouse = ''; 78 | if(data.spouseGivenName) { 79 | spouse += '+fn.' + fixSpace(data.spouseGivenName); 80 | } 81 | if(data.spouseFamilyName) { 82 | spouse += '+ln.' + fixSpace(data.spouseFamilyName); 83 | } 84 | if(spouse){ 85 | query += '&qaddRelative_2_addRelativeName=Name' + spouse + '+lnmsrs.false&qrelatives-addRelative_2=Relative+rt.spouse+rn.*qaddRelative_2_addRelativeName'; 86 | } 87 | 88 | query += '&qrelatives=List'; 89 | 90 | return url + query; 91 | 92 | }; 93 | 94 | // I can't believe we have to do this 95 | function fixSpace(str){ 96 | return str.replace(/ /g, '%2F3'); 97 | } 98 | -------------------------------------------------------------------------------- /src/sites/newspapers.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | lifespan: 90, 5 | datePadding: 5 6 | }; 7 | 8 | module.exports = function(config, data){ 9 | 10 | config = utils.defaults(config, defaultConfig); 11 | 12 | var baseUrl = 'http://go.newspapers.com/results.php?query='; 13 | var query = ''; 14 | 15 | // Name 16 | if(data.givenName) { 17 | query += data.givenName; 18 | } 19 | if(data.familyName) { 20 | if(query) { 21 | query += ' '; 22 | } 23 | query += data.familyName; 24 | } 25 | 26 | // 27 | // Year range 28 | // 29 | 30 | var birthYear = utils.getYearInt(data.birthDate), 31 | deathYear = utils.getYearInt(data.deathDate); 32 | 33 | // We have a birth date 34 | if(birthYear) { 35 | 36 | // We also have death date so add padding 37 | if(deathYear){ 38 | deathYear += config.datePadding; 39 | } 40 | 41 | // We have a birth date but not a death date, so add 42 | // the lifespan value to the birth year 43 | else { 44 | deathYear = birthYear + config.lifespan; 45 | } 46 | 47 | // Pad the birth year 48 | birthYear -= config.datePadding 49 | } 50 | 51 | // We have a death year but not a birth year 52 | else if(deathYear) { 53 | 54 | // Subtract lifespan value from deathYear 55 | birthYear = deathYear - config.lifespan; 56 | 57 | // Pad the death year 58 | deathYear += config.datePadding; 59 | } 60 | 61 | if(birthYear && deathYear){ 62 | query = utils.addQueryParam(query, 'year-start', birthYear); 63 | query = utils.addQueryParam(query, 'year-end', deathYear); 64 | } 65 | 66 | return baseUrl + query; 67 | 68 | }; 69 | -------------------------------------------------------------------------------- /src/sites/nlatrove.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'http://trove.nla.gov.au/newspaper/result?q='; 6 | 7 | var parts = []; 8 | if(data.givenName) { 9 | parts.push(data.givenName); 10 | } 11 | if(data.familyName) { 12 | parts.push(data.familyName) 13 | } 14 | 15 | return url + encodeURIComponent(parts.join(' ')); 16 | }; -------------------------------------------------------------------------------- /src/sites/openarchives.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'https://www.openarch.nl/search.php?lang=en&name='; // defaults to English version of website 6 | var query = ''; 7 | 8 | if(data.givenName) { 9 | query += data.givenName; 10 | } 11 | 12 | if(data.familyName) { 13 | if(query) { 14 | query += ' '; 15 | } 16 | query += data.familyName; 17 | } 18 | 19 | // Replace spaces with + 20 | query = query.replace(/ /g, '+'); 21 | 22 | return url + query; 23 | 24 | }; -------------------------------------------------------------------------------- /src/sites/usgenweb.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | // http://www.usgwarchives.net/search/search.cgi/search.htm?q=ted+yurkiewicz&cmd=Search%21&form=extended&wm=sub 6 | 7 | var url = 'http://www.usgwarchives.net/search/search.cgi/search.htm', 8 | query = '?cmd=Search%21&form=extended'; 9 | 10 | var nameParts = []; 11 | if(data.givenName) { 12 | nameParts.push(data.givenName); 13 | } 14 | if(data.familyName) { 15 | nameParts.push(data.familyName); 16 | } 17 | query = utils.addQueryParam(query, 'q', nameParts.join(' ')); 18 | 19 | return url + query; 20 | 21 | }; -------------------------------------------------------------------------------- /src/sites/werelate.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | birthRange: 2, 5 | deathRange: 2 6 | }; 7 | 8 | module.exports = function(config, data){ 9 | 10 | config = utils.defaults(config, defaultConfig); 11 | 12 | var baseUrl = 'http://www.werelate.org/wiki/Special:Search?sort=score&ns=Person&rows=20&ecp=p'; 13 | var query = ''; 14 | 15 | // Simple mappings from the person data object to params 16 | // These don't need any further processing 17 | var mappings = [ 18 | ['g', 'givenName'], 19 | ['s', 'familyName'], 20 | ['bp', 'birthPlace'], 21 | ['dp', 'deathPlace'], 22 | ['fg', 'fatherGivenName'], 23 | ['fs', 'fatherFamilyName'], 24 | ['mg', 'motherGivenName'], 25 | ['ms', 'motherFamilyName'], 26 | ['sg', 'spouseGivenName'], 27 | ['ss', 'spouseFamilyName'] 28 | ]; 29 | utils.each(mappings, function(map) { 30 | if(data[map[1]]) { 31 | query = utils.addQueryParam(query, map[0], data[map[1]]); 32 | } 33 | }); 34 | 35 | // Process dates and add the ranges 36 | if(data.birthDate) { 37 | query = utils.addQueryParam(query, 'bd', utils.getYear(data.birthDate)); 38 | query = utils.addQueryParam(query, 'br', config.birthRange); 39 | } 40 | if(data.deathDate) { 41 | query = utils.addQueryParam(query, 'dd', utils.getYear(data.deathDate)); 42 | query = utils.addQueryParam(query, 'dr', config.deathRange); 43 | } 44 | 45 | return baseUrl + query; 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /src/sites/wikitree.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | module.exports = function(config, data){ 4 | 5 | var url = 'https://www.google.com/search?q='; 6 | 7 | var searchWords = ['site:wikitree.com']; 8 | 9 | if(data.givenName) { 10 | searchWords.push(data.givenName); 11 | } 12 | if(data.familyName) { 13 | searchWords.push(data.familyName); 14 | } 15 | 16 | return url += encodeURIComponent(searchWords.join(' ')); 17 | }; -------------------------------------------------------------------------------- /src/sites/worldvitalrecords.js: -------------------------------------------------------------------------------- 1 | var utils = require('../utils.js'); 2 | 3 | var defaultConfig = { 4 | dateRange: 2 5 | }; 6 | 7 | module.exports = function(config, data){ 8 | 9 | config = utils.defaults(config, defaultConfig); 10 | 11 | var baseUrl = 'http://www.worldvitalrecords.com/GlobalSearch.aspx?qt=g'; 12 | var query = ''; 13 | 14 | // Name 15 | query = utils.addQueryParam(query, 'zfn', data.givenName); 16 | query = utils.addQueryParam(query, 'zln', data.familyName); 17 | 18 | // Place 19 | if(data.birthPlace){ 20 | query = utils.addQueryParam(query, 'zplace', data.birthPlace); 21 | } else if(data.deathPlace){ 22 | query = utils.addQueryParam(query, 'zplace', data.deathPlace); 23 | } 24 | 25 | // Date 26 | if(data.birthDate) { 27 | query = utils.addQueryParam(query, 'zdate', utils.getYear(data.birthDate)); 28 | query = utils.addQueryParam(query, 'zdater', config.dateRange); 29 | } else if(data.deathDate) { 30 | query = utils.addQueryParam(query, 'zdate', utils.getYear(data.deathDate)); 31 | query = utils.addQueryParam(query, 'zdater', config.dateRange); 32 | } 33 | 34 | // TODO record type? 35 | 36 | return baseUrl + query; 37 | 38 | }; 39 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | var utils = {}; 2 | 3 | /** 4 | * Extract the year from a date. 5 | * Capture the special case of just a year because 6 | * javascript will consider it as the first second 7 | * of that year in GMT then convert it to the current 8 | * timezone which could be the previous year. 9 | */ 10 | utils.getYear = function(date){ 11 | return /^\d{4}$/.test(date) ? date : new Date(date).getFullYear(); 12 | }; 13 | 14 | /** 15 | * Extract the year from a date and return as an integer. 16 | */ 17 | utils.getYearInt = function(date){ 18 | return parseInt(utils.getYear(date)); 19 | }; 20 | 21 | /** 22 | * Add a query param to a url 23 | */ 24 | utils.addQueryParam = function(query, name, value){ 25 | if(value){ 26 | query += '&' + name + '=' + encodeURIComponent(value); 27 | } 28 | return query; 29 | }; 30 | 31 | /** 32 | * Take in a map of param names and values 33 | * and return an encoded query string 34 | * without the leading '?' 35 | */ 36 | utils.queryString = function(params){ 37 | var parts = []; 38 | utils.each(params, function(val, key){ 39 | parts.push(key + '=' + encodeURIComponent(val)); 40 | }); 41 | return parts.join('&'); 42 | }; 43 | 44 | /** 45 | * Functions lifted from underscore.js 46 | * http://underscorejs.org/ 47 | */ 48 | 49 | utils.isObject = function(obj) { 50 | return obj === Object(obj); 51 | }; 52 | 53 | utils.isString = function(obj){ 54 | return toString.call(obj) == '[object String]'; 55 | }; 56 | 57 | utils.isUndefined = function(obj){ 58 | return obj === void 0; 59 | }; 60 | 61 | utils.each = function(obj, iterator, context) { 62 | if (obj == null) return obj; 63 | if (Array.prototype.forEach && obj.forEach === Array.prototype.forEach) { 64 | obj.forEach(iterator, context); 65 | } else if (obj.length === +obj.length) { 66 | for (var i = 0, length = obj.length; i < length; i++) { 67 | iterator.call(context, obj[i], i, obj); 68 | } 69 | } else { 70 | var keys = utils.keys(obj); 71 | for (var i = 0, length = keys.length; i < length; i++) { 72 | iterator.call(context, obj[keys[i]], keys[i], obj); 73 | } 74 | } 75 | return obj; 76 | }; 77 | 78 | utils.keys = function(obj) { 79 | if (!utils.isObject(obj)) return []; 80 | if (Object.keys) return Object.keys(obj); 81 | var keys = []; 82 | for (var key in obj) if (hasOwnProperty.call(obj, key)) keys.push(key); 83 | return keys; 84 | }; 85 | 86 | utils.defaults = function(obj) { 87 | utils.each(Array.prototype.slice.call(arguments, 1), function(source) { 88 | if (source) { 89 | for (var prop in source) { 90 | if (obj[prop] === void 0) obj[prop] = source[prop]; 91 | } 92 | } 93 | }); 94 | return obj; 95 | }; 96 | 97 | utils.extend = function(obj) { 98 | utils.each(Array.prototype.slice.call(arguments, 1), function(source) { 99 | if (source) { 100 | for (var prop in source) { 101 | obj[prop] = source[prop]; 102 | } 103 | } 104 | }); 105 | return obj; 106 | }; 107 | 108 | module.exports = utils; 109 | -------------------------------------------------------------------------------- /test/search.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | search = require(require('path').join(__dirname, '..', 'src', 'search.js')); 3 | 4 | describe('utils', function(){ 5 | 6 | it('empty config', function(){ 7 | assert.deepEqual(search.config(), {}); 8 | }); 9 | 10 | it('one site config', function(){ 11 | search.config('ancestry', {a: 'a'}); 12 | assert.deepEqual(search.config(), {ancestry: {a: 'a'}}); 13 | }); 14 | 15 | it('multi site configs', function(){ 16 | search.config({ancestry: {a: 'b'}, fold3: {a: 'a'}}); 17 | search.config({site: {c: 'c'}}); 18 | assert.deepEqual(search.config(), {ancestry: {a: 'b'}, fold3: {a: 'a'}, site: {c: 'c'}}); 19 | }); 20 | 21 | }); -------------------------------------------------------------------------------- /test/sites/americanancestors.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('americanancestors'), 2 | utils = require(require('path').join(__dirname, '..', '..', 'src', 'utils.js')); 3 | 4 | describe('americanancestors', function(){ 5 | 6 | it('1', function(){ 7 | test(test.data[0], 'http://www.americanancestors.org/search/database-search?firstname=Joe%20William&lastname=Clark'); 8 | }); 9 | 10 | it('2', function(){ 11 | test(test.data[1], 'http://www.americanancestors.org/search/database-search?firstname=Joe%20William&lastname=Clark&fromyear=1835&toyear=1889&location=Texas'); 12 | }); 13 | 14 | it('use death place when birth place is not available', function(){ 15 | var data = utils.extend({}, test.data[1]); 16 | delete data.birthPlace; 17 | test(data, 'http://www.americanancestors.org/search/database-search?firstname=Joe%20William&lastname=Clark&fromyear=1835&toyear=1889&location=Springfield%2C%20Illinois'); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /test/sites/ancestry.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('ancestry'); 2 | 3 | describe('ancestry', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://search.ancestry.com/cgi-bin/sse.dll?rank=1&gsfn=Joe%20William&gsln=Clark&gl=allgs'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://search.ancestry.com/cgi-bin/sse.dll?rank=1&gsfn=Joe%20William&gsln=Clark&msbpn__ftp=Texas&msdpn__ftp=Springfield%2C%20Illinois&msfng0=Dale&msfns0=Clark&msmng0=Susan&msmns0=Anthony&mssng0=Jennifer&mssns0=Thomas&msgpn__ftp=St%20Louis%2C%20MO&msbdy=1835&msddy=1889&msgdy=1858&gl=allgs'); 11 | }); 12 | 13 | it('db', function(){ 14 | test(test.data[0], 'http://search.ancestry.com/cgi-bin/sse.dll?rank=1&gsfn=Joe%20William&gsln=Clark&db=bivri_EnglandBirth', {db: 'bivri_EnglandBirth'}); 15 | }); 16 | 17 | }); 18 | -------------------------------------------------------------------------------- /test/sites/archives.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('archives'); 2 | 3 | describe('archives', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.archives.com/GA.aspx?_act=registerAS_org&Location=US&FirstName=Joe%20William&LastName=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://www.archives.com/GA.aspx?_act=registerAS_org&Location=US&FirstName=Joe%20William&LastName=Clark&BirthYear=1835&BirthYearSpan=2&DeathYear=1889&DeathYearSpan=2'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/sites/billiongraves.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('billiongraves'); 2 | 3 | describe('billiongraves', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://billiongraves.com/pages/search/index.php#year_range=2&lim=0&action=search&exact=false&country=0&state=0&county=0&given_names=Joe%20William&family_names=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://billiongraves.com/pages/search/index.php#year_range=2&lim=0&action=search&exact=false&country=0&state=0&county=0&given_names=Joe%20William&family_names=Clark&birth_year=1835&death_year=1889'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/sites/chroniclingamerica.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('chroniclingamerica'); 2 | 3 | describe('chroniclingamerica', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://chroniclingamerica.loc.gov/search/pages/results/?dateFilterType=yearRange&proxtext=Joe%20William%20Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://chroniclingamerica.loc.gov/search/pages/results/?dateFilterType=yearRange&proxtext=Joe%20William%20Clark&date1=1835&date2=1889'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/sites/familysearch.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('familysearch'); 2 | 3 | describe('familysearch', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'https://www.familysearch.org/search/record/results?q.givenName=Joe%20William&q.surname=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'https://www.familysearch.org/search/record/results?q.birthLikeDate.from=1833&q.birthLikeDate.to=1837&q.birthLikePlace=Texas&q.deathLikeDate.from=1887&q.deathLikeDate.to=1891&q.deathLikePlace=Springfield%2C%20Illinois&q.fatherGivenName=Dale&q.fatherSurname=Clark&q.givenName=Joe%20William&q.marriageLikeDate.from=1856&q.marriageLikeDate.to=1860&q.marriageLikePlace=St%20Louis%2C%20MO&q.motherGivenName=Susan&q.motherSurname=Anthony&q.spouseGivenName=Jennifer&q.spouseSurname=Thomas&q.surname=Clark'); 11 | }); 12 | 13 | it('config', function(){ 14 | test(test.data[1], 'https://www.familysearch.org/search/record/results?q.birthLikeDate.from=1832&q.birthLikeDate.to=1838&q.birthLikePlace=Texas&q.deathLikeDate.from=1885&q.deathLikeDate.to=1893&q.deathLikePlace=Springfield%2C%20Illinois&q.fatherGivenName=Dale&q.fatherSurname=Clark&q.givenName=Joe%20William&q.marriageLikeDate.from=1853&q.marriageLikeDate.to=1863&q.marriageLikePlace=St%20Louis%2C%20MO&q.motherGivenName=Susan&q.motherSurname=Anthony&q.spouseGivenName=Jennifer&q.spouseSurname=Thomas&q.surname=Clark', { 15 | birthRange: 3, 16 | deathRange: 4, 17 | marriageRange: 5 18 | }); 19 | }); 20 | 21 | it('collection', function(){ 22 | test(test.data[0], 'https://www.familysearch.org/search/record/results?q.givenName=Joe%20William&q.surname=Clark&f.collectionId=1473014', { 23 | collectionId: 1473014 24 | }); 25 | }); 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /test/sites/findagrave.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('findagrave'); 2 | 3 | describe('findagrave', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.findagrave.com/cgi-bin/fg.cgi?page=gsr&GScntry=0&GSst=0&GSgrid=&df=all&GSob=n&GSfn=Joe%20William&GSln=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://www.findagrave.com/cgi-bin/fg.cgi?page=gsr&GScntry=0&GSst=0&GSgrid=&df=all&GSob=n&GSfn=Joe%20William&GSln=Clark&GSbyrel=in&GSby=1835&GSdyrel=in&GSdy=1889'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/sites/findmypast.co.uk.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('findmypast.co.uk'); 2 | 3 | describe('findmypast.co.uk', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://search.findmypast.co.uk/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark'); 7 | }); 8 | 9 | it('birth', function(){ 10 | test(test.data[1], 'http://search.findmypast.co.uk/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark&yearofbirth=1835&keywordsplace=Texas&yearofbirth_offset=5', { 11 | event: 'birth', 12 | birthRange: 5 13 | }); 14 | }); 15 | 16 | it('death', function(){ 17 | test(test.data[1], 'http://search.findmypast.co.uk/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark&yearofdeath=1889&keywordsplace=Springfield%2C%20Illinois&yearofdeath_offset=10', { 18 | event: 'death', 19 | deathRange: 10 20 | }); 21 | }); 22 | 23 | it('other', function(){ 24 | test(test.data[0], 'http://search.findmypast.co.uk/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark&eventyear=1850&keywordsplace=Middlesex&eventyear_offset=1', { 25 | event: 'other', 26 | otherRange: 1, 27 | otherDate: '1850', 28 | otherPlace: 'Middlesex' 29 | }); 30 | }); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /test/sites/findmypast.com.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('findmypast.com'); 2 | 3 | describe('findmypast.com', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://search.findmypast.com/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark'); 7 | }); 8 | 9 | it('birth', function(){ 10 | test(test.data[1], 'http://search.findmypast.com/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark&yearofbirth=1835&keywordsplace=Texas&yearofbirth_offset=5', { 11 | event: 'birth', 12 | birthRange: 5 13 | }); 14 | }); 15 | 16 | it('death', function(){ 17 | test(test.data[1], 'http://search.findmypast.com/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark&yearofdeath=1889&keywordsplace=Springfield%2C%20Illinois&yearofdeath_offset=10', { 18 | event: 'death', 19 | deathRange: 10 20 | }); 21 | }); 22 | 23 | it('other', function(){ 24 | test(test.data[0], 'http://search.findmypast.com/search/world-records?firstname_variants=true&firstname=Joe%20William&lastname=Clark&eventyear=1850&keywordsplace=Middlesex&eventyear_offset=1', { 25 | event: 'other', 26 | otherRange: 1, 27 | otherDate: '1850', 28 | otherPlace: 'Middlesex' 29 | }); 30 | }); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /test/sites/fold3.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('fold3'); 2 | 3 | describe('fold3', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://go.fold3.com/query.php?query=Joe+William+Clark'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /test/sites/genealogieonline.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('genealogieonline'); 2 | 3 | describe('genealogieonline', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'https://www.genealogieonline.nl/en/zoeken/?publication=0&q=Clark&vn=Joe%20William'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'https://www.genealogieonline.nl/en/zoeken/?publication=0&q=Clark&vn=Joe%20William&pa=Thomas&pn=Texas&gv=1830>=1840&ov=1884&ot=1894'); 11 | }); 12 | 13 | }); -------------------------------------------------------------------------------- /test/sites/genealogybank.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('genealogybank'); 2 | 3 | describe('genealogybank', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.genealogybank.com/gbnk/?dateType=range&fname=Joe%20William&lname=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://www.genealogybank.com/gbnk/?dateType=range&fname=Joe%20William&lname=Clark&rgfromDate=1830&rgtoDate=1894'); 11 | }); 12 | 13 | // TODO Test combinations of birth, death dates 14 | // TODO Test config 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /test/sites/geneanet.en.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('geneanet.en'); 2 | 3 | describe('en.geneanet', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://en.geneanet.org/search/?periode_type=entre&name=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://en.geneanet.org/search/?periode_type=entre&name=Clark&place=Texas&annee_debut=1835&annee_fin=1889'); 11 | }); 12 | 13 | it('death place', function(){ 14 | test(test.data[1], 'http://en.geneanet.org/search/?periode_type=entre&name=Clark&place=Springfield%2C%20Illinois&annee_debut=1835&annee_fin=1889', { 15 | place: 'death' 16 | }); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /test/sites/gengophers.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('gengophers'); 2 | 3 | describe('gengophers', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'https://www.gengophers.com/#/search?page=1&given=Joe%20William&surname=Clark'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /test/sites/geni.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('geni'); 2 | 3 | describe('geni', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.geni.com/search?search_type=people&names=Joe+William+Clark'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /test/sites/google.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('google'); 2 | 3 | describe('google', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'https://www.google.com/search?q=~genealogy%20Joe%20William%20Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'https://www.google.com/search?q=~genealogy%20Joe%20William%20Clark%20Texas'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/sites/myheritage.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('myheritage'); 2 | 3 | describe('myheritage', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.myheritage.com/research?formId=master&formMode=1&action=query&catId=1&qname=Name+fn.Joe%2F3William+ln.Clark&qevents=List&qrelatives=List'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://www.myheritage.com/research?formId=master&formMode=1&action=query&catId=1&qname=Name+fn.Joe%2F3William+ln.Clark&qevents-event1=Event+et.birth+ey.1835+ep.Texas+epmo.similar&qevents-any%2F1event_1=Event+et.death+ey.1889+ep.Springfield,%2F3Illinois+epmo.similar&qevents-any%2F1event_2=Event+et.marriage+ey.1858+ep.St%2F3Louis,%2F3MO+epmo.similar&qevents=List&qrelative_relativeName=Name+fn.Dale+ln.Clark+lnmsrs.false&qrelatives-relative=Relative+rt.father+rn.*qrelative_relativeName&qaddRelative_1_addRelativeName=Name+fn.Susan+ln.Anthony+lnmsrs.false&qrelatives-addRelative_1=Relative+rt.mother+rn.*qaddRelative_1_addRelativeName&qaddRelative_2_addRelativeName=Name+fn.Jennifer+ln.Thomas+lnmsrs.false&qrelatives-addRelative_2=Relative+rt.spouse+rn.*qaddRelative_2_addRelativeName&qrelatives=List'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/sites/newspapers.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('newspapers'); 2 | 3 | describe('newspapers', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://go.newspapers.com/results.php?query=Joe William Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://go.newspapers.com/results.php?query=Joe William Clark&year-start=1830&year-end=1894'); 11 | }); 12 | 13 | // TODO Test combinations of birth, death dates 14 | // TODO Test config 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /test/sites/nlatrove.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('nlatrove'); 2 | 3 | describe('nlatrove', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://trove.nla.gov.au/newspaper/result?q=Joe%20William%20Clark'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /test/sites/openarchives.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('openarchives'); 2 | 3 | describe('openarchives', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'https://www.openarch.nl/search.php?lang=en&name=Joe+William+Clark'); 7 | }); 8 | 9 | }); -------------------------------------------------------------------------------- /test/sites/usgenweb.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('usgenweb'); 2 | 3 | describe('usgenweb', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.usgwarchives.net/search/search.cgi/search.htm?cmd=Search%21&form=extended&q=Joe%20William%20Clark'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /test/sites/werelate.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('werelate'); 2 | 3 | describe('werelate', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.werelate.org/wiki/Special:Search?sort=score&ns=Person&rows=20&ecp=p&g=Joe%20William&s=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://www.werelate.org/wiki/Special:Search?sort=score&ns=Person&rows=20&ecp=p&g=Joe%20William&s=Clark&bp=Texas&dp=Springfield%2C%20Illinois&fg=Dale&fs=Clark&mg=Susan&ms=Anthony&sg=Jennifer&ss=Thomas&bd=1835&br=2&dd=1889&dr=2'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/sites/wikitree.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('wikitree'); 2 | 3 | describe('wikitree', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'https://www.google.com/search?q=site%3Awikitree.com%20Joe%20William%20Clark'); 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /test/sites/worldvitalrecords.js: -------------------------------------------------------------------------------- 1 | var test = require('../tester.js')('worldvitalrecords'); 2 | 3 | describe('worldvitalrecords', function(){ 4 | 5 | it('1', function(){ 6 | test(test.data[0], 'http://www.worldvitalrecords.com/GlobalSearch.aspx?qt=g&zfn=Joe%20William&zln=Clark'); 7 | }); 8 | 9 | it('2', function(){ 10 | test(test.data[1], 'http://www.worldvitalrecords.com/GlobalSearch.aspx?qt=g&zfn=Joe%20William&zln=Clark&zplace=Texas&zdate=1835&zdater=2'); 11 | }); 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /test/test-data.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | givenName: 'Joe William', 4 | familyName: 'Clark' 5 | }, 6 | { 7 | givenName: 'Joe William', 8 | familyName: 'Clark', 9 | birthPlace: 'Texas', 10 | birthDate: '4 February 1835', 11 | deathPlace: 'Springfield, Illinois', 12 | deathDate: '1889', 13 | marriagePlace: 'St Louis, MO', 14 | marriageDate: '5 June 1858', 15 | fatherGivenName: 'Dale', 16 | fatherFamilyName: 'Clark', 17 | motherGivenName: 'Susan', 18 | motherFamilyName: 'Anthony', 19 | spouseGivenName: 'Jennifer', 20 | spouseFamilyName: 'Thomas' 21 | } 22 | ]; -------------------------------------------------------------------------------- /test/tester.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | search = require(require('path').join(__dirname, '..', 'src', 'search')), 3 | data = require('./test-data.js'); 4 | 5 | module.exports = function(site){ 6 | var tester = function(data, url, opts){ 7 | // Parse URLs so that we can compare query params without requiring them to be in the same order 8 | const searchUrl = new URL(search(site, data, opts)); 9 | const expectedUrl = new URL(url); 10 | // Compare origin and path 11 | assert.equal(`${searchUrl.origin}${searchUrl.pathname}`, `${expectedUrl.origin}${expectedUrl.pathname}`); 12 | // Compare query params 13 | searchUrl.searchParams.sort(); 14 | expectedUrl.searchParams.sort() 15 | assert.equal(searchUrl.searchParams.toString(), expectedUrl.searchParams.toString()); 16 | }; 17 | tester.data = data; 18 | return tester; 19 | }; 20 | -------------------------------------------------------------------------------- /test/utils.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | utils = require(require('path').join(__dirname, '..', 'src', 'utils.js')); 3 | 4 | describe('utils', function(){ 5 | 6 | it('getYear', function(){ 7 | assert.equal(utils.getYear('2 February 1835'), '1835'); 8 | }); 9 | 10 | it('getYearInt', function(){ 11 | assert.equal(utils.getYearInt('2 February 1835'), 1835); 12 | }); 13 | 14 | it('extend', function(){ 15 | assert.deepEqual(utils.extend({}, {one:1},{two:2},{one:3}), {one:3,two:2}); 16 | }); 17 | 18 | it('queryString', function(){ 19 | assert.equal(utils.queryString({ 20 | 'some': 'vals,', 21 | 'more': 'we-rd' 22 | }), 'some=vals%2C&more=we-rd'); 23 | }); 24 | 25 | }); -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var bannerjs = require('bannerjs'), 2 | webpack = require('webpack'); 3 | 4 | module.exports = function(env) { 5 | 6 | var config = { 7 | context: __dirname, 8 | entry: './src/search.js', 9 | output: { 10 | filename: 'gensearch.js', 11 | path: __dirname + '/dist', 12 | library: 'gensearch', 13 | libraryTarget: 'umd' 14 | }, 15 | plugins: [ 16 | new webpack.BannerPlugin({ 17 | banner: bannerjs.onebanner(), 18 | raw: true 19 | }) 20 | ] 21 | }; 22 | 23 | // Minify for production build 24 | if(env && env.production){ 25 | config.plugins.push(new webpack.optimize.UglifyJsPlugin()); 26 | config.output.filename = 'gensearch.min.js'; 27 | } 28 | 29 | return config; 30 | }; --------------------------------------------------------------------------------