Skip to content

Commit

Permalink
Merge pull request #372 from freelawproject/feat-adds-logic-to-upload…
Browse files Browse the repository at this point in the history
…-acms-docket-report

feat(appellate): Adds logic to upload the Docket report from ACMS
  • Loading branch information
mlissner committed Apr 24, 2024
2 parents 84c232c + 5618a23 commit 3a2a781
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The following changes are not yet released, but are code complete:

Features:
- Introduces a new upload type for Dockets from ACMS and enhances code maintainability by refactoring common upload logic into reusable functions.([#368](https://github.com/freelawproject/recap-chrome/pull/371))
- Docket reports from ACMS are now uploaded to CourtListener.([#372](https://github.com/freelawproject/recap-chrome/pull/372))

Changes:
- None yet
Expand Down
92 changes: 86 additions & 6 deletions src/appellate/appellate.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Abstraction of scripts related to Appellate PACER to make them modular and testable.
let AppellateDelegate = function (tabId, court, url, links) {
let AppellateDelegate = function (tabId, court, url, path, links) {
this.tabId = tabId;
this.court = court;
this.url = url;
this.path = path;
this.links = links || [];
this.recap = importInstance(Recap);
this.notifier = importInstance(Notifier);
Expand All @@ -11,10 +12,10 @@ let AppellateDelegate = function (tabId, court, url, links) {
this.docketNumber = APPELLATE.getDocketNumber(this.queryParameters);
};

// Identify the current page using the URL and the query string,
// then dispatch the associated handler
AppellateDelegate.prototype.dispatchPageHandler = function () {
let targetPage = this.queryParameters.get('servlet') || APPELLATE.getServletFromInputs();
// Identify regular Appellate pages using the URL and the query string,
AppellateDelegate.prototype.regularAppellatePageHandler = function () {
let targetPage =
this.queryParameters.get('servlet') || APPELLATE.getServletFromInputs();
switch (targetPage) {
case 'CaseSummary.jsp':
this.handleDocketDisplayPage();
Expand All @@ -34,7 +35,7 @@ AppellateDelegate.prototype.dispatchPageHandler = function () {
break;
case 'ShowDocMulti':
this.handleCombinedPdfPageView();
break
break;
default:
if (APPELLATE.isAttachmentPage()) {
this.handleAttachmentPage();
Expand All @@ -48,6 +49,85 @@ AppellateDelegate.prototype.dispatchPageHandler = function () {
}
};

AppellateDelegate.prototype.ACMSPageHandler = function () {
if (this.path.match(/^\/[0-9\-]+$/)) {
this.handleAcmsDocket();
}
};

// Identify and handle pages from Appellate courts.
AppellateDelegate.prototype.dispatchPageHandler = function () {
if (PACER.isACMSWebsite(this.url)) {
this.ACMSPageHandler();
} else {
this.regularAppellatePageHandler();
}
};

AppellateDelegate.prototype.handleAcmsDocket = async function () {
const processDocket = async () => {
const caseSummary = JSON.parse(sessionStorage.caseSummary);
const caseId = caseSummary.caseDetails.caseId;
this.pacer_case_id = caseId;

if (history.state && history.state.uploaded) {
return;
}

const options = await getItemsFromStorage('options');
if (!options['recap_enabled']) {
console.info('RECAP: Not uploading docket json. RECAP is disabled.');
return;
}

this.recap.uploadDocket(
this.court,
this.pacer_case_id,
sessionStorage.caseSummary,
'ACMS_DOCKET_JSON',
(ok) => {
if (ok) {
history.replaceState({ uploaded: true }, '');
this.notifier.showUpload(
'Docket uploaded to the public RECAP Archive.',
() => {}
);
} else {
console.log('cb fail');
}
}
);
};

// Since this page uses Vue.js for dynamic data rendering and shows a loader
// during API requests, an observer is necessary to monitor DOM changes and
// update the component accordingly.
const footerObserver = async (mutationList, observer) => {
for (const r of mutationList) {
// We could restrict this to div#box, but that feels overspecific
for (const a of r.addedNodes) {
// We use the the footer element as an indicator that the entire page
// has finished loading.
if (a.localName === 'footer') {
if ('caseSummary' in sessionStorage) {
processDocket();
observer.disconnect();
} else {
console.log(
'We observed a <footer> being added, but no ' +
'sessionStorage.caseSummary; this is unexpected.'
);
}
}
}
}
};

const body = document.querySelector('body');
const observer = new MutationObserver(footerObserver);
observer.observe(body, { subtree: true, childList: true });
};

AppellateDelegate.prototype.handleCaseSearchPage = () => {
if (!PACER.hasFilingCookie(document.cookie)) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ async function addRecapInformation(msg) {
}

if (PACER.isAppellateCourt(court)) {
let AppDelegate = new AppellateDelegate(tabId, court, url, links);
let AppDelegate = new AppellateDelegate(tabId, court, url, path, links);

AppDelegate.dispatchPageHandler();
} else {
Expand Down

0 comments on commit 3a2a781

Please sign in to comment.