successfully intercept the mp4 request (but 401 response get, as cookie not sent)
This commit is contained in:
parent
b9248eecb9
commit
28e4e07b83
89
main.js
89
main.js
|
|
@ -1,5 +1,7 @@
|
||||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
|
const { app, BrowserWindow, ipcMain, dialog, session } = require('electron');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const https = require('https');
|
||||||
|
|
||||||
let store;
|
let store;
|
||||||
let mainWindow;
|
let mainWindow;
|
||||||
|
|
@ -8,9 +10,11 @@ let mainWindow;
|
||||||
(async () => {
|
(async () => {
|
||||||
const Store = await import('electron-store');
|
const Store = await import('electron-store');
|
||||||
store = new Store.default();
|
store = new Store.default();
|
||||||
|
console.log('Store initialized');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
|
console.log('Creating main window...');
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 800,
|
height: 800,
|
||||||
|
|
@ -21,8 +25,79 @@ function createWindow() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set up network request monitoring
|
||||||
|
console.log('Setting up network request monitoring...');
|
||||||
|
session.defaultSession.webRequest.onBeforeRequest(
|
||||||
|
{ urls: ['*://*.onedrive.com/*', '*://*.1drv.com/*', '*://*.microsoftpersonalcontent.com/*'] },
|
||||||
|
(details, callback) => {
|
||||||
|
console.log('Intercepted request:', details.url);
|
||||||
|
// Check if this is a video request (typically .mov for Live Photos)
|
||||||
|
if (details.url.toLowerCase().includes('.mov') || details.url.toLowerCase().includes('mp4')) {
|
||||||
|
console.log('✓ Detected video URL:', details.url);
|
||||||
|
if (store) {
|
||||||
|
const destFolder = store.get('destFolder', '');
|
||||||
|
if (destFolder) {
|
||||||
|
// Extract item ID from URL
|
||||||
|
const urlObj = new URL(details.url);
|
||||||
|
const pathParts = urlObj.pathname.split('/');
|
||||||
|
const itemIndex = pathParts.findIndex(part => part === 'items');
|
||||||
|
const itemId = itemIndex !== -1 ? pathParts[itemIndex + 1] : null;
|
||||||
|
|
||||||
|
// Create filename with item ID and extension
|
||||||
|
const extension = details.url.toLowerCase().includes('.mov') ? '.mov' : '.mp4';
|
||||||
|
const filename = itemId ? `${itemId}${extension}` : `video_${Date.now()}${extension}`;
|
||||||
|
|
||||||
|
console.log('Downloading video as:', filename);
|
||||||
|
console.log('To folder:', destFolder);
|
||||||
|
downloadVideo(details.url, path.join(destFolder, filename));
|
||||||
|
} else {
|
||||||
|
console.warn('⚠ No destination folder configured');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('⚠ Store not initialized');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback({ cancel: false });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
mainWindow.loadFile(path.join(__dirname, 'renderer/index.html'));
|
mainWindow.loadFile(path.join(__dirname, 'renderer/index.html'));
|
||||||
mainWindow.setTitle('OneDrive Photos');
|
mainWindow.setTitle('OneDrive Photos');
|
||||||
|
console.log('Main window created and loaded');
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadVideo(url, filepath) {
|
||||||
|
console.log('Starting video download:', url);
|
||||||
|
console.log('Save path:', filepath);
|
||||||
|
|
||||||
|
const dir = path.dirname(filepath);
|
||||||
|
if (!fs.existsSync(dir)) {
|
||||||
|
console.log('Creating directory:', dir);
|
||||||
|
fs.mkdirSync(dir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = fs.createWriteStream(filepath);
|
||||||
|
https.get(url, (response) => {
|
||||||
|
console.log('Download started, status:', response.statusCode);
|
||||||
|
console.log('Content type:', response.headers['content-type']);
|
||||||
|
console.log('Content length:', response.headers['content-length']);
|
||||||
|
|
||||||
|
response.pipe(file);
|
||||||
|
file.on('finish', () => {
|
||||||
|
file.close();
|
||||||
|
console.log('✓ Video saved successfully:', filepath);
|
||||||
|
mainWindow.webContents.send('video-saved', {
|
||||||
|
filename: path.basename(filepath),
|
||||||
|
path: filepath
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}).on('error', (err) => {
|
||||||
|
console.error('⚠ Download error:', err);
|
||||||
|
fs.unlink(filepath, () => {
|
||||||
|
console.log('Cleaned up failed download file');
|
||||||
|
});
|
||||||
|
mainWindow.webContents.send('video-save-error', err.message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
app.whenReady().then(createWindow);
|
app.whenReady().then(createWindow);
|
||||||
|
|
@ -39,26 +114,34 @@ app.on('activate', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Modified IPC handlers
|
// IPC Handlers with debug logs
|
||||||
ipcMain.on('toggle-config', () => {
|
ipcMain.on('toggle-config', () => {
|
||||||
|
console.log('Toggle config panel requested');
|
||||||
mainWindow.webContents.send('toggle-config');
|
mainWindow.webContents.send('toggle-config');
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('set-config', (event, config) => {
|
ipcMain.on('set-config', (event, config) => {
|
||||||
|
console.log('Saving configuration:', config);
|
||||||
if (store) {
|
if (store) {
|
||||||
store.set('destFolder', config.destFolder);
|
store.set('destFolder', config.destFolder);
|
||||||
store.set('onedriveSource', config.onedriveSource);
|
store.set('onedriveSource', config.onedriveSource);
|
||||||
console.log('Configuration saved:', config);
|
console.log('✓ Configuration saved successfully');
|
||||||
|
} else {
|
||||||
|
console.error('⚠ Store not initialized, cannot save config');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('load-config', (event) => {
|
ipcMain.on('load-config', (event) => {
|
||||||
|
console.log('Loading configuration...');
|
||||||
if (store) {
|
if (store) {
|
||||||
const config = {
|
const config = {
|
||||||
destFolder: store.get('destFolder', ''),
|
destFolder: store.get('destFolder', ''),
|
||||||
onedriveSource: store.get('onedriveSource', '')
|
onedriveSource: store.get('onedriveSource', '')
|
||||||
};
|
};
|
||||||
|
console.log('Configuration loaded:', config);
|
||||||
event.reply('config-loaded', config);
|
event.reply('config-loaded', config);
|
||||||
|
} else {
|
||||||
|
console.error('⚠ Store not initialized, cannot load config');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,36 +2,54 @@ const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
// Wait for webview to load
|
// Wait for webview to load
|
||||||
const webview = document.getElementById('main-content');
|
const webview = document.getElementById('main-content');
|
||||||
|
console.log('Setting up webview event listeners...');
|
||||||
|
|
||||||
|
webview.addEventListener('did-start-loading', () => {
|
||||||
|
console.log('Webview started loading');
|
||||||
|
});
|
||||||
|
|
||||||
webview.addEventListener('did-finish-load', () => {
|
webview.addEventListener('did-finish-load', () => {
|
||||||
|
console.log('Webview finished loading');
|
||||||
// Create and add the configuration button
|
// Create and add the configuration button
|
||||||
|
console.log('Creating configuration button');
|
||||||
const button = document.createElement('button');
|
const button = document.createElement('button');
|
||||||
button.id = 'config-button';
|
button.id = 'config-button';
|
||||||
button.innerHTML = '<i class="fas fa-cog"></i> Configuration';
|
button.innerHTML = '<i class="fas fa-cog"></i> Configuration';
|
||||||
document.body.appendChild(button);
|
document.body.appendChild(button);
|
||||||
|
console.log('Configuration button added to DOM');
|
||||||
|
|
||||||
// Add click handler to the dynamically created button
|
|
||||||
button.addEventListener('click', () => {
|
button.addEventListener('click', () => {
|
||||||
|
console.log('Configuration button clicked');
|
||||||
ipcRenderer.send('toggle-config');
|
ipcRenderer.send('toggle-config');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
webview.addEventListener('did-fail-load', (event) => {
|
||||||
|
console.error('Webview failed to load:', event);
|
||||||
|
});
|
||||||
|
|
||||||
// Configuration panel toggle
|
// Configuration panel toggle
|
||||||
ipcRenderer.on('toggle-config', () => {
|
ipcRenderer.on('toggle-config', () => {
|
||||||
|
console.log('Toggling configuration panel');
|
||||||
const panel = document.getElementById('config-panel');
|
const panel = document.getElementById('config-panel');
|
||||||
|
const isOpening = !panel.classList.contains('open');
|
||||||
panel.classList.toggle('open');
|
panel.classList.toggle('open');
|
||||||
|
console.log(isOpening ? 'Panel opened' : 'Panel closed');
|
||||||
|
|
||||||
// Load saved config when panel opens
|
if (isOpening) {
|
||||||
if (panel.classList.contains('open')) {
|
console.log('Loading saved configuration...');
|
||||||
ipcRenderer.send('load-config');
|
ipcRenderer.send('load-config');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Folder selection
|
// Folder selection
|
||||||
document.getElementById('select-folder').addEventListener('click', () => {
|
document.getElementById('select-folder').addEventListener('click', () => {
|
||||||
|
console.log('Folder selection requested');
|
||||||
ipcRenderer.send('select-folder');
|
ipcRenderer.send('select-folder');
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcRenderer.on('folder-selected', (event, path) => {
|
ipcRenderer.on('folder-selected', (event, path) => {
|
||||||
|
console.log('Folder selected:', path);
|
||||||
document.getElementById('dest-folder').value = path;
|
document.getElementById('dest-folder').value = path;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -40,18 +58,46 @@ document.getElementById('config-form').addEventListener('submit', (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const destFolder = document.getElementById('dest-folder').value;
|
const destFolder = document.getElementById('dest-folder').value;
|
||||||
const onedriveSource = document.getElementById('onedrive-source').value;
|
const onedriveSource = document.getElementById('onedrive-source').value;
|
||||||
|
console.log('Saving configuration:', { destFolder, onedriveSource });
|
||||||
ipcRenderer.send('set-config', { destFolder, onedriveSource });
|
ipcRenderer.send('set-config', { destFolder, onedriveSource });
|
||||||
// Close the panel after saving
|
|
||||||
document.getElementById('config-panel').classList.remove('open');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Close button handler
|
|
||||||
document.getElementById('close-config').addEventListener('click', () => {
|
|
||||||
document.getElementById('config-panel').classList.remove('open');
|
document.getElementById('config-panel').classList.remove('open');
|
||||||
|
console.log('Configuration panel closed');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Config loaded handler
|
// Config loaded handler
|
||||||
ipcRenderer.on('config-loaded', (event, config) => {
|
ipcRenderer.on('config-loaded', (event, config) => {
|
||||||
|
console.log('Received saved configuration:', config);
|
||||||
document.getElementById('dest-folder').value = config.destFolder;
|
document.getElementById('dest-folder').value = config.destFolder;
|
||||||
document.getElementById('onedrive-source').value = config.onedriveSource;
|
document.getElementById('onedrive-source').value = config.onedriveSource;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Video handling
|
||||||
|
ipcRenderer.on('video-saved', (event, { filename, path }) => {
|
||||||
|
console.log('✓ Video saved successfully:', { filename, path });
|
||||||
|
showStatus(`Saved: ${filename}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('video-save-error', (event, error) => {
|
||||||
|
console.error('⚠ Video save error:', error);
|
||||||
|
showStatus(`Error: ${error}`, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
function showStatus(message, isError = false) {
|
||||||
|
console.log(`Showing status: ${message} (${isError ? 'error' : 'success'})`);
|
||||||
|
const statusDiv = document.getElementById('status-display') || createStatusDisplay();
|
||||||
|
statusDiv.textContent = message;
|
||||||
|
statusDiv.className = `show ${isError ? 'error' : 'success'}`;
|
||||||
|
|
||||||
|
// Reset animation
|
||||||
|
statusDiv.style.animation = 'none';
|
||||||
|
statusDiv.offsetHeight;
|
||||||
|
statusDiv.style.animation = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createStatusDisplay() {
|
||||||
|
console.log('Creating status display element');
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.id = 'status-display';
|
||||||
|
document.body.appendChild(div);
|
||||||
|
return div;
|
||||||
|
}
|
||||||
|
|
@ -186,3 +186,35 @@ body {
|
||||||
.submit-button:active {
|
.submit-button:active {
|
||||||
background: #005a9e;
|
background: #005a9e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#status-display {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
z-index: 1002;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status-display.show {
|
||||||
|
display: block;
|
||||||
|
animation: fadeOut 3s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status-display.success {
|
||||||
|
background: rgba(0, 120, 212, 0.9);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status-display.error {
|
||||||
|
background: rgba(232, 17, 35, 0.9);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeOut {
|
||||||
|
0% { opacity: 1; }
|
||||||
|
70% { opacity: 1; }
|
||||||
|
100% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue