mirror of
https://github.com/nadimkobeissi/mkbsd.git
synced 2025-06-08 17:06:13 +00:00
Merge 0749148a7d
into 82e50c64f0
This commit is contained in:
commit
b3dcf41c94
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
.DS_Store
|
||||
downloads
|
||||
MKBSD/target
|
||||
|
|
1349
MKBSD/Cargo.lock
generated
Normal file
1349
MKBSD/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
12
MKBSD/Cargo.toml
Normal file
12
MKBSD/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "MKBSD"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
reqwest = { version = "0.12.7", features = ["json", "blocking"] }
|
||||
tokio = { version = "1.40", features = ["full"] }
|
||||
url = "2.5.2"
|
||||
serde = { version = "1.0.210", features = ["derive"] }
|
||||
serde_json = "1.0.128"
|
||||
futures = "0.3.30"
|
124
MKBSD/src/main.rs
Normal file
124
MKBSD/src/main.rs
Normal file
|
@ -0,0 +1,124 @@
|
|||
// Licensed under the WTFPL License
|
||||
|
||||
use futures::future::join_all;
|
||||
use reqwest::Client;
|
||||
use serde_json::Value;
|
||||
use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
use url::Url;
|
||||
|
||||
const URL: &str = "https://storage.googleapis.com/panels-api/data/20240916/media-1a-i-p~s";
|
||||
const DOWNLOAD_DIR: &str = "downloads";
|
||||
|
||||
async fn download_image(
|
||||
client: &Client,
|
||||
image_url: &str,
|
||||
file_path: &Path,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let response = client.get(image_url).send().await?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(format!("Failed to download image: {}", response.status()).into());
|
||||
}
|
||||
|
||||
let content = response.bytes().await?;
|
||||
let mut file = File::create(file_path)?;
|
||||
file.write_all(&content)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn main_task() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let client = Client::new();
|
||||
|
||||
// Fetch the JSON data
|
||||
let response = client.get(URL).send().await?;
|
||||
if !response.status().is_success() {
|
||||
return Err(format!("⛔ Failed to fetch JSON file: {}", response.status()).into());
|
||||
}
|
||||
|
||||
let json_data: Value = response.json().await?;
|
||||
let data = json_data
|
||||
.get("data")
|
||||
.ok_or("⛔ JSON does not have a 'data' property at its root.")?;
|
||||
|
||||
// Create download directory if it doesn't exist
|
||||
let download_dir = Path::new(DOWNLOAD_DIR);
|
||||
if !download_dir.exists() {
|
||||
fs::create_dir_all(download_dir)?;
|
||||
println!("📁 Created directory: {:?}", download_dir);
|
||||
}
|
||||
|
||||
let mut file_index = 1;
|
||||
let mut download_tasks = vec![];
|
||||
|
||||
for (_key, subproperty) in data.as_object().unwrap().iter() {
|
||||
if let Some(subproperty) = subproperty.as_object() {
|
||||
if let Some(image_url) = subproperty.get("dhd").and_then(|v| v.as_str()) {
|
||||
println!("🔍 Found image URL!");
|
||||
|
||||
// Parse URL to get the file extension
|
||||
let parsed_url = Url::parse(image_url)?;
|
||||
let ext = Path::new(parsed_url.path())
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.unwrap_or("jpg");
|
||||
|
||||
let filename = format!("{}.{ext}", file_index);
|
||||
let file_path = download_dir.join(filename);
|
||||
|
||||
let client_clone = client.clone();
|
||||
let image_url_clone = image_url.to_string();
|
||||
let file_path_clone = file_path.clone();
|
||||
|
||||
// Spawn a new task for each download
|
||||
let download_task = tokio::spawn(async move {
|
||||
if let Err(e) =
|
||||
download_image(&client_clone, &image_url_clone, &file_path_clone).await
|
||||
{
|
||||
eprintln!("Error downloading {}: {}", image_url_clone, e);
|
||||
} else {
|
||||
println!("🖼️ Saved image to {:?}", file_path_clone);
|
||||
}
|
||||
});
|
||||
|
||||
download_tasks.push(download_task);
|
||||
file_index += 1;
|
||||
sleep(Duration::from_millis(250)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for all download tasks to complete
|
||||
join_all(download_tasks).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ascii_art() {
|
||||
println!(
|
||||
r#"
|
||||
/$$ /$$ /$$ /$$ /$$$$$$$ /$$$$$$ /$$$$$$$
|
||||
| $$$ /$$$| $$ /$$/| $$__ $$ /$$__ $$| $$__ $$
|
||||
| $$$$ /$$$$| $$ /$$/ | $$ \ $$| $$ \__/| $$ \ $$
|
||||
| $$ $$/$$ $$| $$$$$/ | $$$$$$$ | $$$$$$ | $$ | $$
|
||||
| $$ $$$| $$| $$ $$ | $$__ $$ \____ $$| $$ | $$
|
||||
| $$\ $ | $$| $$\ $$ | $$ \ $$ /$$ \ $$| $$ | $$
|
||||
| $$ \/ | $$| $$ \ $$| $$$$$$$/| $$$$$$/| $$$$$$$/
|
||||
|__/ |__/|__/ \__/|_______/ \______/ |_______/
|
||||
"#
|
||||
);
|
||||
println!("🤑 Starting downloads from your favorite sellout grifter's wallpaper app...");
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
ascii_art();
|
||||
sleep(Duration::from_secs(5)).await;
|
||||
if let Err(e) = main_task().await {
|
||||
eprintln!("Error: {}", e);
|
||||
}
|
||||
}
|
90
README.md
90
README.md
|
@ -13,7 +13,7 @@ _Because selling out is bad_
|
|||
|
||||
## How to use
|
||||
|
||||
MKBSD comes in two variants! Node.js and Python.
|
||||
MKBSD comes in three variants! Node.js, Python, and Rust.
|
||||
|
||||
### Running in Node.js
|
||||
|
||||
|
@ -30,38 +30,80 @@ MKBSD comes in two variants! Node.js and Python.
|
|||
4. Wait a little.
|
||||
5. All wallpapers are now in a newly created `downloads` subfolder.
|
||||
|
||||
## FAQ
|
||||
### Running in Rust
|
||||
|
||||
### Q: What's the story behind this?
|
||||
1. **Install Rust and Cargo**
|
||||
- If you haven't already, install Rust and Cargo by following the instructions at [rustup.rs](https://rustup.rs/).
|
||||
|
||||
On September 24th, 2024, well-known tech YouTuber MKBHD released Panels, a wallpaper app that:
|
||||
2. **Navigate to the Rust Implementation Directory**
|
||||
- Open your terminal or command prompt.
|
||||
- Navigate to the directory containing the Rust implementation.
|
||||
```bash
|
||||
cd MKBSD
|
||||
```
|
||||
|
||||
- Had insanely invasive, unjustified tracking including for location history and search history.
|
||||
- Charged artists a predatory 50% commission (even Apple takes only 30% for app purchases).
|
||||
- Forced you to watch two ads for every wallpaper that you wanted to download, and then only letting you download it in SD.
|
||||
- Gatekept all HD wallpapers behind a **fifty dollars a year subscription**.
|
||||
- Had many wallpapers that were essentially AI-generated slop or badly edited stock photos.
|
||||
3. **Build the Project**
|
||||
- Run the following command to build the project in release mode:
|
||||
|
||||
Especially given MKBHD's previous criticism of substandard companies and products, people justifiably got upset given that this looked like a pretty blatant grift and cash-grab that is exploitative of the fan base that's trusted his editorial integrity over the past fifteen years. However, on the same day, MKBHD wrote a post doubling down on the app.
|
||||
```bash
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
### Q: Aren't you stealing from artists by running this script?
|
||||
- This will create an optimized executable in the `target/release` directory.
|
||||
|
||||
MKBSD accesses publicly available media through the Panels app's own API. It doesn't do anything shady or illegal. The real problem here is Panels and MKBHD's complete inability to provide a secure platform for the artists that they're ~~exploiting~~ working with. Any other app could have avoided the issues that make MKBSD possible had it been engineered competently.
|
||||
4. **Run the Executable**
|
||||
- After building, run the executable:
|
||||
|
||||
## License
|
||||
- On Linux/macOS:
|
||||
|
||||
```
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
```bash
|
||||
./target/release/mkbsd
|
||||
```
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
- On Windows:
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
```bash
|
||||
.\target\release\mkbsd.exe
|
||||
```
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
5. **Wait for the Process to Complete**
|
||||
- The program will start downloading wallpapers. Wait until it finishes.
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
```
|
||||
6. **Find Your Wallpapers**
|
||||
- All wallpapers are now in a newly created `downloads` subfolder.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Q: What's the story behind this?
|
||||
|
||||
On September 24th, 2024, well-known tech YouTuber MKBHD released Panels, a wallpaper app that:
|
||||
|
||||
- Had insanely invasive, unjustified tracking including for location history and search history.
|
||||
- Charged artists a predatory 50% commission (even Apple takes only 30% for app purchases).
|
||||
- Forced you to watch two ads for every wallpaper that you wanted to download, and then only letting you download it in SD.
|
||||
- Gatekept all HD wallpapers behind a **fifty dollars a year subscription**.
|
||||
- Had many wallpapers that were essentially AI-generated slop or badly edited stock photos.
|
||||
|
||||
Especially given MKBHD's previous criticism of substandard companies and products, people justifiably got upset given that this looked like a pretty blatant grift and cash-grab that is exploitative of the fan base that's trusted his editorial integrity over the past fifteen years. However, on the same day, MKBHD wrote a post doubling down on the app.
|
||||
|
||||
### Q: Aren't you stealing from artists by running this script?
|
||||
|
||||
MKBSD accesses publicly available media through the Panels app's own API. It doesn't do anything shady or illegal. The real problem here is Panels and MKBHD's complete inability to provide a secure platform for the artists that they're ~~exploiting~~ working with. Any other app could have avoided the issues that make MKBSD possible had it been engineered competently.
|
||||
|
||||
## License
|
||||
|
||||
```
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue