!/usr/bin/env python3
— coding: utf-8 —
import os, time, random, yaml, requests, re
from io import BytesIO
from datetime import datetime
from PIL import Image, ImageEnhance, ImageDraw, ImageFont
from bs4 import BeautifulSoup
from ddgs import DDGS
import unicodedata
import xmlrpc.client
try:
import pytumblr2 as pytumblr
except ImportError:
import pytumblr
from requests_oauthlib import OAuth1Session
—————– Yardımcı Fonksiyonlar —————–
def load_yaml(path, default=None):
if not os.path.exists(path):
return default or {}
with open(path, “r”, encoding=”utf-8″) as f:
return yaml.safe_load(f) or (default or {})
def save_yaml(path, data):
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, “w”, encoding=”utf-8″) as f:
yaml.safe_dump(data, f, allow_unicode=True, sort_keys=False)
def ensure_tokens(yaml_path):
if os.path.exists(yaml_path):
with open(yaml_path, “r”, encoding=”utf-8″) as f:
return yaml.safe_load(f)
print(“Tumblr OAuth kurulumu başlatılıyor.”)
consumer_key = input(“Consumer key: “).strip()
consumer_secret = input(“Consumer secret: “).strip()
request_token_url = “http://www.tumblr.com/oauth/request_token”
authorize_url = “http://www.tumblr.com/oauth/authorize”
access_token_url = “http://www.tumblr.com/oauth/access_token”
oauth = OAuth1Session(consumer_key, client_secret=consumer_secret)
fetch_response = oauth.fetch_request_token(request_token_url)
resource_owner_key = fetch_response.get(“oauth_token”)
resource_owner_secret = fetch_response.get(“oauth_token_secret”)
full_authorize_url = oauth.authorization_url(authorize_url)
print(“\nİzin ver ve geri dönüş URL’sini yapıştır:\n{}”.format(full_authorize_url))
redirect_response = input(“Tam geri dönüş URL’si: “).strip()
oauth_response = oauth.parse_authorization_response(redirect_response)
verifier = oauth_response.get(“oauth_verifier”)
oauth = OAuth1Session(
consumer_key,
client_secret=consumer_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret,
verifier=verifier
)
oauth_tokens = oauth.fetch_access_token(access_token_url)
tokens = {
“consumer_key”: consumer_key,
“consumer_secret”: consumer_secret,
“oauth_token”: oauth_tokens.get(“oauth_token”),
“oauth_token_secret”: oauth_tokens.get(“oauth_token_secret”)
}
save_yaml(yaml_path, tokens)
return tokens
def build_client(tokens):
return pytumblr.TumblrRestClient(
tokens[“consumer_key”],
tokens[“consumer_secret”],
tokens[“oauth_token”],
tokens[“oauth_token_secret”]
)
—————– Metin Normalizasyonu —————–
def normalize_text(text):
mapping = str.maketrans(“çğıöşüÇĞİÖŞÜ”, “cgiosuCGIOSU”)
text = text.translate(mapping)
text = unicodedata.normalize(“NFKD”, text).encode(“ascii”, “ignore”).decode(“ascii”)
return text
—————– Görsel İşleme —————–
def add_text_to_image(img, text, font_size=28):
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype(“arial.ttf”, font_size)
except IOError:
font = ImageFont.load_default()
color = “red”
img_width, img_height = img.size
text_bbox = draw.textbbox((0, 0), text, font=font)
text_width = text_bbox[2] – text_bbox[0]
text_height = text_bbox[3] – text_bbox[1]
positions = [
(10, img_height – text_height – 10),
(img_width – text_width – 10, img_height – text_height – 10)
]
position = random.choice(positions)
draw.text(position, text, font=font, fill=color)
return img
def enhance_image(img):
brightness_factor = random.uniform(1.05, 1.15)
sharpness_factor = random.uniform(1.05, 1.15)
img = ImageEnhance.Brightness(img).enhance(brightness_factor)
img = ImageEnhance.Sharpness(img).enhance(sharpness_factor)
return img
—————– Resim Arama —————–
def search_images(search_term, count=1):
urls = []
try:
with DDGS() as ddgs:
results = list(ddgs.images(query=search_term, safesearch=’Off’, max_results=15))
urls = [r[‘image’] for r in results if r.get(‘image’)]
except Exception as e:
print(f”[DDGS Hata] {e}”)
if not urls:
print(f”[INFO] DDGS sonuç vermedi, Unsplash fallback deneyelim…”)
try:
access_key = “YOUR_UNSPLASH_ACCESS_KEY” # Unsplash API key
r = requests.get(f”https://api.unsplash.com/photos/random?query={search_term}&count={count}&client_id={access_key}”)
if r.status_code == 200:
data = r.json()
urls = [d[“urls”][“regular”] for d in data]
except Exception as e:
print(f”[Unsplash Hata] {e}”)
if not urls:
print(f”[INFO] Tüm aramalarda sonuç bulunamadı: {search_term}”)
return []
return random.sample(urls, min(count, len(urls)))
def download_image(url, watermark):
headers = {‘User-Agent’: ‘Mozilla/5.0’}
try:
r = requests.get(url, timeout=20, headers=headers)
if r.status_code == 200 and “image” in r.headers.get(“Content-Type”, “”).lower():
img = Image.open(BytesIO(r.content)).convert(“RGB”)
img = enhance_image(add_text_to_image(img, watermark))
path = f”temp_{random.randint(1000,9999)}.jpg”
img.save(path, “JPEG”)
return path
except Exception as e:
print(f”[Resim İndirme Hata] {e}”)
return None
—————– İçerik Alma —————–
def get_first_post(site):
feed_url = f”https://{site}/feed/”
try:
r = requests.get(feed_url, timeout=20, headers={“User-Agent”: “Mozilla/5.0”})
if r.status_code == 200:
soup = BeautifulSoup(r.text, “xml”)
item = soup.find(“item”)
if item:
title = item.find(“title”).text.strip()
link = item.find(“link”).text.strip()
return title, link
except Exception as e:
print(f”{site} feed okunamadı: {e}”)
try:
url = f”https://{site}/”
r = requests.get(url, timeout=20, headers={“User-Agent”: “Mozilla/5.0”})
soup = BeautifulSoup(r.text, “html.parser”)
first_link = soup.find(“a”, href=True)
if first_link and first_link.text.strip():
title = re.sub(r”<.?>“, “”, first_link.text).strip()
link = first_link[“href”]
if not link.startswith(“http”):
link = url.rstrip(“/”) + “/” + link.lstrip(“/”)
return title, link
except Exception as e:
print(f”{site} içerik alınamadı: {e}”)
return None, None
—————– Ping —————–
PING_URLS = [
“http://pingoat.com/goat/RPC2”,
“http://ping.blo.gs/”,
“http://blog.with2.net/ping.php”,
“http://rpc.pingomatic.com”
]
def ping_sites(url):
for s in PING_URLS:
try:
if s.endswith(“.php”) or “RPC2” in s:
proxy = xmlrpc.client.ServerProxy(s)
proxy.weblogUpdates.ping(“Tumblr Bot”, url)
print(f”[PING-XMLRPC] Başarılı: {s}”)
else:
requests.get(s, params={“ping”: url}, timeout=10)
print(f”[PING-HTTP] Başarılı: {s}”)
except Exception as e:
print(f”[PING-HATA] {s}: {e}”)
time.sleep(2)
—————– Tumblr Etiket —————–
TAG_POOL = [
“amor”,”photooftheday”,”f”,”beautiful”,”photo”,”pinterest”,”frases”,”amore”,”vintage”,”frasiamore”,”tiktok”,
“frasibelle”,”model”,”followme”,”followforfollowback”,”aforismi”,”frasiitaliane”,”twitter”,”style”,”aesthetics”,
“music”,”fotografia”,”pensieri”,”likeforlike”,”tumblrphoto”,”makeup”,”alternative”,”funny”,”o”,”edits”,
“tumblr”,”aesthetic”,”love”,”like”,”tumblrgirl”,”instagram”,”follow”,”instagood”,”photography”,”frasi”,
“art”,”frasitumblr”,”grunge”,”fashion”,”sad”,”tumblrboy”,”quotes”,”likeforlikes”,”explore”,”s”,”memes”,
“tumblraesthetic”,”cute”,”explorepage”,”citazioni”,”meme”,”girl”,”likes”,”tumblrpost”,”l”
]
def random_tags(extra=None):
n = random.randint(2,5)
chosen = random.sample(TAG_POOL, n)
if extra:
chosen.append(extra)
return chosen
—————– Ana Program —————–
def main():
token_path = os.path.expanduser(“~/.pytumblr”)
tokens = ensure_tokens(token_path)
client = build_client(tokens)
info = client.info()
blogs = [b[“name”] for b in info[“user”][“blogs”] if “name” in b]
if not blogs:
print(“Blog yok.”)
return
print(f”Bloglar: {blogs}”)
yesil_file = r”C:\Users\Kullanıcı\Desktop\kuzen\tumblr\yesil.txt”
sites = [s.strip() for s in open(yesil_file, “r”, encoding=”utf-8″) if s.strip()]
blog_index = 0
while True:
for site in sites:
print(f”\n— {site} işleniyor —“)
title, link = get_first_post(site)
if not title or not link:
continue
clean_title = title.strip()
query = normalize_text(clean_title)
domain = site.split(“.”)[0]
img_path = None
urls = search_images(query, count=3)
if urls:
print(f”[RESİM BULUNDU] URL: {urls[0]}”)
img_path = download_image(urls[0], domain)
else:
print(f”[RESİM BULUNAMADI] {clean_title}”)
blog = blogs[blog_index % len(blogs)]
blog_index += 1
tags = random_tags(domain)
try:
if img_path:
resp = client.create_photo(blog,
state=”published”,
caption=f”{clean_title}\n{link}”,
tags=tags,
data=[img_path])
os.remove(img_path)
print(f”[OK] {blog} → Resimli post: {clean_title} | Etiketler: {tags}”)
else:
resp = client.create_text(blog,
state=”published”,
title=clean_title,
body=f”{clean_title}
{link}”,
tags=tags)
print(f”[OK] {blog} → Resimsiz post: {clean_title} | Etiketler: {tags}”)
post_id = resp.get(“id”) if isinstance(resp, dict) else None
tumblr_url = f”https://{blog}.tumblr.com/post/{post_id or ‘UNKNOWN’}”
ping_sites(tumblr_url)
except Exception as e:
print(f”[HATA] {blog}: {e}”)
time.sleep(50)
if __name__ == “__main__”:
main()