research paper renamer
2025-05-07 06:58 Note Type: completed Tags: python, research-papers, productivity
import os
import subprocess
import re
import google.generativeai as genai
from pdf2image import convert_from_path
import pytesseract
๐ Load Gemini API key from env var
genai.configure(api_key="AIzaSyAj8iiaCcSYEMAVhB_E2se14P2WR9eNkP0")
โก๏ธ Use the faster Gemini 2.0 Flash model
model = genai.GenerativeModel("gemini-2.0-flash")
def extract_text_with_fallback(pdf_path, max_chars=3000):
"""Try pdftotext first; fallback to OCR if the result looks empty or unhelpful."""
try:
result = subprocess.run(
['pdftotext', pdf_path, '-'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True
)
text = result.stdout.decode('utf-8').strip()
๐ก Check if the text looks real (not boilerplate or junk)
if len(text) >= 100 and "All Rights Reserved" not in text:
return text[:max_chars]
else:
print(f"โ ๏ธ pdftotext returned low-value text, falling back to OCR for: {os.path.basename(pdf_path)}")
except Exception as e:
print(f"โ pdftotext failed: {e}")
Fallback to OCR
try:
images = convert_from_path(pdf_path, dpi=400, first_page=1, last_page=3)
text = ""
for i, img in enumerate(images):
ocr_text = pytesseract.image_to_string(img, lang="eng")
print(f"--- OCR Page {i+1} ---\n{ocr_text[:300]}\n")
text += ocr_text
if len(text) > max_chars:
break
return text.strip()[:max_chars]
except Exception as e:
print(f"โ OCR failed for {pdf_path}: {e}")
return ""
def ask_gpt_to_name(text):
"""Send PDF text to Gemini and return a filename."""
prompt = f"""
Extract the following from the academic paper text below:
The full title of the paper
The last names of all authors (in order)
The year of publication
Then return a filename in the format:
{{Paper title in sentence case}} - {{Author1, Author2, ..., AuthorN}} - {{Year}}.pdf
Rules:
Authors must be comma-separated
Use ' - ' as the separator
Only return the filename. No commentary, no quotes.
Remove double quotes ' " ' if present in title
In case the paper has both a title and subtitle, in place of {{Paper title in sentence case}}, use {{Paper title in sentence case}} - {{Paper subtitle in sentence case}}, using ' - ' as the separator
TEXT:
{text}
"""
try:
response = model.generate_content(prompt)
filename = response.text.strip()
filename = re.sub(r'[\/*?:"<>|]', '', filename) # Clean illegal filename chars
return filename
except Exception as e:
print(f"โ Gemini API error: {e}")
return None
def rename_pdfs(folder_path):
"""Rename PDFs in folder based on AI-generated filename."""
for file in os.listdir(folder_path):
if file.lower().endswith(".pdf"):
full_path = os.path.join(folder_path, file)
print(f"๐ Processing: {file}")
text = extract_text_with_fallback(full_path)
if not text:
print(f"โ ๏ธ Skipping (no extractable text): {file}")
continue
new_name = ask_gpt_to_name(text)
if new_name:
new_path = os.path.join(folder_path, new_name)
try:
os.rename(full_path, new_path)
print(f"โ Renamed: {file} โ {new_name}")
except Exception as e:
print(f"โ Failed to rename {file}: {e}")
else:
print(f"โ ๏ธ Skipping (Gemini failed): {file}")
๐ Entry point
if name == "main":
import sys
if len(sys.argv) < 2:
print("Usage: python3 rename_with_gemini_ocr.py /path/to/pdf/folder")
sys.exit(1)
folder = sys.argv[1]
rename_pdfs(folder)