nadimkobeissi / mkbsd

Download all the wallpapers in MKBHD's "Panels" app
Do What The F*ck You Want To Public License
2.43k stars 180 forks source link

[JS] A little modification to download all avaliable formats and also sort into folders. Also updated to ES6 imports #46

Open inuzen opened 16 hours ago

inuzen commented 16 hours ago

Basically title. In this version i first get the list of content from 'https://storage.googleapis.com/panels-api/data/20240916/content-1a'; And then use HD download key to get the item from data link. This allows to create folders with pictures names and download all avaliable formats for each picture from data url. It will download like

Note: also used axios but you can replace it with fetch easily (i just had it installed already)

Code:

import axios from 'axios';
import { join, normalize } from 'path';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import fs from 'fs';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// URLs
const CONTENT_URL =
  'https://storage.googleapis.com/panels-api/data/20240916/content-1a';
const MEDIA_URL =
  'https://storage.googleapis.com/panels-api/data/20240916/media-1a-i-p~uhd';

// Create "downloads" folder if it doesn't exist
const downloadDir = join(__dirname, 'downloads');
if (!fs.existsSync(downloadDir)) {
  fs.mkdirSync(downloadDir);
}

const downloadImage = async (url, filePath) => {
  try {
    const response = await axios({
      url,
      method: 'GET',
      responseType: 'stream',
    });
    const writer = fs.createWriteStream(filePath);
    response.data.pipe(writer);

    return new Promise((resolve, reject) => {
      writer.on('finish', resolve);
      writer.on('error', reject);
    });
  } catch (error) {
    console.error(`Failed to download image from ${url}`, error);
  }
};

const downloadWallpapers = async () => {
  try {
    const contentResponse = await axios.get(CONTENT_URL);
    const mediaResponse = await axios.get(MEDIA_URL);
    const wallpapers = contentResponse.data.wallpapers;

    for (const wallpaper of wallpapers) {
      const label = wallpaper.label.replace(/[/\\?%*:|"<>]/g, '-'); // Sanitize folder name
      const folderPath = join(downloadDir, label);
      const dlKey = wallpaper?.dlm?.hd;
      if (!fs.existsSync(folderPath)) {
        fs.mkdirSync(folderPath);
      }

      const mediaData = mediaResponse.data.data?.[dlKey] || {};

      for (const key in mediaData) {
        const downloadLink = mediaData[key];
        const imageFileName = `${label}-${key}.jpg`;
        const filePath = join(folderPath, imageFileName);

        await downloadImage(downloadLink, filePath);
        console.log(`Downloaded ${imageFileName} to ${filePath}`);
      }
      return;
    }
  } catch (error) {
    console.error('Error downloading wallpapers:', error);
  }
};

downloadWallpapers();
faithfulojebiyi commented 4 hours ago

?did you test you PR at all?