gfathertech commited on
Commit
e906004
ยท
verified ยท
1 Parent(s): 6f369d6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -20
app.py CHANGED
@@ -10,15 +10,44 @@ import gradio as gr
10
  from PIL import Image
11
  import pytesseract
12
  from pdf2image import convert_from_path
 
13
 
14
  app = FastAPI(title="Free MarkItDown Service")
15
  md = MarkItDown()
16
 
17
  IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".webp"}
 
18
  LEGACY_OFFICE_EXTENSIONS = {".doc", ".xls", ".ppt", ".rtf"}
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  def run_free_ocr(file_path: str) -> str:
21
- """Fallback OCR pipeline using Tesseract."""
22
  file_ext = os.path.splitext(file_path)[1].lower()
23
 
24
  if file_ext in IMAGE_EXTENSIONS:
@@ -55,7 +84,7 @@ def process_input(source_path_or_url: str, original_filename: str = None) -> str
55
 
56
  target = source_path_or_url.strip()
57
 
58
- # If HTTP/HTTPS URL
59
  if target.startswith("http://") or target.startswith("https://"):
60
  try:
61
  res = md.convert(target)
@@ -63,10 +92,8 @@ def process_input(source_path_or_url: str, original_filename: str = None) -> str
63
  except Exception as e:
64
  return f"URL Conversion Error: {str(e)}"
65
 
66
- # 1. Detect extension from the original filename (e.g., 'document.doc')
67
  ext = os.path.splitext(original_filename or target)[1].lower()
68
 
69
- # 2. FORCE the temp file on disk to have the real extension so MarkItDown knows what it is!
70
  working_path = target
71
  temp_with_ext = None
72
  if ext and not target.lower().endswith(ext):
@@ -77,40 +104,43 @@ def process_input(source_path_or_url: str, original_filename: str = None) -> str
77
  temp_converted_office = None
78
 
79
  try:
80
- # Route Images directly to Tesseract
 
 
 
 
81
  if ext in IMAGE_EXTENSIONS:
82
  return run_free_ocr(working_path)
83
 
84
- # Route Legacy Office files (.doc) to LibreOffice first
85
  if ext in LEGACY_OFFICE_EXTENSIONS:
86
  temp_converted_office = convert_legacy_office_file(working_path, ext)
87
  working_path = temp_converted_office
88
 
89
- # Standard MarkItDown extraction
90
  result = md.convert(working_path)
91
  text_content = result.text_content if result else ""
92
 
93
- # Fallback to Tesseract if extraction yielded blank text
94
- if not text_content.strip():
95
  text_content = run_free_ocr(working_path)
96
 
97
  return text_content if text_content.strip() else "Unable to extract text from document."
98
 
99
  except Exception as e:
100
- print(f"MarkItDown failed on '{working_path}'. Executing Tesseract OCR fallback...")
101
- try:
102
- ocr_text = run_free_ocr(working_path)
103
- if ocr_text and ocr_text.strip():
104
- return ocr_text
105
- except Exception:
106
- pass
 
107
 
108
  print("--- CONVERSION ERROR ---")
109
  traceback.print_exc()
110
  return f"Conversion Error: File type '{ext}' could not be processed."
111
 
112
  finally:
113
- # Cleanup temporary files
114
  if temp_with_ext and os.path.exists(temp_with_ext):
115
  os.remove(temp_with_ext)
116
  if temp_converted_office and os.path.exists(temp_converted_office):
@@ -149,7 +179,6 @@ async def convert_file_api(file: UploadFile = None, url: str = None):
149
  # -------------------------------------------------------------
150
  def gradio_handler(file_obj, url_input):
151
  if file_obj is not None:
152
- # Extract the real filename (e.g. "my_doc.pdf" instead of "/tmp/gradio/xyz123")
153
  orig_name = getattr(file_obj, "orig_name", file_obj.name)
154
  return process_input(file_obj.name, original_filename=orig_name)
155
  elif url_input and url_input.strip():
@@ -157,11 +186,11 @@ def gradio_handler(file_obj, url_input):
157
  return "Please upload a document or enter a valid URL."
158
 
159
  with gr.Blocks(title="Free MarkItDown Tester") as demo:
160
- gr.Markdown("# ๐Ÿ“„ Free Document & URL Converter")
161
 
162
  with gr.Row():
163
  with gr.Column():
164
- file_input = gr.File(label="Upload File")
165
  url_input = gr.Textbox(label="Or enter URL", placeholder="https://example.com/document.pdf")
166
  submit_btn = gr.Button("Convert to Markdown", variant="primary")
167
 
 
10
  from PIL import Image
11
  import pytesseract
12
  from pdf2image import convert_from_path
13
+ import speech_recognition as sr
14
 
15
  app = FastAPI(title="Free MarkItDown Service")
16
  md = MarkItDown()
17
 
18
  IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".bmp", ".tiff", ".webp"}
19
+ AUDIO_EXTENSIONS = {".mp3", ".wav", ".m4a", ".ogg", ".flac"}
20
  LEGACY_OFFICE_EXTENSIONS = {".doc", ".xls", ".ppt", ".rtf"}
21
 
22
+ def process_audio_file(file_path: str) -> str:
23
+ """Transcribes audio files locally using speech_recognition and ffmpeg."""
24
+ file_ext = os.path.splitext(file_path)[1].lower()
25
+ wav_path = file_path
26
+
27
+ # Convert non-WAV audio formats to WAV using ffmpeg
28
+ if file_ext != ".wav":
29
+ wav_path = f"/tmp/{uuid4()}.wav"
30
+ subprocess.run(
31
+ ["ffmpeg", "-y", "-i", file_path, "-ac", "1", "-ar", "16000", wav_path],
32
+ check=True,
33
+ stdout=subprocess.DEVNULL,
34
+ stderr=subprocess.DEVNULL
35
+ )
36
+
37
+ recognizer = sr.Recognizer()
38
+ try:
39
+ with sr.AudioFile(wav_path) as source:
40
+ audio_data = recognizer.record(source)
41
+ text = recognizer.recognize_sphinx(audio_data)
42
+ return f"## Audio Transcription\n\n{text}" if text.strip() else "Audio processed, but no speech was detected."
43
+ except Exception as e:
44
+ return f"Audio Transcription Error: {str(e)}"
45
+ finally:
46
+ if wav_path != file_path and os.path.exists(wav_path):
47
+ os.remove(wav_path)
48
+
49
  def run_free_ocr(file_path: str) -> str:
50
+ """Fallback OCR pipeline using Tesseract (images and PDFs only)."""
51
  file_ext = os.path.splitext(file_path)[1].lower()
52
 
53
  if file_ext in IMAGE_EXTENSIONS:
 
84
 
85
  target = source_path_or_url.strip()
86
 
87
+ # Route URLs
88
  if target.startswith("http://") or target.startswith("https://"):
89
  try:
90
  res = md.convert(target)
 
92
  except Exception as e:
93
  return f"URL Conversion Error: {str(e)}"
94
 
 
95
  ext = os.path.splitext(original_filename or target)[1].lower()
96
 
 
97
  working_path = target
98
  temp_with_ext = None
99
  if ext and not target.lower().endswith(ext):
 
104
  temp_converted_office = None
105
 
106
  try:
107
+ # Route 1: Audio files -> Local Speech Recognition
108
+ if ext in AUDIO_EXTENSIONS:
109
+ return process_audio_file(working_path)
110
+
111
+ # Route 2: Images -> Tesseract OCR
112
  if ext in IMAGE_EXTENSIONS:
113
  return run_free_ocr(working_path)
114
 
115
+ # Route 3: Legacy Office (.doc, .xls) -> LibreOffice
116
  if ext in LEGACY_OFFICE_EXTENSIONS:
117
  temp_converted_office = convert_legacy_office_file(working_path, ext)
118
  working_path = temp_converted_office
119
 
120
+ # Route 4: Standard MarkItDown extraction (PDFs, DOCX, XLSX, PPTX, HTML, TXT)
121
  result = md.convert(working_path)
122
  text_content = result.text_content if result else ""
123
 
124
+ if not text_content.strip() and ext in {".pdf"}:
 
125
  text_content = run_free_ocr(working_path)
126
 
127
  return text_content if text_content.strip() else "Unable to extract text from document."
128
 
129
  except Exception as e:
130
+ # OCR fallback ONLY for documents/images, never audio
131
+ if ext in IMAGE_EXTENSIONS or ext == ".pdf":
132
+ try:
133
+ ocr_text = run_free_ocr(working_path)
134
+ if ocr_text and ocr_text.strip():
135
+ return ocr_text
136
+ except Exception:
137
+ pass
138
 
139
  print("--- CONVERSION ERROR ---")
140
  traceback.print_exc()
141
  return f"Conversion Error: File type '{ext}' could not be processed."
142
 
143
  finally:
 
144
  if temp_with_ext and os.path.exists(temp_with_ext):
145
  os.remove(temp_with_ext)
146
  if temp_converted_office and os.path.exists(temp_converted_office):
 
179
  # -------------------------------------------------------------
180
  def gradio_handler(file_obj, url_input):
181
  if file_obj is not None:
 
182
  orig_name = getattr(file_obj, "orig_name", file_obj.name)
183
  return process_input(file_obj.name, original_filename=orig_name)
184
  elif url_input and url_input.strip():
 
186
  return "Please upload a document or enter a valid URL."
187
 
188
  with gr.Blocks(title="Free MarkItDown Tester") as demo:
189
+ gr.Markdown("# ๐Ÿ“„ Free Document & Audio Converter")
190
 
191
  with gr.Row():
192
  with gr.Column():
193
+ file_input = gr.File(label="Upload File (.pdf, .doc, .mp3, .png, etc.)")
194
  url_input = gr.Textbox(label="Or enter URL", placeholder="https://example.com/document.pdf")
195
  submit_btn = gr.Button("Convert to Markdown", variant="primary")
196