launch-calcium commited on
Commit
db5570b
ยท
verified ยท
1 Parent(s): 4956627

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. __pycache__/app.cpython-312.pyc +0 -0
  2. app.py +255 -0
  3. requirements.txt +3 -0
__pycache__/app.cpython-312.pyc ADDED
Binary file (13.4 kB). View file
 
app.py ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sqlite3
3
+ import io
4
+ import pandas as pd
5
+ from PIL import Image
6
+ import gradio as gr
7
+
8
+ def connect_db(db_file):
9
+ if not db_file:
10
+ return None
11
+ db_path = db_file.name if hasattr(db_file, "name") else str(db_file)
12
+ if not os.path.exists(db_path):
13
+ return None
14
+ return db_path
15
+
16
+ def get_all_records(db_path):
17
+ if not db_path or not os.path.exists(db_path):
18
+ return pd.DataFrame(), "No database loaded or file does not exist."
19
+
20
+ try:
21
+ conn = sqlite3.connect(db_path)
22
+ cursor = conn.cursor()
23
+ cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='files';")
24
+ if not cursor.fetchone():
25
+ conn.close()
26
+ return pd.DataFrame(), "Table 'files' not found in database."
27
+
28
+ query = """
29
+ SELECT id, filename, file_type, file_size_bytes, upload_timestamp, is_large_file,
30
+ CASE WHEN file_content_blob IS NOT NULL THEN 'BLOB Present' ELSE 'None' END as blob_status,
31
+ COALESCE(relative_path, 'N/A') as relative_path
32
+ FROM files
33
+ ORDER BY id ASC
34
+ """
35
+ df = pd.read_sql_query(query, conn)
36
+ conn.close()
37
+ return df, f"Loaded {len(df)} record(s) from database."
38
+ except Exception as e:
39
+ return pd.DataFrame(), f"Error reading database: {str(e)}"
40
+
41
+ def extract_file_content(row, db_dir):
42
+ """
43
+ Extract content (bytes or text) from a DB record tuple/dict.
44
+ row: (id, filename, file_type, file_size_bytes, upload_timestamp, is_large_file, file_content_blob, relative_path)
45
+ """
46
+ filename = row['filename']
47
+ blob = row['file_content_blob']
48
+ rel_path = row['relative_path']
49
+
50
+ # 1. Check BLOB content
51
+ if blob is not None:
52
+ return blob, filename
53
+
54
+ # 2. Check relative_path or upload_dir fallback
55
+ paths_to_check = []
56
+ if rel_path:
57
+ paths_to_check.append(rel_path)
58
+ if db_dir:
59
+ paths_to_check.append(os.path.join(db_dir, rel_path))
60
+ paths_to_check.append(os.path.join(db_dir, os.path.basename(rel_path)))
61
+
62
+ if db_dir:
63
+ paths_to_check.append(os.path.join(db_dir, "uploads", filename))
64
+ paths_to_check.append(os.path.join(db_dir, filename))
65
+
66
+ for path in paths_to_check:
67
+ if path and os.path.exists(path) and os.path.isfile(path):
68
+ try:
69
+ with open(path, "rb") as f:
70
+ return f.read(), filename
71
+ except Exception:
72
+ pass
73
+
74
+ return None, filename
75
+
76
+ def is_image_file(filename, file_type=""):
77
+ ext = os.path.splitext(filename)[1].lower()
78
+ if ext in ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg']:
79
+ return True
80
+ if file_type and file_type.startswith('image/'):
81
+ return True
82
+ return False
83
+
84
+ def is_text_file(filename, file_type=""):
85
+ ext = os.path.splitext(filename)[1].lower()
86
+ if ext in ['.txt', '.log', '.md', '.csv', '.json', '.yaml', '.yml']:
87
+ return True
88
+ if file_type and file_type.startswith('text/'):
89
+ return True
90
+ return False
91
+
92
+ def load_gallery_and_texts(db_file):
93
+ db_path = connect_db(db_file)
94
+ if not db_path:
95
+ return [], [], "Please upload a valid SQLite database file (.db)."
96
+
97
+ db_dir = os.path.dirname(db_path)
98
+
99
+ try:
100
+ conn = sqlite3.connect(db_path)
101
+ conn.row_factory = sqlite3.Row
102
+ cursor = conn.cursor()
103
+ cursor.execute("SELECT * FROM files ORDER BY id ASC")
104
+ rows = cursor.fetchall()
105
+ conn.close()
106
+ except Exception as e:
107
+ return [], [], f"Failed to load records from DB: {str(e)}"
108
+
109
+ gallery_images = []
110
+ text_previews = []
111
+
112
+ for row in rows:
113
+ filename = row['filename']
114
+ file_type = row['file_type'] or ""
115
+ content_bytes, _ = extract_file_content(row, db_dir)
116
+
117
+ if content_bytes is None:
118
+ continue
119
+
120
+ if is_image_file(filename, file_type):
121
+ try:
122
+ img = Image.open(io.BytesIO(content_bytes))
123
+ gallery_images.append((img, filename))
124
+ except Exception:
125
+ pass
126
+
127
+ if is_text_file(filename, file_type):
128
+ try:
129
+ text_str = content_bytes.decode('utf-8', errors='replace')
130
+ text_previews.append(f"=== {filename} ===\n{text_str}")
131
+ except Exception:
132
+ pass
133
+
134
+ joined_texts = "\n\n".join(text_previews) if text_previews else "No text (.txt) files found in DB."
135
+ status_msg = f"Loaded {len(gallery_images)} image(s) and {len(text_previews)} text file(s)."
136
+ return gallery_images, joined_texts, status_msg
137
+
138
+ def search_samename(db_file, search_query):
139
+ db_path = connect_db(db_file)
140
+ if not db_path:
141
+ return [], "Please upload a database file first.", "No database loaded."
142
+
143
+ if not search_query or not search_query.strip():
144
+ return [], "Please enter a search query.", "Empty query."
145
+
146
+ query_str = search_query.strip()
147
+ target_basename = os.path.splitext(query_str)[0].strip().lower()
148
+
149
+ db_dir = os.path.dirname(db_path)
150
+
151
+ try:
152
+ conn = sqlite3.connect(db_path)
153
+ conn.row_factory = sqlite3.Row
154
+ cursor = conn.cursor()
155
+ cursor.execute("SELECT * FROM files")
156
+ rows = cursor.fetchall()
157
+ conn.close()
158
+ except Exception as e:
159
+ return [], f"Database query error: {str(e)}", "Error querying DB."
160
+
161
+ matched_txt_contents = []
162
+ matched_images = []
163
+
164
+ for row in rows:
165
+ filename = row['filename']
166
+ file_type = row['file_type'] or ""
167
+ base, ext = os.path.splitext(filename)
168
+ base_lower = base.lower()
169
+
170
+ # Check if basename matches search target, or full filename matches
171
+ if base_lower == target_basename or filename.lower() == query_str.lower():
172
+ content_bytes, _ = extract_file_content(row, db_dir)
173
+ if content_bytes is None:
174
+ continue
175
+
176
+ if is_text_file(filename, file_type):
177
+ try:
178
+ text_str = content_bytes.decode('utf-8', errors='replace')
179
+ matched_txt_contents.append(f"๐Ÿ“„ [{filename}]\n{text_str}")
180
+ except Exception:
181
+ pass
182
+
183
+ if is_image_file(filename, file_type):
184
+ try:
185
+ img = Image.open(io.BytesIO(content_bytes))
186
+ matched_images.append((img, filename))
187
+ except Exception:
188
+ pass
189
+
190
+ txt_output = "\n\n".join(matched_txt_contents) if matched_txt_contents else f"No .txt content matched for basename '{target_basename}'."
191
+ status_output = f"Search for '{search_query}' finished. Found {len(matched_images)} image(s) and {len(matched_txt_contents)} text file(s)."
192
+
193
+ return matched_images, txt_output, status_output
194
+
195
+ def refresh_all(db_file):
196
+ df, table_status = get_all_records(connect_db(db_file))
197
+ images, texts, gallery_status = load_gallery_and_texts(db_file)
198
+ return images, texts, df, f"{table_status} | {gallery_status}"
199
+
200
+ # Gradio Interface
201
+ with gr.Blocks(title="Image Gallery & SQL Viewer") as demo:
202
+ gr.Markdown("# ๐Ÿ–ผ๏ธ Image Gallery & SQLite Database Viewer")
203
+ gr.Markdown("Upload a SQLite database file (`.db` generated by SQLite Maker) to inspect records, view images/texts, and search samename files.")
204
+
205
+ with gr.Row():
206
+ db_file_input = gr.File(label="Upload SQLite Database (.db)", file_types=[".db", ".sqlite", ".sqlite3"])
207
+ load_btn = gr.Button("Load Database", variant="primary")
208
+
209
+ status_box = gr.Textbox(label="Status", interactive=False)
210
+
211
+ with gr.Tabs():
212
+ with gr.Tab("๐Ÿ–ผ๏ธ Image Gallery & Text Viewer"):
213
+ gallery_display = gr.Gallery(label="Loaded Images", columns=4, height="auto")
214
+ text_viewer = gr.TextArea(label="Text Files (.txt) Content", lines=12, interactive=False)
215
+
216
+ with gr.Tab("๐Ÿ” Samename Search"):
217
+ gr.Markdown("Type a filename or basename (e.g., `image1` or `image1.txt`) to find the corresponding `.txt` text and same-basename image `samename.(png/jpg/etc)`.")
218
+ with gr.Row():
219
+ search_input = gr.Textbox(label="Search Query (e.g. sample.txt or sample)", placeholder="Enter text filename or basename...")
220
+ search_btn = gr.Button("Search Samename", variant="primary")
221
+
222
+ search_status = gr.Textbox(label="Search Status", interactive=False)
223
+ search_text_output = gr.TextArea(label="Matched .txt File Content", lines=8, interactive=False)
224
+ search_gallery_output = gr.Gallery(label="Matched Samename Image(s)", columns=4, height="auto")
225
+
226
+ with gr.Tab("๐Ÿ“Š Database Records"):
227
+ records_table = gr.Dataframe(label="Files Table Records", interactive=False, wrap=True)
228
+
229
+ # Event handlers
230
+ load_btn.click(
231
+ fn=refresh_all,
232
+ inputs=[db_file_input],
233
+ outputs=[gallery_display, text_viewer, records_table, status_box]
234
+ )
235
+
236
+ db_file_input.change(
237
+ fn=refresh_all,
238
+ inputs=[db_file_input],
239
+ outputs=[gallery_display, text_viewer, records_table, status_box]
240
+ )
241
+
242
+ search_btn.click(
243
+ fn=search_samename,
244
+ inputs=[db_file_input, search_input],
245
+ outputs=[search_gallery_output, search_text_output, search_status]
246
+ )
247
+
248
+ search_input.submit(
249
+ fn=search_samename,
250
+ inputs=[db_file_input, search_input],
251
+ outputs=[search_gallery_output, search_text_output, search_status]
252
+ )
253
+
254
+ if __name__ == "__main__":
255
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ pillow
3
+ pandas