/loadDockets.js (d5aebf741e6d5fe88f99b0f99831eb5e24c38a86) (5757 bytes) (mode 100644) (type blob)

/*
  This file is part of datajams-evictions.

  datajams-evictions is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  datajams-evictions is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with datajams-evictions.  If not, see <https://www.gnu.org/licenses/>.

  Copyright 2020 Luigi Bai
*/
const DAO = require("./lib/sqlDAO");
const Court = require("./lib/Court.class");
const OI = require("./lib/OdysseyInfo.class");

let today = new Date();
let future = (new Date(today.valueOf()));
future.setDate(today.getDate() + 6);

// Emit the CSV headers; we get a line for each case, below:
console.log(
    '"Case Number",',
    '"Precinct",',
    '"Place",',
    '"Date",',
    '"Time",',
    '"DateTime",',
    '"Claim",',
    '"Plaintiff",',
    '"Defendant 1",',
    '"Defendant 2",',
    '"Defendant 3",',
    '"Case URL",',
    '"Docket URL"'
);

let opts = require("./creds")["SQLITE3"];

opts.connectCallback = (database) => {
    let casePromises = [];
    let oiPromises = [];
    // Prep the databse to update each case as we get its updated info:
    let pDao = new DAO.PartyCtlr(database);
    pDao.stmts.update = pDao.prepare(
	database,
	"UPDATE party SET party_address = $pa WHERE casenumber = $cnum AND party_role = $pr AND party_name = $pn"
    );
    pDao.ignoreInsertErrors = true;

    let cDao = new DAO.CaseCtlr(database);
    cDao.stmts.update = cDao.prepare(
	database,
	"UPDATE cases SET odyssey_ID = $oid WHERE casenumber = $cnum"
    );	    

    // Loop over all 8 precincts, two places per precinct:
    for (let pct = 1; pct <= 8; pct ++) {
	for (let plc = 1; plc <= 2; plc ++) {
	    // param is pct * 10 + plc:
	    let court = new Court({
		precinct: pct,
		place: plc
	    });

	    casePromises.push(court.getDockets({
		startDate: today,
		endDate: future,
		docketType: "Eviction Docket",
		caseCallback: (caseObj) => {
		    // First, store the case into the database:
		    caseObj.storeSQL(database);

		    if (!caseObj.caseNumber) {
			console.error("Can't find casenumber to load OI on case", caseObj);
		    } else {
			// Does it already have an OdysseyID?
			database.get(
			    "SELECT * FROM cases WHERE casenumber = $cn AND odyssey_ID IS NULL",
			    { $cn: caseObj.caseNumber },
			    (err, row) => {
				if (err) {
				    console.error("Error finding OI for case", caseObj, err);
				} else if (row) {
				    // Then, try to load the OI:
				    oiPromises.push(
					new OI(row.casenumber)
					    .findCasePromise()
					    .then(oi => {
						// Store the OdysseyID into Cases
						cDao.update({
						    $cnum: oi.caseNumber,
						    $oid: oi.caseID
						});
						// Store the party addresses
						oi.parties.forEach(party => {
						    if (party.address) {
							// If this has been a bulk extract,
							// probably should insert first, given
							// the bulk extracts only have 2 parties
							// per case.
							pDao.insert({
							    $addr: party.address.join(" "),
							    $cnum: oi.caseNumber,
							    $role: party.role,
							    $name: party.name
							});
							pDao.update({
							    $pa: party.address.join(" "),
							    $cnum: oi.caseNumber,
							    $pr: party.role,
							    $pn: party.name
							});
						    }
						});
						return {
						    msg: "OI stored",
						    case: row.casenumber
						};
					    })
					    .catch(err => {
						return {
						    msg: "Error retrieving OI",
						    case: row.casenumber,
						    err: err
						};
					    })			
				    );		    
				}
			    }
			);
		    }


		    // These functions allow the "pivot" below on each case:
		    let plaintiffs = caseObj.parties.filter((party) => {
			return ("Plaintiff" === party.role);
		    });
		    let defendants = caseObj.parties.filter((party) => {
			return ("Defendant" === party.role);
		    });

		    // See the CSV header above? Emit each case to that format:
		    console.log(
			caseObj.caseNumber + ",",
			caseObj.docket.court.precinct + ",",
			caseObj.docket.court.place + ",",
			caseObj.docket.date + ",",
			caseObj.docket.time + ",",
			'"' +
			    caseObj.docket.date.substr(6)+"-"+
			    caseObj.docket.date.substr(0, 2)+"-"+
			    caseObj.docket.date.substr(3, 2)+" "+
			    caseObj.docket.time
			    + '",',
			'"' + caseObj.claimAmount + '",',
			(plaintiffs.length > 0) ? '"' + plaintiffs[0].name + '",' : '"",',
			(defendants.length > 0) ? '"' + defendants[0].name + '",' : '"",',
			(defendants.length > 1) ? '"' + defendants[1].name + '",' : '"",',
			(defendants.length > 2) ? '"' + defendants[2].name + '",' : '"",',
			'"' + caseObj.URL + '",',
			'"' + caseObj.docket.URL.href +'"'
		    );
		}
	    }));
	}
    }

    // Wait for all the dockets to load, then emit their info:
    Promise.all(casePromises)
	.then(val => {
	    console.error("Finished loading all dockets from all courts.");
	    // Wait for the OIs to finish:
	    Promise.all(oiPromises)
		.then(val => { console.error("Finished loading OIs."); })
		.catch(err => { console.error("Error loading OIs", err); })
		.finally(() => {
		    (require("./lib/httpOptions").getGlobalAgent().destroy());
		    pDao.finalize();
		    cDao.finalize();
		    DAO.disconnect(database);
		});
	    ;
	})
	.catch(err => { console.error("Error loading dockets", err); })
    ;
};

DAO.connect(opts);


Mode Type Size Ref File
100644 blob 31 ce60eb947708d4530bee8739c111f9c0ab750eaa .gitignore
100644 blob 33877 e37e32e4e836c2394b62c0a848c2094f687eb530 LICENSE
100644 blob 1171 354a297411cdddbe0355507766510a182aba0874 Promise.shim.js
100644 blob 1710 7dcf242a339081ab4c71cde50af7195a3eb26843 README.md
100644 blob 364 c97984072c2cd4c8daa74c3e6ff6eb0434dc5d72 creds.example.js
100644 blob 1410 bc1777db47110f7e7bfdfee7895204fbfa0f68ba extractFile.js
100644 blob 2009 530f6b3bddfca745b628f7a4a226796d17a18605 extractMonth.js
040000 tree - f58128e0057868d554a3e2eab7c2344bb117af0b lib
100644 blob 5757 d5aebf741e6d5fe88f99b0f99831eb5e24c38a86 loadDockets.js
100644 blob 49735 4e6be3f3100b172d1571d6ddf21eeabe70876b5c package-lock.json
100644 blob 626 129b1f2d2524cefe2b3ab9aa4eacae3ad9748089 package.json
100644 blob 4159 888ba8ce11fdf4d3e1d197ef755e74ee1e7af1d9 schema.mssql.sql
100644 blob 3696 062c3cb093340952c06b7fcd84dd52422bb21714 schema.sqlite3.sql
100644 blob 2349 334eca19c709741ee6a386fe4c9527c3ac1b0b4d searchNames.js
100755 blob 162 7c25a482064c9580388f09c4d91683f3858ff7ca sqdump
100644 blob 1762 b50d6a4a406e9e3c54fbbdc8c1038c4da4bc14cd updateAddress.js
100644 blob 3915 77c7694889dcc3c422bff5c1ebc15ccd0c366e4c updateDates.ms.sql
100644 blob 3663 af9d94ba2bf7fbaf736c02e433b89248f3fbad13 updateDates.sqlite.sql
100644 blob 1741 142275091c4c26bd8b9fedb51788e84047beaa57 updateEvents.js
100644 blob 1744 173e2db9359912e78ff22c440443d6b11637bf9f updateStatus.js
100644 blob 6799 dba4385e740197b0fe1e19c89a39052ab799bdb0 xferData.js
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/datajams-lbai/datajams-evictions

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/datajams-lbai/datajams-evictions

Clone this repository using git:
git clone git://git.rocketgit.com/user/datajams-lbai/datajams-evictions

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main