Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(appellate): Adds logic to upload the Docket report from ACMS #372

Merged
merged 5 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading