Skip to content

Auto-open PDFs after download for WhatsApp & other services #627

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

Open
dimrim opened this issue Mar 18, 2025 · 1 comment
Open

Auto-open PDFs after download for WhatsApp & other services #627

dimrim opened this issue Mar 18, 2025 · 1 comment

Comments

@dimrim
Copy link

dimrim commented Mar 18, 2025

🛠 Feature Request: Auto-open PDFs after download for WhatsApp & other services

📌 Background

Ferdium automatically downloads PDFs, but it does not open them directly.
In services like WhatsApp, it would be very convenient if PDFs would immediately open after download, without requiring the user to manually navigate to the file.

With the help of @chatgpt, I have developed a script that does exactly that! 🚀


🔧 How does the script work?

✅ Automatically detects when a PDF file is downloaded
✅ Waits until the file is fully saved before opening it
✅ Opens the PDF automatically with the default PDF viewer (e.g., Atril)
✅ Prevents duplicate or premature openings
✅ Dynamically loads the download folder from settings.json, making it flexible for all users


📝 Full script for user.js:

// Module imports
const { execFile } = require("child_process");
const fs = require("fs");
const path = require("path");

// Read the download path from Ferdium settings
const settingsPath = path.join(process.env.HOME, ".config/Ferdium/config/settings.json");

// Default download folder (fallback)
let DOWNLOAD_FOLDER = path.join(process.env.HOME, "Downloads");

// Check if settings.json exists and contains a download path
if (fs.existsSync(settingsPath)) {
    try {
        const settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
        if (settings.downloadFolderPath) {
            DOWNLOAD_FOLDER = settings.downloadFolderPath;
        }
    } catch (err) {
        console.error(`❌ Error reading settings file: ${err.message}`);
    }
}

let lastOpenedFile = ""; // Variable to store the last opened file

// Watch for new downloads and open PDFs, but only ONCE
fs.watch(DOWNLOAD_FOLDER, (eventType, filename) => {
    if (eventType === "rename" && filename.toLowerCase().endsWith(".pdf")) {
        const filePath = path.join(DOWNLOAD_FOLDER, filename);
        
        // Skip if the file has already been opened
        if (filePath === lastOpenedFile) {
            console.log(`⏳ PDF was already opened, skipping: ${filePath}`);
            return;
        }

        // Wait until the file is completely downloaded
        let retries = 20; // Max wait time: 10 seconds (20 x 500ms)
        const checkFileReady = setInterval(() => {
            if (fs.existsSync(filePath) && fs.statSync(filePath).size > 0) {
                clearInterval(checkFileReady); // Stop waiting
                lastOpenedFile = filePath; // Mark the file as opened
                console.log(`📂 PDF downloaded: ${filePath}`);

                execFile("atril", [filePath], (error, stdout, stderr) => {
                    if (error) {
                        console.error(`❌ Error opening PDF: ${error.message}`);
                        return;
                    }
                    console.log(`📖 PDF successfully opened with Atril: ${filePath}`);
                });
            } else if (retries <= 0) {
                clearInterval(checkFileReady);
                console.log(`⚠️ File was not fully downloaded after 10 seconds: ${filePath}`);
            }
            retries--;
        }, 500); // Check every 500ms
    }
});
@dimrim
Copy link
Author

dimrim commented Mar 18, 2025

This script is currently optimized for Linux and the Atril PDF viewer.
If this feature is implemented officially, it might be useful to make the PDF viewer configurable or detect the default PDF application dynamically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant