Extensions are now lazy loaded to prevent
long wait times to use the app.
This commit is contained in:
59
main.js
59
main.js
@@ -7,9 +7,6 @@ const initDatabase = require('./src/database/db-init');
|
|||||||
const { initDiscordRPC } = require('./src/discord-rpc');
|
const { initDiscordRPC } = require('./src/discord-rpc');
|
||||||
const headlessBrowser = require('./src/utils/headless-browser');
|
const headlessBrowser = require('./src/utils/headless-browser');
|
||||||
|
|
||||||
const fetchPath = require.resolve('node-fetch');
|
|
||||||
const cheerioPath = require.resolve('cheerio');
|
|
||||||
|
|
||||||
const waifuBoardsPath = path.join(app.getPath('home'), 'WaifuBoards');
|
const waifuBoardsPath = path.join(app.getPath('home'), 'WaifuBoards');
|
||||||
const pluginsPath = path.join(waifuBoardsPath, 'extensions');
|
const pluginsPath = path.join(waifuBoardsPath, 'extensions');
|
||||||
const dbPath = path.join(waifuBoardsPath, 'favorites.db');
|
const dbPath = path.join(waifuBoardsPath, 'favorites.db');
|
||||||
@@ -25,44 +22,34 @@ try {
|
|||||||
console.error('Failed to create directories:', error);
|
console.error('Failed to create directories:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadedScrapers = {};
|
const availableScrapers = {};
|
||||||
|
|
||||||
function loadScrapers() {
|
function loadScrapers() {
|
||||||
console.log('Loading scrapers...');
|
console.log('Scanning for plugins...');
|
||||||
console.log(`Checking for plugins in: ${pluginsPath}`);
|
|
||||||
|
let files = [];
|
||||||
|
try {
|
||||||
|
files = fs.readdirSync(pluginsPath).filter((file) => file.endsWith('.js'));
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to read plugins directory", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const files = fs.readdirSync(pluginsPath);
|
files.forEach((file) => {
|
||||||
files
|
const name = file.replace('.js', '');
|
||||||
.filter((file) => file.endsWith('.js'))
|
|
||||||
.forEach((file) => {
|
|
||||||
const filePath = path.join(pluginsPath, file);
|
const filePath = path.join(pluginsPath, file);
|
||||||
try {
|
|
||||||
const scraperModule = require(filePath);
|
availableScrapers[name] = {
|
||||||
const className = Object.keys(scraperModule)[0];
|
name: name,
|
||||||
const ScraperClass = scraperModule[className];
|
path: filePath,
|
||||||
|
instance: null
|
||||||
if (
|
};
|
||||||
typeof ScraperClass === 'function' &&
|
});
|
||||||
ScraperClass.prototype.fetchSearchResult
|
|
||||||
) {
|
console.log(`Found ${files.length} plugins. (Lazy Loaded)`);
|
||||||
const instance = new ScraperClass(fetchPath, cheerioPath, headlessBrowser);
|
|
||||||
|
|
||||||
loadedScrapers[className] = {
|
|
||||||
instance: instance,
|
|
||||||
baseUrl: instance.baseUrl,
|
|
||||||
};
|
|
||||||
console.log(
|
|
||||||
`Successfully loaded scraper: ${className} from ${instance.baseUrl}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.warn(`File ${file} does not export a valid scraper class.`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to load scraper from ${file}:`, error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
loadScrapers();
|
loadScrapers();
|
||||||
|
|
||||||
const db = initDatabase(dbPath);
|
const db = initDatabase(dbPath);
|
||||||
@@ -100,7 +87,7 @@ app.on('window-all-closed', function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const apiHandlers = require('./src/ipc/api-handlers')(loadedScrapers);
|
const apiHandlers = require('./src/ipc/api-handlers')(availableScrapers, headlessBrowser);
|
||||||
const dbHandlers = require('./src/ipc/db-handlers')(db);
|
const dbHandlers = require('./src/ipc/db-handlers')(db);
|
||||||
|
|
||||||
ipcMain.handle('api:getSources', apiHandlers.getSources);
|
ipcMain.handle('api:getSources', apiHandlers.getSources);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "waifu-board",
|
"name": "waifu-board",
|
||||||
"version": "v1.3.0",
|
"version": "v1.3.1",
|
||||||
"description": "An image board app to store and browse your favorite waifus!",
|
"description": "An image board app to store and browse your favorite waifus!",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,29 +1,80 @@
|
|||||||
module.exports = function (loadedScrapers) {
|
const fs = require('fs');
|
||||||
|
const fetchPath = require.resolve('node-fetch');
|
||||||
|
const cheerioPath = require.resolve('cheerio');
|
||||||
|
|
||||||
|
function peekBaseUrl(filePath) {
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8');
|
||||||
|
const match = content.match(/baseUrl\s*=\s*["']([^"']+)["']/);
|
||||||
|
return match ? match[1] : null;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (availableScrapers, headlessBrowser) {
|
||||||
|
|
||||||
|
Object.keys(availableScrapers).forEach(name => {
|
||||||
|
const scraper = availableScrapers[name];
|
||||||
|
if (!scraper.url) {
|
||||||
|
const url = peekBaseUrl(scraper.path);
|
||||||
|
if (url) {
|
||||||
|
scraper.url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getSources: () => {
|
getSources: () => {
|
||||||
return Object.keys(loadedScrapers).map((name) => {
|
return Object.keys(availableScrapers).map((name) => {
|
||||||
|
const scraper = availableScrapers[name];
|
||||||
return {
|
return {
|
||||||
name: name,
|
name: name,
|
||||||
url: loadedScrapers[name].baseUrl,
|
url: scraper.url || name
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
search: async (event, source, query, page) => {
|
search: async (event, source, query, page) => {
|
||||||
try {
|
const scraperData = availableScrapers[source];
|
||||||
if (loadedScrapers[source] && loadedScrapers[source].instance) {
|
|
||||||
const results = await loadedScrapers[source].instance.fetchSearchResult(
|
if (!scraperData) {
|
||||||
query,
|
return { success: false, error: `Source ${source} not found.` };
|
||||||
page
|
|
||||||
);
|
|
||||||
return { success: true, data: results };
|
|
||||||
} else {
|
|
||||||
throw new Error(`Unknown source or source failed to load: ${source}`);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error searching ${source}:`, error);
|
|
||||||
return { success: false, error: error.message };
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
if (!scraperData.instance) {
|
||||||
|
console.log(`[LazyLoad] Initializing scraper: ${source}...`);
|
||||||
|
try {
|
||||||
|
const scraperModule = require(scraperData.path);
|
||||||
|
|
||||||
|
const className = Object.keys(scraperModule)[0];
|
||||||
|
const ScraperClass = scraperModule[className];
|
||||||
|
|
||||||
|
if (!ScraperClass || typeof ScraperClass !== 'function') {
|
||||||
|
throw new Error(`File ${scraperData.path} does not export a valid class.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = new ScraperClass(fetchPath, cheerioPath, headlessBrowser);
|
||||||
|
|
||||||
|
scraperData.instance = instance;
|
||||||
|
|
||||||
|
if (instance.baseUrl) {
|
||||||
|
scraperData.url = instance.baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Failed to lazy load ${source}:`, err);
|
||||||
|
return { success: false, error: `Failed to load extension: ${err.message}` };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const results = await scraperData.instance.fetchSearchResult(query, page);
|
||||||
|
return { success: true, data: results };
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error during search in ${source}:`, err);
|
||||||
|
return { success: false, error: err.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
const GITHUB_OWNER = 'ItsSkaiya';
|
const GITHUB_OWNER = 'ItsSkaiya';
|
||||||
const GITHUB_REPO = 'WaifuBoard';
|
const GITHUB_REPO = 'WaifuBoard';
|
||||||
const CURRENT_VERSION = 'v1.3.0';
|
const CURRENT_VERSION = 'v1.3.1';
|
||||||
const UPDATE_CHECK_INTERVAL = 5 * 60 * 1000;
|
const UPDATE_CHECK_INTERVAL = 5 * 60 * 1000;
|
||||||
|
|
||||||
let currentVersionDisplay;
|
let currentVersionDisplay;
|
||||||
|
|||||||
Reference in New Issue
Block a user