number and stuff
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1 @@
|
|||||||
konachan/
|
Pictures/
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
tags = "catgirl" #separate with +
|
tags = "wedding_dress" #separate with +
|
||||||
rating = "rating%3A" + "safe" #all, safe, questionable, questionableplus, explicit
|
rating = "rating%3A" + "all" #all, safe, questionable, questionableplus, explicit
|
||||||
order = "order%3A" + "date" #date, fav, score, random, wide, nonwide
|
order = "order%3A" + "date" #date, fav, score, random, wide, nonwide
|
||||||
site = "konachan.com" #konachan.com, yande.re, danbooru.donmai.us
|
site = "konachan.com" #konachan.com, yande.re, danbooru.donmai.us
|
||||||
downloadnummer = 1
|
downloadnummer = 1
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
from flask import Flask, render_template
|
from flask import Flask, render_template
|
||||||
import os
|
import os
|
||||||
|
|
||||||
app = Flask(__name__, static_folder='konachan')
|
app = Flask(__name__, static_folder='Pictures')
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def slideshow():
|
def slideshow():
|
||||||
image_folder = 'konachan'
|
image_folder = 'Pictures/lori_bondage'
|
||||||
images = [f'/{image_folder}/{f}' for f in os.listdir(image_folder)
|
images = [f'/{image_folder}/{f}' for f in os.listdir(image_folder)
|
||||||
if f.lower().endswith(('png', 'jpg', 'jpeg', 'gif'))]
|
if f.lower().endswith(('png', 'jpg', 'jpeg', 'gif'))]
|
||||||
return render_template('slideshow.html', images=images)
|
return render_template('slideshow.html', images=images)
|
||||||
|
|||||||
88
get_pics_kona.py
Normal file
88
get_pics_kona.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
import os
|
||||||
|
import requests
|
||||||
|
from tqdm import tqdm
|
||||||
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
|
||||||
|
URL = "https://konachan.com/" #https://e621.net/
|
||||||
|
# === CONFIGURATION ===
|
||||||
|
QUERY = "cleavage barefoot rating:questionableless" # Replace with your search query
|
||||||
|
SAVE_DIR = "semi_safe_cleave"
|
||||||
|
LIMIT = 10000
|
||||||
|
PER_PAGE = 100 # API max is 320, but let's be safe
|
||||||
|
USER_AGENT = "e621-downloader/1.0 (by username on e621)" # Replace 'username' with your e621 username
|
||||||
|
THREADS = 100 # Number of parallel download threads
|
||||||
|
|
||||||
|
# Ensure save directory exists
|
||||||
|
os.makedirs(SAVE_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
headers = {"User-Agent": USER_AGENT}
|
||||||
|
|
||||||
|
all_posts = []
|
||||||
|
current_page = 1
|
||||||
|
total_fetched = 0
|
||||||
|
|
||||||
|
print("Fetching posts in batches...")
|
||||||
|
|
||||||
|
while total_fetched < LIMIT:
|
||||||
|
params = {
|
||||||
|
"tags": QUERY,
|
||||||
|
"limit": PER_PAGE,
|
||||||
|
"page": current_page,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.get(URL + "post.json", headers=headers, params=params)
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
#print(data[0]["tags"])
|
||||||
|
posts = data
|
||||||
|
#posts = data.get("posts", [])
|
||||||
|
if not posts:
|
||||||
|
print(f"No more posts found at page {current_page}.")
|
||||||
|
break
|
||||||
|
|
||||||
|
all_posts.extend(posts)
|
||||||
|
total_fetched += len(posts)
|
||||||
|
|
||||||
|
print(f"Fetched {len(posts)} posts from page {current_page}. Total so far: {total_fetched}.")
|
||||||
|
|
||||||
|
current_page += 1
|
||||||
|
|
||||||
|
# Stop if we fetched fewer than requested in this batch (meaning it's probably the end)
|
||||||
|
if len(posts) < PER_PAGE:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Trim to desired limit, just in case we overfetched
|
||||||
|
all_posts = all_posts[:LIMIT]
|
||||||
|
print(f"Total posts collected for download: {len(all_posts)}")
|
||||||
|
|
||||||
|
|
||||||
|
def download_file(post):
|
||||||
|
#file_url = post.get("file", {}).get("url")
|
||||||
|
file_url = post["file_url"]
|
||||||
|
if not file_url:
|
||||||
|
return f"Skipped: No file URL for post {post.get('id')}"
|
||||||
|
|
||||||
|
#file_name = os.path.basename(file_url)
|
||||||
|
file_name = str(post["id"]) + os.path.splitext(post["file_url"])[1]
|
||||||
|
file_path = os.path.join(SAVE_DIR, file_name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
file_response = requests.get(file_url, headers=headers)
|
||||||
|
file_response.raise_for_status()
|
||||||
|
with open(file_path, "wb") as f:
|
||||||
|
f.write(file_response.content)
|
||||||
|
return f"Downloaded: {file_name}"
|
||||||
|
except Exception as e:
|
||||||
|
return f"Failed: {file_url} with error {e}"
|
||||||
|
|
||||||
|
|
||||||
|
print("Starting download...")
|
||||||
|
|
||||||
|
with ThreadPoolExecutor(max_workers=THREADS) as executor:
|
||||||
|
futures = [executor.submit(download_file, post) for post in all_posts]
|
||||||
|
for future in tqdm(as_completed(futures), total=len(futures), desc="Downloading"):
|
||||||
|
result = future.result()
|
||||||
|
if result.startswith("Failed") or result.startswith("Skipped"):
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
print("Download complete!")
|
||||||
89
get_pics_yan.py
Normal file
89
get_pics_yan.py
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import os
|
||||||
|
import requests
|
||||||
|
from tqdm import tqdm
|
||||||
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
|
||||||
|
URL = "https://yande.re/" #https://e621.net/
|
||||||
|
# === CONFIGURATION ===
|
||||||
|
QUERY = "loli bondage" # Replace with your search query
|
||||||
|
SAVE_DIR = "lori_bondage"
|
||||||
|
LIMIT = 10000
|
||||||
|
PER_PAGE = 100 # API max is 320, but let's be safe
|
||||||
|
USER_AGENT = "e621-downloader/1.0 (by username on e621)" # Replace 'username' with your e621 username
|
||||||
|
THREADS = 100 # Number of parallel download threads
|
||||||
|
|
||||||
|
# Ensure save directory exists
|
||||||
|
os.makedirs(SAVE_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
headers = {"User-Agent": USER_AGENT}
|
||||||
|
|
||||||
|
all_posts = []
|
||||||
|
current_page = 1
|
||||||
|
total_fetched = 0
|
||||||
|
|
||||||
|
print("Fetching posts in batches...")
|
||||||
|
|
||||||
|
while total_fetched < LIMIT:
|
||||||
|
params = {
|
||||||
|
"tags": QUERY,
|
||||||
|
"limit": PER_PAGE,
|
||||||
|
"page": current_page,
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.get(URL + "post.json", headers=headers, params=params)
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
#print(data[0]["tags"])
|
||||||
|
posts = data
|
||||||
|
#print (posts)
|
||||||
|
#posts = data.get("posts", [])
|
||||||
|
if not posts:
|
||||||
|
print(f"No more posts found at page {current_page}.")
|
||||||
|
break
|
||||||
|
|
||||||
|
all_posts.extend(posts)
|
||||||
|
total_fetched += len(posts)
|
||||||
|
|
||||||
|
print(f"Fetched {len(posts)} posts from page {current_page}. Total so far: {total_fetched}.")
|
||||||
|
|
||||||
|
current_page += 1
|
||||||
|
|
||||||
|
# Stop if we fetched fewer than requested in this batch (meaning it's probably the end)
|
||||||
|
if len(posts) < PER_PAGE:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Trim to desired limit, just in case we overfetched
|
||||||
|
all_posts = all_posts[:LIMIT]
|
||||||
|
print(f"Total posts collected for download: {len(all_posts)}")
|
||||||
|
|
||||||
|
|
||||||
|
def download_file(post):
|
||||||
|
#file_url = post.get("file", {}).get("url")
|
||||||
|
file_url = post["file_url"]
|
||||||
|
if not file_url:
|
||||||
|
return f"Skipped: No file URL for post {post.get('id')}"
|
||||||
|
|
||||||
|
#file_name = os.path.basename(file_url)
|
||||||
|
file_name = str(post["id"]) + os.path.splitext(post["file_url"])[1]
|
||||||
|
file_path = os.path.join(SAVE_DIR, file_name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
file_response = requests.get(file_url, headers=headers)
|
||||||
|
file_response.raise_for_status()
|
||||||
|
with open(file_path, "wb") as f:
|
||||||
|
f.write(file_response.content)
|
||||||
|
return f"Downloaded: {file_name}"
|
||||||
|
except Exception as e:
|
||||||
|
return f"Failed: {file_url} with error {e}"
|
||||||
|
|
||||||
|
|
||||||
|
print("Starting download...")
|
||||||
|
|
||||||
|
with ThreadPoolExecutor(max_workers=THREADS) as executor:
|
||||||
|
futures = [executor.submit(download_file, post) for post in all_posts]
|
||||||
|
for future in tqdm(as_completed(futures), total=len(futures), desc="Downloading"):
|
||||||
|
result = future.result()
|
||||||
|
if result.startswith("Failed") or result.startswith("Skipped"):
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
print("Download complete!")
|
||||||
@@ -3,30 +3,65 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Slideshow</title>
|
<title>Slideshow</title>
|
||||||
<style>
|
<style>
|
||||||
body { background: #111; color: #fff; text-align: center; }
|
body { background:#111; color:#fff; text-align:center; }
|
||||||
img { max-width: 90vw; max-height: 90vh; margin-top: 2vh; }
|
img { max-width:90vw; max-height:80vh; margin-top:2vh; }
|
||||||
|
#controls { margin-top:2vh; }
|
||||||
|
button { padding:.6rem 1.1rem; font-size:1rem; margin:.2rem;
|
||||||
|
border:0; border-radius:.4rem; cursor:pointer; }
|
||||||
|
#counter { margin-top: 1vh; font-size: 1.1rem; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Slideshow</h1>
|
<h1>Slideshow</h1>
|
||||||
<img id="slide" src="{{ images[0] }}" />
|
|
||||||
|
<img id="slide" src="{{ images[0] }}"/>
|
||||||
|
|
||||||
|
<div id="controls">
|
||||||
|
<button id="prev">◀︎ Prev</button>
|
||||||
|
<button id="toggle">Pause</button>
|
||||||
|
<button id="next">Next ▶︎</button>
|
||||||
|
<button id="fullscreen">⛶ Fullscreen</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="counter">1 / {{ images|length }}</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const images = {{ images | tojson }};
|
const images = {{ images|tojson }};
|
||||||
const img = document.getElementById('slide');
|
const img = document.getElementById('slide');
|
||||||
let i = 0;
|
const btnT = document.getElementById('toggle');
|
||||||
|
const btnF = document.getElementById('fullscreen');
|
||||||
|
const counter = document.getElementById('counter');
|
||||||
|
let i = 0, playing = true, timer = setInterval(next, 15000);
|
||||||
|
|
||||||
function show(n) { // update helper
|
function show(n) {
|
||||||
i = (n + images.length) % images.length;
|
i = (n + images.length) % images.length;
|
||||||
img.src = images[i];
|
img.src = images[i];
|
||||||
|
counter.textContent = `${i + 1} / ${images.length}`;
|
||||||
}
|
}
|
||||||
|
function next() { show(i + 1); }
|
||||||
|
function prev() { show(i - 1); }
|
||||||
|
|
||||||
// auto-advance every 3000 ms
|
document.getElementById('next').onclick = next;
|
||||||
setInterval(() => show(i + 1), 3000);
|
document.getElementById('prev').onclick = prev;
|
||||||
|
|
||||||
|
btnT.onclick = () => {
|
||||||
|
playing = !playing;
|
||||||
|
btnT.textContent = playing ? 'Pause' : 'Play';
|
||||||
|
if (playing) timer = setInterval(next, 15000);
|
||||||
|
else clearInterval(timer);
|
||||||
|
};
|
||||||
|
|
||||||
|
btnF.onclick = () => {
|
||||||
|
if (!document.fullscreenElement) {
|
||||||
|
document.documentElement.requestFullscreen();
|
||||||
|
} else {
|
||||||
|
document.exitFullscreen();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// keyboard control
|
|
||||||
document.addEventListener('keydown', e => {
|
document.addEventListener('keydown', e => {
|
||||||
if (e.key === 'ArrowRight') show(i + 1); // next
|
if (e.key === 'ArrowRight') next();
|
||||||
if (e.key === 'ArrowLeft') show(i - 1); // previous
|
if (e.key === 'ArrowLeft') prev();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
BIN
test/347822.jpg
Normal file
BIN
test/347822.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 925 KiB |
Reference in New Issue
Block a user