Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2af2b28d84 | |||
| 76c6eefb36 | |||
| 2b355bf057 | |||
| 6759916323 | |||
| 6124a6d582 | |||
| 1d50da987f |
+17
-22
@@ -1,32 +1,25 @@
|
|||||||
# Use an official Node.js runtime as a parent image
|
# Use an official Node.js runtime as a parent image
|
||||||
FROM node:22
|
FROM node:22.16.0-alpine3.21
|
||||||
|
|
||||||
RUN apt-get update -qq -y && \
|
RUN apk add --no-cache \
|
||||||
apt-get install -y \
|
alsa-lib \
|
||||||
libasound2 \
|
at-spi2-atk \
|
||||||
libatk-bridge2.0-0 \
|
gtk+3.0 \
|
||||||
libgtk-4-1 \
|
nss \
|
||||||
libnss3 \
|
|
||||||
xdg-utils \
|
xdg-utils \
|
||||||
wget && \
|
wget \
|
||||||
wget -q -O chrome-linux64.zip https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.204/linux64/chrome-linux64.zip && \
|
unzip \
|
||||||
unzip chrome-linux64.zip && \
|
chromium=136.0.7103.113-r0 \
|
||||||
rm chrome-linux64.zip && \
|
chromium-chromedriver=136.0.7103.113-r0
|
||||||
mv chrome-linux64 /opt/chrome/ && \
|
|
||||||
ln -s /opt/chrome/chrome /usr/local/bin/ && \
|
|
||||||
wget -q -O chromedriver-linux64.zip https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.204/linux64/chromedriver-linux64.zip && \
|
|
||||||
unzip -j chromedriver-linux64.zip chromedriver-linux64/chromedriver && \
|
|
||||||
rm chromedriver-linux64.zip && \
|
|
||||||
mv chromedriver /usr/local/bin/
|
|
||||||
|
|
||||||
# Don't run as root
|
|
||||||
USER node
|
|
||||||
|
|
||||||
# Set the working directory in the container
|
# Set the working directory in the container
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
# Create the cache directory
|
# Create the cache directory and set ownership (as root)
|
||||||
RUN mkdir -p ./cache && chown node:node ./cache
|
RUN mkdir -p ./cache && chown -R node:node ./cache
|
||||||
|
|
||||||
|
# Don't run as root
|
||||||
|
USER node
|
||||||
|
|
||||||
# Define environment variables
|
# Define environment variables
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
@@ -67,9 +60,11 @@ ENV BITCOIN_PAYEE_NAME="Bitcoin Price Change"
|
|||||||
VOLUME ./cache
|
VOLUME ./cache
|
||||||
|
|
||||||
# Copy the current directory contents into the container at /usr/src/app
|
# Copy the current directory contents into the container at /usr/src/app
|
||||||
|
# This should happen after WORKDIR is set and USER is node
|
||||||
COPY --chown=node:node . .
|
COPY --chown=node:node . .
|
||||||
|
|
||||||
# Install any needed packages specified in package.json
|
# Install any needed packages specified in package.json
|
||||||
|
# This should run as the node user
|
||||||
RUN npm install && npm update
|
RUN npm install && npm update
|
||||||
|
|
||||||
# Run the app when the container launches
|
# Run the app when the container launches
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
# Require APT to utilizelocal proxy
|
||||||
|
echo "Acquire::http::proxy \"http://192.168.128.185:3142\";" >> /etc/apt/apt.conf.d/02proxy
|
||||||
|
|
||||||
|
# Set TimeZone :)
|
||||||
|
timedatectl set-timezone America/Chicago
|
||||||
|
|
||||||
|
# Perform update / upgrade of all existing packages and repos
|
||||||
|
apt update && apt upgrade -y
|
||||||
|
|
||||||
|
# Install all identified dependencies
|
||||||
|
apt install curl git ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 \
|
||||||
|
libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 \
|
||||||
|
libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 \
|
||||||
|
libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 \
|
||||||
|
libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils -y
|
||||||
|
|
||||||
|
# Add NodeSource repository (replace 22.x with your desired version, e.g., 20.x, 18.x)
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
||||||
|
|
||||||
|
# Install Node.js
|
||||||
|
apt install -y nodejs
|
||||||
|
|
||||||
|
# Git clone the actual-helpers repo
|
||||||
|
cd /opt
|
||||||
|
git clone https://git.kollman.net/rlkollman/actual-helpers
|
||||||
|
|
||||||
|
# Install all dependencies
|
||||||
|
cd /opt/actual-helpers
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Write crontab file with scheduled tasks
|
||||||
|
echo "" >> /etc/crontab
|
||||||
|
echo "# Sync ActualBudget Bank Accounts daily at 2 AM" >> /etc/crontab
|
||||||
|
echo "00 2 * * * root cd /opt/actual-helpers && node sync-banks.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "05 2 * * * root cd /opt/actual-helpers && node update-investments.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "" >> /etc/crontab
|
||||||
|
echo "# Sync ActualBudget Vehicles & Apply Mortgage Interest on the 1st day of every month at 3 AM" >> /etc/crontab
|
||||||
|
echo "00 3 1 * * root cd /opt/actual-helpers && node kbb.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "15 3 6 * * root cd /opt/actual-helpers && node apply-interest.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "" >> /etc/crontab
|
||||||
|
echo "# Sync ActualBudget Residence through RentCast on the 1st & 15th day of every month at 4 AM" >> /etc/crontab
|
||||||
|
echo "#00 4 1 * * root cd /opt/actual-helpers && node rentcast.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "#00 4 15 * * root cd /opt/actual-helpers && node rentcast.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "" >> /etc/crontab
|
||||||
|
echo "# Sync ActualBudget Residence through Zillow on the 1st & 16th day of every month at 5 AM" >> /etc/crontab
|
||||||
|
echo "30 4 1 * * root cd /opt/actual-helpers && node zestimate.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "30 4 16 * * root cd /opt/actual-helpers && node zestimate.js > /dev/null" >> /etc/crontab
|
||||||
|
echo "" >> /etc/crontab
|
||||||
|
echo "# Output the current budget status to a file" >> /etc/crontab
|
||||||
|
echo "00 5 * * * root cd /opt/actual-helpers && node budget.js > /root/budget.txt" >> /etc/crontab
|
||||||
+31
-11
@@ -1,35 +1,55 @@
|
|||||||
const { Builder, Browser, By, until } = require('selenium-webdriver')
|
const puppeteer = require('puppeteer-extra');
|
||||||
|
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
|
||||||
const api = require('@actual-app/api');
|
const api = require('@actual-app/api');
|
||||||
const { closeBudget, ensurePayee, getAccountBalance, getAccountNote, getTagValue, openBudget, showPercent, sleep } = require('./utils');
|
const { closeBudget, ensurePayee, getAccountBalance, getAccountNote, getTagValue, openBudget, showPercent, sleep } = require('./utils');
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
|
|
||||||
|
puppeteer.use(StealthPlugin());
|
||||||
|
|
||||||
async function getZestimate(URL) {
|
async function getZestimate(URL) {
|
||||||
let driver = await new Builder()
|
const browser = await puppeteer.launch({
|
||||||
.forBrowser(Browser.CHROME)
|
headless: 'new',
|
||||||
.build();
|
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
||||||
|
});
|
||||||
|
|
||||||
|
const page = await browser.newPage();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await driver.get(URL);
|
await page.goto(URL, { waitUntil: 'domcontentloaded', timeout: 20000 });
|
||||||
const html = await driver.wait(until.elementLocated(By.css('body')), 5000).getAttribute('innerHTML');
|
const html = await page.content();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let match = html.match(/"zestimate":"(\d+)"/);
|
console.log('Got html data!');
|
||||||
|
let match = html.match(/"price":"(\d+)"/);
|
||||||
if (match) {
|
if (match) {
|
||||||
|
console.log('matched 1st');
|
||||||
return parseInt(match[1]) * 100;
|
return parseInt(match[1]) * 100;
|
||||||
}
|
}
|
||||||
match = html.match(/\\"zestimate\\":\\"(\d+)\\"/);
|
match = html.match(/\\"price\\":(\d+)/);
|
||||||
if (match) {
|
if (match) {
|
||||||
|
console.log('matched 2nd');
|
||||||
return parseInt(match[1]) * 100;
|
return parseInt(match[1]) * 100;
|
||||||
}
|
}
|
||||||
|
match = html.match(/\\"price\\":\\"(\d+)\\"/);
|
||||||
|
if (match) {
|
||||||
|
console.log('matched 3rd');
|
||||||
|
return parseInt(match[1]) * 100;
|
||||||
|
}
|
||||||
|
console.log('didn\'t match any :(');
|
||||||
|
console.log('~~!!');
|
||||||
|
// console.log(html);
|
||||||
|
console.log('!!~~');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('Error parsing Zillow page:');
|
console.log('Error parsing Zillow page:');
|
||||||
console.log(error);
|
console.log(error);
|
||||||
console.log(html);
|
console.log(html);
|
||||||
}
|
}
|
||||||
|
} catch (er) {
|
||||||
|
console.log('Error while fetching zestimate:');
|
||||||
|
console.log(er);
|
||||||
|
console.lo(html);
|
||||||
} finally {
|
} finally {
|
||||||
await driver.quit();
|
await browser.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user