Add Docker support and fix rating change extraction
- Add Dockerfile with optimized Puppeteer configuration for containers - Add .dockerignore for efficient builds - Fix rating change regex to match actual PDGA format (no brackets) - Update Puppeteer launch args for Docker compatibility - Use new headless mode to resolve deprecation warning 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
node_modules
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
*.log
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
# Use official Node.js runtime as base image
|
||||
FROM node:18-alpine
|
||||
|
||||
# Install Chromium and dependencies for Puppeteer
|
||||
RUN apk add --no-cache \
|
||||
chromium \
|
||||
nss \
|
||||
freetype \
|
||||
freetype-dev \
|
||||
harfbuzz \
|
||||
ca-certificates \
|
||||
ttf-freefont
|
||||
|
||||
# Tell Puppeteer to skip installing Chromium. We'll be using the installed package.
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
|
||||
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup -g 1001 -S nodejs
|
||||
RUN adduser -S nextjs -u 1001
|
||||
|
||||
# Change ownership of the app directory
|
||||
RUN chown -R nextjs:nodejs /app
|
||||
USER nextjs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Start the application
|
||||
CMD ["npm", "start"]
|
||||
@@ -20,7 +20,18 @@ async function scrapePDGARating(pdgaNumber) {
|
||||
return cached.data;
|
||||
}
|
||||
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
const browser = await puppeteer.launch({
|
||||
headless: "new",
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-accelerated-2d-canvas',
|
||||
'--no-first-run',
|
||||
'--no-zygote',
|
||||
'--disable-gpu'
|
||||
]
|
||||
});
|
||||
const page = await browser.newPage();
|
||||
|
||||
try {
|
||||
@@ -37,29 +48,14 @@ async function scrapePDGARating(pdgaNumber) {
|
||||
for (const el of elements) {
|
||||
const text = el.innerText || el.textContent;
|
||||
if (text.includes('Current Rating:')) {
|
||||
console.log('Found rating text:', text);
|
||||
const ratingMatch = text.match(/Current Rating:\s*(\d+)/);
|
||||
|
||||
// Try different patterns for rating change
|
||||
const changePatterns = [
|
||||
/\[(\+\d+)\]/,
|
||||
/\[(\-\d+)\]/,
|
||||
/(\+\d+)/,
|
||||
/(\-\d+)/
|
||||
];
|
||||
|
||||
let change = null;
|
||||
for (const pattern of changePatterns) {
|
||||
const match = text.match(pattern);
|
||||
if (match) {
|
||||
change = match[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Look for rating change pattern: "Current Rating: 911 +6 (as of..."
|
||||
const changeMatch = text.match(/Current Rating:\s*\d+\s+([+\-]\d+)\s+\(as of/);
|
||||
|
||||
return {
|
||||
rating: ratingMatch ? ratingMatch[1] : null,
|
||||
change: change
|
||||
change: changeMatch ? changeMatch[1] : null
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -318,7 +314,18 @@ app.get('/api/ratings', async (req, res) => {
|
||||
app.post('/api/predicted-rating/:pdgaNumber', async (req, res) => {
|
||||
try {
|
||||
const { pdgaNumber } = req.params;
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
const browser = await puppeteer.launch({
|
||||
headless: "new",
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-accelerated-2d-canvas',
|
||||
'--no-first-run',
|
||||
'--no-zygote',
|
||||
'--disable-gpu'
|
||||
]
|
||||
});
|
||||
|
||||
console.log(`Calculating predicted rating for PDGA ${pdgaNumber}...`);
|
||||
const predictedRating = await getPredictedRating(browser, pdgaNumber);
|
||||
|
||||
Reference in New Issue
Block a user