frendyrachman's picture
Update app.py
c0dfddb verified
raw
history blame
8.36 kB
import os
from pdf2image import convert_from_path
from datetime import date
from PIL import Image
import gradio as gr
from google import genai
import zipfile
import tempfile
os.system("apt-get install poppler-utils")
import datetime
from docx import Document
# Function to process a list of PDF files and convert them to images
def process_pdfs(pdf_files):
"""
Process a list of PDF files, convert each to images, and return all images.
"""
all_images = []
for pdf_file in pdf_files:
if not os.path.isfile(pdf_file):
raise ValueError(f"File {pdf_file} does not exist.")
images = convert_from_path(pdf_file, dpi=200) # Convert PDF pages to images
all_images.extend(images)
return all_images
# Function to analyze the extracted image using Google GenAI
def gemini_analysis(images, tanggal_berangkat, tanggal_pulang):
"""
Analyze the extracted image using Google GenAI.
"""
# Initialize the GenAI client (make sure the API key is set properly)
today = date.today()
client = genai.Client(api_key=os.getenv("GOOGLE_API_KEY"))
# Define your prompt
prompt = f'''Anda bertugas memvalidasi kesesuaian dan konsistensi data dari dokumen individual berdasarkan syarat Visa di bawah. Cukup fokus pada syarat yang diberikan tanpa mengambil referensi lain.
Gunakan tanggal hari ini ({today}) sebagai tanggal pemeriksaan visa (bukan pengajuan). Gunakan {tanggal_berangkat} sebagai tanggal berangkat, dan {tanggal_pulang} sebagai tanggal kepulangan.
Pastikan data seperti nama, tanggal, tujuan dan lainnya sama/konsisten antar dokumen. Di akhir, berikan kesimpulan dari pemeriksaan dokumen. Jika ada yang kurang lengkap atau tidak valid, berikan pesan pemberitahuan untuk pemilik data tersebut terkait data yang kurang atau tidak sesuai.
---
DAFTAR SYARAT DOKUMEN YANG WAJIB DIPERIKSA:
1. Paspor
Asli, aktif min. 6 bulan setelah tanggal kepulangan
Ada tanda tangan pemilik
Lampirkan paspor lama jika ada visa perjalanan sebelumnya
Copy paspor sponsor jika disponsori
2. Fotokopi Paspor
Halaman depan & tanda tangan
Semua visa perjalanan sebelumnya jika ada (terutama 5 tahun terakhir)
Jika tidak ada, cukup beritahu bahwa Fotokopi Paspor belum ada.
3. Pas Foto
Ukuran kurang lebih 3.5 x 4.5 cm, background putih
Wajah terlihat 80%, alis tidak tertutup, tidak pakai softlens, tidak berbayang
4. Kartu Keluarga (KK)
Minimal versi 2019 atau berbarcode
Harus sesuai status (nikah/cerai/anak-anak β†’ lampirkan dokumen pendukung)
Harus ditranslate untuk VFS Germany
5. Akte Nikah/Bukti nikah
Halaman biodata suami dan istri saja
Jika istri ikut, wajib melampirkan surat izin suami
6. KTP
Nama harus sama dengan paspor dan tercantum pada Kartu Keluarga (KK)
Jika nama berbeda maka wajib lampirkan surat beda nama
7. Akta Kelahiran / Surat Kelahiran / Ijazah
Wajib jika anak-anak atau peserta disponsori oranglain
8. Surat Sponsor (Guarantee Letter)
Dalam Bahasa Inggris
Tujuan negara, tanggal trip
Siapa yang menanggung biaya
Wajib ada tertulis menjamin akan kembali ke Indonesia
9. Status Pekerjaan
Pegawai: Surat kerja + Slip gaji 3 bulan
Pemilik usaha: NIB/SIUP + Surat jaminan staf
Pelajar: Surat sekolah/universitas + kartu pelajar
Freelancer/onlineshop: Kontrak kerja & 5 bukti transaksi
Pensiun: Surat pensiun + guarantee dari keluarga
10. Rekening Koran (3 bulan)
Atas nama pribadi & sponsor
Cap & logo bank, nama, nomor rekening
Saldo stabil min. Rp 35 juta/orang
11. Slip Gaji
3 bulan terakhir
Jika suami lengkap β†’ istri cukup lampirkan rekening koran suami
---
FORMAT JAWABAN UNTUK SETIAP DOKUMEN YANG DIUPLOAD:
- Jenis Dokumen : (jenis dokumen)
- Status : (Valid / Perlu cek ulang / Tidak diperlukan / Tidak ada)
- Catatan : (Catatan singkat terkait isi dokumen)
---
FORMAT KESIMPULAN:
- List dokumen yang sudah valid: ...
- List dokumen yang perlu pemeriksaan ulang: ...
- List dokumen yang tidak ada/belum lengkap: ...
---
TEMPLATE PESAN PEMBERITAHUAN:
P, dokumen lau masih kurang ....
'''
# Perform content generation using Google Gemini (images passed as files)
response = client.models.generate_content(
model="gemini-1.5-flash",
contents=[prompt] + images # Pass prompt and image files
)
return response.text
def extract_zip_and_collect_files(zip_file_path):
"""
Extract zip file to a temp directory and return list of pdf/image file paths inside.
"""
temp_dir = tempfile.mkdtemp()
with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:
zip_ref.extractall(temp_dir)
# Collect all pdf and image files in extracted folder recursively
collected_files = []
for root, _, files in os.walk(temp_dir):
for f in files:
if f.lower().endswith(('.pdf', '.jpg', '.jpeg', '.png')):
collected_files.append(os.path.join(root, f))
return collected_files
def main_process(files, tanggal_berangkat, tanggal_pulang):
all_images = []
for file in files:
file_path = file.name if hasattr(file, 'name') else file
if file_path.lower().endswith('.zip'):
extracted_files = extract_zip_and_collect_files(file_path)
for extracted_file in extracted_files:
if extracted_file.lower().endswith('.pdf'):
images = process_pdfs([extracted_file])
all_images.extend(images)
elif extracted_file.lower().endswith(('.jpg', '.jpeg', '.png')):
image = Image.open(extracted_file)
all_images.append(image)
elif file_path.lower().endswith('.pdf'):
images = process_pdfs([file_path])
all_images.extend(images)
elif file_path.lower().endswith(('.jpg', '.jpeg', '.png')):
image = Image.open(file_path)
all_images.append(image)
else:
raise ValueError(f"File {file_path} is not a valid image, PDF, or ZIP.")
summary = gemini_analysis(all_images, tanggal_berangkat, tanggal_pulang)
# πŸ“„ Create DOCX with custom filename
doc = Document()
doc.add_heading("Visa Document Check Summary", level=1)
for line in summary.split("\n"):
doc.add_paragraph(line)
# Use first input file name for filename
first_file = files[0]
first_filename = os.path.basename(first_file.name if hasattr(first_file, 'name') else first_file)
base_name = os.path.splitext(first_filename)[0]
docx_filename = f"summary_{base_name}.docx"
temp_docx_path = os.path.join(tempfile.gettempdir(), docx_filename)
doc.save(temp_docx_path)
return summary, temp_docx_path
# Save to DOCX
doc = Document()
doc.add_heading("Visa Document Check Summary", level=1)
for line in summary.split("\n"):
doc.add_paragraph(line)
temp_docx_path = os.path.join(tempfile.gettempdir(), f"summary_{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}.docx")
doc.save(temp_docx_path)
return summary, temp_docx_path
# Gradio UI update: add ".zip" to accepted file types
with gr.Blocks() as demo:
gr.Markdown("## 🧠 Document Analyzer using Gemini AI for Visa Document Checking ✈️ ")
file_input = gr.File(
label="Upload PDFs, Images or ZIP files (Multiple Supported)",
file_types=[".pdf", ".jpg", ".jpeg", ".png", ".zip"],
file_count="multiple"
)
with gr.Row():
tanggal_berangkat = gr.Textbox(
label="Tanggal Keberangkatan",
placeholder="Masukan Tanggal Keberangkatan",
type="text"
)
tanggal_pulang = gr.Textbox(
label="Tanggal Kepulangan",
placeholder="Masukan Tanggal Kepulangan",
type="text"
)
with gr.Row():
run_btn = gr.Button("πŸƒ Run Analysis")
download_output = gr.File(label="πŸ“₯ Download Summary as DOCX", visible=True)
output = gr.Textbox(label="πŸ“ Summary Result", lines=20)
run_btn.click(fn=main_process,
inputs=[file_input, tanggal_berangkat, tanggal_pulang],
outputs=[output, download_output])
demo.launch()