File size: 5,744 Bytes
64b5d29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import PyPDF2 # PDF dosyalarını okumak için
from pathlib import Path
from datetime import datetime
import logging
import re # Tarih ayrıştırma için Regular Expressions

# Mevcut modüldeki storage fonksiyonlarını içe aktar (aynı klasörde olduğu için .)
from .storage import add_document, load_dataframe, save_dataframe, DOC_COLUMNS

# Ham veri klasörünün yolu
RAW_DATA_PATH = Path("data/raw")

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def extract_text_from_pdf(pdf_path: Path) -> str | None:
    """

    Verilen PDF dosyasının metin içeriğini çıkarır.



    Args:

        pdf_path (Path): PDF dosyasının yolu.



    Returns:

        str | None: Çıkarılan metin veya hata durumunda None.

    """
    try:
        with open(pdf_path, 'rb') as file:
            reader = PyPDF2.PdfReader(file)
            text = ""
            for page in reader.pages:
                page_text = page.extract_text()
                if page_text:
                    text += page_text + "\n" # Sayfalar arasına yeni satır ekle
            logging.info(f"Metin çıkarıldı: {pdf_path.name}")
            return text
    except Exception as e:
        logging.error(f"PDF metni çıkarılırken hata ({pdf_path.name}): {e}")
        # Şifreli PDF'ler veya bozuk dosyalar PyPDF2 tarafından hata verebilir
        if "password" in str(e).lower():
             logging.warning(f"Dosya şifreli olabilir: {pdf_path.name}")
        return None

def parse_date_from_filename(filename: str) -> datetime | None:
    """

    Dosya adından YYYY-MM-DD veya YYYYMMDD formatında tarih ayrıştırmaya çalışır.



    Args:

        filename (str): Dosya adı.



    Returns:

        datetime | None: Bulunan tarih veya None.

    """
    # Örnek: 2023-10-26_paper.pdf, 20231026-paper.pdf, 2023_10_26 paper.pdf
    patterns = [
        r"(\d{4}-\d{2}-\d{2})", # YYYY-MM-DD
        r"(\d{4}_\d{2}_\d{2})", # YYYY_MM_DD
        r"(\d{8})"             # YYYYMMDD
    ]
    for pattern in patterns:
        match = re.search(pattern, filename)
        if match:
            date_str = match.group(1).replace("_", "-") # Alt çizgiyi tireye çevir
            try:
                # Sadece tarih kısmını al, saat bilgisi ekleme
                return datetime.strptime(date_str, '%Y-%m-%d').date()
            except ValueError:
                continue # Geçersiz tarih formatı varsa diğer deseni dene
    logging.warning(f"Dosya adından geçerli tarih ayrıştırılamadı: {filename}")
    return None

def process_raw_documents():
    """

    'data/raw/' klasöründeki tüm PDF dosyalarını işler,

    tarihlerini ayrıştırır ve sisteme ekler (eğer zaten ekli değillerse).

    """
    if not RAW_DATA_PATH.exists():
        logging.error(f"Ham veri klasörü bulunamadı: {RAW_DATA_PATH}")
        return

    logging.info(f"'{RAW_DATA_PATH}' klasöründeki PDF dosyaları işleniyor...")
    processed_count = 0
    added_count = 0

    # Tüm PDF dosyalarını bul
    pdf_files = list(RAW_DATA_PATH.glob('*.pdf'))

    if not pdf_files:
        logging.warning(f"'{RAW_DATA_PATH}' klasöründe işlenecek PDF dosyası bulunamadı.")
        return

    for pdf_path in pdf_files:
        processed_count += 1
        filename = pdf_path.name
        filepath_str = str(pdf_path.resolve()) # Tam dosya yolunu al

        # Dosya adından tarihi ayrıştır
        publication_date = parse_date_from_filename(filename)

        if publication_date:
            # Dokümanı sisteme ekle (storage modülünü kullanarak)
            # add_document, zaten varsa None yerine mevcut ID'yi döndürecek şekilde güncellendi
            doc_id = add_document(filepath_str, publication_date)
            if doc_id:
                 # Eğer yeni eklendiyse (veya mevcut ID döndüyse), sayacı artırabiliriz
                 # Şimdilik sadece eklenip eklenmediğini kontrol etmek yeterli
                 # Gerçek ekleme 'add_document' içinde loglanıyor
                 pass # Şimdilik ek bir işlem yapmıyoruz

        else:
            logging.warning(f"'{filename}' için yayın tarihi bulunamadı, doküman eklenemedi.")

    logging.info(f"Toplam {processed_count} PDF dosyası tarandı.")
    # Gerçekte kaç tane yeni eklendiği bilgisini storage loglarından takip edebiliriz.

# --- Metin Çıkarma ve Kaydetme (Sonraki Fazlar İçin Hazırlık) ---
# İleride bu fonksiyonu çağırıp metinleri ayrı dosyalara kaydedebiliriz
# ve documents_df'i güncelleyebiliriz.
#
# def extract_and_save_text(doc_id: str, pdf_path: Path):
#    text = extract_text_from_pdf(pdf_path)
#    if text:
#        # Metni kaydet (örn: data/processed_data/text/{doc_id}.txt)
#        text_path = DATA_PATH / "text" / f"{doc_id}.txt"
#        text_path.parent.mkdir(parents=True, exist_ok=True)
#        try:
#            with open(text_path, 'w', encoding='utf-8') as f:
#                f.write(text)
#            logging.info(f"Metin '{text_path}' olarak kaydedildi.")
#            # documents_df'i güncelle (status='text_extracted', processed_text_path=str(text_path))
#            docs_df = load_dataframe('documents', DOC_COLUMNS)
#            doc_index = docs_df[docs_df['doc_id'] == doc_id].index
#            if not doc_index.empty:
#                docs_df.loc[doc_index, 'status'] = 'text_extracted'
#                docs_df.loc[doc_index, 'processed_text_path'] = str(text_path)
#                save_dataframe(docs_df, 'documents')
#        except Exception as e:
#            logging.error(f"Metin kaydedilirken hata ({doc_id}): {e}")