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

37
Paste ID
b915d916d6533d30
Oluşturan
anonim
Oluşturulma
08 Dec 2025, 19:44
Süre Sonu
Süresiz
Boyut
20.98 KB