cWriter BETA
import json
import os
import sqlite3
import tkinter as tk
import webbrowser
from datetime import datetime
from tkinter import messagebox, scrolledtext
# --- GLOBAL SABİTLER ---
DESTEKLENEN_DİLLER = ["Türkçe", "İngilizce", "İspanyolca", "Almanca", "Fransızca",
"Rusça", "Arapça", "Çince", "Japonca", "İtalyanca"]
# --- VERİ YÖNETİMİ SINIFI (SQLITE ENTEGRASYONU) ---
class NotYoneticisi:
def __init__(self, db_adi):
self.db_adi = db_adi
self.conn = sqlite3.connect(db_adi)
self.cursor = self.conn.cursor()
self._veritabani_olustur()
self.ai_aktif = False
def _veritabani_olustur(self):
"""Notlar tablosunu oluşturur ve uzun metin (LONG-FORM) desteği sağlar."""
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS notlar (
id INTEGER PRIMARY KEY,
eklenme_tarihi TEXT,
anahtar TEXT NOT NULL,
icerik TEXT NOT NULL,
link TEXT,
foto_yolu TEXT
)
''')
self.conn.commit()
def notlari_yukle(self):
"""Tüm notları veritabanından yükler."""
self.cursor.execute("SELECT id, eklenme_tarihi, anahtar, icerik, link, foto_yolu FROM notlar ORDER BY id DESC")
# Sütun isimlerini de alarak sözlük listesi döndürür
kolonlar = [aciklama[0] for aciklama in self.cursor.description]
return [dict(zip(kolonlar, satir)) for satir in self.cursor.fetchall()]
def not_ekle(self, anahtar, icerik, link="", foto_yolu=""):
tarih = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
self.cursor.execute(
"INSERT INTO notlar (eklenme_tarihi, anahtar, icerik, link, foto_yolu) VALUES (?, ?, ?, ?, ?)",
(tarih, anahtar, icerik, link, foto_yolu)
)
self.conn.commit()
def akilli_ara(self, arama_terimi):
"""SQL LIKE komutu ile hızlı ve kapsamlı arama yapar."""
arama_terimi = f'%{arama_terimi.strip()}%'
self.cursor.execute(
"SELECT id, eklenme_tarihi, anahtar, icerik, link, foto_yolu FROM notlar WHERE anahtar LIKE ? OR icerik LIKE ?",
(arama_terimi, arama_terimi)
)
kolonlar = [aciklama[0] for aciklama in self.cursor.description]
return [dict(zip(kolonlar, satir)) for satir in self.cursor.fetchall()]
def not_sil(self, silinecek_id):
self.cursor.execute("DELETE FROM notlar WHERE id = ?", (silinecek_id,))
if self.cursor.rowcount > 0:
self.conn.commit()
return True
return False
def istatistik_al(self):
"""Toplam kelime sayısını ve not sayısını döndürür (GAMIFICATION)."""
self.cursor.execute("SELECT COUNT(*) FROM notlar")
toplam_not = self.cursor.fetchone()[0]
self.cursor.execute("SELECT SUM(LENGTH(icerik)) FROM notlar")
toplam_karakter = self.cursor.fetchone()[0] or 0
# Basit kelime sayısı tahmini (kelime = karakter/5)
tahmini_kelime = int(toplam_karakter / 5)
return {
"toplam_not": toplam_not,
"toplam_kelime": tahmini_kelime,
"ort_kelime_not": tahmini_kelime / toplam_not if toplam_not > 0 else 0
}
def baglantiyi_kapat(self):
"""Uygulama kapatılırken bağlantıyı kapatır."""
self.conn.close()
# --- YAPAY ZEKA HİZMETLERİ SINIFI (YER TUTUCU) ---
class AIHizmetleri:
"""Dilbilgisi, stil analizi, çeviri ve yeniden yazma gibi AI destekli hizmetlerin yer tutucusu."""
def __init__(self, not_icerigi):
self.icerik = not_icerigi
def dil_bilgisi_ve_stil_kontrolu(self):
if len(self.icerik) < 30:
return "**DURUM:** Metin çok kısa. Kapsamlı analiz için daha uzun metin girin."
dil_listesi = ", ".join(DESTEKLENEN_DİLLER)
return (
f"**DİL BİLGİSİ SONUCU (Simülasyon):**\n"
f"✅ Yazım ve noktalama kontrolü yapıldı.\n"
f"🌐 Desteklenen Diller: {dil_listesi}\n\n"
f"🧠 Stil Önerisi: İlk paragrafı daha akıcı hale getirmek için 'akıcılaştırma' aracını kullanın.\n"
f"🎯 Ton Önerisi: Metninizin tonu hedef kitleniz için uygundur."
)
def yeniden_yaz(self):
return "**YENİDEN YAZILMIŞ METİN (Simülasyon):**\n" \
"Metniniz, anlam bütünlüğü korunarak daha özgün bir ifadeyle yeniden oluşturuldu. " \
"Bu özellik, İntihalden Kaçınma ve Akıcılık artırma için idealdir. (*Harici API anahtarı gereklidir*)"
# --- YENİ NOT EKLEME PENCERESİ ---
class AddNoteWindow(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.master = master
self.title("Yeni Not Ekle")
self.geometry("450x480")
self.resizable(False, False)
self.create_widgets()
def create_widgets(self):
tk.Label(self, text="1. Konu Başlığı/Anahtar:").pack(pady=5)
self.anahtar_entry = tk.Entry(self, width=50)
self.anahtar_entry.pack(pady=5)
tk.Label(self, text="2. Detaylı Not/İçerik: (Biçimlendirme için: **koyu**, __alticizgi__)").pack(pady=5)
self.icerik_text = tk.Text(self, width=50, height=7)
self.icerik_text.pack(pady=5)
tk.Label(self, text="3. İlgili Link (URL):").pack(pady=5)
self.link_entry = tk.Entry(self, width=50)
self.link_entry.pack(pady=5)
tk.Label(self, text="4. Fotoğraf Dosya Yolu:").pack(pady=5)
self.foto_entry = tk.Entry(self, width=50)
self.foto_entry.pack(pady=5)
tk.Button(self, text="Kaydet ve Kapat", command=self.kaydet_ve_kapat, bg="green", fg="white").pack(pady=15)
def kaydet_ve_kapat(self):
anahtar = self.anahtar_entry.get().strip()
icerik = self.icerik_text.get(1.0, tk.END).strip()
link = self.link_entry.get().strip()
foto_yolu = self.foto_entry.get().strip()
if anahtar and icerik:
self.master.yonetici.not_ekle(anahtar, icerik, link, foto_yolu)
messagebox.showinfo("Başarılı", f"'{anahtar}' başarıyla kaydedildi.")
self.master.istatistikleri_guncelle() # İstatistikleri güncelle
self.master.tum_notlari_goster()
self.destroy()
else:
messagebox.showwarning("Uyarı", "Lütfen hem Başlık hem de İçerik girin.")
# --- YAZI ANALİZİ PENCERESİ ---
class AnalysisWindow(tk.Toplevel):
def __init__(self, master):
super().__init__(master)
self.master = master
self.title("Kapsamlı Yazı Analizi ve Düzeltme")
self.geometry("700x550")
dil_listesi_str = ", ".join(DESTEKLENEN_DİLLER)
tk.Label(self, text=f"**10 Dil Desteği Aktif:** {dil_listesi_str}", fg="purple", wraplength=680).pack(pady=5)
tk.Label(self, text="Analiz edilecek metni girin veya notlardan kopyalayın:").pack(pady=5)
self.input_text = scrolledtext.ScrolledText(self, width=80, height=10, wrap=tk.WORD)
self.input_text.pack(pady=5, padx=10)
button_frame = tk.Frame(self)
button_frame.pack(pady=10)
tk.Button(button_frame, text="✅ Stil/Dil Bilgisi Kontrolü", command=self.kontrol_yap, bg="lightblue").pack(side=tk.LEFT, padx=10)
tk.Button(button_frame, text="🔄 Metni Yeniden Yaz", command=self.yeniden_yaz, bg="orange").pack(side=tk.LEFT, padx=10)
tk.Button(button_frame, text="🚫 İntihal Tespiti (API Gerekir)", state=tk.DISABLED, bg="lightcoral").pack(side=tk.LEFT, padx=10)
tk.Button(button_frame, text="🇹🇷 Çoklu Dil (API Gerekir)", state=tk.DISABLED, bg="lightcoral").pack(side=tk.LEFT, padx=10)
tk.Button(button_frame, text="📐 Anlam Bütünlüğü (API Gerekir)", state=tk.DISABLED, bg="lightcoral").pack(side=tk.LEFT, padx=10)
tk.Label(self, text="Analiz Sonucu:").pack(pady=5)
self.result_text = scrolledtext.ScrolledText(self, width=80, height=12, wrap=tk.WORD)
self.result_text.pack(pady=5, padx=10)
def kontrol_yap(self):
icerik = self.input_text.get(1.0, tk.END).strip()
if not icerik:
self.result_text.delete(1.0, tk.END)
self.result_text.insert(tk.END, "Lütfen analiz etmek istediğiniz metni girin.")
return
ai_servis = AIHizmetleri(icerik)
sonuc = ai_servis.dil_bilgisi_ve_stil_kontrolu()
self.result_text.delete(1.0, tk.END)
self.result_text.insert(tk.END, sonuc)
self.result_text.insert(tk.END, "\n\n*** AI ANALİZİ İÇİN API KEY GEREKLİDİR. Bu sonuç simülasyondur. ***")
def yeniden_yaz(self):
icerik = self.input_text.get(1.0, tk.END).strip()
if not icerik:
self.result_text.delete(1.0, tk.END)
self.result_text.insert(tk.END, "Lütfen yeniden yazmak istediğiniz metni girin.")
return
ai_servis = AIHizmetleri(icerik)
sonuc = ai_servis.yeniden_yaz()
self.result_text.delete(1.0, tk.END)
self.result_text.insert(tk.END, sonuc)
self.result_text.insert(tk.END, "\n\n*** YENİDEN YAZMA İÇİN API KEY GEREKLİDİR. Bu sonuç simülasyondur. ***")
# --- ANA UYGULAMA SINIFI ---
class Uygulama(tk.Tk):
def __init__(self, yonetici):
super().__init__()
self.yonetici = yonetici
self.title(f"cWriter | ULTRA MEGA Sürüm | Veritabanı: {self.yonetici.db_adi}")
self.geometry("1100x700")
self.protocol("WM_DELETE_WINDOW", self.on_kapat)
self.create_widgets()
self.tum_notlari_goster()
def create_widgets(self):
# Sol Taraf: İstatistiksel Gösterge Tablosu (Dashboard)
dashboard_frame = tk.Frame(self, width=200, bg="#f0f0f0", padx=10, pady=10)
dashboard_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(10, 0), pady=10)
tk.Label(dashboard_frame, text="📈 cWriter ANALİZ", font=("Arial", 12, "bold"), bg="#f0f0f0").pack(pady=10)
self.stats_not = tk.Label(dashboard_frame, text="Toplam Not: 0", bg="#f0f0f0", anchor="w")
self.stats_not.pack(fill=tk.X, pady=5)
self.stats_kelime = tk.Label(dashboard_frame, text="Tahmini Kelime: 0", bg="#f0f0f0", anchor="w")
self.stats_kelime.pack(fill=tk.X, pady=5)
self.stats_ort = tk.Label(dashboard_frame, text="Ort. Not Uzunluğu: 0", bg="#f0f0f0", anchor="w")
self.stats_ort.pack(fill=tk.X, pady=5)
tk.Button(dashboard_frame, text="✨ İstatistikleri Güncelle", command=self.istatistikleri_guncelle, bg="#98FB98").pack(pady=15)
# Sağ Taraf: Ana Çalışma Alanı
main_frame = tk.Frame(self, padx=10, pady=10)
main_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
# 1. Kontrol Çerçevesi (Üst Kısım)
control_frame = tk.Frame(main_frame)
control_frame.pack(side=tk.TOP, fill=tk.X)
tk.Label(control_frame, text=self.yonetici.db_adi, fg="blue").pack(side=tk.LEFT, padx=5)
tk.Button(control_frame, text="YENİ NOT EKLE", command=self.yeni_not_ac, bg="green", fg="white").pack(side=tk.LEFT, padx=10)
self.arama_entry = tk.Entry(control_frame, width=20)
self.arama_entry.pack(side=tk.LEFT, padx=5)
tk.Button(control_frame, text="AKILLI ARA", command=self.arama_yap).pack(side=tk.LEFT, padx=5)
tk.Button(control_frame, text="✍️ Yazı Analizi Yap", command=self.yazi_analizi_penceresi, bg="#FFD700").pack(side=tk.LEFT, padx=10)
tk.Button(control_frame, text="🌍 Paylaş (Gerekiyor!)", command=self.online_paylas, bg="#008CBA", fg="white").pack(side=tk.LEFT, padx=5)
tk.Button(control_frame, text="TÜMÜNÜ GÖSTER", command=self.tum_notlari_goster).pack(side=tk.RIGHT, padx=5)
# 2. Sonuç Alanı
self.sonuc_text = scrolledtext.ScrolledText(main_frame, wrap=tk.WORD, width=100, height=30, font=("Arial", 10))
self.sonuc_text.pack(expand=True, fill=tk.BOTH, padx=10, pady=(10, 0))
self.sonuc_text.tag_config('id', foreground='red')
self.sonuc_text.tag_config('tarih', foreground='gray')
self.sonuc_text.tag_config('anahtar', foreground='purple', font=("Arial", 10, "bold"))
self.sonuc_text.tag_config('link', foreground='blue', underline=1)
self.sonuc_text.tag_config('foto', foreground='orange')
self.sonuc_text.tag_config('koyu', font=("Arial", 10, "bold"))
self.sonuc_text.tag_config('alticizgi', underline=1)
# 3. serDRA Etiketi (Köşe)
serdra_label = tk.Label(main_frame, text="serDRA", font=("Arial", 8, "italic"), fg="darkgrey")
serdra_label.pack(side=tk.BOTTOM, anchor=tk.SE, padx=10, pady=5)
self.istatistikleri_guncelle()
def istatistikleri_guncelle(self):
istatistikler = self.yonetici.istatistik_al()
self.stats_not.config(text=f"Toplam Not: {istatistikler['toplam_not']}")
self.stats_kelime.config(text=f"Tahmini Kelime: {istatistikler['toplam_kelime']:,}")
self.stats_ort.config(text=f"Ort. Kelime/Not: {int(istatistikler['ort_kelime_not'])}")
def parse_and_insert_content(self, raw_text):
kalan_metin = raw_text
while kalan_metin:
bold_start = kalan_metin.find('**')
underline_start = kalan_metin.find('__')
if bold_start == -1 and underline_start == -1:
self.sonuc_text.insert(tk.END, kalan_metin)
break
start_index = -1
marker = ""
tag_name = ""
if bold_start != -1 and (bold_start < underline_start or underline_start == -1):
marker = '**'
start_index = bold_start
tag_name = 'koyu'
elif underline_start != -1:
marker = '__'
start_index = underline_start
tag_name = 'alticizgi'
else:
self.sonuc_text.insert(tk.END, kalan_metin)
break
if start_index > 0:
self.sonuc_text.insert(tk.END, kalan_metin[:start_index])
end_marker_index = kalan_metin.find(marker, start_index + len(marker))
if end_marker_index != -1:
formatted_text = kalan_metin[start_index + len(marker):end_marker_index]
self.sonuc_text.insert(tk.END, formatted_text, tag_name)
kalan_metin = kalan_metin[end_marker_index + len(marker):]
else:
self.sonuc_text.insert(tk.END, kalan_metin[start_index:])
break
self.sonuc_text.insert(tk.END, "\n")
def notu_arayuze_ekle(self, n):
self.sonuc_text.insert(tk.END, f"ID: {n['id']} | ", 'id')
self.sonuc_text.insert(tk.END, f"Eklenme: {n['eklenme_tarihi']}\n", 'tarih')
self.sonuc_text.insert(tk.END, f"🔑 Anahtar: {n['anahtar']}\n", 'anahtar')
self.sonuc_text.insert(tk.END, f"💬 İçerik: ")
self.parse_and_insert_content(n['icerik'])
if n.get('link'):
link_url = n['link']
self.sonuc_text.window_create(tk.END, window=tk.Button(self.sonuc_text, text="🔗 Linke Git",
command=lambda url=link_url: webbrowser.open_new_tab(url),
fg="blue", relief=tk.FLAT))
self.sonuc_text.insert(tk.END, f" ({link_url})\n", 'link')
if n.get('foto_yolu'):
foto_yolu = n['foto_yolu']
self.sonuc_text.insert(tk.END, f"🖼️ Fotoğraf Yolu: {foto_yolu}\n", 'foto')
self.sonuc_text.window_create(tk.END, window=tk.Button(self.sonuc_text, text="🔍 Fotoğrafı Aç",
command=lambda yol=foto_yolu: os.startfile(yol) if os.name == 'nt' else webbrowser.open('file://' + os.path.abspath(yol)),
fg="orange", relief=tk.FLAT))
self.sonuc_text.insert(tk.END, "\n")
self.sonuc_text.window_create(tk.END, window=tk.Button(self.sonuc_text, text="🗑️ Sil",
command=lambda id=n['id']: self.not_sil(id),
fg="red", relief=tk.FLAT))
self.sonuc_text.insert(tk.END, "\n--------------------------------------------------\n\n")
def tum_notlari_goster(self):
self.sonuc_text.delete(1.0, tk.END)
notlar = self.yonetici.notlari_yukle()
if not notlar:
self.sonuc_text.insert(tk.END, "📝 Hafızada kayıtlı hiçbir not yok.\n")
return
self.sonuc_text.insert(tk.END, f"--- Tüm Kayıtlı Notlar ({len(notlar)} adet) ---\n\n", 'anahtar')
for n in notlar:
self.notu_arayuze_ekle(n)
def arama_yap(self):
arama_terimi = self.arama_entry.get()
bulunanlar = self.yonetici.akilli_ara(arama_terimi)
self.sonuc_text.delete(1.0, tk.END)
if bulunanlar:
self.sonuc_text.insert(tk.END, f"--- 🔎 '{arama_terimi}' İçeren Bilgiler ({len(bulunanlar)} adet) ---\n\n", 'anahtar')
for n in bulunanlar:
self.notu_arayuze_ekle(n)
else:
self.sonuc_text.insert(tk.END, f"🤔 '{arama_terimi}' terimiyle eşleşen hiçbir bilgi bulunamadı.\n")
def not_sil(self, id_numarasi):
cevap = messagebox.askyesno("Not Silme Onayı", f"ID {id_numarasi} numaralı notu silmek istediğinizden emin misiniz?")
if cevap:
if self.yonetici.not_sil(id_numarasi):
messagebox.showinfo("Başarılı", f"ID {id_numarasi} numaralı not başarıyla silindi.")
self.istatistikleri_guncelle() # İstatistikleri güncelle
self.tum_notlari_goster()
else:
messagebox.showerror("Hata", f"ID {id_numarasi} numaralı not bulunamadı.")
def yeni_not_ac(self):
AddNoteWindow(self)
def web_arama(self):
terim = self.arama_entry.get().strip() or "Arama Terimi"
webbrowser.open_new_tab(f"https://www.google.com/search?q={terim}")
def web_cevir(self):
webbrowser.open_new_tab("https://translate.google.com/")
def yazi_analizi_penceresi(self):
AnalysisWindow(self)
def online_paylas(self):
messagebox.showwarning("Çevrimiçi Paylaşım ve Entegrasyon",
"Bu özellik, bir sunucu (backend) ve veritabanı kurulumu gerektirir. "
"Mevcut yerel yapıda aktif edilemez.")
def on_kapat(self):
print("👋 Ultra Mega cWriter kapatılıyor...")
self.yonetici.baglantiyi_kapat() # SQLite bağlantısını kapat
self.destroy()
# --- BAŞLANGIÇ ---
if __name__ == "__main__":
try:
final_db_adi = "cwriter_ultramega.db"
yonetici = NotYoneticisi(final_db_adi)
app = Uygulama(yonetici)
app.mainloop()
except Exception as e:
print(f"Uygulama başlatılırken kritik bir hata oluştu: {e}")
Paste Bilgileri
37Paste ID
b915d916d6533d30
Oluşturan
anonim
Oluşturulma
08 Dec 2025, 19:44
Süre Sonu
Süresiz
Boyut
20.98 KB