Skip to content

Commit

Permalink
Merge pull request #13 from jat255/fix_ontrac
Browse files Browse the repository at this point in the history
Fix Ontrac tracker and update package structure
  • Loading branch information
jat255 authored May 21, 2023
2 parents b473526 + ae432bf commit 619f739
Show file tree
Hide file tree
Showing 31 changed files with 339 additions and 351 deletions.
2 changes: 0 additions & 2 deletions .dockerignore

This file was deleted.

6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ MONGO_PASSWORD={PASSWORD HERE}
MONGO_PORT=27017
MONGO_DB=packages

TZ='America/Denver'
TZ='America/Denver'

# change the following when using the debug-xxx-parser or debug-xxx-tracker
# scripts from package.json
TEST_TRACKING_NUMBER=XYZ123ABC789
27 changes: 27 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"name": "Debug Fedex Tracker",
"request": "launch",
Expand Down Expand Up @@ -108,5 +109,31 @@
],
"type": "node"
},
{
"name": "Debug OnTrac Tracker",
"request": "launch",
"runtimeArgs": [
"run-script",
"debug-ontrac-tracker"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
{
"name": "Debug OnTrac Parser",
"request": "launch",
"runtimeArgs": [
"run-script",
"debug-ontrac-parser"
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
]
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![animated demo of the client application](img/demo.gif)
![animated demo of the client application](_img/demo.gif)
<p align="center"><em>PackageMate: Self-hosted package tracking!</em></p>

This is a simple app using MongoDB, Express.js, React, and Node to allow a user
Expand Down Expand Up @@ -118,7 +118,7 @@ $ docker volume rm packagemate_dbdata
When you visit the app for the first time, there will be no packages in the system, so
the display will be empty:

![](img/new_install.png)
![](_img/new_install.png)

To add a package to the tracker, select the
correct carrier from the dropdown, paste the
Expand All @@ -137,7 +137,7 @@ and OnTrac, currently) will be significantly
slower than the direct API methods, unfortunately.
Be patient, and they should finish updating.

![app with some packages loaded in](img/active_packages.png)
![app with some packages loaded in](_img/active_packages.png)

To update all packages at once, click the blue
button above the table. The button will show
Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
7 changes: 7 additions & 0 deletions api_server/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.gitignore
.env
node_modules/**/*
node_modules/*
node_modules
client/**/*
client
31 changes: 17 additions & 14 deletions 3rd-party/parsers.js → api_server/3rd-party/parsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -466,25 +466,28 @@ const fedExParser = (response) => {

const onTracParser = (response) => {
var tc = require("timezonecomplete");

let res = response[0];
// response format:
// [
// 09/08/20, # date
// 05:03PM, # time
// Delivered # status
// BOULDER, CO # location
// 11/11/21 By End of Day # expected
// ]
const res = response[0];
let [city, state] = res[3].split(', ');
// {
// expected_date: '05/23/23',
// event_summary: 'Package en route.',
// event_detail: 'The package arrived at an originating OnTrac location and is on its way to your local OnTrac facility for final delivery.',
// event_location: 'PHOENIX, AZ',
// event_date: '05/20/23 at 6:55 PM'
// }
let [city, state] = res.event_location.split(', ');
city = city.charAt(0).toUpperCase() + city.slice(1).toLowerCase();
console.debug(`city, state: ${city}, ${state}`);
let [event_date, event_time] = res.event_date.split(' at ');
let dateTime = new tc.DateTime(
`${res[0]} - ${res[1]}`,
"MM/dd/yy - hh:mmaa"
`${event_date} - ${event_time}`,
"MM/dd/yy - hh:mm aa"
)

let stat = `${city}, ${state} (${dateTime.format("yyyy-MM-dd hh:mm a")}) - ${res[2]}`;
// let stat = `${city}, ${state} (${dateTime.format("yyyy-MM-dd hh:mm a")}) - ${res[2]}
let stat = `${city}, ${state} (${dateTime.format("yyyy-MM-dd hh:mm a")}) - ${res.event_summary}
${res.event_detail}
Expected: ${res.expected_date}`;
console.debug(`stat: ${stat}`)
// Expected: ${res[res.length - 1]}`;
return stat;
}
Expand Down
65 changes: 39 additions & 26 deletions 3rd-party/trackers.js → api_server/3rd-party/trackers.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const fedExTracker = (trackingNumber) => {
}

const onTracTracker = (trackingNumber) => {
const url = `https://www.ontrac.com/trackingresults.asp?tracking_number=${trackingNumber}`;
const url = `https://www.ontrac.com/tracking/?number=${trackingNumber}`;

// async function to scrape status from ontrac website (since API is
// unavailable...)
Expand All @@ -99,33 +99,46 @@ const onTracTracker = (trackingNumber) => {
const page = await browser.newPage();
await page.goto(url);

// Click on "See Details link"
const DETAILS_SELECTOR = 'div.trackNumber a';
await page.waitForSelector(DETAILS_SELECTOR)
const results = await page.$(DETAILS_SELECTOR);
results.click();

// Get most recent event
const EVENT_SELECTOR = '//tbody[@id="OnTracEvents"]/tr'
await page.waitForSelector(EVENT_SELECTOR)
const results2 = await page.$(EVENT_SELECTOR);
const text = await results2.evaluate(element => element.innerText);
let res = text.split(/[\n\t]+/)
res = res.slice(0, res.length - 1)

// get expected delivery date (if present)
// const EXP_DELIVERY_SELECTOR = '#trackOverview > div > ul > li.trackDestination > ul > li:nth-child(2) > ul > li'
// await page.waitForSelector(EXP_DELIVERY_SELECTOR)
// results = await page.$(EXP_DELIVERY_SELECTOR);
// text = await results.evaluate(element => element.innerText);
// if (text) {
// res.push(text);
// }

console.log(`Ontrac tracker res: ${res}`);
// Get expected delivery date
const EXP_DELIVERY_SELECTOR = 'p[name="ExpectedDeliveryDateFormatted"]';
await page.waitForSelector(EXP_DELIVERY_SELECTOR);
const exp_delivery_res = await page.$(EXP_DELIVERY_SELECTOR);
let exp_delivery_date = await exp_delivery_res.evaluate(element => element.innerText);

const LATEST_EVENT_SELECTOR = 'p[name="EventShortDescriptionFormatted"]';
await page.waitForSelector(LATEST_EVENT_SELECTOR);
const latest_event_res = await page.$(LATEST_EVENT_SELECTOR);
let latest_event_text = await latest_event_res.evaluate(el => el.innerText);

const LATEST_EVENT_DETAIL_SELECTOR = 'p[name="EventLongDescriptionFormatted"]';
await page.waitForSelector(LATEST_EVENT_DETAIL_SELECTOR);
const latest_event_detail_res = await page.$(LATEST_EVENT_DETAIL_SELECTOR);
let latest_event_detail_text = await latest_event_detail_res.evaluate(el => el.innerText);

const LOCATION_SELECTOR = 'p[name="EventCityFormatted"]';
await page.waitForSelector(LOCATION_SELECTOR);
const location_res = await page.$(LOCATION_SELECTOR);
let location_text = await location_res.evaluate(el => el.innerText);

const EVENT_DATE_SELECTOR = 'p[name="EventLastDateFormatted"]';
await page.waitForSelector(EVENT_DATE_SELECTOR);
const event_date_res = await page.$(EVENT_DATE_SELECTOR);
let event_date_text = await event_date_res.evaluate(el => el.innerText);

let res = {
expected_date: exp_delivery_date,
event_summary: latest_event_text,
event_detail: latest_event_detail_text,
event_location: location_text,
event_date: event_date_text
}

// console.log(`Ontrac tracker res: ${res}`);
console.debug(`Ontrac tracker res: ${util.inspect(res, depth = null)}`);

// Returns object with keys of
// ["expected_date", "event_summary", "event_detail", "event_location", "event_date"]
return res;
// Returns array of ["date", "time", "status", "location", "expected"]
})();
}

Expand Down
6 changes: 3 additions & 3 deletions Dockerfile → api_server/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
FROM node:14.10.1-stretch
FROM node:20-bullseye-slim
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app

RUN apt update
RUN apt-get update
RUN apt-get install -y netcat ffmpeg libnss3 libnspr4 libatk-bridge2.0-0 libx11-xcb1 libxcb-dri3-0 libdrm2 libgbm1 libasound2 libatspi2.0-0 libgtk-3-0

WORKDIR /home/node/app
COPY package*.json ./
COPY --chown=node:node package*.json ./
USER node
RUN npm install
COPY --chown=node:node . .
Expand Down
2 changes: 0 additions & 2 deletions index.js → api_server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ const {

const options = {
useNewUrlParser: true,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 500,
connectTimeoutMS: 10000,
};

Expand Down
File renamed without changes.
File renamed without changes.
40 changes: 40 additions & 0 deletions api_server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "packagemate-server",
"version": "1.2.2",
"description": "A self-hosted package tracking app",
"main": "index.js",
"scripts": {
"start": "node index.js",
"start-watch": "nodemon index.js",
"dev": "concurrently \"yarn run start-watch\" \"cd client && yarn start\"",
"debug-usps-tracker": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").usps(process.env.TEST_TRACKING_NUMBER).then(res => console.log(res))'",
"debug-usps-parser": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").usps(process.env.TEST_TRACKING_NUMBER).then(res => console.log(require(\"./3rd-party/parsers\").usps([res])))'",
"debug-fedex-tracker": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").fedex(process.env.TEST_TRACKING_NUMBER).then(res => console.log(res))'",
"debug-fedex-parser": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").fedex(process.env.TEST_TRACKING_NUMBER).then(res => console.log(require(\"./3rd-party/parsers\").fedex([res])))'",
"debug-amazon-tracker": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").amazon(process.env.TEST_TRACKING_NUMBER).then(res => console.log(res))'",
"debug-amazon-parser": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").amazon(process.env.TEST_TRACKING_NUMBER).then(res => console.log(require(\"./3rd-party/parsers\").amazon([res])))'",
"debug-ups-tracker": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").ups(process.env.TEST_TRACKING_NUMBER).then(res => console.log(res))'",
"debug-ups-parser": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").ups(process.env.TEST_TRACKING_NUMBER).then(res => console.log(require(\"./3rd-party/parsers\").ups([res])))'",
"debug-ontrac-tracker": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").ontrac(process.env.TEST_TRACKING_NUMBER).then(res => console.log(res))'",
"debug-ontrac-parser": "node -e 'require(\"dotenv\").config(); require(\"./3rd-party/trackers\").ontrac(process.env.TEST_TRACKING_NUMBER).then(res => console.log(require(\"./3rd-party/parsers\").ontrac([res])))'"
},
"author": "Joshua Taillon",
"license": "MIT",
"dependencies": {
"axios": ">=0.21.1",
"body-parser": "^1.18.3",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"ini": ">=1.3.6",
"jsdom": "^16.4.0",
"mongoose": "^6.5.2",
"mquery": ">=3.2.3",
"playwright": "^1.8.0",
"timezonecomplete": "^5.11.2",
"yarn": "^1.22.5"
},
"devDependencies": {
"concurrently": "^5.3.0",
"nodemon": "^2.0.4"
}
}
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions client/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.gitignore
.env
node_modules/**/*
node_modules
4 changes: 2 additions & 2 deletions client/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM node:10-alpine
FROM node:20-alpine
RUN mkdir -p /home/node/app/client/node_modules && chown -R node:node /home/node/app

WORKDIR /home/node/app/client
COPY package*.json ./
COPY --chown=node:node package*.json ./
USER node
RUN npm install
COPY --chown=node:node . .
Expand Down
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "packagemate-client",
"version": "1.2.1",
"version": "1.2.2",
"private": true,
"proxy": "http://packagemate-server:5000",
"dependencies": {
Expand Down
16 changes: 16 additions & 0 deletions client/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,20 @@ a#package-tabs-tab-archived.active {
.update-one-btn, .archive-btn {
width: 50%;
}
}

.footer {
border-top: 1px solid #eee;
position: fixed;
width: 100%;
bottom: 0;
left: 0;
color: #999;
margin-left: auto;
margin-right: auto;
font-size: small;
}
.footer > p {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
2 changes: 2 additions & 0 deletions client/src/App.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from 'react';

import Package from './components/Package';
import Footer from "./components/Footer";
import './App.css';

const App = () => {
return (
<div className="App">
<Package />
<Footer />
</div>
);
}
Expand Down
10 changes: 10 additions & 0 deletions client/src/components/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import packageJson from '../../package.json';

const Footer = () => (
<footer className="footer">
<p>PackageMate v{packageJson.version}</p>
</footer>
);

export default Footer;
3 changes: 2 additions & 1 deletion client/src/components/Package.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class Package extends Component {
href='https://github.com/jat255/PackageMate'
size='sm'
target='_blank'
rel='noreferrer'
>
<FontAwesomeIcon icon={faGithub} /> View project on GitHub
</Button>
Expand All @@ -138,7 +139,7 @@ class Package extends Component {
so any packages added for Amazon will return
"Invalid Tracking_id". See <a
href="https://github.com/jat255/PackageMate/issues/11"
target="_blank">this issue</a> for details/updates.
target="_blank" rel="noreferrer">this issue</a> for details/updates.
</Alert>
</Col>
</Row>
Expand Down
Loading

0 comments on commit 619f739

Please sign in to comment.