Quick code refactor for major startup speedup when no gui is needed and fixed program exit after file save
This commit is contained in:
parent
7edbf9f200
commit
b7d19123fe
@ -17,25 +17,130 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
import time
|
#import stuff that's needed for both gui and check mode plus tkinter to make inheritance easier (for now)
|
||||||
import sys
|
import sys
|
||||||
import json
|
|
||||||
import tkinter as tk
|
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import json
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import numpy as np
|
|
||||||
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,NavigationToolbar2Tk)
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import tkinter as tk
|
||||||
from time import strftime, localtime
|
|
||||||
from tkinter import messagebox
|
|
||||||
from tkinter import Frame
|
|
||||||
from tkcalendar import Calendar
|
|
||||||
from PIL import Image, ImageTk
|
|
||||||
|
|
||||||
background_color='#DDDDDD'
|
background_color='#DDDDDD'
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: python script.py path_to_image")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
image_path = sys.argv[1]
|
||||||
|
|
||||||
|
import matplotlib.pyplot
|
||||||
|
import numpy
|
||||||
|
import time
|
||||||
|
from tkinter import messagebox
|
||||||
|
from tkinter import Frame
|
||||||
|
from tkcalendar import Calendar
|
||||||
|
from PIL import Image, ImageTk
|
||||||
|
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||||
|
from time import strftime, localtime
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"version": "v0.0-dev",
|
||||||
|
"title": "",
|
||||||
|
"capture_time_start": 0,
|
||||||
|
"capture_time_end": 0,
|
||||||
|
"image_sha512": sha512Checksum(image_path),
|
||||||
|
"description": "",
|
||||||
|
"events" : [{ "time": 1733055790, "text": "Data captured" },
|
||||||
|
{ "time": 1741745288, "text": "Raw file developed"},
|
||||||
|
{ "time": 1747012088, "text": "Metadata written" },
|
||||||
|
{ "time": 1747876088, "text": "Metadata modified" },
|
||||||
|
{ "time": 1759876088, "text": "Metadata version updated" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
def save_and_exit():
|
||||||
|
description_value = description_entry.get("1.0",'end-1c')
|
||||||
|
data["title"] = title.get()
|
||||||
|
data["capture_time_start"] = int(time.mktime(time.strptime(timestamp_start.get(), '%Y-%m-%d %H:%M:%S')))
|
||||||
|
data["capture_time_end"] = int(time.mktime(time.strptime(timestamp_end.get(), '%Y-%m-%d %H:%M:%S')))
|
||||||
|
data["description"] = description_value
|
||||||
|
|
||||||
|
with open("output.json", "w") as f:
|
||||||
|
json.dump(data, f, indent=4)
|
||||||
|
|
||||||
|
root.destroy()
|
||||||
|
|
||||||
|
# GUI setup
|
||||||
|
root = tk.Tk()
|
||||||
|
root.title("Metadata Writer")
|
||||||
|
root.configure(background=background_color)
|
||||||
|
|
||||||
|
# Load and display image
|
||||||
|
img = Image.open(image_path)
|
||||||
|
img.thumbnail((400, 400)) # Resize for display
|
||||||
|
photo = ImageTk.PhotoImage(img)
|
||||||
|
img_label = tk.Label(root, image=photo, bg=background_color, x)
|
||||||
|
|
||||||
|
#Start/end timestamp fields
|
||||||
|
timestamp=Frame(root)
|
||||||
|
timestamp.configure(bg=background_color)
|
||||||
|
start_var = tk.StringVar(value=strftime('%Y-%m-%d %H:%M:%S', localtime(data["capture_time_start"])))
|
||||||
|
end_var = tk.StringVar(value=strftime('%Y-%m-%d %H:%M:%S', localtime(data["capture_time_end"])))
|
||||||
|
timestamp_start = tk.Entry(timestamp,textvariable=start_var)
|
||||||
|
timestamp_end = tk.Entry(timestamp,textvariable=end_var)
|
||||||
|
tk.Label(timestamp, text="Shot time/date start:", bg=background_color).grid(row=0,column=0)
|
||||||
|
tk.Label(timestamp, text="Shot time/date end:",bg=background_color).grid(row=0,column=2)
|
||||||
|
timestamp_start.grid(row=0,column=1)
|
||||||
|
timestamp_end.grid(row=0,column=3)
|
||||||
|
|
||||||
|
#Description field
|
||||||
|
description=Frame(root)
|
||||||
|
tk.Label(description, text="Description:",bg=background_color).pack(side=tk.LEFT)
|
||||||
|
description_entry = TextScrollCombo(description)
|
||||||
|
description_entry.pack()
|
||||||
|
description.configure(bg=background_color)
|
||||||
|
description_entry.config(width=600, height=100)
|
||||||
|
|
||||||
|
#title field
|
||||||
|
title=TitledEntry(root,"Ttile",tk.NORMAL,"")
|
||||||
|
|
||||||
|
#sha512 field
|
||||||
|
sha512sum=TitledEntry(root,"Image SHA512",tk.DISABLED,data["image_sha512"])
|
||||||
|
|
||||||
|
#version field
|
||||||
|
version=TitledEntry(root,"Version",tk.DISABLED,data["version"])
|
||||||
|
|
||||||
|
#timeline field
|
||||||
|
timeline = event_timeline(root,data["events"],matplotlib.pyplot,numpy,FigureCanvasTkAgg)
|
||||||
|
timeline.configure(bg=background_color)
|
||||||
|
|
||||||
|
# Save button
|
||||||
|
save_button = tk.Button(root, text="Save and Exit", command=save_and_exit, bg=background_color)
|
||||||
|
|
||||||
|
#Window layout
|
||||||
|
img_label .grid(row=0,column=0,rowspan=6,sticky='n')
|
||||||
|
title .grid(row=0,column=1,sticky="we")
|
||||||
|
description .grid(row=1,column=1,sticky="we")
|
||||||
|
timestamp .grid(row=2,column=1,sticky="we")
|
||||||
|
sha512sum .grid(row=3,column=1,sticky="we")
|
||||||
|
version .grid(row=4,column=1,sticky="we")
|
||||||
|
save_button .grid(row=5,column=1)
|
||||||
|
timeline .grid(row=6,column=0,columnspan=2)
|
||||||
|
|
||||||
|
root.mainloop()
|
||||||
|
|
||||||
|
|
||||||
|
#Got md5Checksum (sha512Checksum now) from someones blog https://www.joelverhagen.com/blog/2011/02/md5-hash-of-file-in-python/
|
||||||
|
def sha512Checksum(filePath):
|
||||||
|
with open(filePath, 'rb') as fh:
|
||||||
|
m = hashlib.sha512()
|
||||||
|
while True:
|
||||||
|
data = fh.read(8192)
|
||||||
|
if not data:
|
||||||
|
break
|
||||||
|
m.update(data)
|
||||||
|
return m.hexdigest()
|
||||||
|
|
||||||
#Got TextScrollCombo from stack overflow https://stackoverflow.com/questions/13832720/how-to-attach-a-scrollbar-to-a-text-widget
|
#Got TextScrollCombo from stack overflow https://stackoverflow.com/questions/13832720/how-to-attach-a-scrollbar-to-a-text-widget
|
||||||
class TextScrollCombo(tk.Frame):
|
class TextScrollCombo(tk.Frame):
|
||||||
|
|
||||||
@ -62,6 +167,7 @@ class TextScrollCombo(tk.Frame):
|
|||||||
def get(c,a,b):
|
def get(c,a,b):
|
||||||
return c.txt.get(a,b)
|
return c.txt.get(a,b)
|
||||||
|
|
||||||
|
|
||||||
class TitledEntry(tk.Frame):
|
class TitledEntry(tk.Frame):
|
||||||
|
|
||||||
def __init__(self, root_window, text, input_state, init_text):
|
def __init__(self, root_window, text, input_state, init_text):
|
||||||
@ -74,19 +180,8 @@ class TitledEntry(tk.Frame):
|
|||||||
def get(c):
|
def get(c):
|
||||||
return c.title_entry.get()
|
return c.title_entry.get()
|
||||||
|
|
||||||
#Got md5Checksum from someones blog https://www.joelverhagen.com/blog/2011/02/md5-hash-of-file-in-python/
|
|
||||||
def md5Checksum(filePath):
|
|
||||||
with open(filePath, 'rb') as fh:
|
|
||||||
m = hashlib.sha512()
|
|
||||||
while True:
|
|
||||||
data = fh.read(8192)
|
|
||||||
if not data:
|
|
||||||
break
|
|
||||||
m.update(data)
|
|
||||||
return m.hexdigest()
|
|
||||||
|
|
||||||
|
def event_timeline(window,events,plt,np,FigureCanvasTkAgg):
|
||||||
def event_timeline(window,events):
|
|
||||||
plot_line_width=0.8
|
plot_line_width=0.8
|
||||||
|
|
||||||
fig, ax = plt.subplots(figsize=(12, 1.8), constrained_layout=True)
|
fig, ax = plt.subplots(figsize=(12, 1.8), constrained_layout=True)
|
||||||
@ -122,103 +217,9 @@ def event_timeline(window,events):
|
|||||||
|
|
||||||
canvas = FigureCanvasTkAgg(fig, master = window)
|
canvas = FigureCanvasTkAgg(fig, master = window)
|
||||||
canvas.draw()
|
canvas.draw()
|
||||||
|
plt.close()
|
||||||
|
|
||||||
return canvas.get_tk_widget()
|
return canvas.get_tk_widget()
|
||||||
|
|
||||||
|
|
||||||
def main(image_path):
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"version": "v0.0-dev",
|
|
||||||
"title": "",
|
|
||||||
"capture_time_start": 0,
|
|
||||||
"capture_time_end": 0,
|
|
||||||
"image_sha512": md5Checksum(image_path),
|
|
||||||
"description": "",
|
|
||||||
"events" : [{ "time": 1733055790, "text": "Data captured" },
|
|
||||||
{ "time": 1741745288, "text": "Raw file developed"},
|
|
||||||
{ "time": 1747012088, "text": "Metadata written" },
|
|
||||||
{ "time": 1747876088, "text": "Metadata modified" },
|
|
||||||
{ "time": 1759876088, "text": "Metadata version updated" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
def save_and_exit():
|
|
||||||
description_value = description_entry.get("1.0",'end-1c')
|
|
||||||
data["title"] = title.get()
|
|
||||||
data["capture_time_start"] = int(time.mktime(time.strptime(timestamp_start.get(), '%Y-%m-%d %H:%M:%S')))
|
|
||||||
data["capture_time_end"] = int(time.mktime(time.strptime(timestamp_end.get(), '%Y-%m-%d %H:%M:%S')))
|
|
||||||
data["description"] = description_value
|
|
||||||
|
|
||||||
with open("output.json", "w") as f:
|
|
||||||
json.dump(data, f, indent=4)
|
|
||||||
|
|
||||||
root.destroy()
|
|
||||||
|
|
||||||
# GUI setup
|
|
||||||
root = tk.Tk()
|
|
||||||
root.title("Metadata Writer")
|
|
||||||
root.configure(background=background_color)
|
|
||||||
|
|
||||||
# Load and display image
|
|
||||||
img = Image.open(image_path)
|
|
||||||
img.thumbnail((400, 400)) # Resize for display
|
|
||||||
photo = ImageTk.PhotoImage(img)
|
|
||||||
|
|
||||||
img_label = tk.Label(root, image=photo, bg=background_color)
|
|
||||||
img_label.image = photo # keep a reference
|
|
||||||
|
|
||||||
|
|
||||||
time_start=1347517370
|
|
||||||
time_end=1547517370
|
|
||||||
|
|
||||||
timestamp=Frame(root)
|
|
||||||
timestamp.configure(bg=background_color)
|
|
||||||
start_var = tk.StringVar(value=strftime('%Y-%m-%d %H:%M:%S', localtime(time_start)))
|
|
||||||
end_var = tk.StringVar(value=strftime('%Y-%m-%d %H:%M:%S', localtime(time_end)))
|
|
||||||
timestamp_start = tk.Entry(timestamp,textvariable=start_var)
|
|
||||||
timestamp_end = tk.Entry(timestamp,textvariable=end_var)
|
|
||||||
tk.Label(timestamp, text="Shot time/date start:", bg=background_color).grid(row=0,column=0)
|
|
||||||
tk.Label(timestamp, text="Shot time/date end:",bg=background_color).grid(row=0,column=2)
|
|
||||||
timestamp_start.grid(row=0,column=1)
|
|
||||||
timestamp_end.grid(row=0,column=3)
|
|
||||||
|
|
||||||
# Input fields
|
|
||||||
|
|
||||||
description=Frame(root)
|
|
||||||
tk.Label(description, text="Description:",bg=background_color).pack(side=tk.LEFT)
|
|
||||||
description_entry = TextScrollCombo(description)
|
|
||||||
description_entry.pack()
|
|
||||||
description.configure(bg=background_color)
|
|
||||||
|
|
||||||
description_entry.config(width=600, height=100)
|
|
||||||
|
|
||||||
title=TitledEntry(root,"Ttile",tk.NORMAL,"")
|
|
||||||
sha512sum=TitledEntry(root,"Image SHA512",tk.DISABLED,data["image_sha512"])
|
|
||||||
version=TitledEntry(root,"Version",tk.DISABLED,data["version"])
|
|
||||||
|
|
||||||
timeline = event_timeline(root,data["events"])
|
|
||||||
timeline.configure(bg=background_color)
|
|
||||||
|
|
||||||
# Save button
|
|
||||||
save_button = tk.Button(root, text="Save and Exit", command=save_and_exit, bg=background_color)
|
|
||||||
|
|
||||||
img_label .grid(row=0,column=0,rowspan=6,sticky='n')
|
|
||||||
title .grid(row=0,column=1,sticky="we")
|
|
||||||
description .grid(row=1,column=1,sticky="we")
|
|
||||||
timestamp .grid(row=2,column=1,sticky="we")
|
|
||||||
sha512sum .grid(row=3,column=1,sticky="we")
|
|
||||||
version .grid(row=4,column=1,sticky="we")
|
|
||||||
save_button .grid(row=5,column=1)
|
|
||||||
timeline .grid(row=6,column=0,columnspan=2)
|
|
||||||
|
|
||||||
|
|
||||||
root.mainloop()
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) < 2:
|
main()
|
||||||
print("Usage: python script.py path_to_image")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
image_path = sys.argv[1]
|
|
||||||
main(image_path)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user