+ Init Wallify Manager Code

wallify-manager-code
Mathis CHIRAT 7 months ago
parent 96194f524b
commit f7a4a25cc8

@ -0,0 +1,9 @@
appId: wallify-manager-app
productName: Wallify Manager
copyright: Copyright 2023 Mathis CHIRAT
electronVersion: 14.2.9
appImage:
category: Utility
mimeTypes: ['image/jpeg', 'image/png']

@ -0,0 +1,528 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Wallpaper Manager</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
<style>
:root {
--primary-color: #3498db;
--secondary-color: #136ba5;
--background-color: #1f1f1f;
--text-color: #ffffff;
}
body {
font-family: Arial, sans-serif;
background-color: var(--background-color);
color: var(--text-color)
}
.wallpaper-container {
padding: 100px 20px 20px 20px;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.wallpaper-item {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
position: relative;
width: 200px;
height: 200px;
overflow: hidden;
}
.wallpaper-item img {
width: 200px;
height: 200px;
object-fit: cover;
transition: transform 0.3s ease-in-out;
-webkit-filter: grayscale(100%);
}
.wallpaper-item:hover img {
transform: scale(1.1);
-webkit-filter: grayscale(0%);
cursor: pointer;
}
.wallpaper-item video {
position: absolute;
width: 200px;
height: 200px;
object-fit: cover;
transition: transform 0.3s ease-in-out;
-webkit-filter: grayscale(100%);
}
.wallpaper-item:hover video {
transform: scale(1.1);
-webkit-filter: grayscale(0%);
cursor: pointer;
}
#install-new-wallpaper,
#installed-wallpaper,
#workshop-wallpaper {
position: absolute;
top: 10px;
padding: 10px;
height: 30px;
justify-content: center;
align-items: center;
display: flex;
cursor: pointer;
background: var(--background-color);
border: 1px solid var(--primary-color);
color: var(--text-color);
transition: transform 0.3s ease-in-out;
}
#install-new-wallpaper {
right: 10px;
width: 150px;
}
#installed-wallpaper {
left: 10px;
width: 120px;
}
#workshop-wallpaper {
left: 135px;
width: 120px;
}
.active {
background: var(--secondary-color) !important;
}
.delete-wallpaper {
position: absolute;
top: 10px;
right: 10px;
background-color: #ca0000;
color: #161616;
border-radius: 5px;
border: none;
padding: 8px 10px;
font-size: 12px;
cursor: pointer;
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: var(--background-color);
}
::-webkit-scrollbar-thumb {
background: var(--secondary-color);
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--secondary-color);
}
</style>
</head>
<body>
<button id="installed-wallpaper" class="active">Installed</button>
<button id="workshop-wallpaper">Workshop</button>
<button id="install-new-wallpaper">Import Wallpaper</button>
<div style="position: absolute; top: 38px; width: 99%; height: 2px; background: var(--primary-color);"></div>
<div class="wallpaper-container">
<!-- Add wallpaper items dynamically using JavaScript -->
</div>
<div
style="position: fixed; bottom: 0; width: 100%; background: var(--background-color); border-top: 1px solid var(--primary-color); text-align: center; padding: 10px; color: var(--text-color);">
© 2024 PerrierBottle (Mathis CHIRAT). All rights reserved. | Version v1.0.3
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
const path = require('path');
const fs = require('fs');
const os = require('os');
const { spawn, exec } = require('child_process');
const { ipcRenderer } = require('electron');
// Get the wallpaper directory
const wallpaperDir = path.join(os.homedir() + '/.config/Wallify/wallpapers');
function reloadPage() {
console.log('Reloading page...');
// Get the wallpaper container element
const wallpaperContainer = document.querySelector('.wallpaper-container');
wallpaperContainer.innerHTML = '';
if (document.getElementById('installed-wallpaper').classList.contains('active')) {
console.log('Reloading wallpapers...');
// Get all the wallpaper files in the directory
const wallpaperFiles = fs.readdirSync(wallpaperDir);
// Create a search bar
const searchBar = document.createElement('input');
searchBar.type = 'search';
searchBar.placeholder = 'Search wallpapers...';
searchBar.style.position = 'absolute';
searchBar.style.top = '50px';
searchBar.style.left = '10px';
searchBar.style.width = '200px';
searchBar.style.height = '30px';
searchBar.style.padding = '10px';
searchBar.style.fontFamily = 'Arial, sans-serif';
searchBar.style.background = '#000000'
searchBar.style.color = '#ffffff'
// Add an event listener to the search bar
searchBar.addEventListener('input', () => {
const searchQuery = searchBar.value.toLowerCase();
const wallpaperItems = wallpaperContainer.children;
for (const wallpaperItem of wallpaperItems) {
const wallpaperName = path.basename(wallpaperItem.querySelector('.banner').textContent, path.extname(wallpaperItem.querySelector('.banner').textContent));
if (wallpaperName.toLowerCase().includes(searchQuery)) {
wallpaperItem.style.display = 'block';
} else {
wallpaperItem.style.display = 'none';
}
}
});
// Append the search bar to the page
document.body.appendChild(searchBar);
// Loop through the wallpaper files and create preview items
wallpaperFiles.forEach((wallpaperFile) => {
let actualWallpaper;
// Create a preview item
const wallpaperItem = document.createElement('a');
wallpaperItem.classList.add('wallpaper-item');
const execPromise = new Promise((resolve, reject) => {
exec(`cat ~/.config/Wallify/wallpaper.conf`, (error, stdout, stderr) => {
if (error) {
console.error(`Error reading wallpaper file: ${error}`);
} else {
actualWallpaper = stdout.replace('WALLPAPER_FILE=', '').replace('\n', '') == path.join(wallpaperDir, wallpaperFile);
resolve(actualWallpaper);
}
});
});
execPromise.then((actualWallpaper) => {
wallpaperItem.style.border = actualWallpaper ? '4px solid #1597ed' : 'none';
const mediaElement = wallpaperItem.querySelector('img, video');
mediaElement.style.webkitFilter = actualWallpaper ? 'grayscale(0%)' : '';
});
wallpaperItem.addEventListener('click', () => {
event.preventDefault();
const mediaElement = path.join(wallpaperDir, wallpaperFile);
exec(`kill $(ps aux | grep -i 'wallpaper/wallify' | awk '{print $2}')`, (error, stdout, stderr) => { });
exec(`echo "WALLPAPER_FILE=${mediaElement}" > ~/.config/Wallify/wallpaper.conf`, (error, stdout, stderr) => {
if (error) {
console.error(`Error writing wallpaper file: ${error}`);
} else {
console.log(`Wallpaper file written successfully`);
}
});
setTimeout(function () { }, 2000);
if (mediaElement.endsWith('.mp4')) {
console.log("Applying MP4 wallpaper...");
exec(`rm ~/.config/Wallify/wallify-picture-uri.png`, (error, stdout, stderr) => {
if (error) {
console.debug(`Error removing temp file: ${error}`);
}
});
exec(`convert ${mediaElement}[0] ~/.config/Wallify/wallify-picture-uri.png`, (error, stdout, stderr) => {
if (error) {
console.error(`Error applying wallpaper: ${error}`);
} else {
console.log(`Wallpaper applied successfully`);
}
})
const checkFileExistence = setInterval(() => {
const wallifyConfigFolder = path.join(os.homedir(), '.config', 'Wallify');
if (fs.existsSync(path.join(wallifyConfigFolder, 'wallify-picture-uri.png'))) {
clearInterval(checkFileExistence);
exec(`gsettings set org.gnome.desktop.background picture-uri file://${path.join(os.homedir(), '.config', 'Wallify', 'wallify-picture-uri.png')}`, (error, stdout, stderr) => {
if (error) {
console.error(`Error background file: ${error}`);
} else {
console.log(`Wallpaper MP4 background applied successfully`);
}
});
}
}, 100);
} else {
exec(`gsettings set org.gnome.desktop.background picture-uri file://${mediaElement}`, (error, stdout, stderr) => {
if (error) {
console.error(`Error background file: ${error}`);
} else {
console.log(`Wallpaper IMG/GIF background applied successfully`);
}
});
}
const wallifyProcess = spawn('/home/UCA/machirat1/public/WallPaper/wallify', ['-ni', '-fs', '-s', '-sp', '-st', '-b', '-nf', '--', 'mpv', '-wid', 'WID', '--loop', '--no-audio', mediaElement], {
detached: true,
stdio: 'ignore'
});
console.log(`Animated Wallpaper applied successfully`);
wallifyProcess.unref();
reloadPage();
})
// Create an image or video element based on the file extension
const wallpaperElement = document.createElement(wallpaperFile.endsWith('.mp4') ? 'video' : 'img');
wallpaperElement.src = path.join(wallpaperDir, wallpaperFile);
// Append the wallpaper element to the preview item
wallpaperItem.appendChild(wallpaperElement);
// Create a banner with the file name
const banner = document.createElement('div');
banner.classList.add('banner');
banner.style.position = 'absolute';
banner.style.bottom = '0';
banner.style.left = '50%';
banner.style.transform = 'translateX(-50%)';
banner.style.width = '100%';
banner.style.height = '40px';
banner.style.background = 'rgba(50, 50, 50, 0.5)';
banner.style.color = 'white';
banner.style.padding = '10px';
banner.style.fontFamily = 'Arial, sans-serif';
banner.style.fontSize = '16px';
banner.style.textAlign = 'center';
banner.style.cursor = 'pointer';
banner.textContent = path.basename(wallpaperFile, path.extname(wallpaperFile));
// Append the banner to the preview item
wallpaperItem.appendChild(banner);
// Create a delete button with a trash icon
const deleteButton = document.createElement('button');
deleteButton.classList.add('delete-wallpaper');
deleteButton.innerHTML = '<i class="fas fa-trash"></i>';
deleteButton.style.position = 'absolute';
deleteButton.style.top = '10px';
deleteButton.style.right = '10px';
deleteButton.style.display = 'none';
// Add an event listener to the delete button
deleteButton.addEventListener('click', (event) => {
event.stopPropagation();
// Confirm deletion
if (confirm(`Are you sure you want to delete ${wallpaperFile}?`)) {
// Delete the wallpaper file
fs.unlinkSync(path.join(wallpaperDir, wallpaperFile));
console.log(`Deleted wallpaper: ${wallpaperFile}`);
// Update the wallpaper list
reloadPage();
}
});
// Add an event listener to the wallpaper item to show the delete button on hover
wallpaperItem.addEventListener('mouseover', () => {
deleteButton.style.display = 'block';
});
wallpaperItem.addEventListener('mouseout', () => {
deleteButton.style.display = 'none';
});
// Append the delete button to the preview item
wallpaperItem.appendChild(deleteButton);
// Append the preview item to the wallpaper container
wallpaperContainer.appendChild(wallpaperItem);
});
} else if (document.getElementById('workshop-wallpaper').classList.contains('active')) {
// Fetch the list of wallpapers from the GitHub raw file
fetch('https://raw.githubusercontent.com/PerrierBouteille/WallifyWorkshop/refs/heads/main/wallpapers.txt')
.then(response => response.text())
.then(data => {
const wallpapers = data.split('\n');
wallpapers.forEach(wallpaperUrl => {
console.log("Loading wallpaper: " + wallpaperUrl);
if (wallpaperUrl == '') return;
// Create a wallpaper item
const wallpaperItem = document.createElement('div');
wallpaperItem.classList.add('wallpaper-item');
// Create an image element for the wallpaper
const img = document.createElement(wallpaperUrl.endsWith('.mp4') ? 'video' : 'img');
img.src = wallpaperUrl.trim();
if (wallpaperUrl.endsWith('.mp4')) {
img.loop = true;
img.autoplay = true;
}
img.style.webkitFilter = 'grayscale(0%)';
wallpaperItem.appendChild(img);
// Create a banner with the file name
const banner = document.createElement('div');
banner.classList.add('banner');
banner.style.position = 'absolute';
banner.style.bottom = '0';
banner.style.left = '50%';
banner.style.transform = 'translateX(-50%)';
banner.style.width = '100%';
banner.style.height = '40px';
banner.style.background = 'rgba(50, 50, 50, 0.5)';
banner.style.color = 'white';
banner.style.padding = '10px';
banner.style.fontFamily = 'Arial, sans-serif';
banner.style.fontSize = '16px';
banner.style.textAlign = 'center';
banner.style.cursor = 'pointer';
banner.textContent = path.basename(wallpaperUrl.trim(), path.extname(wallpaperUrl.trim()));
// Append the banner to the wallpaper item
wallpaperItem.appendChild(banner);
// Add an icon to show what type of wallpaper it is
const icon = document.createElement('div');
icon.classList.add('icon');
icon.style.position = 'absolute';
icon.style.top = '5px';
icon.style.right = '5px';
icon.style.width = '20px';
icon.style.height = '20px';
if (wallpaperUrl.trim().endsWith('.gif')) {
icon.classList.add('fas', 'fa-file-image'); // Font Awesome icon for gif
} else if (wallpaperUrl.trim().endsWith('.mp4')) {
icon.classList.add('fas', 'fa-video'); // Font Awesome icon for video
} else {
icon.classList.add('fas', 'fa-image'); // Font Awesome icon for image
}
wallpaperItem.appendChild(icon);
// Create a download button with a download icon
const downloadButton = document.createElement('button');
downloadButton.classList.add('download-wallpaper');
downloadButton.innerHTML = '<i class="fas fa-download"></i>';
downloadButton.style.position = 'absolute';
downloadButton.style.top = '5px';
downloadButton.style.left = '5px';
downloadButton.style.padding = '7px';
downloadButton.style.display = 'none';
downloadButton.style.cursor = 'pointer';
downloadButton.style.border = '1px solid rgb(50,50,50)';
downloadButton.style.borderRadius = '5px';
downloadButton.style.background = 'rgb(0,250,0)';
downloadButton.addEventListener('click', () => {
downloadButton.style.background = 'rgb(250,0,0)';
// Download the wallpaper
const downloadPath = path.join(os.homedir(), '.config/Wallify/wallpapers', path.basename(new URL(wallpaperUrl.trim()).pathname));
if (!fs.existsSync(downloadPath)) {
const xhr = new XMLHttpRequest();
xhr.open('GET', wallpaperUrl.trim(), true);
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
if (xhr.status === 200) {
const writer = fs.createWriteStream(downloadPath);
writer.write(new Buffer(xhr.response), 'binary');
writer.on('finish', () => {
console.log(`Downloaded wallpaper to: ${downloadPath}`);
});
writer.on('error', (error) => {
console.log(`Error downloading wallpaper: ${error}`);
});
writer.end();
downloadButton.style.background = 'rgb(0,250,0)';
} else {
downloadButton.style.background = 'rgb(0,250,0)';
console.log(`Error fetching wallpaper: ${xhr.statusText} (${xhr.status})`);
}
};
xhr.send();
} else {
console.log(`Wallpaper already downloaded, skipping: ${downloadPath}`);
}
});
wallpaperItem.addEventListener('mouseover', () => {
downloadButton.style.display = 'block';
wallpaperItem.style.boxSizing = 'border-box';
wallpaperItem.style.border = '2px solid #3498db';
});
wallpaperItem.addEventListener('mouseout', () => {
downloadButton.style.display = 'none';
wallpaperItem.style.border = 'none';
});
wallpaperItem.appendChild(downloadButton);
// Append the wallpaper item to the wallpaper container
wallpaperContainer.appendChild(wallpaperItem);
});
})
.catch(error => console.error('Error fetching wallpapers:', error));
}
}
// Get the existing button element
const installButton = document.getElementById('install-new-wallpaper');
installButton.addEventListener('click', () => {
ipcRenderer.send('show-dialog');
});
ipcRenderer.on('dialog-response', (event, filePath) => {
if (filePath) {
const wallpaperName = path.basename(filePath);
// Copy the wallpaper file to the wallpapers directory
fs.copyFileSync(filePath, path.join(wallpaperDir, wallpaperName));
// Update the wallpaper list
reloadPage();
}
});
const navInstalled = document.getElementById('installed-wallpaper');
navInstalled.addEventListener('click', () => {
navInstalled.classList.add('active');
document.getElementById('workshop-wallpaper').classList.remove('active');
reloadPage();
});
const navWorkshop = document.getElementById('workshop-wallpaper');
navWorkshop.addEventListener('click', () => {
navWorkshop.classList.add('active');
document.getElementById('installed-wallpaper').classList.remove('active');
reloadPage();
});
reloadPage();
</script>
</body>
</html>

@ -0,0 +1,202 @@
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
const path = require('path');
const fs = require('fs');
const exec = require('child_process').exec;
const spawn = require('child_process').spawn;
const version = require('./package.json').version;
//TODO: Search for update
const axios = require('axios');
async function getLatestRelease() {
try {
const https = require('https');
return new Promise((resolve, reject) => {
https.get('https://codefirst.iut.uca.fr/git/api/v1/repos/mathis.chirat/Wallify/releases?pre-release=true&limit=1&access_token=043f410b985c5dc4b58f49c80661a4b90afe638b', (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
resolve(JSON.parse(data));
} catch (error) {
reject(error);
}
});
}).on('error', (error) => {
reject(error);
});
});
} catch (error) {
if (error.response && error.response.status === 502) {
console.error('Error fetching JSON data: AxiosError: Request failed with status code 502');
} else {
console.error('Error fetching JSON data:', error);
}
return null;
}
}
getLatestRelease().then(latestRelease => {
if(latestRelease && latestRelease[0].tag_name != version) {
console.log('New version available:', latestRelease[0].tag_name);
console.log('Cuurent version:', version);
dialog.showMessageBox({
type: 'info',
title: 'New version available',
message: 'A new version of Wallify is available. Do you want to download it now?',
buttons: ['Yes', 'No'],
defaultId: 0,
cancelId: 1
}).then(result => {
if (result.response === 0) { // If 'Yes' is clicked
const newAppImagePath = '/home/UCA/machirat1/public/Wallify/Wallify.AppImage';
exec(`cp ${newAppImagePath} ${path.join(__dirname, 'Wallify.AppImage')}`, (error, stdout, stderr) => {
if (error) {
console.error('Error copying the new version:', error);
} else {
console.log('New version copied successfully.');
}
});
}
});
}
}).catch(error => {
console.error('Error fetching JSON data:', error);
});
//Setup Wallify config folder
if(!fs.existsSync(app.getPath('userData'))) {
console.log('Creating user data directory...');
fs.mkdirSync(app.getPath('userData'), { recursive: true }, (err) => {
if (err) {
console.error('Error creating user data directory:', err);
process.exit(1);
}
});
}
// Set wallpaper directory
const wallpaperDir = path.join(app.getPath('userData'), 'wallpapers');
// Create wallpaper directory if it doesn't exist
if (!fs.existsSync(wallpaperDir)) {
console.log('Creating wallpaper directory...');
fs.mkdirSync(wallpaperDir);
}
// Create start.sh file
const startFile = path.join(app.getPath('userData'), 'start.sh');
if (!fs.existsSync(startFile)) {
console.log('Creating start.sh file...');
const user = require('os').userInfo().username;
fs.writeFileSync(startFile, `#!/bin/sh\n\nsleep 2\nWALLPAPER_FILE=\"$(cat /home/UCA/${user}/.config/Wallify/wallpaper.conf`+" | sed 's/WALLPAPER_FILE=//g')\"\n/home/UCA/machirat1/public/WallPaper/wallify -ni -fs -s -sp -st -b -nf -- mpv -wid WID --loop --no-audio ${WALLPAPER_FILE} &", { mode: 0o755 });
exec(`chmod +x ${startFile}`, (error, stdout, stderr) => {
if (error) {
console.error(`Error applying execute permission to start.sh: ${error}`);
}
});
}
// Create autostartup file
const autostartupFile = path.join(app.getPath('home'), '.config', 'autostart', 'wallify.desktop');
if (!fs.existsSync(autostartupFile)) {
console.log('Creating autostartup file...');
const user = require('os').userInfo().username;
fs.writeFileSync(autostartupFile, `[Desktop Entry]
Type=Application
Version=1.0
Name=Wallify
Comment=Wallify
Exec=/home/UCA/${user}/.config/Wallify/start.sh
`, { mode: 0o755 });
}
// Create wallpaper.conf file
const configFile = path.join(app.getPath('userData'), 'wallpaper.conf');
if(!fs.existsSync(configFile)) {
console.log('Creating wallpaper.conf file...');
fs.writeFileSync(configFile, '');
}
// Create main window
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
icon: __dirname + '/Wallify.png'
});
mainWindow.setAutoHideMenuBar(true);
mainWindow.setMenuBarVisibility(false);
//mainWindow.setMenu(null);
mainWindow.loadURL(`file://${__dirname}/index.html`);
// Handle wallpaper apply command
ipcMain.on('apply-wallpaper', (event, wallpaperPath) => {
applyWallpaper(wallpaperPath);
});
// Handle show dialog command
ipcMain.on('show-dialog', (event) => {
dialog.showOpenDialog({
title: 'Select a wallpaper file',
filters: [
{ name: 'Wallpaper files', extensions: ['gif', 'mp4'] }
],
properties: ['openFile']
}).then((result) => {
if (result.filePaths.length > 0) {
event.sender.send('dialog-response', result.filePaths[0]);
} else {
event.sender.send('dialog-response', null);
}
});
});
}
// Apply wallpaper using command
function applyWallpaper(wallpaperPath) {
const command = `gsettings set org.gnome.desktop.background picture-uri 'file://${wallpaperPath}'`;
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`Error applying wallpaper: ${error}`);
} else {
console.log(`Wallpaper applied successfully`);
}
});
}
// Create window on app ready
app.on('ready', createWindow);
// Quit app on window close
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
// Open window on app activate (MacOS)
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});

3876
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,19 @@
{
"name": "Wallify",
"version": "1.0.3",
"description": "Wallpaper manager",
"devDependencies": {
"electron-builder": "^25.1.8"
},
"author": {
"name": "PerrierBottle"
},
"linux": {
"icon": "Wallify.png"
},
"dependencies": {
"axios": "^1.7.7",
"deasync": "^0.1.30",
"https": "^1.0.0"
}
}
Loading…
Cancel
Save