Skip to content

Commit 6b41cfb

Browse files
committed
more fixes
1 parent 7508631 commit 6b41cfb

File tree

3 files changed

+285
-243
lines changed

3 files changed

+285
-243
lines changed

src/exiftoolgui/__main__.py

Lines changed: 1 addition & 223 deletions
Original file line numberDiff line numberDiff line change
@@ -1,226 +1,4 @@
1-
import os
2-
import subprocess
3-
import tkinter as tk
4-
from tkinter import filedialog, messagebox, scrolledtext, ttk
5-
import json
6-
7-
class ExifToolGUI:
8-
def __init__(self, master=None, string_var_class=None):
9-
self.master = master if master else tk.Tk()
10-
self.master.title("ExifTool GUI")
11-
self.master.geometry("900x600")
12-
self.StringVar = string_var_class if string_var_class else tk.StringVar
13-
14-
self.create_widgets()
15-
self.current_file = None
16-
self.batch_directory = None
17-
18-
def create_widgets(self):
19-
self.master.columnconfigure(0, weight=1)
20-
self.master.rowconfigure(0, weight=1)
21-
22-
# Create notebook for tabs
23-
self.notebook = ttk.Notebook(self.master)
24-
self.notebook.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
25-
26-
# View tab
27-
self.view_frame = ttk.Frame(self.notebook)
28-
self.notebook.add(self.view_frame, text="View EXIF")
29-
self.create_view_tab()
30-
31-
# Edit tab
32-
self.edit_frame = ttk.Frame(self.notebook)
33-
self.notebook.add(self.edit_frame, text="Edit EXIF")
34-
self.create_edit_tab()
35-
36-
# Remove tab
37-
self.remove_frame = ttk.Frame(self.notebook)
38-
self.notebook.add(self.remove_frame, text="Remove EXIF")
39-
self.create_remove_tab()
40-
41-
# Batch tab
42-
self.batch_frame = ttk.Frame(self.notebook)
43-
self.notebook.add(self.batch_frame, text="Batch Process")
44-
self.create_batch_tab()
45-
46-
def create_view_tab(self):
47-
self.view_frame.columnconfigure(0, weight=1)
48-
self.view_frame.rowconfigure(1, weight=1)
49-
50-
ttk.Button(self.view_frame, text="Browse Image", command=self.browse_file).grid(
51-
row=0, column=0, pady=10
52-
)
53-
self.view_text = scrolledtext.ScrolledText(
54-
self.view_frame, wrap=tk.WORD, width=80, height=30
55-
)
56-
self.view_text.grid(row=1, column=0, padx=10, pady=10, sticky="nsew")
57-
58-
def create_edit_tab(self):
59-
self.edit_frame.columnconfigure(1, weight=1)
60-
61-
ttk.Button(
62-
self.edit_frame, text="Select Image", command=self.select_image_for_edit
63-
).grid(row=0, column=0, columnspan=2, pady=10)
64-
ttk.Label(self.edit_frame, text="Tag:").grid(
65-
row=1, column=0, padx=5, pady=5, sticky="e"
66-
)
67-
self.tag_entry = ttk.Entry(self.edit_frame)
68-
self.tag_entry.grid(row=1, column=1, padx=5, pady=5, sticky="ew")
69-
ttk.Label(self.edit_frame, text="Value:").grid(
70-
row=2, column=0, padx=5, pady=5, sticky="e"
71-
)
72-
self.value_entry = ttk.Entry(self.edit_frame)
73-
self.value_entry.grid(row=2, column=1, padx=5, pady=5, sticky="ew")
74-
ttk.Button(self.edit_frame, text="Apply Edit", command=self.apply_edit).grid(
75-
row=3, column=1, pady=10
76-
)
77-
78-
def create_remove_tab(self):
79-
ttk.Button(
80-
self.remove_frame, text="Select Image", command=self.select_image_for_remove
81-
).grid(row=0, column=0, pady=10)
82-
ttk.Button(
83-
self.remove_frame, text="Remove All EXIF Data", command=self.remove_all_exif
84-
).grid(row=1, column=0, pady=10)
85-
86-
def create_batch_tab(self):
87-
self.batch_frame.columnconfigure(0, weight=1)
88-
self.batch_frame.rowconfigure(4, weight=1)
89-
90-
ttk.Button(
91-
self.batch_frame, text="Select Directory", command=self.select_directory
92-
).grid(row=0, column=0, pady=10)
93-
self.batch_operation = tk.StringVar()
94-
ttk.Radiobutton(
95-
self.batch_frame,
96-
text="View EXIF",
97-
variable=self.batch_operation,
98-
value="view",
99-
).grid(row=1, column=0)
100-
ttk.Radiobutton(
101-
self.batch_frame,
102-
text="Remove EXIF",
103-
variable=self.batch_operation,
104-
value="remove",
105-
).grid(row=2, column=0)
106-
ttk.Button(self.batch_frame, text="Process", command=self.batch_process).grid(
107-
row=3, column=0, pady=10
108-
)
109-
self.batch_text = scrolledtext.ScrolledText(
110-
self.batch_frame, wrap=tk.WORD, width=80, height=20
111-
)
112-
self.batch_text.grid(row=4, column=0, padx=10, pady=10, sticky="nsew")
113-
114-
def run_exiftool(self, args):
115-
try:
116-
result = subprocess.run(
117-
["exiftool"] + args, capture_output=True, text=True, check=True
118-
)
119-
return result.stdout
120-
except subprocess.CalledProcessError as e:
121-
return f"Error: {e.stderr}"
122-
except FileNotFoundError:
123-
return "Error: ExifTool not found. Please make sure it's installed and in your PATH."
124-
125-
def pretty_print_json(self, text):
126-
lines = text.split("\n")
127-
pretty_lines = []
128-
for line in lines:
129-
if ":" in line:
130-
tag, value = line.split(":", 1)
131-
value = value.strip()
132-
try:
133-
# Try to parse the value as JSON
134-
json_data = json.loads(value)
135-
# If successful, pretty print the JSON
136-
pretty_json = json.dumps(json_data, indent=2)
137-
pretty_lines.append(f"{tag}:\n{pretty_json}")
138-
except json.JSONDecodeError:
139-
# If it's not valid JSON, keep the original line
140-
pretty_lines.append(line)
141-
else:
142-
pretty_lines.append(line)
143-
return "\n".join(pretty_lines)
144-
145-
def browse_file(self):
146-
file_path = filedialog.askopenfilename(
147-
filetypes=[("Image files", "*.jpg *.jpeg *.png *.gif *.bmp *.tiff")]
148-
)
149-
if file_path:
150-
self.current_file = file_path
151-
exif_data = self.run_exiftool([file_path])
152-
pretty_exif_data = self.pretty_print_json(exif_data)
153-
self.view_text.delete(1.0, tk.END)
154-
self.view_text.insert(tk.END, pretty_exif_data)
155-
156-
def select_image_for_edit(self):
157-
self.current_file = filedialog.askopenfilename(
158-
filetypes=[("Image files", "*.jpg *.jpeg *.png *.gif *.bmp *.tiff")]
159-
)
160-
161-
def apply_edit(self):
162-
if not self.current_file:
163-
messagebox.showerror("Error", "No image selected")
164-
return
165-
tag = self.tag_entry.get()
166-
value = self.value_entry.get()
167-
if not tag or not value:
168-
messagebox.showerror("Error", "Both tag and value must be provided")
169-
return
170-
result = self.run_exiftool([f"-{tag}={value}", self.current_file])
171-
messagebox.showinfo("Result", result)
172-
173-
def select_image_for_remove(self):
174-
self.current_file = filedialog.askopenfilename(
175-
filetypes=[("Image files", "*.jpg *.jpeg *.png *.gif *.bmp *.tiff")]
176-
)
177-
178-
def remove_all_exif(self):
179-
if not self.current_file:
180-
messagebox.showerror("Error", "No image selected")
181-
return
182-
result = self.run_exiftool(["-all=", "-overwrite_original", self.current_file])
183-
messagebox.showinfo("Result", result)
184-
185-
def select_directory(self):
186-
self.batch_directory = filedialog.askdirectory()
187-
188-
def batch_process(self):
189-
if not self.batch_directory:
190-
messagebox.showerror("Error", "No directory selected")
191-
return
192-
193-
operation = self.batch_operation.get()
194-
if operation == "view":
195-
result = self.run_exiftool(['-recurse', self.batch_directory])
196-
result = self.pretty_print_json(result)
197-
elif operation == "remove":
198-
result = self.run_exiftool(['-all=', '-overwrite_original', '-recurse', self.batch_directory])
199-
else:
200-
result = "Please select an operation"
201-
self.batch_text.delete(1.0, tk.END)
202-
self.batch_text.insert(tk.END, result)
203-
204-
def create_batch_tab(self):
205-
self.batch_frame.columnconfigure(0, weight=1)
206-
self.batch_frame.rowconfigure(4, weight=1)
207-
208-
ttk.Button(self.batch_frame, text="Select Directory", command=self.select_directory).grid(row=0, column=0, pady=10)
209-
self.batch_operation = self.StringVar()
210-
ttk.Radiobutton(self.batch_frame, text="View EXIF", variable=self.batch_operation, value="view").grid(row=1, column=0)
211-
ttk.Radiobutton(self.batch_frame, text="Remove EXIF", variable=self.batch_operation, value="remove").grid(row=2, column=0)
212-
ttk.Button(self.batch_frame, text="Process", command=self.batch_process).grid(row=3, column=0, pady=10)
213-
self.batch_text = scrolledtext.ScrolledText(self.batch_frame, wrap=tk.WORD, width=80, height=20)
214-
self.batch_text.grid(row=4, column=0, padx=10, pady=10, sticky='nsew')
215-
216-
def run(self):
217-
self.master.mainloop()
218-
219-
@classmethod
220-
def main(cls):
221-
root = tk.Tk()
222-
app = cls(root)
223-
app.run()
1+
from exiftoolgui.exiftoolgui import ExifToolGUI
2242

2253
if __name__ == "__main__":
2264
ExifToolGUI.main()

0 commit comments

Comments
 (0)