Spaces:
Sleeping
Sleeping
| """ | |
| Kutuphane veritabani katmani (SQLite). | |
| - Kitap envanteri, odunc kayitlari. | |
| - Hem okuma (arama, listeleme) hem yazma (odunc, iade) fonksiyonlari. | |
| Tum tool fonksiyonlari bu katmani kullanir; boylece cevaplar daima gercek | |
| veriye dayanir (halusinasyon engellenir). | |
| """ | |
| import sqlite3 | |
| import os | |
| from datetime import datetime, timedelta | |
| DB_PATH = os.environ.get("KUTUPHANE_DB", "kutuphane.db") | |
| ODUNC_GUN = 14 # odunc suresi: 2 hafta | |
| def _conn(): | |
| conn = sqlite3.connect(DB_PATH) | |
| conn.row_factory = sqlite3.Row | |
| return conn | |
| def init_db(seed=True): | |
| """Tablolari olusturur ve (bosssa) ornek kitaplarla doldurur.""" | |
| conn = _conn() | |
| c = conn.cursor() | |
| c.execute(""" | |
| CREATE TABLE IF NOT EXISTS kitaplar ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| baslik TEXT NOT NULL, | |
| yazar TEXT NOT NULL, | |
| tur TEXT NOT NULL, | |
| sayfa INTEGER, | |
| koken TEXT, -- 'yerli' / 'yabanci' | |
| durum TEXT DEFAULT 'bosta', -- 'bosta' / 'oduncte' | |
| odunc_alan TEXT, -- okuyucu adi (oduncteyse) | |
| odunc_tarih TEXT, -- odunc alinma tarihi (ISO) | |
| teslim_tarih TEXT -- en gec teslim tarihi (ISO) | |
| ) | |
| """) | |
| c.execute(""" | |
| CREATE TABLE IF NOT EXISTS gecmis ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| kitap_id INTEGER, | |
| okuyucu TEXT, | |
| odunc_tarih TEXT, | |
| iade_tarih TEXT, | |
| durum_notu TEXT -- 'erken', 'zamaninda', 'gec' | |
| ) | |
| """) | |
| conn.commit() | |
| if seed: | |
| c.execute("SELECT COUNT(*) AS n FROM kitaplar") | |
| if c.fetchone()["n"] == 0: | |
| for k in ORNEK_KITAPLAR: | |
| c.execute( | |
| "INSERT INTO kitaplar (baslik,yazar,tur,sayfa,koken,durum) VALUES (?,?,?,?,?,?)", | |
| (k[0], k[1], k[2], k[3], k[4], "bosta"), | |
| ) | |
| conn.commit() | |
| conn.close() | |
| # (baslik, yazar, tur, sayfa, koken) | |
| ORNEK_KITAPLAR = [ | |
| # Yerli roman / edebiyat (+ 1 tarih) | |
| ("Kürk Mantolu Madonna", "Sabahattin Ali", "roman", 160, "yerli"), | |
| ("Şu Çılgın Türkler", "Turgut Özakman", "tarih", 720, "yerli"), | |
| ("Benim Adım Kırmızı", "Orhan Pamuk", "roman", 472, "yerli"), | |
| ("Tutunamayanlar", "Oğuz Atay", "roman", 724, "yerli"), | |
| ("İnce Memed", "Yaşar Kemal", "roman", 456, "yerli"), | |
| ("Çalıkuşu", "Reşat Nuri Güntekin", "roman", 408, "yerli"), | |
| ("Aşk", "Elif Şafak", "roman", 420, "yerli"), | |
| ("Serenad", "Zülfü Livaneli", "roman", 480, "yerli"), | |
| ("Cinai Meseleler", "Ahmet Ümit", "polisiye", 336, "yerli"), | |
| ("Beyoğlu Rapsodisi", "Ahmet Ümit", "polisiye", 400, "yerli"), | |
| ("İstanbul Hatırası", "Ahmet Ümit", "polisiye", 528, "yerli"), | |
| ("Sis ve Gece", "Ahmet Ümit", "polisiye", 320, "yerli"), | |
| ("Şeytan Ayrıntıda Gizlidir", "Ahmet Ümit", "polisiye", 280, "yerli"), | |
| # Yabanci polisiye | |
| ("Cinayet Alfabesi", "Agatha Christie", "polisiye", 256, "yabanci"), | |
| ("Doğu Ekspresinde Cinayet", "Agatha Christie", "polisiye", 288, "yabanci"), | |
| ("On Küçük Zenci", "Agatha Christie", "polisiye", 264, "yabanci"), | |
| ("Sherlock Holmes: Kızıl Dosya", "Arthur Conan Doyle", "polisiye", 224, "yabanci"), | |
| ("Baskerville'lerin Köpeği", "Arthur Conan Doyle", "polisiye", 256, "yabanci"), | |
| ("Ejderha Dövmeli Kız", "Stieg Larsson", "polisiye", 640, "yabanci"), | |
| ("Gone Girl", "Gillian Flynn", "polisiye", 512, "yabanci"), | |
| # Bilim kurgu | |
| ("Dune", "Frank Herbert", "bilim kurgu", 688, "yabanci"), | |
| ("1984", "George Orwell", "bilim kurgu", 352, "yabanci"), | |
| ("Fahrenheit 451", "Ray Bradbury", "bilim kurgu", 256, "yabanci"), | |
| ("Ben, Robot", "Isaac Asimov", "bilim kurgu", 320, "yabanci"), | |
| ("Vakıf", "Isaac Asimov", "bilim kurgu", 296, "yabanci"), | |
| ("Cesur Yeni Dünya", "Aldous Huxley", "bilim kurgu", 288, "yabanci"), | |
| ("Marslı", "Andy Weir", "bilim kurgu", 448, "yabanci"), | |
| # Klasik | |
| ("Suç ve Ceza", "Dostoyevski", "klasik", 687, "yabanci"), | |
| ("Karamazov Kardeşler", "Dostoyevski", "klasik", 1024, "yabanci"), | |
| ("Sefiller", "Victor Hugo", "klasik", 1463, "yabanci"), | |
| ("Savaş ve Barış", "Tolstoy", "klasik", 1392, "yabanci"), | |
| ("Anna Karenina", "Tolstoy", "klasik", 864, "yabanci"), | |
| ("Bülbülü Öldürmek", "Harper Lee", "klasik", 384, "yabanci"), | |
| ("Gurur ve Önyargı", "Jane Austen", "klasik", 432, "yabanci"), | |
| ("Sineklerin Tanrısı", "William Golding", "klasik", 256, "yabanci"), | |
| # Cocuk / genclik | |
| ("Şeker Portakalı", "José Mauro de Vasconcelos", "çocuk", 182, "yabanci"), | |
| ("Küçük Prens", "Antoine de Saint-Exupéry", "çocuk", 96, "yabanci"), | |
| ("Momo", "Michael Ende", "çocuk", 288, "yabanci"), | |
| ("Bitmeyen Öykü", "Michael Ende", "çocuk", 448, "yabanci"), | |
| ("Charlie'nin Çikolata Fabrikası", "Roald Dahl", "çocuk", 192, "yabanci"), | |
| ("Matilda", "Roald Dahl", "çocuk", 240, "yabanci"), | |
| ("Pal Sokağı Çocukları", "Ferenc Molnár", "çocuk", 224, "yabanci"), | |
| # Kisisel gelisim / bilim | |
| ("Sapiens", "Yuval Noah Harari", "bilim", 512, "yabanci"), | |
| ("Homo Deus", "Yuval Noah Harari", "bilim", 496, "yabanci"), | |
| ("Kozmos", "Carl Sagan", "bilim", 432, "yabanci"), | |
| ("Zamanın Kısa Tarihi", "Stephen Hawking", "bilim", 256, "yabanci"), | |
| ("Hayvanlardan Tanrılara", "Yuval Noah Harari", "bilim", 512, "yabanci"), | |
| # Fantastik | |
| ("Yüzüklerin Efendisi", "J.R.R. Tolkien", "fantastik", 1178, "yabanci"), | |
| ("Hobbit", "J.R.R. Tolkien", "fantastik", 320, "yabanci"), | |
| ("Harry Potter ve Felsefe Taşı", "J.K. Rowling", "fantastik", 276, "yabanci"), | |
| ("Buz ve Ateşin Şarkısı", "George R.R. Martin", "fantastik", 704, "yabanci"), | |
| ] | |
| # ---------- OKUMA ---------- | |
| def kitap_ara_db(sorgu): | |
| """Baslik ya da yazarda gecen kelimeye gore kitaplari arar.""" | |
| conn = _conn() | |
| like = f"%{sorgu.strip()}%" | |
| rows = conn.execute( | |
| "SELECT * FROM kitaplar WHERE baslik LIKE ? OR yazar LIKE ? ORDER BY baslik", | |
| (like, like), | |
| ).fetchall() | |
| conn.close() | |
| return [dict(r) for r in rows] | |
| def kitap_getir(kitap_id): | |
| conn = _conn() | |
| r = conn.execute("SELECT * FROM kitaplar WHERE id=?", (kitap_id,)).fetchone() | |
| conn.close() | |
| return dict(r) if r else None | |
| def oneri_db(tur=None, koken=None, max_sayfa=None, min_sayfa=None, sadece_bosta=True): | |
| """Turku ve filtrelere gore DB'den kitap onerir.""" | |
| conn = _conn() | |
| q = "SELECT * FROM kitaplar WHERE 1=1" | |
| p = [] | |
| if tur: | |
| q += " AND tur LIKE ?"; p.append(f"%{tur.strip()}%") | |
| if koken: | |
| q += " AND koken = ?"; p.append(koken.strip().lower()) | |
| if max_sayfa: | |
| q += " AND sayfa <= ?"; p.append(int(max_sayfa)) | |
| if min_sayfa: | |
| q += " AND sayfa >= ?"; p.append(int(min_sayfa)) | |
| if sadece_bosta: | |
| q += " AND durum = 'bosta'" | |
| q += " ORDER BY sayfa" | |
| rows = conn.execute(q, p).fetchall() | |
| conn.close() | |
| return [dict(r) for r in rows] | |
| # ---------- YAZMA ---------- | |
| def odunc_al_db(kitap_id, okuyucu): | |
| """Kitabi odunc verir: durumu gunceller, 2 hafta teslim tarihi yazar.""" | |
| conn = _conn() | |
| r = conn.execute("SELECT * FROM kitaplar WHERE id=?", (kitap_id,)).fetchone() | |
| if not r: | |
| conn.close(); return {"ok": False, "hata": "Kitap bulunamadi."} | |
| if r["durum"] == "oduncte": | |
| conn.close(); return {"ok": False, "hata": "Kitap su an oduncte.", | |
| "teslim_tarih": r["teslim_tarih"]} | |
| bugun = datetime.now() | |
| teslim = bugun + timedelta(days=ODUNC_GUN) | |
| conn.execute( | |
| "UPDATE kitaplar SET durum='oduncte', odunc_alan=?, odunc_tarih=?, teslim_tarih=? WHERE id=?", | |
| (okuyucu, bugun.date().isoformat(), teslim.date().isoformat(), kitap_id), | |
| ) | |
| conn.commit(); conn.close() | |
| return {"ok": True, "teslim_tarih": teslim.date().isoformat(), | |
| "odunc_tarih": bugun.date().isoformat()} | |
| def iade_et_db(kitap_id): | |
| """Kitabi iade alir: erken/zamaninda/gec notu duser, bosa cikarir.""" | |
| conn = _conn() | |
| r = conn.execute("SELECT * FROM kitaplar WHERE id=?", (kitap_id,)).fetchone() | |
| if not r: | |
| conn.close(); return {"ok": False, "hata": "Kitap bulunamadi."} | |
| if r["durum"] != "oduncte": | |
| conn.close(); return {"ok": False, "hata": "Bu kitap zaten kutuphanede (bosta)."} | |
| bugun = datetime.now().date() | |
| teslim = datetime.fromisoformat(r["teslim_tarih"]).date() if r["teslim_tarih"] else bugun | |
| if bugun < teslim: | |
| notu = "erken" | |
| elif bugun == teslim: | |
| notu = "zamaninda" | |
| else: | |
| notu = "gec" | |
| conn.execute( | |
| "INSERT INTO gecmis (kitap_id, okuyucu, odunc_tarih, iade_tarih, durum_notu) VALUES (?,?,?,?,?)", | |
| (kitap_id, r["odunc_alan"], r["odunc_tarih"], bugun.isoformat(), notu), | |
| ) | |
| conn.execute( | |
| "UPDATE kitaplar SET durum='bosta', odunc_alan=NULL, odunc_tarih=NULL, teslim_tarih=NULL WHERE id=?", | |
| (kitap_id,), | |
| ) | |
| conn.commit(); conn.close() | |
| gun_farki = (teslim - bugun).days | |
| return {"ok": True, "durum_notu": notu, "teslim_tarih": teslim.isoformat(), | |
| "gun_farki": gun_farki} | |
| if __name__ == "__main__": | |
| init_db() | |
| print("DB hazir. Toplam kitap:", len(kitap_ara_db(""))) | |